ASF Bugzilla – Attachment 23967 Details for
Bug 47514
Personal data and restrictions based on subject directory attributes extension
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch to add basic suport for Subject Directory Attributes extension (revision 2)
mod_ssl_with_subject_dir_attrs_patch_r2.diff (text/plain), 13.34 KB, created by
Jordi Marine
on 2009-07-13 06:38:56 UTC
(
hide
)
Description:
Patch to add basic suport for Subject Directory Attributes extension (revision 2)
Filename:
MIME Type:
Creator:
Jordi Marine
Created:
2009-07-13 06:38:56 UTC
Size:
13.34 KB
patch
obsolete
>Index: httpd-trunk/modules/ssl/ssl_private.h >=================================================================== >--- httpd-trunk/modules/ssl/ssl_private.h (revision 793375) >+++ httpd-trunk/modules/ssl/ssl_private.h (working copy) >@@ -199,7 +199,8 @@ > #define SSL_OPT_FAKEBASICAUTH (1<<4) > #define SSL_OPT_STRICTREQUIRE (1<<5) > #define SSL_OPT_OPTRENEGOTIATE (1<<6) >-#define SSL_OPT_ALL (SSL_OPT_STDENVVARS|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH|SSL_OPT_STRICTREQUIRE|SSL_OPT_OPTRENEGOTIATE) >+#define SSL_OPT_SUBJECTDIRATTR (1<<7) >+#define SSL_OPT_ALL (SSL_OPT_STDENVVARS|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH|SSL_OPT_STRICTREQUIRE|SSL_OPT_OPTRENEGOTIATE|SSL_OPT_SUBJECTDIRATTR) > typedef int ssl_opt_t; > > /** >@@ -504,6 +505,7 @@ > apr_size_t nRenegBufferSize; > } SSLDirConfigRec; > >+ > /** > * function prototypes > */ >@@ -690,7 +692,13 @@ > void ssl_var_register(apr_pool_t *p); > char *ssl_var_lookup(apr_pool_t *, server_rec *, conn_rec *, request_rec *, char *); > apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, const char *extension); >+apr_array_header_t *ssl_ext_subject_dir_attr_lookup(apr_pool_t *p, X509 *xs, int nid); >+apr_array_header_t *ssl_ext_get_subject_dir_attr_values_by_NID(apr_pool_t *p, void *sda_object_ptr, int pdaNID); >+void *ssl_ext_get_subject_dir_attrs_object_ptr(X509 *xs); >+void ssl_ext_free_subject_dir_attrs_object_ptr(void *sda_object_ptr); >+char *get_age_from_generalizedtime_str(apr_pool_t *p, char *str); > >+ > void ssl_var_log_config_register(apr_pool_t *p); > > /* Extract SSL_*_DN_* variables into table 't' from SSL object 'ssl', >Index: httpd-trunk/modules/ssl/ssl_engine_config.c >=================================================================== >--- httpd-trunk/modules/ssl/ssl_engine_config.c (revision 793375) >+++ httpd-trunk/modules/ssl/ssl_engine_config.c (working copy) >@@ -1100,6 +1100,9 @@ > else if (strcEQ(w, "OptRenegotiate")) { > opt = SSL_OPT_OPTRENEGOTIATE; > } >+ else if (strcEQ(w, "SubjectDirAttrVars")) { >+ opt = SSL_OPT_SUBJECTDIRATTR; >+ } > else { > return apr_pstrcat(cmd->pool, > "SSLOptions: Illegal option '", w, "'", >Index: httpd-trunk/modules/ssl/ssl_engine_vars.c >=================================================================== >--- httpd-trunk/modules/ssl/ssl_engine_vars.c (revision 793375) >+++ httpd-trunk/modules/ssl/ssl_engine_vars.c (working copy) >@@ -32,6 +32,26 @@ > > #include "apr_time.h" > >+#ifdef HAVE_OPENSSL >+ >+#include <openssl/asn1.h> >+#include <openssl/asn1t.h> >+ >+/** >+ * Subject Directory Attributes extension >+ */ >+typedef STACK_OF(X509_ATTRIBUTE) SUBJECT_DIRECTORY_ATTRIBUTES; >+ >+ASN1_ITEM_TEMPLATE(SUBJECT_DIRECTORY_ATTRIBUTES) = >+ ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Attributes, X509_ATTRIBUTE) >+ASN1_ITEM_TEMPLATE_END(SUBJECT_DIRECTORY_ATTRIBUTES) >+ >+DECLARE_ASN1_FUNCTIONS(SUBJECT_DIRECTORY_ATTRIBUTES) >+ >+IMPLEMENT_ASN1_FUNCTIONS(SUBJECT_DIRECTORY_ATTRIBUTES) >+ >+#endif >+ > /* _________________________________________________________________ > ** > ** Variable Lookup >@@ -51,6 +71,7 @@ > static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize); > static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var); > static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl); >+static char *ssl_var_lookup_ssl_cert_ext_subject_dir_attrs(apr_pool_t *p, X509 *xs, char *var); > > static int ssl_is_https(conn_rec *c) > { >@@ -399,6 +420,10 @@ > (nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid)); > resdup = FALSE; > } >+ else if (strcEQn(var, "EXT_SDA_", 8)) { >+ result = ssl_var_lookup_ssl_cert_ext_subject_dir_attrs(p, xs, var+8); >+ resdup = FALSE; >+ } > else if (strcEQ(var, "CERT")) { > result = ssl_var_lookup_ssl_cert_PEM(p, xs); > } >@@ -408,6 +433,79 @@ > return result; > } > >+static char *ssl_var_lookup_ssl_cert_ext_subject_dir_attrs(apr_pool_t *p, X509 *xs, char *var) >+{ >+ char *result = NULL; >+ >+ if (strcEQ(var, "GENDER")) { >+ apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_gender); >+ if(values != NULL) { >+ char **elts = (char **) values->elts; >+ result = elts[0]; >+ } >+ } >+ else if (strlen(var) > 21 && strcEQn(var, "COUNTRYOFCITIZENSHIP_", 21)) { >+ int index = atoi(var+21); >+ apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_countryOfCitizenship); >+ if((values != NULL) && (index < values->nelts)) { >+ char **elts = (char **) values->elts; >+ result = elts[index]; >+ } >+ } >+ else if (strlen(var) > 19 && strcEQn(var, "COUNTRYOFRESIDENCE_", 19)) { >+ int index = atoi(var+19); >+ apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_countryOfResidence); >+ if((values != NULL) && (index < values->nelts)) { >+ char **elts = (char **) values->elts; >+ result = elts[index]; >+ } >+ } >+ else if (strcEQ(var, "PLACEOFBIRTH")) { >+ apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_placeOfBirth); >+ if(values != NULL) { >+ char **elts = (char **) values->elts; >+ result = elts[0]; >+ } >+ } >+ else if (strcEQ(var, "DATEOFBIRTH")) { >+ apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_dateOfBirth); >+ if(values != NULL) { >+ char **elts = (char **) values->elts; >+ result = elts[0]; >+ } >+ } >+ else if (strcEQ(var, "AGE")) { >+ apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_dateOfBirth); >+ if(values != NULL) { >+ char **elts = (char **) values->elts; >+ result = get_age_from_generalizedtime_str(p, elts[0]); >+ } >+ } >+ return result; >+} >+ >+ >+char *get_age_from_generalizedtime_str(apr_pool_t *p, char *str) >+{ >+ char *result = NULL; >+ char format[] = "%Y%m%d%H%M%S"; >+ char tmp[20]; >+ struct tm dateOfBirth; >+ struct tm today; >+ time_t now = time(0); >+ gmtime_r(&now, &today); >+ strptime(str, format, &dateOfBirth); >+ int age = today.tm_year - dateOfBirth.tm_year - 1; >+ if( (today.tm_mon > dateOfBirth.tm_mon) || ((today.tm_mon == dateOfBirth.tm_mon) && (today.tm_mday > dateOfBirth.tm_mday)) ) { >+ age++; >+ } >+ >+ sprintf(tmp, "%d", age); >+ result = apr_pstrdup(p, tmp); >+ return result; >+} >+ >+ > /* In this table, .extract is non-zero if RDNs using the NID should be > * extracted to for the SSL_{CLIENT,SERVER}_{I,S}_DN_* environment > * variables. */ >@@ -849,6 +947,122 @@ > return array; > } > >+ >+void *ssl_ext_get_subject_dir_attrs_object_ptr(X509 *xs) >+{ >+ void *retval = NULL; >+ >+#ifdef HAVE_OPENSSL >+ X509_EXTENSION *ext = NULL; >+ ASN1_OCTET_STRING *ext_data_ocstr = NULL; >+ const unsigned char *ext_data; >+ int sdaIndex; >+ >+ if (xs == NULL) { >+ return NULL; >+ } >+ >+ /* Search "Subject Directory Attributes" extension */ >+ sdaIndex = X509_get_ext_by_NID(xs, NID_subject_directory_attributes, -1); >+ if(sdaIndex < 0) { >+ return NULL; >+ } >+ >+ /* Get Subject Directory Attributes OCTET_STRING */ >+ ext = X509_get_ext(xs, sdaIndex); >+ ext_data_ocstr = X509_EXTENSION_get_data(ext); >+ if(ext_data_ocstr == NULL) { >+ return NULL; >+ } >+ >+ /* Convert extension data (OCTET_STRING) to internal representation object */ >+ ext_data = ext_data_ocstr->data; >+ retval = (void *)d2i_SUBJECT_DIRECTORY_ATTRIBUTES(NULL, &ext_data, (long)ext_data_ocstr->length); >+#endif >+ >+ return retval; >+} >+ >+ >+void ssl_ext_free_subject_dir_attrs_object_ptr(void *sda_object_ptr) >+{ >+#ifdef HAVE_OPENSSL >+ SUBJECT_DIRECTORY_ATTRIBUTES *sda = (SUBJECT_DIRECTORY_ATTRIBUTES *)sda_object_ptr; >+ if(sda != NULL) SUBJECT_DIRECTORY_ATTRIBUTES_free(sda); >+#endif >+} >+ >+ >+apr_array_header_t *ssl_ext_get_subject_dir_attr_values_by_NID(apr_pool_t *p, void *sda_object_ptr, int pdaNID) >+{ >+ apr_array_header_t *array = NULL; >+ >+#ifdef HAVE_OPENSSL >+ SUBJECT_DIRECTORY_ATTRIBUTES *sda = (SUBJECT_DIRECTORY_ATTRIBUTES *)sda_object_ptr; >+ int attr_index, value_index, num_values; >+ >+ if(sda == NULL) { >+ return NULL; >+ } >+ >+ /* Search pdaNID in "Subject Directory Attributes", and create an array with a copy of all attribute values (as strings) */ >+ for (attr_index = 0; attr_index < sk_X509_ATTRIBUTE_num(sda); attr_index++) { >+ X509_ATTRIBUTE *attribute = sk_X509_ATTRIBUTE_value(sda, attr_index); >+ if(pdaNID == OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attribute))) { >+ >+ num_values = X509_ATTRIBUTE_count(attribute); >+ if(num_values > 0) { >+ if(array == NULL) { >+ array = apr_array_make(p, num_values, sizeof(char *)); >+ } >+ >+ for (value_index = 0; value_index < num_values; value_index++) { >+ ASN1_TYPE *type = X509_ATTRIBUTE_get0_type(attribute, value_index); >+ if(type->type == V_ASN1_GENERALIZEDTIME) { // i.e: dateOfBirth >+ ASN1_GENERALIZEDTIME *val = (ASN1_GENERALIZEDTIME *)X509_ATTRIBUTE_get0_data(attribute, value_index, type->type, NULL); >+ char **ptr = apr_array_push(array); >+ *ptr = apr_pstrdup(p, val->data); >+ } else { // ASN1_STRING >+ ASN1_STRING *val = (ASN1_STRING *)X509_ATTRIBUTE_get0_data(attribute, value_index, type->type, NULL); >+ char **ptr = apr_array_push(array); >+ *ptr = apr_pstrdup(p, val->data); >+ } >+ } >+ } >+ >+ } >+ } >+ >+ ERR_clear_error(); >+#endif >+ >+ return array; >+} >+ >+apr_array_header_t *ssl_ext_subject_dir_attr_lookup(apr_pool_t *p, X509 *xs, int pdaNID) >+{ >+ apr_array_header_t *array = NULL; >+ void *sda_object_ptr = NULL; >+ >+ /* Check certificate */ >+ if(xs == NULL) { >+ return NULL; >+ } >+ >+ /* Check "Subject Directory Attributes" */ >+ sda_object_ptr = ssl_ext_get_subject_dir_attrs_object_ptr(xs); >+ if(sda_object_ptr == NULL) { >+ return NULL; >+ } >+ >+ array = ssl_ext_get_subject_dir_attr_values_by_NID(p, sda_object_ptr, pdaNID); >+ >+ ssl_ext_free_subject_dir_attrs_object_ptr(sda_object_ptr); >+ >+ return array; >+} >+ >+ > static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl) > { > char *result = "NULL"; >Index: httpd-trunk/modules/ssl/ssl_engine_kernel.c >=================================================================== >--- httpd-trunk/modules/ssl/ssl_engine_kernel.c (revision 793375) >+++ httpd-trunk/modules/ssl/ssl_engine_kernel.c (working copy) >@@ -1133,6 +1133,67 @@ > } > } > >+ /* >+ * On-demand subject directory attributes >+ */ >+ if (dc->nOptions & SSL_OPT_SUBJECTDIRATTR) { >+ apr_array_header_t *array; >+ X509 *peercert = SSL_get_peer_certificate(ssl); >+ void *sda_object_ptr = ssl_ext_get_subject_dir_attrs_object_ptr(peercert); >+ >+ if(sda_object_ptr != NULL) { >+ >+ array = ssl_ext_get_subject_dir_attr_values_by_NID(r->pool, sda_object_ptr, NID_id_pda_dateOfBirth); >+ if( (array != NULL) && (array->nelts > 0) ) { >+ char **elts = (char **) array->elts; >+ val = elts[0]; >+ apr_table_setn(env, "SSL_CLIENT_EXT_SDA_DATEOFBIRTH", val); >+ apr_table_setn(env, "SSL_CLIENT_EXT_SDA_AGE", get_age_from_generalizedtime_str(r->pool, val)); >+ } >+ >+ array = ssl_ext_get_subject_dir_attr_values_by_NID(r->pool, sda_object_ptr, NID_id_pda_gender); >+ if( (array != NULL) && (array->nelts > 0) ) { >+ char **elts = (char **) array->elts; >+ val = elts[0]; >+ apr_table_setn(env, "SSL_CLIENT_EXT_SDA_GENDER", val); >+ } >+ >+ array = ssl_ext_get_subject_dir_attr_values_by_NID(r->pool, sda_object_ptr, NID_id_pda_placeOfBirth); >+ if( (array != NULL) && (array->nelts > 0) ) { >+ char **elts = (char **) array->elts; >+ val = elts[0]; >+ apr_table_setn(env, "SSL_CLIENT_EXT_SDA_PLACEOFBIRTH", val); >+ } >+ >+ array = ssl_ext_get_subject_dir_attr_values_by_NID(r->pool, sda_object_ptr, NID_id_pda_countryOfResidence); >+ if( (array != NULL) && (array->nelts > 0) ) { >+ for(i = 0; i < array->nelts; i++) { >+ char **elts = (char **) array->elts; >+ val = elts[i]; >+ var = apr_psprintf(r->pool, "SSL_CLIENT_EXT_SDA_COUNTRYOFRESIDENCE_%d", i); >+ apr_table_setn(env, var, val); >+ } >+ } >+ >+ array = ssl_ext_get_subject_dir_attr_values_by_NID(r->pool, sda_object_ptr, NID_id_pda_countryOfCitizenship); >+ if( (array != NULL) && (array->nelts > 0) ) { >+ for(i = 0; i < array->nelts; i++) { >+ char **elts = (char **) array->elts; >+ val = elts[i]; >+ var = apr_psprintf(r->pool, "SSL_CLIENT_EXT_SDA_COUNTRYOFCITIZENSHIP_%d", i); >+ apr_table_setn(env, var, val); >+ } >+ } >+ >+ ssl_ext_free_subject_dir_attrs_object_ptr(sda_object_ptr); >+ } >+ >+ if(peercert != NULL) { >+ X509_free(peercert); >+ } >+ >+ } >+ > return DECLINED; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 47514
:
23961
| 23967