From ba67253db19d0319f672d47aa359032e5e66d1b8 Mon Sep 17 00:00:00 2001 From: Rob Stradling Date: Fri, 4 Dec 2015 14:35:43 +0000 Subject: [PATCH] Support the TLS Feature (aka Must Staple) X.509v3 extension (RFC7633). Signed-off-by: Kurt Roeckx Reviewed-by: Rich Salz Reviewed-by: Dr. Stephen Henson GH: #495, MR: #1435 --- crypto/objects/obj_dat.h | 15 ++- crypto/objects/obj_mac.num | 1 + crypto/objects/objects.txt | 1 + crypto/x509v3/Makefile | 18 +++- crypto/x509v3/ext_dat.h | 1 + crypto/x509v3/v3_lib.c | 1 + crypto/x509v3/v3_tlsf.c | 186 ++++++++++++++++++++++++++++++++++ crypto/x509v3/v3err.c | 1 + doc/apps/x509v3_config.pod | 14 +++ doc/crypto/X509V3_get_d2i.pod | 2 + include/openssl/obj_mac.h | 5 + include/openssl/x509v3.h | 5 + util/libeay.num | 2 + 13 files changed, 245 insertions(+), 7 deletions(-) create mode 100644 crypto/x509v3/v3_tlsf.c diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h index d1382a2665..debf8cccf6 100644 --- a/crypto/objects/obj_dat.h +++ b/crypto/objects/obj_dat.h @@ -62,12 +62,12 @@ * [including the GNU Public Licence.] */ -#define NUM_NID 1020 -#define NUM_SN 1013 -#define NUM_LN 1013 -#define NUM_OBJ 936 +#define NUM_NID 1021 +#define NUM_SN 1014 +#define NUM_LN 1014 +#define NUM_OBJ 937 -static const unsigned char lvalues[6604]={ +static const unsigned char lvalues[6612]={ 0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */ 0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */ @@ -998,6 +998,7 @@ static const unsigned char lvalues[6604]={ 0x2A,0x85,0x03,0x64,0x03, /* [6588] OBJ_SNILS */ 0x2A,0x85,0x03,0x64,0x6F, /* [6593] OBJ_subjectSignTool */ 0x2A,0x85,0x03,0x64,0x70, /* [6598] OBJ_issuerSignTool */ +0x2B,0x06,0x01,0x05,0x05,0x07,0x01,0x18, /* [6603] OBJ_tlsfeature */ }; static const ASN1_OBJECT nid_objs[NUM_NID]={ @@ -2669,6 +2670,7 @@ static const ASN1_OBJECT nid_objs[NUM_NID]={ {"grasshopper-mac","grasshopper-mac",NID_grasshopper_mac,0,NULL,0}, {"ChaCha20-Poly1305","chacha20-poly1305",NID_chacha20_poly1305,0,NULL,0}, {"ChaCha20","chacha20",NID_chacha20,0,NULL,0}, +{"tlsfeature","TLS Feature",NID_tlsfeature,8,&(lvalues[6603]),0}, }; static const unsigned int sn_objs[NUM_SN]={ @@ -3656,6 +3658,7 @@ static const unsigned int sn_objs[NUM_SN]={ 293, /* "textNotice" */ 133, /* "timeStamping" */ 106, /* "title" */ +1020, /* "tlsfeature" */ 682, /* "tpBasis" */ 375, /* "trustRoot" */ 436, /* "ucl" */ @@ -3813,6 +3816,7 @@ static const unsigned int ln_objs[NUM_LN]={ 1007, /* "Signing Tool of Subject" */ 143, /* "Strong Extranet ID" */ 398, /* "Subject Information Access" */ +1020, /* "TLS Feature" */ 130, /* "TLS Web Client Authentication" */ 129, /* "TLS Web Server Authentication" */ 133, /* "Time Stamping" */ @@ -5244,6 +5248,7 @@ static const unsigned int obj_objs[NUM_OBJ]={ 397, /* OBJ_ac_proxying 1 3 6 1 5 5 7 1 10 */ 398, /* OBJ_sinfo_access 1 3 6 1 5 5 7 1 11 */ 663, /* OBJ_proxyCertInfo 1 3 6 1 5 5 7 1 14 */ +1020, /* OBJ_tlsfeature 1 3 6 1 5 5 7 1 24 */ 164, /* OBJ_id_qt_cps 1 3 6 1 5 5 7 2 1 */ 165, /* OBJ_id_qt_unotice 1 3 6 1 5 5 7 2 2 */ 293, /* OBJ_textNotice 1 3 6 1 5 5 7 2 3 */ diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num index 2993f5647e..5c6ffd41af 100644 --- a/crypto/objects/obj_mac.num +++ b/crypto/objects/obj_mac.num @@ -1017,3 +1017,4 @@ grasshopper_cfb 1016 grasshopper_mac 1017 chacha20_poly1305 1018 chacha20 1019 +tlsfeature 1020 diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt index 29517e3d7a..f34609dd26 100644 --- a/crypto/objects/objects.txt +++ b/crypto/objects/objects.txt @@ -472,6 +472,7 @@ id-pe 10 : ac-proxying !Cname sinfo-access id-pe 11 : subjectInfoAccess : Subject Information Access id-pe 14 : proxyCertInfo : Proxy Certificate Information +id-pe 24 : tlsfeature : TLS Feature # PKIX policyQualifiers for Internet policy qualifiers id-qt 1 : id-qt-cps : Policy Qualifier CPS diff --git a/crypto/x509v3/Makefile b/crypto/x509v3/Makefile index cd490ed914..775f88b524 100644 --- a/crypto/x509v3/Makefile +++ b/crypto/x509v3/Makefile @@ -20,13 +20,13 @@ 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 v3_pcia.c v3_pci.c \ pcy_cache.c pcy_node.c pcy_data.c pcy_map.c pcy_tree.c pcy_lib.c \ -v3_asid.c v3_addr.c v3_scts.c +v3_asid.c v3_addr.c v3_scts.c v3_tlsf.c LIBOBJ= v3_bcons.o v3_bitst.o v3_conf.o v3_extku.o v3_ia5.o v3_lib.o \ v3_prn.o v3_utl.o v3err.o v3_genn.o v3_alt.o v3_skey.o v3_akey.o v3_pku.o \ v3_int.o v3_enum.o v3_sxnet.o v3_cpols.o v3_crld.o v3_purp.o v3_info.o \ v3_akeya.o v3_pmaps.o v3_pcons.o v3_ncons.o v3_pcia.o v3_pci.o \ pcy_cache.o pcy_node.o pcy_data.o pcy_map.o pcy_tree.o pcy_lib.o \ -v3_asid.o v3_addr.o v3_scts.o +v3_asid.o v3_addr.o v3_scts.o v3_tlsf.o SRC= $(LIBSRC) @@ -534,6 +534,20 @@ v3_sxnet.o: ../../include/openssl/sha.h ../../include/openssl/stack.h v3_sxnet.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h v3_sxnet.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h v3_sxnet.o: ../include/internal/cryptlib.h ext_dat.h v3_sxnet.c +v3_tlsf.o: ../../e_os.h ../../include/internal/o_str.h +v3_tlsf.o: ../../include/openssl/asn1.h ../../include/openssl/asn1t.h +v3_tlsf.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h +v3_tlsf.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h +v3_tlsf.o: ../../include/openssl/e_os2.h ../../include/openssl/ec.h +v3_tlsf.o: ../../include/openssl/err.h ../../include/openssl/evp.h +v3_tlsf.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h +v3_tlsf.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h +v3_tlsf.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h +v3_tlsf.o: ../../include/openssl/pkcs7.h ../../include/openssl/safestack.h +v3_tlsf.o: ../../include/openssl/sha.h ../../include/openssl/stack.h +v3_tlsf.o: ../../include/openssl/symhacks.h ../../include/openssl/x509.h +v3_tlsf.o: ../../include/openssl/x509_vfy.h ../../include/openssl/x509v3.h +v3_tlsf.o: ../include/internal/cryptlib.h ext_dat.h v3_tlsf.c v3_utl.o: ../../e_os.h ../../include/openssl/asn1.h ../../include/openssl/bio.h v3_utl.o: ../../include/openssl/bn.h ../../include/openssl/buffer.h v3_utl.o: ../../include/openssl/conf.h ../../include/openssl/crypto.h diff --git a/crypto/x509v3/ext_dat.h b/crypto/x509v3/ext_dat.h index c1ddedbfab..3f9f7f3efc 100644 --- a/crypto/x509v3/ext_dat.h +++ b/crypto/x509v3/ext_dat.h @@ -70,3 +70,4 @@ extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; extern const X509V3_EXT_METHOD v3_addr, v3_asid; extern const X509V3_EXT_METHOD v3_ct_scts[]; +extern const X509V3_EXT_METHOD v3_tls_feature; diff --git a/crypto/x509v3/v3_lib.c b/crypto/x509v3/v3_lib.c index 8d42147f55..e3cd2ae5ee 100644 --- a/crypto/x509v3/v3_lib.c +++ b/crypto/x509v3/v3_lib.c @@ -156,6 +156,7 @@ static const X509V3_EXT_METHOD *standard_exts[] = { &v3_ct_scts[0], &v3_ct_scts[1], #endif + &v3_tls_feature, }; /* Number of standard extensions */ diff --git a/crypto/x509v3/v3_tlsf.c b/crypto/x509v3/v3_tlsf.c new file mode 100644 index 0000000000..700546f6a6 --- /dev/null +++ b/crypto/x509v3/v3_tlsf.c @@ -0,0 +1,186 @@ +/* v3_tlsf.c */ +/* + * Written by Rob Stradling (rob@comodo.com) for the OpenSSL project 2015. + */ +/* ==================================================================== + * Copyright (c) 2015 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ + +#include +#include "internal/cryptlib.h" +#include "internal/o_str.h" +#include +#include +#include +#include "ext_dat.h" + +static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method, + TLS_FEATURE *tls_feature, + STACK_OF(CONF_VALUE) *ext_list); +static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *nval); + +ASN1_ITEM_TEMPLATE(TLS_FEATURE) = + ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, TLS_FEATURE, ASN1_INTEGER) +static_ASN1_ITEM_TEMPLATE_END(TLS_FEATURE) + +IMPLEMENT_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE) + +const X509V3_EXT_METHOD v3_tls_feature = { + NID_tlsfeature, 0, + ASN1_ITEM_ref(TLS_FEATURE), + 0, 0, 0, 0, + 0, 0, + (X509V3_EXT_I2V)i2v_TLS_FEATURE, + (X509V3_EXT_V2I)v2i_TLS_FEATURE, + 0, 0, + NULL +}; + + +typedef struct { + long num; + const char *name; +} TLS_FEATURE_NAME; + +static TLS_FEATURE_NAME tls_feature_tbl[] = { + { 5, "status_request" }, + { 17, "status_request_v2" } +}; + +/* + * i2v_TLS_FEATURE converts the TLS_FEATURE structure tls_feature into the + * STACK_OF(CONF_VALUE) structure ext_list. STACK_OF(CONF_VALUE) is the format + * used by the CONF library to represent a multi-valued extension. ext_list is + * returned. + */ +static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method, + TLS_FEATURE *tls_feature, + STACK_OF(CONF_VALUE) *ext_list) +{ + int i; + size_t j; + ASN1_INTEGER *ai; + long tlsextid; + for (i = 0; i < sk_ASN1_INTEGER_num(tls_feature); i++) { + ai = sk_ASN1_INTEGER_value(tls_feature, i); + tlsextid = ASN1_INTEGER_get(ai); + for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++) + if (tlsextid == tls_feature_tbl[j].num) + break; + if (j < OSSL_NELEM(tls_feature_tbl)) + X509V3_add_value(NULL, tls_feature_tbl[j].name, &ext_list); + else + X509V3_add_value_int(NULL, ai, &ext_list); + } + return ext_list; +} + +/* + * v2i_TLS_FEATURE converts the multi-valued extension nval into a TLS_FEATURE + * structure, which is returned if the conversion is successful. In case of + * error, NULL is returned. + */ +static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + TLS_FEATURE *tlsf; + char *extval, *endptr; + ASN1_INTEGER *ai; + CONF_VALUE *val; + int i; + size_t j; + long tlsextid; + + if ((tlsf = sk_ASN1_INTEGER_new_null()) == NULL) { + X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { + val = sk_CONF_VALUE_value(nval, i); + if (val->value) + extval = val->value; + else + extval = val->name; + + for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++) + if (OPENSSL_strcasecmp(extval, tls_feature_tbl[j].name) == 0) + break; + if (j < OSSL_NELEM(tls_feature_tbl)) + tlsextid = tls_feature_tbl[j].num; + else { + tlsextid = strtol(extval, &endptr, 10); + if (((*endptr) != '\0') || (extval == endptr) || (tlsextid < 0) || + (tlsextid > 65535)) { + X509V3err(X509V3_F_V2I_TLS_FEATURE, X509V3_R_INVALID_SYNTAX); + X509V3_conf_err(val); + goto err; + } + } + + ai = ASN1_INTEGER_new(); + if (ai == NULL) { + X509V3err(X509V3_F_V2I_TLS_FEATURE, ERR_R_MALLOC_FAILURE); + goto err; + } + ASN1_INTEGER_set(ai, tlsextid); + sk_ASN1_INTEGER_push(tlsf, ai); + } + return tlsf; + + err: + sk_ASN1_INTEGER_pop_free(tlsf, ASN1_INTEGER_free); + return NULL; +} diff --git a/crypto/x509v3/v3err.c b/crypto/x509v3/v3err.c index f9eb064b54..529346b480 100644 --- a/crypto/x509v3/v3err.c +++ b/crypto/x509v3/v3err.c @@ -124,6 +124,7 @@ static ERR_STRING_DATA X509V3_str_functs[] = { {ERR_FUNC(X509V3_F_V2I_POLICY_CONSTRAINTS), "v2i_POLICY_CONSTRAINTS"}, {ERR_FUNC(X509V3_F_V2I_POLICY_MAPPINGS), "v2i_POLICY_MAPPINGS"}, {ERR_FUNC(X509V3_F_V2I_SUBJECT_ALT), "v2i_subject_alt"}, + {ERR_FUNC(X509V3_F_V2I_TLS_FEATURE), "v2i_TLS_FEATURE"}, {ERR_FUNC(X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL), "v3_addr_validate_path_internal"}, {ERR_FUNC(X509V3_F_V3_GENERIC_EXTENSION), "v3_generic_extension"}, diff --git a/doc/apps/x509v3_config.pod b/doc/apps/x509v3_config.pod index e965be6480..c2c710b6c7 100644 --- a/doc/apps/x509v3_config.pod +++ b/doc/apps/x509v3_config.pod @@ -399,6 +399,20 @@ Example: noCheck = ignored +=head2 TLS Feature (aka Must Staple) + +This is a multi-valued extension consisting of a list of TLS extension +identifiers. Each identifier may be a number (0..65535) or a supported name. +When a TLS client sends a listed extension, the TLS server is expected to +include that extension in its reply. + +The supported names are: B and B. + +Example: + + tlsfeature = status_request + + =head1 DEPRECATED EXTENSIONS The following extensions are non standard, Netscape specific and largely diff --git a/doc/crypto/X509V3_get_d2i.pod b/doc/crypto/X509V3_get_d2i.pod index 82500106cc..4b50a10221 100644 --- a/doc/crypto/X509V3_get_d2i.pod +++ b/doc/crypto/X509V3_get_d2i.pod @@ -139,6 +139,8 @@ RFC5280. Policy Constraints NID_policy_constraints Inhibit Any Policy NID_inhibit_any_policy + TLS Feature NID_tlsfeature + =head2 NETSCAPE CERTIFICATE EXTENSIONS The following are (largely obsolete) Netscape certificate extensions. diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h index 060126b56c..5f21fd5a32 100644 --- a/include/openssl/obj_mac.h +++ b/include/openssl/obj_mac.h @@ -1490,6 +1490,11 @@ #define NID_proxyCertInfo 663 #define OBJ_proxyCertInfo OBJ_id_pe,14L +#define SN_tlsfeature "tlsfeature" +#define LN_tlsfeature "TLS Feature" +#define NID_tlsfeature 1020 +#define OBJ_tlsfeature OBJ_id_pe,24L + #define SN_id_qt_cps "id-qt-cps" #define LN_id_qt_cps "Policy Qualifier CPS" #define NID_id_qt_cps 164 diff --git a/include/openssl/x509v3.h b/include/openssl/x509v3.h index 9a68b7316c..7932acb9c8 100644 --- a/include/openssl/x509v3.h +++ b/include/openssl/x509v3.h @@ -217,6 +217,8 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; +typedef STACK_OF(ASN1_INTEGER) TLS_FEATURE; + DECLARE_STACK_OF(GENERAL_NAME) DECLARE_STACK_OF(ACCESS_DESCRIPTION) @@ -561,6 +563,8 @@ ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) int i2a_ACCESS_DESCRIPTION(BIO *bp, ACCESS_DESCRIPTION *a); +DECLARE_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE) + DECLARE_ASN1_FUNCTIONS(CERTIFICATEPOLICIES) DECLARE_ASN1_FUNCTIONS(POLICYINFO) DECLARE_ASN1_FUNCTIONS(POLICYQUALINFO) @@ -962,6 +966,7 @@ void ERR_load_X509V3_strings(void); # define X509V3_F_V2I_POLICY_CONSTRAINTS 146 # define X509V3_F_V2I_POLICY_MAPPINGS 145 # define X509V3_F_V2I_SUBJECT_ALT 154 +# define X509V3_F_V2I_TLS_FEATURE 165 # define X509V3_F_V3_ADDR_VALIDATE_PATH_INTERNAL 160 # define X509V3_F_V3_GENERIC_EXTENSION 116 # define X509V3_F_X509V3_ADD1_I2D 140 diff --git a/util/libeay.num b/util/libeay.num index 3318a7eb98..b02248b4c3 100755 --- a/util/libeay.num +++ b/util/libeay.num @@ -4727,3 +4727,5 @@ Poly1305_Update 5086 EXIST::FUNCTION:POLY1305 Poly1305_Final 5087 EXIST::FUNCTION:POLY1305 EVP_chacha20_poly1305 5088 EXIST::FUNCTION:CHACHA,POLY1305 EVP_chacha20 5089 EXIST::FUNCTION:CHACHA +TLS_FEATURE_free 5093 EXIST::FUNCTION: +TLS_FEATURE_new 5094 EXIST::FUNCTION: -- 2.25.1