From 6103f39c0d79e86b58ae9437bc4c55a513a5e1dd Mon Sep 17 00:00:00 2001 From: Nikolay Morozov Date: Fri, 14 Feb 2020 13:14:30 +0300 Subject: [PATCH] x509v3 subjectSignTool extention support Subject Sign Tool (1.2.643.100.111) The name of the tool used to signs the subject (UTF8String) This extention is required to obtain the status of a qualified certificate at Russian Federation. RFC-style description is available here: https://tools.ietf.org/html/draft-deremin-rfc4491-bis-04#section-5 Russian Federal Law 63 "Digital Sign" is available here: http://www.consultant.ru/document/cons_doc_LAW_112701/ Reviewed-by: Matt Caswell Reviewed-by: Dmitry Belyavskiy (Merged from https://github.com/openssl/openssl/pull/11093) --- crypto/err/openssl.txt | 2 + crypto/x509/build.info | 2 +- crypto/x509/ext_dat.h | 3 +- crypto/x509/standard_exts.h | 3 +- crypto/x509/v3_utf8.c | 68 +++++++++++++++++++ doc/internal/man3/s2i_ASN1_UTF8STRING.pod | 45 +++++++++++++ doc/man3/s2i_ASN1_IA5STRING.pod | 82 +++++++++++++++++++++++ include/crypto/x509v3.h | 23 +++++++ include/openssl/x509v3err.h | 4 +- util/missingcrypto.txt | 8 --- 10 files changed, 228 insertions(+), 12 deletions(-) create mode 100644 crypto/x509/v3_utf8.c create mode 100644 doc/internal/man3/s2i_ASN1_UTF8STRING.pod create mode 100644 doc/man3/s2i_ASN1_IA5STRING.pod create mode 100644 include/crypto/x509v3.h diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt index 04775f55ac..0a37d5af23 100644 --- a/crypto/err/openssl.txt +++ b/crypto/err/openssl.txt @@ -1768,6 +1768,7 @@ X509V3_F_GNAMES_FROM_SECTNAME:156:gnames_from_sectname X509V3_F_I2S_ASN1_ENUMERATED:121:i2s_ASN1_ENUMERATED X509V3_F_I2S_ASN1_IA5STRING:149:i2s_ASN1_IA5STRING X509V3_F_I2S_ASN1_INTEGER:120:i2s_ASN1_INTEGER +X509V3_F_I2S_ASN1_UTF8STRING:173: X509V3_F_I2V_AUTHORITY_INFO_ACCESS:138:i2v_AUTHORITY_INFO_ACCESS X509V3_F_LEVEL_ADD_NODE:168:level_add_node X509V3_F_NOTICE_SECTION:132:notice_section @@ -1782,6 +1783,7 @@ X509V3_F_R2I_PCI:155:r2i_pci X509V3_F_S2I_ASN1_IA5STRING:100:s2i_ASN1_IA5STRING X509V3_F_S2I_ASN1_INTEGER:108:s2i_ASN1_INTEGER X509V3_F_S2I_ASN1_OCTET_STRING:112:s2i_ASN1_OCTET_STRING +X509V3_F_S2I_ASN1_UTF8STRING:174: X509V3_F_S2I_SKEY_ID:115:s2i_skey_id X509V3_F_SET_DIST_POINT_NAME:158:set_dist_point_name X509V3_F_SXNET_ADD_ID_ASC:125:SXNET_add_id_asc diff --git a/crypto/x509/build.info b/crypto/x509/build.info index ca7bb2a03f..c836ef1c2e 100644 --- a/crypto/x509/build.info +++ b/crypto/x509/build.info @@ -8,7 +8,7 @@ SOURCE[../../libcrypto]=\ x509_trs.c by_file.c by_dir.c by_store.c x509_vpm.c \ x_crl.c t_crl.c x_req.c t_req.c x_x509.c t_x509.c \ x_pubkey.c x_x509a.c x_attrib.c x_exten.c x_name.c \ - v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_lib.c \ + v3_bcons.c v3_bitst.c v3_conf.c v3_extku.c v3_ia5.c v3_utf8.c v3_lib.c \ v3_prn.c v3_utl.c v3err.c v3_genn.c v3_alt.c v3_skey.c v3_akey.c \ v3_pku.c v3_int.c v3_enum.c v3_sxnet.c v3_cpols.c v3_crld.c v3_purp.c \ v3_info.c v3_akeya.c v3_pmaps.c v3_pcons.c v3_ncons.c \ diff --git a/crypto/x509/ext_dat.h b/crypto/x509/ext_dat.h index f48fa1d3f1..4329c44065 100644 --- a/crypto/x509/ext_dat.h +++ b/crypto/x509/ext_dat.h @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -23,3 +23,4 @@ extern const X509V3_EXT_METHOD v3_addr, v3_asid; extern const X509V3_EXT_METHOD v3_ct_scts[3]; extern const X509V3_EXT_METHOD v3_tls_feature; extern const X509V3_EXT_METHOD v3_ext_admission; +extern const X509V3_EXT_METHOD v3_utf8_list[1]; diff --git a/crypto/x509/standard_exts.h b/crypto/x509/standard_exts.h index bc63696799..d66b6554f1 100644 --- a/crypto/x509/standard_exts.h +++ b/crypto/x509/standard_exts.h @@ -1,5 +1,5 @@ /* - * Copyright 1999-2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1999-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -68,6 +68,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = { &v3_ct_scts[1], &v3_ct_scts[2], #endif + &v3_utf8_list[0], &v3_tls_feature, &v3_ext_admission }; diff --git a/crypto/x509/v3_utf8.c b/crypto/x509/v3_utf8.c new file mode 100644 index 0000000000..df1000def1 --- /dev/null +++ b/crypto/x509/v3_utf8.c @@ -0,0 +1,68 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include +#include "internal/cryptlib.h" +#include +#include +#include +#include +#include "ext_dat.h" + +/* + * Subject Sign Tool (1.2.643.100.111) The name of the tool used to signs the subject (UTF8String) + * This extention is required to obtain the status of a qualified certificate at Russian Federation. + * RFC-style description is available here: https://tools.ietf.org/html/draft-deremin-rfc4491-bis-04#section-5 + * Russian Federal Law 63 "Digital Sign" is available here: http://www.consultant.ru/document/cons_doc_LAW_112701/ + */ + + +const X509V3_EXT_METHOD v3_utf8_list[1] = { + EXT_UTF8STRING(NID_subjectSignTool), +}; + +char *i2s_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, + ASN1_UTF8STRING *utf8) +{ + char *tmp; + + if (utf8 == NULL || utf8->length == 0) { + X509V3err(X509V3_F_I2S_ASN1_UTF8STRING, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + if ((tmp = OPENSSL_zalloc(utf8->length + 1)) == NULL) { + X509V3err(X509V3_F_I2S_ASN1_UTF8STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + memcpy(tmp, utf8->data, utf8->length); + return tmp; +} + +ASN1_UTF8STRING *s2i_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str) +{ + ASN1_UTF8STRING *utf8; + if (str == NULL) { + X509V3err(X509V3_F_S2I_ASN1_UTF8STRING, X509V3_R_INVALID_NULL_ARGUMENT); + return NULL; + } + if ((utf8 = ASN1_UTF8STRING_new()) == NULL) { + X509V3err(X509V3_F_S2I_ASN1_UTF8STRING, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!ASN1_STRING_set((ASN1_STRING *)utf8, str, strlen(str))) { + X509V3err(X509V3_F_S2I_ASN1_UTF8STRING, ERR_R_MALLOC_FAILURE); + ASN1_UTF8STRING_free(utf8); + return NULL; + } +#ifdef CHARSET_EBCDIC + ebcdic2ascii(utf8->data, utf8->data, utf8->length); +#endif /* CHARSET_EBCDIC */ + return utf8; +} diff --git a/doc/internal/man3/s2i_ASN1_UTF8STRING.pod b/doc/internal/man3/s2i_ASN1_UTF8STRING.pod new file mode 100644 index 0000000000..03a309ba22 --- /dev/null +++ b/doc/internal/man3/s2i_ASN1_UTF8STRING.pod @@ -0,0 +1,45 @@ +=pod + +=head1 NAME + +i2s_ASN1_UTF8STRING, +s2i_ASN1_UTF8STRING, +- convert objects from/to ASN.1/string representation + +=head1 SYNOPSIS + +=for openssl generic + + char *i2s_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, + ASN1_UTF8STRING *utf8); + ASN1_UTF8STRING *s2i_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); +=head1 DESCRIPTION + +These functions convert OpenSSL objects to and from their ASN.1/string +representation. This function is used for B extentions. + +=head1 NOTES + +The letters B and B in B() stand for +"internal" (that is, an internal C structure) and string respectively. +So B() converts from internal to string. + +=head1 RETURN VALUES + +B() return a valid +B structure or NULL if an error occurs. + +B() returns the pointer to a UTF-8 string +or NULL if an error occurs. + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/doc/man3/s2i_ASN1_IA5STRING.pod b/doc/man3/s2i_ASN1_IA5STRING.pod new file mode 100644 index 0000000000..08fa984af1 --- /dev/null +++ b/doc/man3/s2i_ASN1_IA5STRING.pod @@ -0,0 +1,82 @@ +=pod + +=head1 NAME + +i2s_ASN1_IA5STRING, +s2i_ASN1_IA5STRING, +i2s_ASN1_INTEGER, +s2i_ASN1_INTEGER, +i2s_ASN1_OCTET_STRING, +s2i_ASN1_OCTET_STRING, +i2s_ASN1_ENUMERATED, +i2s_ASN1_ENUMERATED_TABLE, +- convert objects from/to ASN.1/string representation + +=head1 SYNOPSIS + +=for openssl generic + + char *i2s_ASN1_IA5STRING(X509V3_EXT_METHOD *method, ASN1_IA5STRING *ia5); + ASN1_IA5STRING *s2i_ASN1_IA5STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + char *i2s_ASN1_INTEGER(X509V3_EXT_METHOD *method, const ASN1_INTEGER *a); + ASN1_INTEGER *s2i_ASN1_INTEGER(X509V3_EXT_METHOD *method, const char *value); + char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + const ASN1_OCTET_STRING *oct); + ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + char *i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *method, const ASN1_ENUMERATED *a); + char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, + const ASN1_ENUMERATED *e); + +=head1 DESCRIPTION + +These functions convert OpenSSL objects to and from their ASN.1/string +representation. This function is used for B extentions. + +=head1 NOTES + +The letters B and B in B() stand for +"internal" (that is, an internal C structure) and string respectively. +So B() converts from internal to string. + +It is the caller's responsibility to free the returned string. +In the B() function the string is copied and +the ownership of the original string remains with the caller. + +=head1 RETURN VALUES + +B() returns the pointer to a IA5 string +or NULL if an error occurs. + +B() return a valid +B structure or NULL if an error occurs. + +B() return a valid +string or NULL if an error occurs. + +B() returns the pointer to a B +structure or NULL if an error occurs. + +B() returns the pointer to a OCTET_STRING string +or NULL if an error occurs. + +B() return a valid +B structure or NULL if an error occurs. + +B() return a valid +string or NULL if an error occurs. + +B() returns the pointer to a B +structure or NULL if an error occurs. + +=head1 COPYRIGHT + +Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + +Licensed under the Apache License 2.0 (the "License"). You may not use +this file except in compliance with the License. You can obtain a copy +in the file LICENSE in the source distribution or at +L. + +=cut diff --git a/include/crypto/x509v3.h b/include/crypto/x509v3.h new file mode 100644 index 0000000000..4ca85e9a2e --- /dev/null +++ b/include/crypto/x509v3.h @@ -0,0 +1,23 @@ +/* + * Copyright 2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ +#ifndef OSSL_CRYPTO_X509V3_H +# define OSSL_CRYPTO_X509V3_H + +#define EXT_UTF8STRING(nid) { nid, 0, ASN1_ITEM_ref(ASN1_UTF8STRING), \ + 0,0,0,0, \ + (X509V3_EXT_I2S)i2s_ASN1_UTF8STRING, \ + (X509V3_EXT_S2I)s2i_ASN1_UTF8STRING, \ + 0,0,0,0, \ + NULL} + +char *i2s_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, ASN1_UTF8STRING *utf8); +ASN1_UTF8STRING *s2i_ASN1_UTF8STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, const char *str); + +#endif diff --git a/include/openssl/x509v3err.h b/include/openssl/x509v3err.h index 0dab8a2a36..6e73337e3b 100644 --- a/include/openssl/x509v3err.h +++ b/include/openssl/x509v3err.h @@ -1,6 +1,6 @@ /* * Generated by util/mkerr.pl DO NOT EDIT - * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -44,6 +44,7 @@ int ERR_load_X509V3_strings(void); # define X509V3_F_I2S_ASN1_ENUMERATED 0 # define X509V3_F_I2S_ASN1_IA5STRING 0 # define X509V3_F_I2S_ASN1_INTEGER 0 +# define X509V3_F_I2S_ASN1_UTF8STRING 0 # define X509V3_F_I2V_AUTHORITY_INFO_ACCESS 0 # define X509V3_F_LEVEL_ADD_NODE 0 # define X509V3_F_NOTICE_SECTION 0 @@ -58,6 +59,7 @@ int ERR_load_X509V3_strings(void); # define X509V3_F_S2I_ASN1_IA5STRING 0 # define X509V3_F_S2I_ASN1_INTEGER 0 # define X509V3_F_S2I_ASN1_OCTET_STRING 0 +# define X509V3_F_S2I_ASN1_UTF8STRING 0 # define X509V3_F_S2I_SKEY_ID 0 # define X509V3_F_SET_DIST_POINT_NAME 0 # define X509V3_F_SXNET_ADD_ID_ASC 0 diff --git a/util/missingcrypto.txt b/util/missingcrypto.txt index 64ac6845dc..be5535b87d 100644 --- a/util/missingcrypto.txt +++ b/util/missingcrypto.txt @@ -1547,20 +1547,12 @@ i2d_PrivateKey_fp(3) i2d_X509_bio(3) i2d_X509_fp(3) i2o_ECPublicKey(3) -i2s_ASN1_ENUMERATED(3) -i2s_ASN1_ENUMERATED_TABLE(3) -i2s_ASN1_IA5STRING(3) -i2s_ASN1_INTEGER(3) -i2s_ASN1_OCTET_STRING(3) i2v_ASN1_BIT_STRING(3) i2v_GENERAL_NAME(3) i2v_GENERAL_NAMES(3) o2i_ECPublicKey(3) openssl-core_numbers.h(7) provider-kdf(7) -s2i_ASN1_IA5STRING(3) -s2i_ASN1_INTEGER(3) -s2i_ASN1_OCTET_STRING(3) v2i_ASN1_BIT_STRING(3) v2i_GENERAL_NAME(3) v2i_GENERAL_NAMES(3) -- 2.34.1