aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gnutls_hooks.c133
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 */
212static int read_crt_cn(server_rec *s, apr_pool_t * p, gnutls_x509_crt cert, 212static 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