From: Joe Orton Date: Wed, 19 May 2010 15:55:21 +0000 (+0000) Subject: Fix handling of extensions with types not known to OpenSSL in X-Git-Tag: 2.3.6~101 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=baf08c7f66cb72c82c64e0312e8936ce76d52e9a;p=apache Fix handling of extensions with types not known to OpenSSL in PeerExtList(); parse the value as a string primitive, or else fail, rather than rendering the raw DER blob as a string regardless of the type: * modules/ssl/ssl_engine_vars.c: (dump_extn_value): New function. (ssl_ext_list): Use it; tweak error message and free the OID object (thanks to drh for spotting this last issue way back). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@946240 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c index 5a2874732a..a55842abe1 100644 --- a/modules/ssl/ssl_engine_vars.c +++ b/modules/ssl/ssl_engine_vars.c @@ -779,6 +779,27 @@ void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p) } } +/* For an extension type which OpenSSL does not recognize, attempt to + * parse the extension type as a primitive string. This will fail for + * any structured extension type per the docs. Returns non-zero on + * success and writes the string to the given bio. */ +static int dump_extn_value(BIO *bio, ASN1_OCTET_STRING *str) +{ + const unsigned char *pp = str->data; + ASN1_STRING *ret = ASN1_STRING_new(); + int rv = 0; + + /* This allows UTF8String, IA5String, VisibleString, or BMPString; + * conversion to UTF-8 is forced. */ + if (d2i_DISPLAYTEXT(&ret, &pp, str->length)) { + ASN1_STRING_print_ex(bio, ret, ASN1_STRFLGS_UTF8_CONVERT); + rv = 1; + } + + ASN1_STRING_free(ret); + return rv; +} + apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, const char *extension) { @@ -801,8 +822,7 @@ apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, oid = OBJ_txt2obj(extension, 0); if (!oid) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, - "Failed to create an object for extension '%s'", - extension); + "could not parse OID '%s'", extension); ERR_clear_error(); return NULL; } @@ -831,7 +851,7 @@ apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, * not knowing how to handle the data. */ if (X509V3_EXT_print(bio, ext, 0, 0) == 1 || - ASN1_STRING_print(bio, ext->value) == 1) { + dump_extn_value(bio, X509_EXTENSION_get_data(ext)) == 1) { BUF_MEM *buf; char **ptr = apr_array_push(array); BIO_get_mem_ptr(bio, &buf); @@ -853,6 +873,7 @@ apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, X509_free(xs); } + ASN1_OBJECT_free(oid); ERR_clear_error(); return array; }