diff options
author | Nikos Mavrogiannopoulos | 2007-12-02 09:33:19 +0000 |
---|---|---|
committer | Nokis Mavrogiannopoulos | 2007-12-02 09:33:19 +0000 |
commit | a5dc815a9c92f6b496ac8c6bcef67e8f61e175b3 (patch) | |
tree | 0042ffce8878d5b92a9a72449640b13f70b63ebe | |
parent | ee65fcb2aaa2d599d13864090f6e567cdc91a9b0 (diff) |
export the alternative names of the certificate
-rw-r--r-- | src/gnutls_hooks.c | 133 |
1 files changed, 88 insertions, 45 deletions
diff --git a/src/gnutls_hooks.c b/src/gnutls_hooks.c index e89c7f0..6619be5 100644 --- a/src/gnutls_hooks.c +++ b/src/gnutls_hooks.c | |||
@@ -209,8 +209,8 @@ const char static_dh_params[] = "-----BEGIN DH PARAMETERS-----\n" | |||
209 | * | 209 | * |
210 | * Returns negative on error. | 210 | * Returns negative on error. |
211 | */ | 211 | */ |
212 | static int read_crt_cn(server_rec *s, apr_pool_t * p, gnutls_x509_crt cert, | 212 | static int read_crt_cn(server_rec * s, apr_pool_t * p, |
213 | char **cert_cn) | 213 | gnutls_x509_crt cert, char **cert_cn) |
214 | { | 214 | { |
215 | int rv = 0, i; | 215 | int rv = 0, i; |
216 | size_t data_len; | 216 | size_t data_len; |
@@ -225,33 +225,37 @@ static int read_crt_cn(server_rec *s, apr_pool_t * p, gnutls_x509_crt cert, | |||
225 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { | 225 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { |
226 | *cert_cn = apr_palloc(p, data_len); | 226 | *cert_cn = apr_palloc(p, data_len); |
227 | rv = gnutls_x509_crt_get_dn_by_oid(cert, | 227 | rv = gnutls_x509_crt_get_dn_by_oid(cert, |
228 | GNUTLS_OID_X520_COMMON_NAME, 0, 0, *cert_cn, &data_len); | 228 | GNUTLS_OID_X520_COMMON_NAME, 0, |
229 | 0, *cert_cn, &data_len); | ||
229 | } else { /* No CN return subject alternative name */ | 230 | } else { /* No CN return subject alternative name */ |
230 | ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, | 231 | ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, |
231 | "No common name found in certificate for '%s:%d'. Looking for subject alternative name.", | 232 | "No common name found in certificate for '%s:%d'. Looking for subject alternative name.", |
232 | s->server_hostname, s->port); | 233 | s->server_hostname, s->port); |
233 | rv = 0; | 234 | rv = 0; |
234 | /* read subject alternative name */ | 235 | /* read subject alternative name */ |
235 | for (i = 0; !(rv < 0); i++) { | 236 | for (i = 0; !(rv < 0); i++) { |
237 | data_len = 0; | ||
236 | rv = gnutls_x509_crt_get_subject_alt_name(cert, i, | 238 | rv = gnutls_x509_crt_get_subject_alt_name(cert, i, |
237 | NULL, &data_len, NULL); | 239 | NULL, &data_len, |
238 | 240 | NULL); | |
239 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { | 241 | |
240 | /* FIXME: not very efficient. What if we have several alt names | 242 | if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { |
241 | * before DNSName? | 243 | /* FIXME: not very efficient. What if we have several alt names |
242 | */ | 244 | * before DNSName? |
243 | *cert_cn = apr_palloc(p, data_len+1); | 245 | */ |
244 | 246 | *cert_cn = apr_palloc(p, data_len + 1); | |
245 | rv = gnutls_x509_crt_get_subject_alt_name(cert, i, | 247 | |
246 | *cert_cn, &data_len, NULL); | 248 | rv = gnutls_x509_crt_get_subject_alt_name(cert, i, |
247 | (*cert_cn)[data_len]=0; | 249 | *cert_cn, |
248 | 250 | &data_len, NULL); | |
249 | if (rv == GNUTLS_SAN_DNSNAME) | 251 | (*cert_cn)[data_len] = 0; |
250 | break; | 252 | |
251 | } | 253 | if (rv == GNUTLS_SAN_DNSNAME) |
254 | break; | ||
255 | } | ||
252 | } | 256 | } |
253 | } | 257 | } |
254 | 258 | ||
255 | return rv; | 259 | return rv; |
256 | 260 | ||
257 | } | 261 | } |
@@ -365,15 +369,18 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, | |||
365 | if (sc->srp_tpasswd_conf_file != NULL | 369 | if (sc->srp_tpasswd_conf_file != NULL |
366 | && sc->srp_tpasswd_file != NULL) { | 370 | && sc->srp_tpasswd_file != NULL) { |
367 | rv = gnutls_srp_set_server_credentials_file(sc->srp_creds, | 371 | rv = gnutls_srp_set_server_credentials_file(sc->srp_creds, |
368 | sc->srp_tpasswd_file, sc->srp_tpasswd_conf_file); | 372 | sc-> |
369 | 373 | srp_tpasswd_file, | |
370 | if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { | 374 | sc-> |
371 | ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, | 375 | srp_tpasswd_conf_file); |
372 | "[GnuTLS] - Host '%s:%d' is missing a " | 376 | |
373 | "SRP password or conf File!", s->server_hostname, | 377 | if (rv < 0 && sc->enabled == GNUTLS_ENABLED_TRUE) { |
374 | s->port); | 378 | ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, |
375 | exit(-1); | 379 | "[GnuTLS] - Host '%s:%d' is missing a " |
376 | } | 380 | "SRP password or conf File!", |
381 | s->server_hostname, s->port); | ||
382 | exit(-1); | ||
383 | } | ||
377 | } | 384 | } |
378 | 385 | ||
379 | if (sc->cert_x509 == NULL | 386 | if (sc->cert_x509 == NULL |
@@ -397,9 +404,9 @@ mgs_hook_post_config(apr_pool_t * p, apr_pool_t * plog, | |||
397 | if (sc->enabled == GNUTLS_ENABLED_TRUE) { | 404 | if (sc->enabled == GNUTLS_ENABLED_TRUE) { |
398 | rv = read_crt_cn(s, p, sc->cert_x509, &sc->cert_cn); | 405 | rv = read_crt_cn(s, p, sc->cert_x509, &sc->cert_cn); |
399 | if (rv < 0) { | 406 | if (rv < 0) { |
400 | ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, | 407 | ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, |
401 | "[GnuTLS] - Cannot find a certificate for host '%s:%d'!", | 408 | "[GnuTLS] - Cannot find a certificate for host '%s:%d'!", |
402 | s->server_hostname, s->port); | 409 | s->server_hostname, s->port); |
403 | sc->cert_cn = NULL; | 410 | sc->cert_cn = NULL; |
404 | continue; | 411 | continue; |
405 | } | 412 | } |
@@ -502,7 +509,7 @@ static int vhost_cb(void *baton, conn_rec * conn, server_rec * s) | |||
502 | "GnuTLS: Virtual Host CB: " | 509 | "GnuTLS: Virtual Host CB: " |
503 | "'%s' != '%s'", tsc->cert_cn, x->sni_name); | 510 | "'%s' != '%s'", tsc->cert_cn, x->sni_name); |
504 | #endif | 511 | #endif |
505 | 512 | ||
506 | } | 513 | } |
507 | return 0; | 514 | return 0; |
508 | } | 515 | } |
@@ -801,8 +808,9 @@ mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, int side, | |||
801 | unsigned char sbuf[64]; /* buffer to hold serials */ | 808 | unsigned char sbuf[64]; /* buffer to hold serials */ |
802 | char buf[AP_IOBUFSIZE]; | 809 | char buf[AP_IOBUFSIZE]; |
803 | const char *tmp; | 810 | const char *tmp; |
811 | char *tmp2; | ||
804 | size_t len; | 812 | size_t len; |
805 | int alg; | 813 | int ret, i; |
806 | 814 | ||
807 | apr_table_t *env = r->subprocess_env; | 815 | apr_table_t *env = r->subprocess_env; |
808 | 816 | ||
@@ -834,10 +842,11 @@ mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, int side, | |||
834 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL), | 842 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_M_SERIAL", NULL), |
835 | apr_pstrdup(r->pool, tmp)); | 843 | apr_pstrdup(r->pool, tmp)); |
836 | 844 | ||
837 | alg = gnutls_x509_crt_get_version(cert); | 845 | ret = gnutls_x509_crt_get_version(cert); |
838 | if (alg > 0) | 846 | if (ret > 0) |
839 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL), | 847 | apr_table_setn(env, |
840 | apr_psprintf(r->pool, "%u", alg)); | 848 | apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL), |
849 | apr_psprintf(r->pool, "%u", ret)); | ||
841 | 850 | ||
842 | tmp = | 851 | tmp = |
843 | mgs_time2sz(gnutls_x509_crt_get_expiration_time | 852 | mgs_time2sz(gnutls_x509_crt_get_expiration_time |
@@ -851,16 +860,50 @@ mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, int side, | |||
851 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL), | 860 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL), |
852 | apr_pstrdup(r->pool, tmp)); | 861 | apr_pstrdup(r->pool, tmp)); |
853 | 862 | ||
854 | alg = gnutls_x509_crt_get_signature_algorithm(cert); | 863 | ret = gnutls_x509_crt_get_signature_algorithm(cert); |
855 | if (alg >= 0) { | 864 | if (ret >= 0) { |
856 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", NULL), | 865 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_SIG", NULL), |
857 | gnutls_sign_algorithm_get_name(alg)); | 866 | gnutls_sign_algorithm_get_name(ret)); |
858 | } | 867 | } |
859 | 868 | ||
860 | alg = gnutls_x509_crt_get_pk_algorithm(cert, NULL); | 869 | ret = gnutls_x509_crt_get_pk_algorithm(cert, NULL); |
861 | if (alg >= 0) { | 870 | if (ret >= 0) { |
862 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL), | 871 | apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL), |
863 | gnutls_pk_algorithm_get_name(alg)); | 872 | gnutls_pk_algorithm_get_name(ret)); |
873 | } | ||
874 | |||
875 | /* export all the alternative names (DNS, RFC822 and URI) */ | ||
876 | for (i = 0; !(ret < 0); i++) { | ||
877 | len = 0; | ||
878 | ret = gnutls_x509_crt_get_subject_alt_name(cert, i, | ||
879 | NULL, &len, NULL); | ||
880 | |||
881 | if (ret == GNUTLS_E_SHORT_MEMORY_BUFFER && len > 1) { | ||
882 | tmp2 = apr_palloc(r->pool, len + 1); | ||
883 | |||
884 | ret = | ||
885 | gnutls_x509_crt_get_subject_alt_name(cert, i, tmp2, &len, | ||
886 | NULL); | ||
887 | tmp2[len] = 0; | ||
888 | |||
889 | if (ret == GNUTLS_SAN_DNSNAME) { | ||
890 | apr_table_setn(env, | ||
891 | apr_psprintf(r->pool, "%s_SAN%u", MGS_SIDE, i), | ||
892 | apr_psprintf(r->pool, "DNSNAME:%s", tmp2)); | ||
893 | } else if (ret == GNUTLS_SAN_RFC822NAME) { | ||
894 | apr_table_setn(env, | ||
895 | apr_psprintf(r->pool, "%s_SAN%u", MGS_SIDE, i), | ||
896 | apr_psprintf(r->pool, "RFC822NAME:%s", tmp2)); | ||
897 | } else if (ret == GNUTLS_SAN_URI) { | ||
898 | apr_table_setn(env, | ||
899 | apr_psprintf(r->pool, "%s_SAN%u", MGS_SIDE, i), | ||
900 | apr_psprintf(r->pool, "URI:%s", tmp2)); | ||
901 | } else { | ||
902 | apr_table_setn(env, | ||
903 | apr_psprintf(r->pool, "%s_SAN%u", MGS_SIDE, i), | ||
904 | "UNSUPPORTED"); | ||
905 | } | ||
906 | } | ||
864 | } | 907 | } |
865 | 908 | ||
866 | 909 | ||