1 /* 2 * Copyright 2015-2022 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the Apache License 2.0 (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include "internal/e_os.h" 11 #include "internal/cryptlib.h" 12 #include <stdio.h> 13 #include <openssl/asn1t.h> 14 #include <openssl/conf.h> 15 #include <openssl/x509v3.h> 16 #include "ext_dat.h" 17 #include "x509_local.h" 18 19 static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method, 20 TLS_FEATURE *tls_feature, 21 STACK_OF(CONF_VALUE) *ext_list); 22 static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, 23 X509V3_CTX *ctx, 24 STACK_OF(CONF_VALUE) *nval); 25 26 ASN1_ITEM_TEMPLATE(TLS_FEATURE) = ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, TLS_FEATURE, ASN1_INTEGER) 27 static_ASN1_ITEM_TEMPLATE_END(TLS_FEATURE) 28 29 IMPLEMENT_ASN1_ALLOC_FUNCTIONS(TLS_FEATURE) 30 31 const X509V3_EXT_METHOD ossl_v3_tls_feature = { 32 NID_tlsfeature, 0, 33 ASN1_ITEM_ref(TLS_FEATURE), 34 0, 0, 0, 0, 35 0, 0, 36 (X509V3_EXT_I2V)i2v_TLS_FEATURE, 37 (X509V3_EXT_V2I)v2i_TLS_FEATURE, 38 0, 0, 39 NULL 40 }; 41 42 typedef struct { 43 long num; 44 const char *name; 45 } TLS_FEATURE_NAME; 46 47 static TLS_FEATURE_NAME tls_feature_tbl[] = { 48 { 5, "status_request" }, 49 { 17, "status_request_v2" } 50 }; 51 52 /* 53 * i2v_TLS_FEATURE converts the TLS_FEATURE structure tls_feature into the 54 * STACK_OF(CONF_VALUE) structure ext_list. STACK_OF(CONF_VALUE) is the format 55 * used by the CONF library to represent a multi-valued extension. ext_list is 56 * returned. 57 */ 58 static STACK_OF(CONF_VALUE) *i2v_TLS_FEATURE(const X509V3_EXT_METHOD *method, 59 TLS_FEATURE *tls_feature, 60 STACK_OF(CONF_VALUE) *ext_list) 61 { 62 int i; 63 size_t j; 64 ASN1_INTEGER *ai; 65 long tlsextid; 66 for (i = 0; i < sk_ASN1_INTEGER_num(tls_feature); i++) { 67 ai = sk_ASN1_INTEGER_value(tls_feature, i); 68 tlsextid = ASN1_INTEGER_get(ai); 69 for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++) 70 if (tlsextid == tls_feature_tbl[j].num) 71 break; 72 if (j < OSSL_NELEM(tls_feature_tbl)) 73 X509V3_add_value(NULL, tls_feature_tbl[j].name, &ext_list); 74 else 75 X509V3_add_value_int(NULL, ai, &ext_list); 76 } 77 return ext_list; 78 } 79 80 /* 81 * v2i_TLS_FEATURE converts the multi-valued extension nval into a TLS_FEATURE 82 * structure, which is returned if the conversion is successful. In case of 83 * error, NULL is returned. 84 */ 85 static TLS_FEATURE *v2i_TLS_FEATURE(const X509V3_EXT_METHOD *method, 86 X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) 87 { 88 TLS_FEATURE *tlsf; 89 char *extval, *endptr; 90 ASN1_INTEGER *ai = NULL; 91 CONF_VALUE *val; 92 int i; 93 size_t j; 94 long tlsextid; 95 96 if ((tlsf = sk_ASN1_INTEGER_new_null()) == NULL) { 97 ERR_raise(ERR_LIB_X509V3, ERR_R_CRYPTO_LIB); 98 return NULL; 99 } 100 101 for (i = 0; i < sk_CONF_VALUE_num(nval); i++) { 102 val = sk_CONF_VALUE_value(nval, i); 103 if (val->value) 104 extval = val->value; 105 else 106 extval = val->name; 107 108 for (j = 0; j < OSSL_NELEM(tls_feature_tbl); j++) 109 if (OPENSSL_strcasecmp(extval, tls_feature_tbl[j].name) == 0) 110 break; 111 if (j < OSSL_NELEM(tls_feature_tbl)) 112 tlsextid = tls_feature_tbl[j].num; 113 else { 114 tlsextid = strtol(extval, &endptr, 10); 115 if (((*endptr) != '\0') || (extval == endptr) || (tlsextid < 0) || (tlsextid > 65535)) { 116 ERR_raise(ERR_LIB_X509V3, X509V3_R_INVALID_SYNTAX); 117 X509V3_conf_add_error_name_value(val); 118 goto err; 119 } 120 } 121 122 if ((ai = ASN1_INTEGER_new()) == NULL 123 || !ASN1_INTEGER_set(ai, tlsextid) 124 || sk_ASN1_INTEGER_push(tlsf, ai) <= 0) { 125 ERR_raise(ERR_LIB_X509V3, ERR_R_ASN1_LIB); 126 goto err; 127 } 128 /* So it doesn't get purged if an error occurs next time around */ 129 ai = NULL; 130 } 131 return tlsf; 132 133 err: 134 sk_ASN1_INTEGER_pop_free(tlsf, ASN1_INTEGER_free); 135 ASN1_INTEGER_free(ai); 136 return NULL; 137 } 138