Lines 32-37
Link Here
|
32 |
|
32 |
|
33 |
#include "apr_time.h" |
33 |
#include "apr_time.h" |
34 |
|
34 |
|
|
|
35 |
#ifdef HAVE_OPENSSL |
36 |
|
37 |
#include <openssl/asn1.h> |
38 |
#include <openssl/asn1t.h> |
39 |
|
40 |
/** |
41 |
* Subject Directory Attributes extension |
42 |
*/ |
43 |
typedef STACK_OF(X509_ATTRIBUTE) SUBJECT_DIRECTORY_ATTRIBUTES; |
44 |
|
45 |
ASN1_ITEM_TEMPLATE(SUBJECT_DIRECTORY_ATTRIBUTES) = |
46 |
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Attributes, X509_ATTRIBUTE) |
47 |
ASN1_ITEM_TEMPLATE_END(SUBJECT_DIRECTORY_ATTRIBUTES) |
48 |
|
49 |
DECLARE_ASN1_FUNCTIONS(SUBJECT_DIRECTORY_ATTRIBUTES) |
50 |
|
51 |
IMPLEMENT_ASN1_FUNCTIONS(SUBJECT_DIRECTORY_ATTRIBUTES) |
52 |
|
53 |
#endif |
54 |
|
35 |
/* _________________________________________________________________ |
55 |
/* _________________________________________________________________ |
36 |
** |
56 |
** |
37 |
** Variable Lookup |
57 |
** Variable Lookup |
Lines 51-56
Link Here
|
51 |
static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize); |
71 |
static void ssl_var_lookup_ssl_cipher_bits(SSL *ssl, int *usekeysize, int *algkeysize); |
52 |
static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var); |
72 |
static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var); |
53 |
static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl); |
73 |
static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl); |
|
|
74 |
static char *ssl_var_lookup_ssl_cert_ext_subject_dir_attrs(apr_pool_t *p, X509 *xs, char *var); |
54 |
|
75 |
|
55 |
static int ssl_is_https(conn_rec *c) |
76 |
static int ssl_is_https(conn_rec *c) |
56 |
{ |
77 |
{ |
Lines 399-404
Link Here
|
399 |
(nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid)); |
420 |
(nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid)); |
400 |
resdup = FALSE; |
421 |
resdup = FALSE; |
401 |
} |
422 |
} |
|
|
423 |
else if (strcEQn(var, "EXT_SDA_", 8)) { |
424 |
result = ssl_var_lookup_ssl_cert_ext_subject_dir_attrs(p, xs, var+8); |
425 |
resdup = FALSE; |
426 |
} |
402 |
else if (strcEQ(var, "CERT")) { |
427 |
else if (strcEQ(var, "CERT")) { |
403 |
result = ssl_var_lookup_ssl_cert_PEM(p, xs); |
428 |
result = ssl_var_lookup_ssl_cert_PEM(p, xs); |
404 |
} |
429 |
} |
Lines 408-413
Link Here
|
408 |
return result; |
433 |
return result; |
409 |
} |
434 |
} |
410 |
|
435 |
|
|
|
436 |
static char *ssl_var_lookup_ssl_cert_ext_subject_dir_attrs(apr_pool_t *p, X509 *xs, char *var) |
437 |
{ |
438 |
char *result = NULL; |
439 |
|
440 |
if (strcEQ(var, "GENDER")) { |
441 |
apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_gender); |
442 |
if(values != NULL) { |
443 |
char **elts = (char **) values->elts; |
444 |
result = elts[0]; |
445 |
} |
446 |
} |
447 |
else if (strlen(var) > 21 && strcEQn(var, "COUNTRYOFCITIZENSHIP_", 21)) { |
448 |
int index = atoi(var+21); |
449 |
apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_countryOfCitizenship); |
450 |
if((values != NULL) && (index < values->nelts)) { |
451 |
char **elts = (char **) values->elts; |
452 |
result = elts[index]; |
453 |
} |
454 |
} |
455 |
else if (strlen(var) > 19 && strcEQn(var, "COUNTRYOFRESIDENCE_", 19)) { |
456 |
int index = atoi(var+19); |
457 |
apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_countryOfResidence); |
458 |
if((values != NULL) && (index < values->nelts)) { |
459 |
char **elts = (char **) values->elts; |
460 |
result = elts[index]; |
461 |
} |
462 |
} |
463 |
else if (strcEQ(var, "PLACEOFBIRTH")) { |
464 |
apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_placeOfBirth); |
465 |
if(values != NULL) { |
466 |
char **elts = (char **) values->elts; |
467 |
result = elts[0]; |
468 |
} |
469 |
} |
470 |
else if (strcEQ(var, "DATEOFBIRTH")) { |
471 |
apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_dateOfBirth); |
472 |
if(values != NULL) { |
473 |
char **elts = (char **) values->elts; |
474 |
result = elts[0]; |
475 |
} |
476 |
} |
477 |
else if (strcEQ(var, "AGE")) { |
478 |
apr_array_header_t *values = ssl_ext_subject_dir_attr_lookup(p, xs, NID_id_pda_dateOfBirth); |
479 |
if(values != NULL) { |
480 |
char **elts = (char **) values->elts; |
481 |
result = get_age_from_generalizedtime_str(p, elts[0]); |
482 |
} |
483 |
} |
484 |
return result; |
485 |
} |
486 |
|
487 |
|
488 |
char *get_age_from_generalizedtime_str(apr_pool_t *p, char *str) |
489 |
{ |
490 |
char *result = NULL; |
491 |
char format[] = "%Y%m%d%H%M%S"; |
492 |
char tmp[20]; |
493 |
struct tm dateOfBirth; |
494 |
struct tm today; |
495 |
time_t now = time(0); |
496 |
gmtime_r(&now, &today); |
497 |
strptime(str, format, &dateOfBirth); |
498 |
int age = today.tm_year - dateOfBirth.tm_year - 1; |
499 |
if( (today.tm_mon > dateOfBirth.tm_mon) || ((today.tm_mon == dateOfBirth.tm_mon) && (today.tm_mday > dateOfBirth.tm_mday)) ) { |
500 |
age++; |
501 |
} |
502 |
|
503 |
sprintf(tmp, "%d", age); |
504 |
result = apr_pstrdup(p, tmp); |
505 |
return result; |
506 |
} |
507 |
|
508 |
|
411 |
/* In this table, .extract is non-zero if RDNs using the NID should be |
509 |
/* In this table, .extract is non-zero if RDNs using the NID should be |
412 |
* extracted to for the SSL_{CLIENT,SERVER}_{I,S}_DN_* environment |
510 |
* extracted to for the SSL_{CLIENT,SERVER}_{I,S}_DN_* environment |
413 |
* variables. */ |
511 |
* variables. */ |
Lines 849-854
Link Here
|
849 |
return array; |
947 |
return array; |
850 |
} |
948 |
} |
851 |
|
949 |
|
|
|
950 |
|
951 |
void *ssl_ext_get_subject_dir_attrs_object_ptr(X509 *xs) |
952 |
{ |
953 |
void *retval = NULL; |
954 |
|
955 |
#ifdef HAVE_OPENSSL |
956 |
X509_EXTENSION *ext = NULL; |
957 |
ASN1_OCTET_STRING *ext_data_ocstr = NULL; |
958 |
const unsigned char *ext_data; |
959 |
int sdaIndex; |
960 |
|
961 |
if (xs == NULL) { |
962 |
return NULL; |
963 |
} |
964 |
|
965 |
/* Search "Subject Directory Attributes" extension */ |
966 |
sdaIndex = X509_get_ext_by_NID(xs, NID_subject_directory_attributes, -1); |
967 |
if(sdaIndex < 0) { |
968 |
return NULL; |
969 |
} |
970 |
|
971 |
/* Get Subject Directory Attributes OCTET_STRING */ |
972 |
ext = X509_get_ext(xs, sdaIndex); |
973 |
ext_data_ocstr = X509_EXTENSION_get_data(ext); |
974 |
if(ext_data_ocstr == NULL) { |
975 |
return NULL; |
976 |
} |
977 |
|
978 |
/* Convert extension data (OCTET_STRING) to internal representation object */ |
979 |
ext_data = ext_data_ocstr->data; |
980 |
retval = (void *)d2i_SUBJECT_DIRECTORY_ATTRIBUTES(NULL, &ext_data, (long)ext_data_ocstr->length); |
981 |
#endif |
982 |
|
983 |
return retval; |
984 |
} |
985 |
|
986 |
|
987 |
void ssl_ext_free_subject_dir_attrs_object_ptr(void *sda_object_ptr) |
988 |
{ |
989 |
#ifdef HAVE_OPENSSL |
990 |
SUBJECT_DIRECTORY_ATTRIBUTES *sda = (SUBJECT_DIRECTORY_ATTRIBUTES *)sda_object_ptr; |
991 |
if(sda != NULL) SUBJECT_DIRECTORY_ATTRIBUTES_free(sda); |
992 |
#endif |
993 |
} |
994 |
|
995 |
|
996 |
apr_array_header_t *ssl_ext_get_subject_dir_attr_values_by_NID(apr_pool_t *p, void *sda_object_ptr, int pdaNID) |
997 |
{ |
998 |
apr_array_header_t *array = NULL; |
999 |
|
1000 |
#ifdef HAVE_OPENSSL |
1001 |
SUBJECT_DIRECTORY_ATTRIBUTES *sda = (SUBJECT_DIRECTORY_ATTRIBUTES *)sda_object_ptr; |
1002 |
int attr_index, value_index, num_values; |
1003 |
|
1004 |
if(sda == NULL) { |
1005 |
return NULL; |
1006 |
} |
1007 |
|
1008 |
/* Search pdaNID in "Subject Directory Attributes", and create an array with a copy of all attribute values (as strings) */ |
1009 |
for (attr_index = 0; attr_index < sk_X509_ATTRIBUTE_num(sda); attr_index++) { |
1010 |
X509_ATTRIBUTE *attribute = sk_X509_ATTRIBUTE_value(sda, attr_index); |
1011 |
if(pdaNID == OBJ_obj2nid(X509_ATTRIBUTE_get0_object(attribute))) { |
1012 |
|
1013 |
num_values = X509_ATTRIBUTE_count(attribute); |
1014 |
if(num_values > 0) { |
1015 |
if(array == NULL) { |
1016 |
array = apr_array_make(p, num_values, sizeof(char *)); |
1017 |
} |
1018 |
|
1019 |
for (value_index = 0; value_index < num_values; value_index++) { |
1020 |
ASN1_TYPE *type = X509_ATTRIBUTE_get0_type(attribute, value_index); |
1021 |
if(type->type == V_ASN1_GENERALIZEDTIME) { // i.e: dateOfBirth |
1022 |
ASN1_GENERALIZEDTIME *val = (ASN1_GENERALIZEDTIME *)X509_ATTRIBUTE_get0_data(attribute, value_index, type->type, NULL); |
1023 |
char **ptr = apr_array_push(array); |
1024 |
*ptr = apr_pstrdup(p, val->data); |
1025 |
} else { // ASN1_STRING |
1026 |
ASN1_STRING *val = (ASN1_STRING *)X509_ATTRIBUTE_get0_data(attribute, value_index, type->type, NULL); |
1027 |
char **ptr = apr_array_push(array); |
1028 |
*ptr = apr_pstrdup(p, val->data); |
1029 |
} |
1030 |
} |
1031 |
} |
1032 |
|
1033 |
} |
1034 |
} |
1035 |
|
1036 |
ERR_clear_error(); |
1037 |
#endif |
1038 |
|
1039 |
return array; |
1040 |
} |
1041 |
|
1042 |
apr_array_header_t *ssl_ext_subject_dir_attr_lookup(apr_pool_t *p, X509 *xs, int pdaNID) |
1043 |
{ |
1044 |
apr_array_header_t *array = NULL; |
1045 |
void *sda_object_ptr = NULL; |
1046 |
|
1047 |
/* Check certificate */ |
1048 |
if(xs == NULL) { |
1049 |
return NULL; |
1050 |
} |
1051 |
|
1052 |
/* Check "Subject Directory Attributes" */ |
1053 |
sda_object_ptr = ssl_ext_get_subject_dir_attrs_object_ptr(xs); |
1054 |
if(sda_object_ptr == NULL) { |
1055 |
return NULL; |
1056 |
} |
1057 |
|
1058 |
array = ssl_ext_get_subject_dir_attr_values_by_NID(p, sda_object_ptr, pdaNID); |
1059 |
|
1060 |
ssl_ext_free_subject_dir_attrs_object_ptr(sda_object_ptr); |
1061 |
|
1062 |
return array; |
1063 |
} |
1064 |
|
1065 |
|
852 |
static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl) |
1066 |
static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl) |
853 |
{ |
1067 |
{ |
854 |
char *result = "NULL"; |
1068 |
char *result = "NULL"; |