| 1057 | } |
| 1058 | |
| 1059 | apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, |
| 1060 | const char *extension) |
| 1061 | { |
| 1062 | SSLConnRec *sslconn = ssl_get_effective_config(c); |
| 1063 | SSL *ssl = NULL; |
| 1064 | apr_array_header_t *array = NULL; |
| 1065 | X509 *xs = NULL; |
| 1066 | ASN1_OBJECT *oid = NULL; |
| 1067 | int count = 0, j; |
| 1068 | |
| 1069 | if (!sslconn || !sslconn->ssl || !extension) { |
| 1070 | return NULL; |
| 1071 | } |
| 1072 | ssl = sslconn->ssl; |
| 1073 | |
| 1074 | /* We accept the "extension" string to be converted as |
| 1075 | * a long name (nsComment), short name (DN) or |
| 1076 | * numeric OID (1.2.3.4). |
| 1077 | */ |
| 1078 | oid = OBJ_txt2obj(extension, 0); |
| 1079 | if (!oid) { |
| 1080 | ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01970) |
| 1081 | "could not parse OID '%s'", extension); |
| 1082 | ERR_clear_error(); |
| 1083 | return NULL; |
| 1084 | } |
| 1085 | |
| 1086 | xs = peer ? SSL_get_peer_certificate(ssl) : SSL_get_certificate(ssl); |
| 1087 | if (xs == NULL) { |
| 1088 | return NULL; |
| 1089 | } |
| 1090 | |
| 1091 | count = X509_get_ext_count(xs); |
| 1092 | /* Create an array large enough to accommodate every extension. This is |
| 1093 | * likely overkill, but safe. |
| 1094 | */ |
| 1095 | array = apr_array_make(p, count, sizeof(char *)); |
| 1096 | for (j = 0; j < count; j++) { |
| 1097 | MODSSL_X509_EXT_CONST X509_EXTENSION *ext = X509_get_ext(xs, j); |
| 1098 | |
| 1099 | if (OBJ_cmp(X509_EXTENSION_get_object(ext), oid) == 0) { |
| 1100 | BIO *bio = BIO_new(BIO_s_mem()); |
| 1101 | |
| 1102 | /* We want to obtain a string representation of the extensions |
| 1103 | * value and add it to the array we're building. |
| 1104 | * X509V3_EXT_print() doesn't know about all the possible |
| 1105 | * data types, but the value is stored as an ASN1_OCTET_STRING |
| 1106 | * allowing us a fallback in case of X509V3_EXT_print |
| 1107 | * not knowing how to handle the data. |
| 1108 | */ |
| 1109 | if (X509V3_EXT_print(bio, ext, 0, 0) == 1 || |
| 1110 | dump_extn_value(bio, X509_EXTENSION_get_data(ext)) == 1) { |
| 1111 | BUF_MEM *buf; |
| 1112 | char **ptr = apr_array_push(array); |
| 1113 | BIO_get_mem_ptr(bio, &buf); |
| 1114 | *ptr = apr_pstrmemdup(p, buf->data, buf->length); |
| 1115 | } else { |
| 1116 | ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01971) |
no test coverage detected