Ticket #402: 0003-Make-extract_x509_extension-in-ssl_verify_openssl.c-.patch
File 0003-Make-extract_x509_extension-in-ssl_verify_openssl.c-.patch, 7.9 KB (added by , 10 years ago) |
---|
-
src/openvpn/ssl_verify.c
From 1cd060230653bd93067a0837384907200fa19c74 Mon Sep 17 00:00:00 2001 From: Andris Kalnozols <andris@hpl.hp.com> Date: Sat, 28 Jun 2014 20:26:21 +0200 Subject: [PATCH 3/3] Make extract_x509_extension() in ssl_verify_openssl.c more informative. I did enhance extract_x509_extension() in ssl_verify_openssl.c to be more informative but only when dealing with the client certificate. Getting access to the "cert_depth" variable required minor changes in the following files: ssl_verify.c ssl_verify_backend.h ssl_verify_polarssl.c Signed-off-by: Andris Kalnozols <andris@hpl.hp.com> --- src/openvpn/ssl_verify.c | 2 +- src/openvpn/ssl_verify_backend.h | 3 +- src/openvpn/ssl_verify_openssl.c | 134 +++++++++++++++++++++++--------------- src/openvpn/ssl_verify_polarssl.c | 2 +- 4 files changed, 86 insertions(+), 55 deletions(-) diff --git a/src/openvpn/ssl_verify.c b/src/openvpn/ssl_verify.c index c90c2c3..19df9fb 100644
a b verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep 620 620 621 621 /* extract the username (default is CN) */ 622 622 if (SUCCESS != x509_get_username (common_name, TLS_USERNAME_LEN, 623 opt->x509_username_field, cert ))623 opt->x509_username_field, cert, cert_depth)) 624 624 { 625 625 if (!cert_depth) 626 626 { -
src/openvpn/ssl_verify_backend.h
diff --git a/src/openvpn/ssl_verify_backend.h b/src/openvpn/ssl_verify_backend.h index 6f118c9..14383ad 100644
a b unsigned char *x509_get_sha1_hash (openvpn_x509_cert_t *cert, struct gc_arena *g 106 106 * @param cn_len Length of the cn buffer. 107 107 * @param x509_username_field Name of the field to load from 108 108 * @param cert Certificate to retrieve the common name from. 109 * @param cert_depth Depth of the current certificate 109 110 * 110 111 * @return \c FAILURE, \c or SUCCESS 111 112 */ 112 113 result_t x509_get_username (char *common_name, int cn_len, 113 char * x509_username_field, openvpn_x509_cert_t *peer_cert );114 char * x509_username_field, openvpn_x509_cert_t *peer_cert, int cert_depth); 114 115 115 116 /* 116 117 * Return the certificate's serial number in decimal string representation. -
src/openvpn/ssl_verify_openssl.c
diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c index 19982ae..e5a6904 100644
a b cleanup: 93 93 } 94 94 95 95 #ifdef ENABLE_X509ALTUSERNAME 96 static 97 bool extract_x509_extension(X509 *cert, char *fieldname, char *out, int size) 96 static result_t 97 extract_x509_extension(X509 *cert, int cert_depth, char *fieldname, 98 char *out, int size) 98 99 { 99 bool retval = false; 100 X509_EXTENSION *pExt; 101 char *buf = 0; 100 result_t retval = FAILURE; 101 int nid; 102 102 int length = 0; 103 GENERAL_NAMES *extensions;104 int nid = OBJ_txt2nid(fieldname);103 char *buf = 0; 104 GENERAL_NAMES *extension; 105 105 106 extensions = (GENERAL_NAMES *)X509_get_ext_d2i(cert, nid, NULL, NULL); 107 if ( extensions ) 106 nid = OBJ_txt2nid(fieldname); 107 extension = (GENERAL_NAMES *)X509_get_ext_d2i(cert, nid, NULL, NULL); 108 if (!extension && cert_depth == 0) 109 /* 110 * The cert depth is used to filter message logging to just the 111 * client certificate; we're not concerned about the CA(s) here. 112 */ 113 msg(D_TLS_ERRORS, "VERIFY ERROR: can not find extension %s", 114 fieldname); 115 else 108 116 { 109 117 int numalts; 110 118 int i; 111 /* get amount of alternatives, 112 * RFC2459 claims there MUST be at least 113 * one, but we don't depend on it... 119 STACK_OF(CONF_VALUE) *vals = sk_CONF_VALUE_new_null(); 120 121 /* Get the number of alternatives, i.e., GeneralName fields. 122 * RFC5280, Section 4.2.1.6 states there MUST be at least 123 * one and that no GeneralName field may have an empty value. 124 * We will not trust but verify instead. 114 125 */ 115 126 116 numalts = sk_GENERAL_NAME_num(extensions); 117 118 /* loop through all alternatives */ 119 for (i=0; i<numalts; i++) 120 { 121 /* get a handle to alternative name number i */ 122 const GENERAL_NAME *name = sk_GENERAL_NAME_value (extensions, i ); 123 124 switch (name->type) 125 { 126 case GEN_EMAIL: 127 ASN1_STRING_to_UTF8((unsigned char**)&buf, name->d.ia5); 128 if ( strlen (buf) != name->d.ia5->length ) 129 { 130 msg (D_TLS_ERRORS, "ASN1 ERROR: string contained terminating zero"); 131 OPENSSL_free (buf); 132 } else { 133 strncpynt(out, buf, size); 134 OPENSSL_free(buf); 135 retval = true; 136 } 137 break; 138 default: 139 msg (D_TLS_ERRORS, "ASN1 ERROR: can not handle field type %i", 140 name->type); 141 break; 142 } 143 } 144 sk_GENERAL_NAME_free (extensions); 127 i2v_GENERAL_NAMES(NULL, extension, vals); 128 numalts = sk_GENERAL_NAME_num(extension); 129 if (cert_depth == 0) 130 msg(M_INFO, "Found extension %s with %i alternative name(s)", fieldname, 131 numalts); 132 133 /* loop through all of the alternatives */ 134 for (i = 0; i < numalts; i++) 135 { 136 /* Get a handle to alternative GeneralName number "i" 137 * and to its associated OpenSSL configuration name. 138 */ 139 const GENERAL_NAME *name = sk_GENERAL_NAME_value(extension, i); 140 const CONF_VALUE *conf = sk_CONF_VALUE_value(vals, i); 141 142 switch (name->type) 143 { 144 case GEN_EMAIL: 145 ASN1_STRING_to_UTF8((unsigned char**)&buf, name->d.ia5); 146 if (strlen(buf) != name->d.ia5->length) 147 msg(D_TLS_ERRORS, 148 "ASN1 ERROR: field '%s' (%i of %i) has an embedded NUL", 149 conf->name, i, numalts); 150 else 151 if (name->d.ia5->length == 0) 152 msg(D_TLS_ERRORS, 153 "Field '%s' (%i of %i) has an empty value", 154 conf->name, i, numalts); 155 else 156 { 157 strncpynt(out, buf, size); 158 if (cert_depth == 0) 159 if (retval == SUCCESS) 160 msg(M_INFO, "Updating common name to '%s'", out); 161 else 162 msg(M_INFO, "Setting common name to '%s'", out); 163 retval = SUCCESS; 164 } 165 OPENSSL_free(buf); 166 break; 167 168 default: 169 if (cert_depth == 0) 170 msg(D_TLS_DEBUG, "Ignoring alternative type '%s'", 171 conf->name); 172 break; 173 } 174 } 175 sk_CONF_VALUE_free(vals); 145 176 } 177 sk_GENERAL_NAME_free(extension); 146 178 return retval; 147 179 } 148 180 #endif /* ENABLE_X509ALTUSERNAME */ … … extract_x509_field_ssl (X509_NAME *x509, const char *field_name, char *out, 203 235 204 236 result_t 205 237 x509_get_username (char *common_name, int cn_len, 206 char * x509_username_field, X509 *peer_cert )238 char * x509_username_field, X509 *peer_cert, int cert_depth) 207 239 { 240 result_t retval; 208 241 #ifdef ENABLE_X509ALTUSERNAME 209 if (strncmp("ext:",x509_username_field,4) == 0) 210 { 211 if (!extract_x509_extension (peer_cert, x509_username_field+4, common_name, cn_len)) 212 return FAILURE; 213 } else 242 if (strncmp("ext:", x509_username_field, 4) == 0) 243 retval = extract_x509_extension(peer_cert, cert_depth, 244 x509_username_field+4, common_name, cn_len); 245 else 214 246 #endif 215 if (FAILURE == extract_x509_field_ssl (X509_get_subject_name (peer_cert), 216 x509_username_field, common_name, cn_len)) 217 return FAILURE; 218 219 return SUCCESS; 247 retval = extract_x509_field_ssl(X509_get_subject_name(peer_cert), 248 x509_username_field, common_name, cn_len); 249 return retval; 220 250 } 221 251 222 252 char * -
src/openvpn/ssl_verify_polarssl.c
diff --git a/src/openvpn/ssl_verify_polarssl.c b/src/openvpn/ssl_verify_polarssl.c index 8931f8a..25f1550 100644
a b verify_callback (void *session_obj, x509_cert *cert, int cert_depth, 91 91 92 92 result_t 93 93 x509_get_username (char *cn, int cn_len, 94 char *x509_username_field, x509_cert *cert )94 char *x509_username_field, x509_cert *cert, int cert_depth) 95 95 { 96 96 x509_name *name; 97 97