diff options
Diffstat (limited to 'src')
| -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 | ||
