Changeset e5bbda4 in mod_gnutls for src/gnutls_hooks.c
- Timestamp:
- Dec 15, 2007, 8:26:01 AM (15 years ago)
- Branches:
- asyncio, debian/master, debian/stretch-backports, jessie-backports, main, master, msva, proxy-ticket, upstream
- Children:
- 5542bc6
- Parents:
- d2439b9
- git-author:
- Nikos Mavrogiannopoulos <nmav@…> (12/15/07 08:26:01)
- git-committer:
- Nokis Mavrogiannopoulos <nmav@…> (12/15/07 08:26:01)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/gnutls_hooks.c
rd2439b9 re5bbda4 37 37 static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt); 38 38 /* use side==0 for server and side==1 for client */ 39 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, 39 static void mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, 40 int side, 41 int export_certificates_enabled); 42 static void mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, 40 43 int side, 41 44 int export_certificates_enabled); … … 70 73 71 74 ret = gnutls_global_init(); 75 if (ret < 0) /* FIXME: can we print here? */ 76 exit(ret); 77 78 ret = gnutls_global_init_extra(); 72 79 if (ret < 0) /* FIXME: can we print here? */ 73 80 exit(ret); … … 88 95 } 89 96 90 /* We don't support openpgp certificates, yet */91 const static int cert_type_prio[2] = { GNUTLS_CRT_X509, 0 };92 93 97 static int mgs_select_virtual_server_cb(gnutls_session_t session) 94 98 { … … 96 100 mgs_srvconf_rec *tsc; 97 101 int ret; 102 int cprio[3] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; 98 103 99 104 ctxt = gnutls_transport_get_ptr(session); … … 127 132 */ 128 133 ret = gnutls_priority_set(session, ctxt->sc->priorities); 129 gnutls_certificate_type_set_priority(session, cert_type_prio); 130 134 135 /* Do not allow the user to override certificate priorities. We know 136 * better if the certificate of certain type is enabled. */ 137 if (ctxt->sc->cert_pgp != NULL && ctxt->sc->certs_x509[0] != NULL) { 138 gnutls_certificate_type_set_priority( session, cprio); 139 } else if (ctxt->sc->certs_x509[0] != NULL) { 140 cprio[0] = GNUTLS_CRT_X509; 141 cprio[1] = 0; 142 gnutls_certificate_type_set_priority( session, cprio); 143 } else if (ctxt->sc->cert_pgp != NULL) { 144 cprio[0] = GNUTLS_CRT_OPENPGP; 145 cprio[1] = 0; 146 gnutls_certificate_type_set_priority( session, cprio); 147 } 131 148 132 149 /* actually it shouldn't fail since we have checked at startup */ … … 144 161 ctxt = gnutls_transport_get_ptr(session); 145 162 146 ret->type = GNUTLS_CRT_X509; 147 ret->ncerts = ctxt->sc->certs_x509_num; 148 ret->deinit_all = 0; 149 150 ret->cert.x509 = ctxt->sc->certs_x509; 151 ret->key.x509 = ctxt->sc->privkey_x509; 152 return 0; 163 if (gnutls_certificate_type_get( session) == GNUTLS_CRT_X509) { 164 ret->type = GNUTLS_CRT_X509; 165 ret->ncerts = ctxt->sc->certs_x509_num; 166 ret->deinit_all = 0; 167 168 ret->cert.x509 = ctxt->sc->certs_x509; 169 ret->key.x509 = ctxt->sc->privkey_x509; 170 171 return 0; 172 } else if (gnutls_certificate_type_get( session) == GNUTLS_CRT_OPENPGP) { 173 ret->type = GNUTLS_CRT_OPENPGP; 174 ret->ncerts = 1; 175 ret->deinit_all = 0; 176 177 ret->cert.pgp = ctxt->sc->cert_pgp; 178 ret->key.pgp = ctxt->sc->privkey_pgp; 179 180 return 0; 181 182 } 183 184 return GNUTLS_E_INTERNAL_ERROR; 153 185 } 154 186 … … 168 200 */ 169 201 static int read_crt_cn(server_rec * s, apr_pool_t * p, 170 gnutls_x509_crt cert, char **cert_cn)202 gnutls_x509_crt_t cert, char **cert_cn) 171 203 { 172 204 int rv = 0, i; … … 176 208 *cert_cn = NULL; 177 209 210 data_len = 0; 178 211 rv = gnutls_x509_crt_get_dn_by_oid(cert, 179 212 GNUTLS_OID_X520_COMMON_NAME, … … 187 220 } else { /* No CN return subject alternative name */ 188 221 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, 189 "No common name found in certificate for '%s:%d'. Looking for subject alternative name. ",222 "No common name found in certificate for '%s:%d'. Looking for subject alternative name...", 190 223 s->server_hostname, s->port); 191 224 rv = 0; … … 215 248 216 249 return rv; 217 218 } 250 } 251 252 static int read_pgpcrt_cn(server_rec * s, apr_pool_t * p, 253 gnutls_openpgp_crt_t cert, char **cert_cn) 254 { 255 int rv = 0; 256 size_t data_len; 257 258 259 *cert_cn = NULL; 260 261 data_len = 0; 262 rv = gnutls_openpgp_crt_get_name(cert, 0, NULL, &data_len); 263 264 if (rv == GNUTLS_E_SHORT_MEMORY_BUFFER && data_len > 1) { 265 *cert_cn = apr_palloc(p, data_len); 266 rv = gnutls_openpgp_crt_get_name(cert, 0, *cert_cn, &data_len); 267 } else { /* No CN return subject alternative name */ 268 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, 269 "No name found in PGP certificate for '%s:%d'.", 270 s->server_hostname, s->port); 271 } 272 273 return rv; 274 } 275 219 276 220 277 int … … 351 408 if (sc->enabled == GNUTLS_ENABLED_TRUE) { 352 409 rv = read_crt_cn(s, p, sc->certs_x509[0], &sc->cert_cn); 410 if (rv < 0) /* try openpgp certificate */ 411 rv = read_pgpcrt_cn(s, p, sc->cert_pgp, &sc->cert_cn); 412 353 413 if (rv < 0) { 354 414 ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, … … 479 539 ctxt = gnutls_transport_get_ptr(session); 480 540 481 sni_type = gnutls_certificate_type_get(session);482 if (sni_type != GNUTLS_CRT_X509) {483 /* In theory, we could support OpenPGP Certificates. Theory != code. */484 ap_log_error(APLOG_MARK, APLOG_CRIT, 0,485 ctxt->c->base_server,486 "GnuTLS: Only x509 Certificates are currently supported.");487 return NULL;488 }489 490 541 rv = gnutls_server_name_get(ctxt->session, sni_name, 491 542 &data_len, &sni_type, 0); … … 685 736 apr_table_setn(env, "SSL_SESSION_ID", apr_pstrdup(r->pool, tmp)); 686 737 687 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0, 738 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) 739 mgs_add_common_cert_vars(r, ctxt->sc->certs_x509[0], 0, 740 ctxt->sc->export_certificates_enabled); 741 else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) 742 mgs_add_common_pgpcert_vars(r, ctxt->sc->cert_pgp, 0, 688 743 ctxt->sc->export_certificates_enabled); 689 744 … … 747 802 #define MGS_SIDE ((side==0)?"SSL_SERVER":"SSL_CLIENT") 748 803 static void 749 mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt cert, int side,804 mgs_add_common_cert_vars(request_rec * r, gnutls_x509_crt_t cert, int side, 750 805 int export_certificates_enabled) 751 806 { … … 853 908 } 854 909 } 855 856 857 } 858 859 910 } 911 912 static void 913 mgs_add_common_pgpcert_vars(request_rec * r, gnutls_openpgp_crt_t cert, int side, 914 int export_certificates_enabled) 915 { 916 unsigned char sbuf[64]; /* buffer to hold serials */ 917 char buf[AP_IOBUFSIZE]; 918 const char *tmp; 919 size_t len; 920 int ret; 921 922 apr_table_t *env = r->subprocess_env; 923 924 if (export_certificates_enabled != 0) { 925 char cert_buf[10 * 1024]; 926 len = sizeof(cert_buf); 927 928 if (gnutls_openpgp_crt_export 929 (cert, GNUTLS_OPENPGP_FMT_BASE64, cert_buf, &len) >= 0) 930 apr_table_setn(env, 931 apr_pstrcat(r->pool, MGS_SIDE, "_CERT", NULL), 932 apr_pstrmemdup(r->pool, cert_buf, len)); 933 934 } 935 936 len = sizeof(buf); 937 gnutls_openpgp_crt_get_name(cert, 0, buf, &len); 938 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_NAME", NULL), 939 apr_pstrmemdup(r->pool, buf, len)); 940 941 len = sizeof(sbuf); 942 gnutls_openpgp_crt_get_fingerprint(cert, sbuf, &len); 943 tmp = mgs_session_id2sz(sbuf, len, buf, sizeof(buf)); 944 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_FINGERPRINT", NULL), 945 apr_pstrdup(r->pool, tmp)); 946 947 ret = gnutls_openpgp_crt_get_version(cert); 948 if (ret > 0) 949 apr_table_setn(env, 950 apr_pstrcat(r->pool, MGS_SIDE, "_M_VERSION", NULL), 951 apr_psprintf(r->pool, "%u", ret)); 952 953 apr_table_setn(env, 954 apr_pstrcat(r->pool, MGS_SIDE, "_CERT_TYPE", NULL), "OPENPGP"); 955 956 tmp = 957 mgs_time2sz(gnutls_openpgp_crt_get_expiration_time 958 (cert), buf, sizeof(buf)); 959 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_END", NULL), 960 apr_pstrdup(r->pool, tmp)); 961 962 tmp = 963 mgs_time2sz(gnutls_openpgp_crt_get_creation_time 964 (cert), buf, sizeof(buf)); 965 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_V_START", NULL), 966 apr_pstrdup(r->pool, tmp)); 967 968 ret = gnutls_openpgp_crt_get_pk_algorithm(cert, NULL); 969 if (ret >= 0) { 970 apr_table_setn(env, apr_pstrcat(r->pool, MGS_SIDE, "_A_KEY", NULL), 971 gnutls_pk_algorithm_get_name(ret)); 972 } 973 974 } 975 976 /* FIXME: Allow client sending a certificate chain */ 860 977 static int mgs_cert_verify(request_rec * r, mgs_handle_t * ctxt) 861 978 { … … 863 980 unsigned int cert_list_size, status, expired; 864 981 int rv, ret; 865 gnutls_x509_crt_t cert; 982 union { 983 gnutls_x509_crt_t x509; 984 gnutls_openpgp_crt_t pgp; 985 } cert; 866 986 apr_time_t activation_time, expiration_time, cur_time; 867 987 … … 889 1009 } 890 1010 891 gnutls_x509_crt_init(&cert); 892 rv = gnutls_x509_crt_import(cert, &cert_list[0], GNUTLS_X509_FMT_DER); 1011 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) { 1012 gnutls_x509_crt_init(&cert.x509); 1013 rv = gnutls_x509_crt_import(cert.x509, &cert_list[0], GNUTLS_X509_FMT_DER); 1014 } else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) { 1015 gnutls_openpgp_crt_init(&cert.pgp); 1016 rv = gnutls_openpgp_crt_import(cert.pgp, &cert_list[0], GNUTLS_OPENPGP_FMT_RAW); 1017 } else return HTTP_FORBIDDEN; 1018 893 1019 if (rv < 0) { 894 1020 ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, 895 1021 "GnuTLS: Failed to Verify Peer: " 896 1022 "Failed to import peer certificates."); 897 ret = HTTP_FORBIDDEN; 898 goto exit; 899 } 900 901 apr_time_ansi_put(&expiration_time, 902 gnutls_x509_crt_get_expiration_time(cert)); 903 apr_time_ansi_put(&activation_time, 904 gnutls_x509_crt_get_activation_time(cert)); 905 906 rv = gnutls_x509_crt_verify(cert, ctxt->sc->ca_list, 1023 ret = HTTP_FORBIDDEN; 1024 goto exit; 1025 } 1026 1027 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) { 1028 apr_time_ansi_put(&expiration_time, 1029 gnutls_x509_crt_get_expiration_time(cert.x509)); 1030 apr_time_ansi_put(&activation_time, 1031 gnutls_x509_crt_get_activation_time(cert.x509)); 1032 1033 rv = gnutls_x509_crt_verify(cert.x509, ctxt->sc->ca_list, 907 1034 ctxt->sc->ca_list_size, 0, &status); 1035 } else { 1036 apr_time_ansi_put(&expiration_time, 1037 gnutls_openpgp_crt_get_expiration_time(cert.pgp)); 1038 apr_time_ansi_put(&activation_time, 1039 gnutls_openpgp_crt_get_creation_time(cert.pgp)); 1040 1041 rv = gnutls_openpgp_crt_verify_ring(cert.pgp, ctxt->sc->pgp_list, 1042 0, &status); 1043 } 1044 908 1045 909 1046 if (rv < 0) { … … 958 1095 // rv = mgs_authz_lua(r); 959 1096 960 mgs_add_common_cert_vars(r, cert, 1, 1097 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) 1098 mgs_add_common_cert_vars(r, cert.x509, 1, 1099 ctxt->sc->export_certificates_enabled); 1100 else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) 1101 mgs_add_common_pgpcert_vars(r, cert.pgp, 1, 961 1102 ctxt->sc->export_certificates_enabled); 962 1103 … … 982 1123 983 1124 exit: 984 gnutls_x509_crt_deinit(cert); 1125 if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_X509) 1126 gnutls_x509_crt_deinit(cert.x509); 1127 else if (gnutls_certificate_type_get( ctxt->session) == GNUTLS_CRT_OPENPGP) 1128 gnutls_openpgp_crt_deinit(cert.pgp); 985 1129 return ret; 986 1130
Note: See TracChangeset
for help on using the changeset viewer.