| OLD | NEW |
| 1 /* |
| 2 * Copyright 2016 The Netty Project |
| 3 * |
| 4 * The Netty Project licenses this file to you under the Apache License, |
| 5 * version 2.0 (the "License"); you may not use this file except in compliance |
| 6 * with the License. You may obtain a copy of the License at: |
| 7 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * |
| 10 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 13 * License for the specific language governing permissions and limitations |
| 14 * under the License. |
| 15 */ |
| 1 /* Licensed to the Apache Software Foundation (ASF) under one or more | 16 /* Licensed to the Apache Software Foundation (ASF) under one or more |
| 2 * contributor license agreements. See the NOTICE file distributed with | 17 * contributor license agreements. See the NOTICE file distributed with |
| 3 * this work for additional information regarding copyright ownership. | 18 * this work for additional information regarding copyright ownership. |
| 4 * The ASF licenses this file to You under the Apache License, Version 2.0 | 19 * The ASF licenses this file to You under the Apache License, Version 2.0 |
| 5 * (the "License"); you may not use this file except in compliance with | 20 * (the "License"); you may not use this file except in compliance with |
| 6 * the License. You may obtain a copy of the License at | 21 * the License. You may obtain a copy of the License at |
| 7 * | 22 * |
| 8 * http://www.apache.org/licenses/LICENSE-2.0 | 23 * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 * | 24 * |
| 10 * Unless required by applicable law or agreed to in writing, software | 25 * Unless required by applicable law or agreed to in writing, software |
| 11 * distributed under the License is distributed on an "AS IS" BASIS, | 26 * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | 27 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 * See the License for the specific language governing permissions and | 28 * See the License for the specific language governing permissions and |
| 14 * limitations under the License. | 29 * limitations under the License. |
| 15 */ | 30 */ |
| 16 | 31 |
| 17 /** SSL Utilities | |
| 18 * | |
| 19 * @author Mladen Turk | |
| 20 * @version $Id: sslutils.c 1658728 2015-02-10 14:45:19Z kkolinko $ | |
| 21 */ | |
| 22 | |
| 23 #include "tcn.h" | 32 #include "tcn.h" |
| 24 | 33 |
| 25 #ifdef HAVE_OPENSSL | |
| 26 #include "apr_poll.h" | |
| 27 #include "ssl_private.h" | 34 #include "ssl_private.h" |
| 28 | 35 |
| 29 #ifdef WIN32 | |
| 30 extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data); | |
| 31 #endif | |
| 32 | |
| 33 #ifdef HAVE_OPENSSL_OCSP | |
| 34 #include <openssl/bio.h> | |
| 35 #include <openssl/ocsp.h> | |
| 36 /* defines with the values as seen by the asn1parse -dump openssl command */ | |
| 37 #define ASN1_SEQUENCE 0x30 | |
| 38 #define ASN1_OID 0x06 | |
| 39 #define ASN1_STRING 0x86 | |
| 40 #pragma message("Using OCSP") | |
| 41 static int ssl_verify_OCSP(int ok, X509_STORE_CTX *ctx); | |
| 42 static int ssl_ocsp_request(X509 *cert, X509 *issuer); | |
| 43 #endif | |
| 44 | |
| 45 /* _________________________________________________________________ | 36 /* _________________________________________________________________ |
| 46 ** | 37 ** |
| 47 ** Additional High-Level Functions for OpenSSL | 38 ** Additional High-Level Functions for OpenSSL |
| 48 ** _________________________________________________________________ | 39 ** _________________________________________________________________ |
| 49 */ | 40 */ |
| 50 | 41 |
| 42 |
| 43 /* |
| 44 * Adapted from OpenSSL: |
| 45 * http://osxr.org/openssl/source/ssl/ssl_locl.h#0291 |
| 46 */ |
| 47 /* Bits for algorithm_mkey (key exchange algorithm) */ |
| 48 #define SSL_kRSA 0x00000001L /* RSA key exchange */ |
| 49 #define SSL_kDHr 0x00000002L /* DH cert, RSA CA cert */ /* no such cipher
suites supported! */ |
| 50 #define SSL_kDHd 0x00000004L /* DH cert, DSA CA cert */ /* no such cipher
suite supported! */ |
| 51 #define SSL_kEDH 0x00000008L /* tmp DH key no DH cert */ |
| 52 #define SSL_kKRB5 0x00000010L /* Kerberos5 key exchange */ |
| 53 #define SSL_kECDHr 0x00000020L /* ECDH cert, RSA CA cert */ |
| 54 #define SSL_kECDHe 0x00000040L /* ECDH cert, ECDSA CA cert */ |
| 55 #define SSL_kEECDH 0x00000080L /* ephemeral ECDH */ |
| 56 #define SSL_kPSK 0x00000100L /* PSK */ |
| 57 #define SSL_kGOST 0x00000200L /* GOST key exchange */ |
| 58 #define SSL_kSRP 0x00000400L /* SRP */ |
| 59 |
| 60 /* Bits for algorithm_auth (server authentication) */ |
| 61 #define SSL_aRSA 0x00000001L /* RSA auth */ |
| 62 #define SSL_aDSS 0x00000002L /* DSS auth */ |
| 63 #define SSL_aNULL 0x00000004L /* no auth (i.e. use ADH or AECDH) */ |
| 64 #define SSL_aDH 0x00000008L /* Fixed DH auth (kDHd or kDHr) */ /* no suc
h ciphersuites supported! */ |
| 65 #define SSL_aECDH 0x00000010L /* Fixed ECDH auth (kECDHe or kECDHr) */ |
| 66 #define SSL_aKRB5 0x00000020L /* KRB5 auth */ |
| 67 #define SSL_aECDSA 0x00000040L /* ECDSA auth*/ |
| 68 #define SSL_aPSK 0x00000080L /* PSK auth */ |
| 69 #define SSL_aGOST94 0x00000100L /* GOST R 34.10-94 signature auth */ |
| 70 #define SSL_aGOST01 0x00000200L /* GOST R 34.10-2001 signature auth */ |
| 71 |
| 72 const char* TCN_UNKNOWN_AUTH_METHOD = "UNKNOWN"; |
| 73 |
| 74 /* OpenSSL end */ |
| 75 |
| 76 /* |
| 77 * Adapted from Android: |
| 78 * https://android.googlesource.com/platform/external/openssl/+/master/patches/0
003-jsse.patch |
| 79 */ |
| 80 const char* SSL_cipher_authentication_method(const SSL_CIPHER* cipher){ |
| 81 #ifndef OPENSSL_IS_BORINGSSL |
| 82 switch (cipher->algorithm_mkey) |
| 83 { |
| 84 case SSL_kRSA: |
| 85 return SSL_TXT_RSA; |
| 86 case SSL_kDHr: |
| 87 return SSL_TXT_DH "_" SSL_TXT_RSA; |
| 88 |
| 89 case SSL_kDHd: |
| 90 return SSL_TXT_DH "_" SSL_TXT_DSS; |
| 91 case SSL_kEDH: |
| 92 switch (cipher->algorithm_auth) |
| 93 { |
| 94 case SSL_aDSS: |
| 95 return "DHE_" SSL_TXT_DSS; |
| 96 case SSL_aRSA: |
| 97 return "DHE_" SSL_TXT_RSA; |
| 98 case SSL_aNULL: |
| 99 return SSL_TXT_DH "_anon"; |
| 100 default: |
| 101 return TCN_UNKNOWN_AUTH_METHOD; |
| 102 } |
| 103 case SSL_kKRB5: |
| 104 return SSL_TXT_KRB5; |
| 105 case SSL_kECDHr: |
| 106 return SSL_TXT_ECDH "_" SSL_TXT_RSA; |
| 107 case SSL_kECDHe: |
| 108 return SSL_TXT_ECDH "_" SSL_TXT_ECDSA; |
| 109 case SSL_kEECDH: |
| 110 switch (cipher->algorithm_auth) |
| 111 { |
| 112 case SSL_aECDSA: |
| 113 return "ECDHE_" SSL_TXT_ECDSA; |
| 114 case SSL_aRSA: |
| 115 return "ECDHE_" SSL_TXT_RSA; |
| 116 case SSL_aNULL: |
| 117 return SSL_TXT_ECDH "_anon"; |
| 118 default: |
| 119 return TCN_UNKNOWN_AUTH_METHOD; |
| 120 } |
| 121 default: |
| 122 return TCN_UNKNOWN_AUTH_METHOD; |
| 123 } |
| 124 #else |
| 125 return SSL_CIPHER_get_kx_name(cipher); |
| 126 #endif |
| 127 |
| 128 } |
| 129 |
| 51 /* we initialize this index at startup time | 130 /* we initialize this index at startup time |
| 52 * and never write to it at request time, | 131 * and never write to it at request time, |
| 53 * so this static is thread safe. | 132 * so this static is thread safe. |
| 54 * also note that OpenSSL increments at static variable when | 133 * also note that OpenSSL increments at static variable when |
| 55 * SSL_get_ex_new_index() is called, so we _must_ do this at startup. | 134 * SSL_get_ex_new_index() is called, so we _must_ do this at startup. |
| 56 */ | 135 */ |
| 57 static int SSL_app_data2_idx = -1; | 136 static int SSL_app_data2_idx = -1; |
| 58 static int SSL_app_data3_idx = -1; | 137 static int SSL_app_data3_idx = -1; |
| 59 void SSL_init_app_data2_3_idx(void) | 138 static int SSL_app_data4_idx = -1; |
| 139 void SSL_init_app_data_idx() |
| 60 { | 140 { |
| 61 int i; | 141 int i; |
| 62 | 142 |
| 63 if (SSL_app_data2_idx > -1) { | 143 if (SSL_app_data2_idx == -1) { |
| 64 return; | 144 /* we _do_ need to call this two times */ |
| 145 for (i = 0; i <= 1; i++) { |
| 146 SSL_app_data2_idx = SSL_get_ex_new_index(0, "tcn_ssl_ctxt_t*", NULL,
NULL, NULL); |
| 147 } |
| 65 } | 148 } |
| 66 | 149 |
| 67 /* we _do_ need to call this two times */ | 150 if (SSL_app_data3_idx == -1) { |
| 68 for (i = 0; i <= 1; i++) { | 151 SSL_app_data3_idx = SSL_get_ex_new_index(0, "int* handshakeCount", NULL,
NULL, NULL); |
| 69 SSL_app_data2_idx = | |
| 70 SSL_get_ex_new_index(0, | |
| 71 "Second Application Data for SSL", | |
| 72 NULL, NULL, NULL); | |
| 73 } | 152 } |
| 74 | 153 |
| 75 if (SSL_app_data3_idx > -1) { | 154 if (SSL_app_data4_idx == -1) { |
| 76 return; | 155 SSL_app_data4_idx = SSL_get_ex_new_index(0, "tcn_ssl_verify_config_t*",
NULL, NULL, NULL); |
| 77 } | 156 } |
| 78 | |
| 79 SSL_app_data3_idx = | |
| 80 SSL_get_ex_new_index(0, | |
| 81 "Third Application Data for SSL", | |
| 82 NULL, NULL, NULL); | |
| 83 } | 157 } |
| 84 | 158 |
| 85 void *SSL_get_app_data2(SSL *ssl) | 159 void *SSL_get_app_data2(SSL *ssl) |
| 86 { | 160 { |
| 87 return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx); | 161 return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx); |
| 88 } | 162 } |
| 89 | 163 |
| 90 void SSL_set_app_data2(SSL *ssl, void *arg) | 164 void SSL_set_app_data2(SSL *ssl, void *arg) |
| 91 { | 165 { |
| 92 SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg); | 166 SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg); |
| 93 return; | 167 return; |
| 94 } | 168 } |
| 95 | 169 |
| 96 void *SSL_get_app_data3(SSL *ssl) | 170 void *SSL_get_app_data3(SSL *ssl) |
| 97 { | 171 { |
| 98 return SSL_get_ex_data(ssl, SSL_app_data3_idx); | 172 return SSL_get_ex_data(ssl, SSL_app_data3_idx); |
| 99 } | 173 } |
| 100 | 174 |
| 101 void SSL_set_app_data3(SSL *ssl, void *arg) | 175 void SSL_set_app_data3(SSL *ssl, void *arg) |
| 102 { | 176 { |
| 103 SSL_set_ex_data(ssl, SSL_app_data3_idx, arg); | 177 SSL_set_ex_data(ssl, SSL_app_data3_idx, arg); |
| 104 } | 178 } |
| 105 | 179 |
| 106 /* Simple echo password prompting */ | 180 void *SSL_get_app_data4(SSL *ssl) |
| 107 int SSL_password_prompt(tcn_pass_cb_t *data) | |
| 108 { | 181 { |
| 109 int rv = 0; | 182 return SSL_get_ex_data(ssl, SSL_app_data4_idx); |
| 110 data->password[0] = '\0'; | 183 } |
| 111 if (data->cb.obj) { | 184 |
| 112 JNIEnv *e; | 185 void SSL_set_app_data4(SSL *ssl, void *arg) |
| 113 jobject o; | 186 { |
| 114 jstring prompt; | 187 SSL_set_ex_data(ssl, SSL_app_data4_idx, arg); |
| 115 tcn_get_java_env(&e); | |
| 116 prompt = AJP_TO_JSTRING(data->prompt); | |
| 117 if ((o = (*e)->CallObjectMethod(e, data->cb.obj, | |
| 118 data->cb.mid[0], prompt))) { | |
| 119 TCN_ALLOC_CSTRING(o); | |
| 120 if (J2S(o)) { | |
| 121 strncpy(data->password, J2S(o), SSL_MAX_PASSWORD_LEN); | |
| 122 data->password[SSL_MAX_PASSWORD_LEN-1] = '\0'; | |
| 123 rv = (int)strlen(data->password); | |
| 124 } | |
| 125 TCN_FREE_CSTRING(o); | |
| 126 } | |
| 127 } | |
| 128 else { | |
| 129 #ifdef WIN32 | |
| 130 rv = WIN32_SSL_password_prompt(data); | |
| 131 #elif !defined(OPENSSL_IS_BORINGSSL) | |
| 132 EVP_read_pw_string(data->password, SSL_MAX_PASSWORD_LEN, | |
| 133 data->prompt, 0); | |
| 134 #endif | |
| 135 rv = (int)strlen(data->password); | |
| 136 } | |
| 137 if (rv > 0) { | |
| 138 /* Remove LF char if present */ | |
| 139 char *r = strchr(data->password, '\n'); | |
| 140 if (r) { | |
| 141 *r = '\0'; | |
| 142 rv--; | |
| 143 } | |
| 144 #ifdef WIN32 | |
| 145 if ((r = strchr(data->password, '\r'))) { | |
| 146 *r = '\0'; | |
| 147 rv--; | |
| 148 } | |
| 149 #endif | |
| 150 } | |
| 151 return rv; | |
| 152 } | 188 } |
| 153 | 189 |
| 154 int SSL_password_callback(char *buf, int bufsiz, int verify, | 190 int SSL_password_callback(char *buf, int bufsiz, int verify, |
| 155 void *cb) | 191 void *cb) |
| 156 { | 192 { |
| 157 tcn_pass_cb_t *cb_data = (tcn_pass_cb_t *)cb; | 193 char *password = (char *) cb; |
| 158 | 194 |
| 159 if (buf == NULL) | 195 if (buf == NULL || password == NULL) |
| 160 return 0; | 196 return 0; |
| 161 *buf = '\0'; | 197 *buf = '\0'; |
| 162 if (cb_data == NULL) | 198 |
| 163 cb_data = &tcn_password_callback; | 199 if (password[0]) { |
| 164 if (!cb_data->prompt) | |
| 165 cb_data->prompt = SSL_DEFAULT_PASS_PROMPT; | |
| 166 if (cb_data->password[0]) { | |
| 167 /* Return already obtained password */ | 200 /* Return already obtained password */ |
| 168 strncpy(buf, cb_data->password, bufsiz); | 201 strncpy(buf, password, bufsiz); |
| 169 buf[bufsiz - 1] = '\0'; | |
| 170 return (int)strlen(buf); | |
| 171 } | 202 } |
| 172 else { | 203 |
| 173 if (SSL_password_prompt(cb_data) > 0) | |
| 174 strncpy(buf, cb_data->password, bufsiz); | |
| 175 } | |
| 176 buf[bufsiz - 1] = '\0'; | 204 buf[bufsiz - 1] = '\0'; |
| 177 return (int)strlen(buf); | 205 return (int)strlen(buf); |
| 178 } | 206 } |
| 179 | 207 |
| 208 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(OPENSSL_USE_DEPRECATED) ||
defined(LIBRESSL_VERSION_NUMBER) |
| 209 |
| 180 static unsigned char dh0512_p[]={ | 210 static unsigned char dh0512_p[]={ |
| 181 0xD9,0xBA,0xBF,0xFD,0x69,0x38,0xC9,0x51,0x2D,0x19,0x37,0x39, | 211 0xD9,0xBA,0xBF,0xFD,0x69,0x38,0xC9,0x51,0x2D,0x19,0x37,0x39, |
| 182 0xD7,0x7D,0x7E,0x3E,0x25,0x58,0x55,0x94,0x90,0x60,0x93,0x7A, | 212 0xD7,0x7D,0x7E,0x3E,0x25,0x58,0x55,0x94,0x90,0x60,0x93,0x7A, |
| 183 0xF2,0xD5,0x61,0x5F,0x06,0xE8,0x08,0xB4,0x57,0xF4,0xCF,0xB4, | 213 0xF2,0xD5,0x61,0x5F,0x06,0xE8,0x08,0xB4,0x57,0xF4,0xCF,0xB4, |
| 184 0x41,0xCC,0xC4,0xAC,0xD4,0xF0,0x45,0x88,0xC9,0xD1,0x21,0x4C, | 214 0x41,0xCC,0xC4,0xAC,0xD4,0xF0,0x45,0x88,0xC9,0xD1,0x21,0x4C, |
| 185 0xB6,0x72,0x48,0xBD,0x73,0x80,0xE0,0xDD,0x88,0x41,0xA0,0xF1, | 215 0xB6,0x72,0x48,0xBD,0x73,0x80,0xE0,0xDD,0x88,0x41,0xA0,0xF1, |
| 186 0xEA,0x4B,0x71,0x13 | 216 0xEA,0x4B,0x71,0x13 |
| 187 }; | 217 }; |
| 188 static unsigned char dh1024_p[]={ | 218 static unsigned char dh1024_p[]={ |
| 189 0xA2,0x95,0x7E,0x7C,0xA9,0xD5,0x55,0x1D,0x7C,0x77,0x11,0xAC, | 219 0xA2,0x95,0x7E,0x7C,0xA9,0xD5,0x55,0x1D,0x7C,0x77,0x11,0xAC, |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 0x3E,0x19,0xBD,0xE2,0x80,0x11,0x86,0xC7,0x4B,0x7F,0x67,0x86, | 296 0x3E,0x19,0xBD,0xE2,0x80,0x11,0x86,0xC7,0x4B,0x7F,0x67,0x86, |
| 267 0x47,0xD2,0x38,0xCD,0x8F,0xFE,0x65,0x3C,0x11,0xCD,0x96,0x99, | 297 0x47,0xD2,0x38,0xCD,0x8F,0xFE,0x65,0x3C,0x11,0xCD,0x96,0x99, |
| 268 0x4E,0x45,0xEB,0xEC,0x1D,0x94,0x8C,0x53, | 298 0x4E,0x45,0xEB,0xEC,0x1D,0x94,0x8C,0x53, |
| 269 }; | 299 }; |
| 270 static unsigned char dhxxx2_g[]={ | 300 static unsigned char dhxxx2_g[]={ |
| 271 0x02 | 301 0x02 |
| 272 }; | 302 }; |
| 273 | 303 |
| 274 static DH *get_dh(int idx) | 304 static DH *get_dh(int idx) |
| 275 { | 305 { |
| 276 #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(OPENSSL_USE_DEPRECATED) | |
| 277 DH *dh; | 306 DH *dh; |
| 278 | |
| 279 if ((dh = DH_new()) == NULL) | 307 if ((dh = DH_new()) == NULL) |
| 280 return NULL; | 308 return NULL; |
| 281 switch (idx) { | 309 switch (idx) { |
| 282 case SSL_TMP_KEY_DH_512: | 310 case SSL_TMP_KEY_DH_512: |
| 283 dh->p = BN_bin2bn(dh0512_p, sizeof(dh0512_p), NULL); | 311 dh->p = BN_bin2bn(dh0512_p, sizeof(dh0512_p), NULL); |
| 284 break; | 312 break; |
| 285 case SSL_TMP_KEY_DH_1024: | 313 case SSL_TMP_KEY_DH_1024: |
| 286 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); | 314 dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL); |
| 287 break; | 315 break; |
| 288 case SSL_TMP_KEY_DH_2048: | 316 case SSL_TMP_KEY_DH_2048: |
| 289 dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); | 317 dh->p = BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); |
| 290 break; | 318 break; |
| 291 case SSL_TMP_KEY_DH_4096: | 319 case SSL_TMP_KEY_DH_4096: |
| 292 dh->p = BN_bin2bn(dh4096_p, sizeof(dh2048_p), NULL); | 320 dh->p = BN_bin2bn(dh4096_p, sizeof(dh2048_p), NULL); |
| 293 break; | 321 break; |
| 294 } | 322 } |
| 295 dh->g = BN_bin2bn(dhxxx2_g, sizeof(dhxxx2_g), NULL); | 323 dh->g = BN_bin2bn(dhxxx2_g, sizeof(dhxxx2_g), NULL); |
| 296 if ((dh->p == NULL) || (dh->g == NULL)) { | 324 if ((dh->p == NULL) || (dh->g == NULL)) { |
| 297 DH_free(dh); | 325 DH_free(dh); |
| 298 return NULL; | 326 return NULL; |
| 299 } | 327 } |
| 300 else | 328 else |
| 301 return dh; | 329 return dh; |
| 330 return NULL; |
| 331 } |
| 302 #else | 332 #else |
| 333 static DH *get_dh(int idx) |
| 334 { |
| 303 return NULL; | 335 return NULL; |
| 336 } |
| 304 #endif | 337 #endif |
| 305 } | |
| 306 | 338 |
| 307 DH *SSL_dh_get_tmp_param(int key_len) | 339 DH *SSL_dh_get_tmp_param(int key_len) |
| 308 { | 340 { |
| 309 DH *dh; | 341 DH *dh; |
| 310 | 342 |
| 311 if (key_len == 512) | 343 if (key_len == 512) |
| 312 dh = get_dh(SSL_TMP_KEY_DH_512); | 344 dh = get_dh(SSL_TMP_KEY_DH_512); |
| 313 else if (key_len == 1024) | 345 else if (key_len == 1024) |
| 314 dh = get_dh(SSL_TMP_KEY_DH_1024); | 346 dh = get_dh(SSL_TMP_KEY_DH_1024); |
| 315 else if (key_len == 2048) | 347 else if (key_len == 2048) |
| 316 dh = get_dh(SSL_TMP_KEY_DH_2048); | 348 dh = get_dh(SSL_TMP_KEY_DH_2048); |
| 317 else if (key_len == 4096) | 349 else if (key_len == 4096) |
| 318 dh = get_dh(SSL_TMP_KEY_DH_4096); | 350 dh = get_dh(SSL_TMP_KEY_DH_4096); |
| 319 else | 351 else |
| 320 dh = get_dh(SSL_TMP_KEY_DH_1024); | 352 dh = get_dh(SSL_TMP_KEY_DH_1024); |
| 321 return dh; | 353 return dh; |
| 322 } | 354 } |
| 323 | 355 |
| 324 DH *SSL_dh_get_param_from_file(const char *file) | |
| 325 { | |
| 326 DH *dh = NULL; | |
| 327 BIO *bio; | |
| 328 | |
| 329 if ((bio = BIO_new_file(file, "r")) == NULL) | |
| 330 return NULL; | |
| 331 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL); | |
| 332 BIO_free(bio); | |
| 333 return dh; | |
| 334 } | |
| 335 | |
| 336 /* | |
| 337 * Handle out temporary RSA private keys on demand | |
| 338 * | |
| 339 * The background of this as the TLSv1 standard explains it: | |
| 340 * | |
| 341 * | D.1. Temporary RSA keys | |
| 342 * | | |
| 343 * | US Export restrictions limit RSA keys used for encryption to 512 | |
| 344 * | bits, but do not place any limit on lengths of RSA keys used for | |
| 345 * | signing operations. Certificates often need to be larger than 512 | |
| 346 * | bits, since 512-bit RSA keys are not secure enough for high-value | |
| 347 * | transactions or for applications requiring long-term security. Some | |
| 348 * | certificates are also designated signing-only, in which case they | |
| 349 * | cannot be used for key exchange. | |
| 350 * | | |
| 351 * | When the public key in the certificate cannot be used for encryption, | |
| 352 * | the server signs a temporary RSA key, which is then exchanged. In | |
| 353 * | exportable applications, the temporary RSA key should be the maximum | |
| 354 * | allowable length (i.e., 512 bits). Because 512-bit RSA keys are | |
| 355 * | relatively insecure, they should be changed often. For typical | |
| 356 * | electronic commerce applications, it is suggested that keys be | |
| 357 * | changed daily or every 500 transactions, and more often if possible. | |
| 358 * | Note that while it is acceptable to use the same temporary key for | |
| 359 * | multiple transactions, it must be signed each time it is used. | |
| 360 * | | |
| 361 * | RSA key generation is a time-consuming process. In many cases, a | |
| 362 * | low-priority process can be assigned the task of key generation. | |
| 363 * | Whenever a new key is completed, the existing temporary key can be | |
| 364 * | replaced with the new one. | |
| 365 * | |
| 366 * XXX: base on comment above, if thread support is enabled, | |
| 367 * we should spawn a low-priority thread to generate new keys | |
| 368 * on the fly. | |
| 369 * | |
| 370 * So we generated 512 and 1024 bit temporary keys on startup | |
| 371 * which we now just hand out on demand.... | |
| 372 */ | |
| 373 | |
| 374 RSA *SSL_callback_tmp_RSA(SSL *ssl, int export, int keylen) | |
| 375 { | |
| 376 int idx; | |
| 377 | |
| 378 /* doesn't matter if export flag is on, | |
| 379 * we won't be asked for keylen > 512 in that case. | |
| 380 * if we are asked for a keylen > 1024, it is too expensive | |
| 381 * to generate on the fly. | |
| 382 */ | |
| 383 | |
| 384 switch (keylen) { | |
| 385 case 512: | |
| 386 idx = SSL_TMP_KEY_RSA_512; | |
| 387 break; | |
| 388 case 2048: | |
| 389 idx = SSL_TMP_KEY_RSA_2048; | |
| 390 if (SSL_temp_keys[idx] == NULL) | |
| 391 idx = SSL_TMP_KEY_RSA_1024; | |
| 392 break; | |
| 393 case 4096: | |
| 394 idx = SSL_TMP_KEY_RSA_4096; | |
| 395 if (SSL_temp_keys[idx] == NULL) | |
| 396 idx = SSL_TMP_KEY_RSA_2048; | |
| 397 break; | |
| 398 case 1024: | |
| 399 default: | |
| 400 idx = SSL_TMP_KEY_RSA_1024; | |
| 401 break; | |
| 402 } | |
| 403 return (RSA *)SSL_temp_keys[idx]; | |
| 404 } | |
| 405 | |
| 406 /* | 356 /* |
| 407 * Hand out the already generated DH parameters... | 357 * Hand out the already generated DH parameters... |
| 408 */ | 358 */ |
| 409 DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen) | 359 DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen) |
| 410 { | 360 { |
| 411 int idx; | 361 int idx; |
| 412 switch (keylen) { | 362 switch (keylen) { |
| 413 case 512: | 363 case 512: |
| 414 idx = SSL_TMP_KEY_DH_512; | 364 idx = SSL_TMP_KEY_DH_512; |
| 415 break; | 365 break; |
| 416 case 2048: | 366 case 2048: |
| 417 idx = SSL_TMP_KEY_DH_2048; | 367 idx = SSL_TMP_KEY_DH_2048; |
| 418 break; | 368 break; |
| 419 case 4096: | 369 case 4096: |
| 420 idx = SSL_TMP_KEY_DH_4096; | 370 idx = SSL_TMP_KEY_DH_4096; |
| 421 break; | 371 break; |
| 422 case 1024: | 372 case 1024: |
| 423 default: | 373 default: |
| 424 idx = SSL_TMP_KEY_DH_1024; | 374 idx = SSL_TMP_KEY_DH_1024; |
| 425 break; | 375 break; |
| 426 } | 376 } |
| 427 return (DH *)SSL_temp_keys[idx]; | 377 return (DH *)SSL_temp_keys[idx]; |
| 428 } | 378 } |
| 429 | 379 |
| 380 DH *SSL_callback_tmp_DH_512(SSL *ssl, int export, int keylen) |
| 381 { |
| 382 return (DH *)SSL_temp_keys[SSL_TMP_KEY_DH_512]; |
| 383 } |
| 384 |
| 385 DH *SSL_callback_tmp_DH_1024(SSL *ssl, int export, int keylen) |
| 386 { |
| 387 return (DH *)SSL_temp_keys[SSL_TMP_KEY_DH_1024]; |
| 388 } |
| 389 |
| 390 DH *SSL_callback_tmp_DH_2048(SSL *ssl, int export, int keylen) |
| 391 { |
| 392 return (DH *)SSL_temp_keys[SSL_TMP_KEY_DH_2048]; |
| 393 } |
| 394 |
| 395 DH *SSL_callback_tmp_DH_4096(SSL *ssl, int export, int keylen) |
| 396 { |
| 397 return (DH *)SSL_temp_keys[SSL_TMP_KEY_DH_4096]; |
| 398 } |
| 399 |
| 430 /* | 400 /* |
| 431 * Read a file that optionally contains the server certificate in PEM | 401 * Read a file that optionally contains the server certificate in PEM |
| 432 * format, possibly followed by a sequence of CA certificates that | 402 * format, possibly followed by a sequence of CA certificates that |
| 433 * should be sent to the peer in the SSL Certificate message. | 403 * should be sent to the peer in the SSL Certificate message. |
| 434 */ | 404 */ |
| 435 int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, const char *file, | 405 int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, const char *file, bool skipfirst
) |
| 436 int skipfirst) | |
| 437 { | 406 { |
| 438 BIO *bio; | 407 BIO *bio; |
| 439 int n; | 408 int n; |
| 440 | 409 |
| 441 if ((bio = BIO_new(BIO_s_file())) == NULL) | 410 if ((bio = BIO_new(BIO_s_file())) == NULL) |
| 442 return -1; | 411 return -1; |
| 443 if (BIO_read_filename(bio, file) <= 0) { | 412 if (BIO_read_filename(bio, file) <= 0) { |
| 444 BIO_free(bio); | 413 BIO_free(bio); |
| 445 return -1; | 414 return -1; |
| 446 } | 415 } |
| 447 n = SSL_CTX_use_certificate_chain_bio(ctx, bio, skipfirst); | 416 n = SSL_CTX_use_certificate_chain_bio(ctx, bio, skipfirst); |
| 448 BIO_free(bio); | 417 BIO_free(bio); |
| 449 return n; | 418 return n; |
| 450 } | 419 } |
| 451 | 420 |
| 452 int SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO *bio, | 421 static int SSL_CTX_setup_certs(SSL_CTX *ctx, BIO *bio, bool skipfirst, bool ca) |
| 453 int skipfirst) | |
| 454 { | 422 { |
| 455 X509 *x509; | 423 X509 *x509; |
| 456 unsigned long err; | 424 unsigned long err; |
| 457 int n; | 425 int n; |
| 458 | 426 |
| 459 /* optionally skip a leading server certificate */ | 427 /* optionally skip a leading server certificate */ |
| 460 if (skipfirst) { | 428 if (skipfirst) { |
| 461 if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) { | 429 if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) { |
| 462 return -1; | 430 return -1; |
| 463 } | 431 } |
| 464 X509_free(x509); | 432 X509_free(x509); |
| 465 } | 433 } |
| 466 | 434 |
| 467 /* free a perhaps already configured extra chain */ | 435 n = 0; |
| 468 SSL_CTX_clear_extra_chain_certs(ctx); | 436 if (ca) { |
| 437 while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
| 438 if (SSL_CTX_add_client_CA(ctx, x509) != 1) { |
| 439 X509_free(x509); |
| 440 return -1; |
| 441 } |
| 442 // SSL_CTX_add_client_CA does not take ownership of the x509. It jus
t calls X509_get_subject_name |
| 443 // and make a duplicate of this value. So we should always free the
x509 after this call. |
| 444 // See https://github.com/netty/netty/issues/6249. |
| 445 X509_free(x509); |
| 446 n++; |
| 447 } |
| 448 } else { |
| 449 /* free a perhaps already configured extra chain */ |
| 450 SSL_CTX_clear_extra_chain_certs(ctx); |
| 451 |
| 452 /* create new extra chain by loading the certs */ |
| 453 while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
| 454 // SSL_CTX_add_extra_chain_cert transfers ownership of the x509 cert
ificate if the method succeeds. |
| 455 if (SSL_CTX_add_extra_chain_cert(ctx, x509) != 1) { |
| 456 X509_free(x509); |
| 457 return -1; |
| 458 } |
| 459 n++; |
| 460 } |
| 461 } |
| 462 |
| 463 /* Make sure that only the error is just an EOF */ |
| 464 if ((err = ERR_peek_error()) > 0) { |
| 465 if (!( ERR_GET_LIB(err) == ERR_LIB_PEM |
| 466 && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { |
| 467 return -1; |
| 468 } |
| 469 ERR_clear_error(); |
| 470 } |
| 471 return n; |
| 472 } |
| 473 |
| 474 int SSL_CTX_use_certificate_chain_bio(SSL_CTX *ctx, BIO *bio, bool skipfirst) |
| 475 { |
| 476 return SSL_CTX_setup_certs(ctx, bio, skipfirst, false); |
| 477 } |
| 478 |
| 479 |
| 480 int SSL_CTX_use_client_CA_bio(SSL_CTX *ctx, BIO *bio) |
| 481 { |
| 482 return SSL_CTX_setup_certs(ctx, bio, false, true); |
| 483 } |
| 484 |
| 485 int SSL_use_certificate_chain_bio(SSL *ssl, BIO *bio, bool skipfirst) |
| 486 { |
| 487 #if OPENSSL_VERSION_NUMBER < 0x10002000L || defined(LIBRESSL_VERSION_NUMBER) |
| 488 // Only supported on openssl 1.0.2+ |
| 489 return -1; |
| 490 #else |
| 491 X509 *x509; |
| 492 unsigned long err; |
| 493 int n; |
| 494 |
| 495 /* optionally skip a leading server certificate */ |
| 496 if (skipfirst) { |
| 497 if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) { |
| 498 return -1; |
| 499 } |
| 500 X509_free(x509); |
| 501 } |
| 469 | 502 |
| 470 /* create new extra chain by loading the certs */ | 503 /* create new extra chain by loading the certs */ |
| 471 n = 0; | 504 n = 0; |
| 505 |
| 472 while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { | 506 while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) { |
| 473 if (SSL_CTX_add_extra_chain_cert(ctx, x509) != 1) { | 507 if (SSL_add0_chain_cert(ssl, x509) != 1) { |
| 474 X509_free(x509); | 508 X509_free(x509); |
| 475 return -1; | 509 return -1; |
| 476 } | 510 } |
| 477 n++; | 511 n++; |
| 478 } | 512 } |
| 479 /* Make sure that only the error is just an EOF */ | 513 /* Make sure that only the error is just an EOF */ |
| 480 if ((err = ERR_peek_error()) > 0) { | 514 if ((err = ERR_peek_error()) > 0) { |
| 481 if (!( ERR_GET_LIB(err) == ERR_LIB_PEM | 515 if (!( ERR_GET_LIB(err) == ERR_LIB_PEM |
| 482 && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { | 516 && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) { |
| 483 return -1; | 517 return -1; |
| 484 } | 518 } |
| 485 while (ERR_get_error() > 0) ; | 519 ERR_clear_error(); |
| 486 } | 520 } |
| 487 return n; | 521 return n; |
| 522 #endif |
| 488 } | 523 } |
| 489 | 524 |
| 490 static int ssl_X509_STORE_lookup(X509_STORE *store, int yype, | 525 X509 *load_pem_cert_bio(const char *password, const BIO *bio) |
| 491 X509_NAME *name, X509_OBJECT *obj) | |
| 492 { | 526 { |
| 493 X509_STORE_CTX ctx; | 527 X509 *cert = PEM_read_bio_X509_AUX((BIO*) bio, NULL, |
| 494 int rc; | 528 (pem_password_cb *)SSL_password_callback, |
| 495 | 529 (void *)password); |
| 496 X509_STORE_CTX_init(&ctx, store, NULL, NULL); | 530 if (cert == NULL && |
| 497 rc = X509_STORE_get_by_subject(&ctx, yype, name, obj); | 531 (ERR_GET_REASON(ERR_peek_last_error()) == PEM_R_NO_START_LINE)) { |
| 498 X509_STORE_CTX_cleanup(&ctx); | 532 ERR_clear_error(); |
| 499 return rc; | 533 BIO_ctrl((BIO*) bio, BIO_CTRL_RESET, 0, NULL); |
| 534 cert = d2i_X509_bio((BIO*) bio, NULL); |
| 535 } |
| 536 return cert; |
| 500 } | 537 } |
| 501 | 538 |
| 502 static int ssl_verify_CRL(int ok, X509_STORE_CTX *ctx, tcn_ssl_ctxt_t *c) | 539 EVP_PKEY *load_pem_key_bio(const char *password, const BIO *bio) |
| 503 { | 540 { |
| 504 X509_OBJECT obj; | 541 EVP_PKEY *key = PEM_read_bio_PrivateKey((BIO*) bio, NULL, |
| 505 X509_NAME *subject, *issuer; | 542 (pem_password_cb *)SSL_password_callback, |
| 506 X509 *cert; | 543 (void *)password); |
| 507 X509_CRL *crl; | |
| 508 EVP_PKEY *pubkey; | |
| 509 int i, n, rc; | |
| 510 | 544 |
| 511 /* | 545 BIO_ctrl((BIO*) bio, BIO_CTRL_RESET, 0, NULL); |
| 512 * Determine certificate ingredients in advance | 546 return key; |
| 513 */ | 547 } |
| 514 cert = X509_STORE_CTX_get_current_cert(ctx); | |
| 515 subject = X509_get_subject_name(cert); | |
| 516 issuer = X509_get_issuer_name(cert); | |
| 517 | 548 |
| 518 /* | 549 int tcn_EVP_PKEY_up_ref(EVP_PKEY* pkey) { |
| 519 * OpenSSL provides the general mechanism to deal with CRLs but does not | 550 #if defined(OPENSSL_IS_BORINGSSL) |
| 520 * use them automatically when verifying certificates, so we do it | 551 // Workaround for https://bugs.chromium.org/p/boringssl/issues/detail?id=89# |
| 521 * explicitly here. We will check the CRL for the currently checked | 552 EVP_PKEY_up_ref(pkey); |
| 522 * certificate, if there is such a CRL in the store. | 553 return 1; |
| 523 * | 554 #elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) |
| 524 * We come through this procedure for each certificate in the certificate | 555 return CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY); |
| 525 * chain, starting with the root-CA's certificate. At each step we've to | 556 #else |
| 526 * both verify the signature on the CRL (to make sure it's a valid CRL) | 557 return EVP_PKEY_up_ref(pkey); |
| 527 * and it's revocation list (to make sure the current certificate isn't | 558 #endif |
| 528 * revoked). But because to check the signature on the CRL we need the | 559 } |
| 529 * public key of the issuing CA certificate (which was already processed | |
| 530 * one round before), we've a little problem. But we can both solve it and | |
| 531 * at the same time optimize the processing by using the following | |
| 532 * verification scheme (idea and code snippets borrowed from the GLOBUS | |
| 533 * project): | |
| 534 * | |
| 535 * 1. We'll check the signature of a CRL in each step when we find a CRL | |
| 536 * through the _subject_ name of the current certificate. This CRL | |
| 537 * itself will be needed the first time in the next round, of course. | |
| 538 * But we do the signature processing one round before this where the | |
| 539 * public key of the CA is available. | |
| 540 * | |
| 541 * 2. We'll check the revocation list of a CRL in each step when | |
| 542 * we find a CRL through the _issuer_ name of the current certificate. | |
| 543 * This CRLs signature was then already verified one round before. | |
| 544 * | |
| 545 * This verification scheme allows a CA to revoke its own certificate as | |
| 546 * well, of course. | |
| 547 */ | |
| 548 | 560 |
| 549 /* | 561 int tcn_X509_up_ref(X509* cert) { |
| 550 * Try to retrieve a CRL corresponding to the _subject_ of | 562 #if defined(OPENSSL_IS_BORINGSSL) |
| 551 * the current certificate in order to verify it's integrity. | 563 // Workaround for https://bugs.chromium.org/p/boringssl/issues/detail?id=89# |
| 552 */ | 564 X509_up_ref(cert); |
| 553 memset((char *)&obj, 0, sizeof(obj)); | 565 return 1; |
| 554 rc = ssl_X509_STORE_lookup(c->crl, | 566 #elif OPENSSL_VERSION_NUMBER < 0x10100000L || defined(LIBRESSL_VERSION_NUMBER) |
| 555 X509_LU_CRL, subject, &obj); | 567 return CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); |
| 556 crl = obj.data.crl; | 568 #else |
| 569 return X509_up_ref(cert); |
| 570 #endif |
| 571 } |
| 557 | 572 |
| 558 if ((rc > 0) && crl) { | 573 int tcn_set_verify_config(tcn_ssl_verify_config_t* c, jint tcn_mode, jint depth)
{ |
| 559 /* | 574 if (depth >= 0) { |
| 560 * Log information about CRL | 575 c->verify_depth = depth; |
| 561 * (A little bit complicated because of ASN.1 and BIOs...) | |
| 562 */ | |
| 563 /* | |
| 564 * Verify the signature on this CRL | |
| 565 */ | |
| 566 pubkey = X509_get_pubkey(cert); | |
| 567 rc = X509_CRL_verify(crl, pubkey); | |
| 568 /* Only refcounted in OpenSSL */ | |
| 569 if (pubkey) | |
| 570 EVP_PKEY_free(pubkey); | |
| 571 if (rc <= 0) { | |
| 572 /* TODO: Log Invalid signature on CRL */ | |
| 573 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE); | |
| 574 X509_OBJECT_free_contents(&obj); | |
| 575 return 0; | |
| 576 } | |
| 577 | |
| 578 /* | |
| 579 * Check date of CRL to make sure it's not expired | |
| 580 */ | |
| 581 i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl)); | |
| 582 | |
| 583 if (i == 0) { | |
| 584 /* TODO: Log Found CRL has invalid nextUpdate field */ | |
| 585 | |
| 586 X509_STORE_CTX_set_error(ctx, | |
| 587 X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD); | |
| 588 X509_OBJECT_free_contents(&obj); | |
| 589 return 0; | |
| 590 } | |
| 591 | |
| 592 if (i < 0) { | |
| 593 /* TODO: Log Found CRL is expired */ | |
| 594 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED); | |
| 595 X509_OBJECT_free_contents(&obj); | |
| 596 | |
| 597 return 0; | |
| 598 } | |
| 599 | |
| 600 X509_OBJECT_free_contents(&obj); | |
| 601 } | 576 } |
| 602 | 577 |
| 603 /* | 578 switch (tcn_mode) { |
| 604 * Try to retrieve a CRL corresponding to the _issuer_ of | 579 case SSL_CVERIFY_IGNORED: |
| 605 * the current certificate in order to check for revocation. | 580 switch (c->verify_mode) { |
| 606 */ | 581 case SSL_CVERIFY_NONE: |
| 607 memset((char *)&obj, 0, sizeof(obj)); | 582 return SSL_VERIFY_NONE; |
| 608 rc = ssl_X509_STORE_lookup(c->crl, | 583 case SSL_CVERIFY_OPTIONAL: |
| 609 X509_LU_CRL, issuer, &obj); | 584 return SSL_VERIFY_PEER; |
| 610 | 585 default: |
| 611 crl = obj.data.crl; | 586 return (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT); |
| 612 if ((rc > 0) && crl) { | |
| 613 /* | |
| 614 * Check if the current certificate is revoked by this CRL | |
| 615 */ | |
| 616 n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); | |
| 617 | |
| 618 for (i = 0; i < n; i++) { | |
| 619 X509_REVOKED *revoked = | |
| 620 sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); | |
| 621 | |
| 622 ASN1_INTEGER *sn = revoked->serialNumber; | |
| 623 | |
| 624 if (!ASN1_INTEGER_cmp(sn, X509_get_serialNumber(cert))) { | |
| 625 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); | |
| 626 X509_OBJECT_free_contents(&obj); | |
| 627 | |
| 628 return 0; | |
| 629 } | |
| 630 } | 587 } |
| 631 | 588 case SSL_CVERIFY_NONE: |
| 632 X509_OBJECT_free_contents(&obj); | 589 c->verify_mode = SSL_CVERIFY_NONE; |
| 590 return SSL_VERIFY_NONE; |
| 591 case SSL_CVERIFY_OPTIONAL: |
| 592 c->verify_mode = SSL_CVERIFY_OPTIONAL; |
| 593 return SSL_VERIFY_PEER; |
| 594 default: |
| 595 c->verify_mode = SSL_CVERIFY_REQUIRED; |
| 596 return SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT; |
| 633 } | 597 } |
| 634 | |
| 635 return ok; | |
| 636 } | |
| 637 | |
| 638 /* | |
| 639 * This OpenSSL callback function is called when OpenSSL | |
| 640 * does client authentication and verifies the certificate chain. | |
| 641 */ | |
| 642 | |
| 643 | |
| 644 int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx) | |
| 645 { | |
| 646 /* Get Apache context back through OpenSSL context */ | |
| 647 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, | |
| 648 SSL_get_ex_data_X509_STORE_CTX_idx()); | |
| 649 tcn_ssl_ctxt_t *c = SSL_get_app_data2(ssl); | |
| 650 | |
| 651 /* Get verify ingredients */ | |
| 652 int errnum = X509_STORE_CTX_get_error(ctx); | |
| 653 int errdepth = X509_STORE_CTX_get_error_depth(ctx); | |
| 654 int verify = c->verify_mode; | |
| 655 int depth = c->verify_depth; | |
| 656 int skip_crl = 0; | |
| 657 | |
| 658 if (verify == SSL_CVERIFY_UNSET || | |
| 659 verify == SSL_CVERIFY_NONE) | |
| 660 return 1; | |
| 661 | |
| 662 if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) && | |
| 663 (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) { | |
| 664 ok = 1; | |
| 665 SSL_set_verify_result(ssl, X509_V_OK); | |
| 666 } | |
| 667 | |
| 668 #ifdef HAVE_OPENSSL_OCSP | |
| 669 /* First perform OCSP validation if possible */ | |
| 670 if (ok) { | |
| 671 /* If there was an optional verification error, it's not | |
| 672 * possible to perform OCSP validation since the issuer may be | |
| 673 * missing/untrusted. Fail in that case. | |
| 674 */ | |
| 675 if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum)) { | |
| 676 X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION); | |
| 677 errnum = X509_V_ERR_APPLICATION_VERIFICATION; | |
| 678 ok = 0; | |
| 679 } | |
| 680 else { | |
| 681 int ocsp_response = ssl_verify_OCSP(ok, ctx); | |
| 682 if (ocsp_response == OCSP_STATUS_OK) { | |
| 683 skip_crl = 1; /* we know it is valid we skip crl evaluation */ | |
| 684 } | |
| 685 else if (ocsp_response == OCSP_STATUS_REVOKED) { | |
| 686 ok = 0 ; | |
| 687 errnum = X509_STORE_CTX_get_error(ctx); | |
| 688 } | |
| 689 else if (ocsp_response == OCSP_STATUS_UNKNOWN) { | |
| 690 /* TODO: do nothing for time being, continue with CRL */ | |
| 691 ; | |
| 692 } | |
| 693 } | |
| 694 } | |
| 695 #endif | |
| 696 /* | |
| 697 * Additionally perform CRL-based revocation checks | |
| 698 */ | |
| 699 if (ok && c->crl && !skip_crl) { | |
| 700 if (!(ok = ssl_verify_CRL(ok, ctx, c))) { | |
| 701 errnum = X509_STORE_CTX_get_error(ctx); | |
| 702 /* TODO: Log something */ | |
| 703 } | |
| 704 } | |
| 705 /* | |
| 706 * If we already know it's not ok, log the real reason | |
| 707 */ | |
| 708 if (!ok) { | |
| 709 // Just in case that sslnetwork stuff was used, which is not true for ne
tty but it can't harm to still | |
| 710 // guard against it. | |
| 711 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl); | |
| 712 | |
| 713 /* TODO: Some logging | |
| 714 * Certificate Verification: Error | |
| 715 */ | |
| 716 if (con != NULL && con->peer) { | |
| 717 X509_free(con->peer); | |
| 718 con->peer = NULL; | |
| 719 } | |
| 720 } | |
| 721 if (errdepth > depth) { | |
| 722 /* TODO: Some logging | |
| 723 * Certificate Verification: Certificate Chain too long | |
| 724 */ | |
| 725 ok = 0; | |
| 726 } | |
| 727 return ok; | |
| 728 } | |
| 729 | |
| 730 /* | |
| 731 * This callback function is executed while OpenSSL processes the SSL | |
| 732 * handshake and does SSL record layer stuff. It's used to trap | |
| 733 * client-initiated renegotiations, and for dumping everything to the | |
| 734 * log. | |
| 735 */ | |
| 736 void SSL_callback_handshake(const SSL *ssl, int where, int rc) | |
| 737 { | |
| 738 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl); | |
| 739 | |
| 740 /* Retrieve the conn_rec and the associated SSLConnRec. */ | |
| 741 if (con == NULL) { | |
| 742 return; | |
| 743 } | |
| 744 | |
| 745 | |
| 746 /* If the reneg state is to reject renegotiations, check the SSL | |
| 747 * state machine and move to ABORT if a Client Hello is being | |
| 748 * read. */ | |
| 749 if ((where & SSL_CB_ACCEPT_LOOP) && con->reneg_state == RENEG_REJECT) { | |
| 750 int state = SSL_get_state(ssl); | |
| 751 | |
| 752 if (state == SSL3_ST_SR_CLNT_HELLO_A | |
| 753 #ifndef OPENSSL_IS_BORINGSSL | |
| 754 || state == SSL23_ST_SR_CLNT_HELLO_A | |
| 755 #endif | |
| 756 ) { | |
| 757 con->reneg_state = RENEG_ABORT; | |
| 758 /* XXX: rejecting client initiated renegotiation | |
| 759 */ | |
| 760 } | |
| 761 } | |
| 762 /* If the first handshake is complete, change state to reject any | |
| 763 * subsequent client-initated renegotiation. */ | |
| 764 else if ((where & SSL_CB_HANDSHAKE_DONE) && con->reneg_state == RENEG_INIT)
{ | |
| 765 con->reneg_state = RENEG_REJECT; | |
| 766 } | |
| 767 | |
| 768 } | 598 } |
| 769 | 599 |
| 770 int SSL_callback_next_protos(SSL *ssl, const unsigned char **data, | 600 int SSL_callback_next_protos(SSL *ssl, const unsigned char **data, |
| 771 unsigned int *len, void *arg) | 601 unsigned int *len, void *arg) |
| 772 { | 602 { |
| 773 tcn_ssl_ctxt_t *ssl_ctxt = arg; | 603 tcn_ssl_ctxt_t *ssl_ctxt = arg; |
| 774 | 604 |
| 775 *data = ssl_ctxt->next_proto_data; | 605 *data = ssl_ctxt->next_proto_data; |
| 776 *len = ssl_ctxt->next_proto_len; | 606 *len = ssl_ctxt->next_proto_len; |
| 777 | 607 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 841 void *arg) { | 671 void *arg) { |
| 842 tcn_ssl_ctxt_t *ssl_ctxt = arg; | 672 tcn_ssl_ctxt_t *ssl_ctxt = arg; |
| 843 return select_next_proto(ssl, (const unsigned char**) out, outlen, in, inlen
, ssl_ctxt->next_proto_data, ssl_ctxt->next_proto_len, ssl_ctxt->next_selector_f
ailure_behavior); | 673 return select_next_proto(ssl, (const unsigned char**) out, outlen, in, inlen
, ssl_ctxt->next_proto_data, ssl_ctxt->next_proto_len, ssl_ctxt->next_selector_f
ailure_behavior); |
| 844 } | 674 } |
| 845 | 675 |
| 846 int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char **out, unsigned
char *outlen, | 676 int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char **out, unsigned
char *outlen, |
| 847 const unsigned char *in, unsigned int inlen, void *arg) { | 677 const unsigned char *in, unsigned int inlen, void *arg) { |
| 848 tcn_ssl_ctxt_t *ssl_ctxt = arg; | 678 tcn_ssl_ctxt_t *ssl_ctxt = arg; |
| 849 return select_next_proto(ssl, out, outlen, in, inlen, ssl_ctxt->alpn_proto_d
ata, ssl_ctxt->alpn_proto_len, ssl_ctxt->alpn_selector_failure_behavior); | 679 return select_next_proto(ssl, out, outlen, in, inlen, ssl_ctxt->alpn_proto_d
ata, ssl_ctxt->alpn_proto_len, ssl_ctxt->alpn_selector_failure_behavior); |
| 850 } | 680 } |
| 851 | |
| 852 #ifdef HAVE_OPENSSL_OCSP | |
| 853 | |
| 854 /* Function that is used to do the OCSP verification */ | |
| 855 static int ssl_verify_OCSP(int ok, X509_STORE_CTX *ctx) | |
| 856 { | |
| 857 X509 *cert, *issuer; | |
| 858 int r = OCSP_STATUS_UNKNOWN; | |
| 859 | |
| 860 cert = X509_STORE_CTX_get_current_cert(ctx); | |
| 861 /* if we can't get the issuer, we cannot perform OCSP verification */ | |
| 862 if (X509_STORE_CTX_get1_issuer(&issuer, ctx, cert) == 1 ) { | |
| 863 r = ssl_ocsp_request(cert, issuer); | |
| 864 if (r == OCSP_STATUS_REVOKED) { | |
| 865 /* we set the error if we know that it is revoked */ | |
| 866 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED); | |
| 867 } | |
| 868 else { | |
| 869 /* else we return unknown, so that we can continue with the crl */ | |
| 870 r = OCSP_STATUS_UNKNOWN; | |
| 871 } | |
| 872 X509_free(issuer); /* It appears that we should free issuer since | |
| 873 * X509_STORE_CTX_get1_issuer() calls X509_OBJECT_up_
ref_count() | |
| 874 * on the issuer object (unline X509_STORE_CTX_get_cu
rrent_cert() | |
| 875 * that just returns the pointer | |
| 876 */ | |
| 877 } | |
| 878 return r; | |
| 879 } | |
| 880 | |
| 881 | |
| 882 /* Helps with error handling or realloc */ | |
| 883 static void *apr_xrealloc(void *buf, size_t oldlen, size_t len, apr_pool_t *p) | |
| 884 { | |
| 885 void *newp = apr_palloc(p, len); | |
| 886 | |
| 887 if(newp) | |
| 888 memcpy(newp, buf, oldlen); | |
| 889 return newp; | |
| 890 } | |
| 891 | |
| 892 /* parses the ocsp url and updates the ocsp_urls and nocsp_urls variables | |
| 893 returns 0 on success, 1 on failure */ | |
| 894 static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls, | |
| 895 int *nocsp_urls, apr_pool_t *p) | |
| 896 { | |
| 897 char **new_ocsp_urls, *ocsp_url; | |
| 898 int len, err = 0, new_nocsp_urls; | |
| 899 | |
| 900 if (*asn1 == ASN1_STRING) { | |
| 901 len = *++asn1; | |
| 902 asn1++; | |
| 903 new_nocsp_urls = *nocsp_urls+1; | |
| 904 if ((new_ocsp_urls = apr_xrealloc(*ocsp_urls,*nocsp_urls, new_nocsp_urls
, p)) == NULL) | |
| 905 err = 1; | |
| 906 if (!err) { | |
| 907 *ocsp_urls = new_ocsp_urls; | |
| 908 *nocsp_urls = new_nocsp_urls; | |
| 909 *(*ocsp_urls + *nocsp_urls) = NULL; | |
| 910 if ((ocsp_url = apr_palloc(p, len + 1)) == NULL) { | |
| 911 err = 1; | |
| 912 } | |
| 913 else { | |
| 914 memcpy(ocsp_url, asn1, len); | |
| 915 ocsp_url[len] = '\0'; | |
| 916 *(*ocsp_urls + *nocsp_urls - 1) = ocsp_url; | |
| 917 } | |
| 918 } | |
| 919 } | |
| 920 return err; | |
| 921 | |
| 922 } | |
| 923 | |
| 924 /* parses the ANS1 OID and if it is an OCSP OID then calls the parse_ocsp_url fu
nction */ | |
| 925 static int parse_ASN1_OID(unsigned char *asn1, char ***ocsp_urls, int *nocsp_url
s, apr_pool_t *p) | |
| 926 { | |
| 927 int len, err = 0 ; | |
| 928 const unsigned char OCSP_OID[] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30,
0x01}; | |
| 929 | |
| 930 len = *++asn1; | |
| 931 asn1++; | |
| 932 if (memcmp(asn1, OCSP_OID, len) == 0) { | |
| 933 asn1+=len; | |
| 934 err = parse_ocsp_url(asn1, ocsp_urls, nocsp_urls, p); | |
| 935 } | |
| 936 return err; | |
| 937 } | |
| 938 | |
| 939 | |
| 940 /* Parses an ASN1 Sequence. It is a recursive function, since if it finds a seq
uence | |
| 941 within the sequence it calls recursively itself. This function stops when it
finds | |
| 942 the end of the ASN1 sequence (marked by '\0'), so if there are other sequence
s within | |
| 943 the same sequence the while loop parses the sequences */ | |
| 944 | |
| 945 /* This algo was developed with AIA in mind so it was tested only with this exte
nsion */ | |
| 946 static int parse_ASN1_Sequence(unsigned char *asn1, char ***ocsp_urls, | |
| 947 int *nocsp_urls, apr_pool_t *p) | |
| 948 { | |
| 949 int len = 0 , err = 0; | |
| 950 | |
| 951 while (!err && *asn1 != '\0') { | |
| 952 switch(*asn1) { | |
| 953 case ASN1_SEQUENCE: | |
| 954 len = *++asn1; | |
| 955 asn1++; | |
| 956 err = parse_ASN1_Sequence(asn1, ocsp_urls, nocsp_urls, p); | |
| 957 break; | |
| 958 case ASN1_OID: | |
| 959 err = parse_ASN1_OID(asn1,ocsp_urls,nocsp_urls, p); | |
| 960 return 0; | |
| 961 break; | |
| 962 default: | |
| 963 err = 1; /* we shouldn't have any errors */ | |
| 964 break; | |
| 965 } | |
| 966 asn1+=len; | |
| 967 } | |
| 968 return err; | |
| 969 } | |
| 970 | |
| 971 /* the main function that gets the ASN1 encoding string and returns | |
| 972 a pointer to a NULL terminated "array" of char *, that contains | |
| 973 the ocsp_urls */ | |
| 974 static char **decode_OCSP_url(ASN1_OCTET_STRING *os, apr_pool_t *p) | |
| 975 { | |
| 976 char **response = NULL; | |
| 977 unsigned char *ocsp_urls; | |
| 978 int len, numofresponses = 0 ; | |
| 979 | |
| 980 len = ASN1_STRING_length(os); | |
| 981 | |
| 982 ocsp_urls = apr_palloc(p, len + 1); | |
| 983 memcpy(ocsp_urls,os->data, len); | |
| 984 ocsp_urls[len] = '\0'; | |
| 985 | |
| 986 if ((response = apr_pcalloc(p, sizeof(char *))) == NULL) | |
| 987 return NULL; | |
| 988 if (parse_ASN1_Sequence(ocsp_urls, &response, &numofresponses, p)) | |
| 989 response = NULL; | |
| 990 return response; | |
| 991 } | |
| 992 | |
| 993 | |
| 994 /* stolen from openssl ocsp command */ | |
| 995 static int add_ocsp_cert(OCSP_REQUEST **req, X509 *cert, X509 *issuer, | |
| 996 STACK_OF(OCSP_CERTID) *ids) | |
| 997 { | |
| 998 OCSP_CERTID *id; | |
| 999 | |
| 1000 if (!issuer) | |
| 1001 return 0; | |
| 1002 if (!*req) | |
| 1003 *req = OCSP_REQUEST_new(); | |
| 1004 if (!*req) | |
| 1005 return 0; | |
| 1006 id = OCSP_cert_to_id(NULL, cert, issuer); | |
| 1007 if (!id || !sk_OCSP_CERTID_push(ids, id)) | |
| 1008 return 0; | |
| 1009 if (!OCSP_request_add0_id(*req, id)) | |
| 1010 return 0; | |
| 1011 else | |
| 1012 return 1; | |
| 1013 } | |
| 1014 | |
| 1015 | |
| 1016 /* Creates the APR socket and connect to the hostname. Returns the | |
| 1017 socket or NULL if there is an error. | |
| 1018 */ | |
| 1019 static apr_socket_t *make_socket(char *hostname, int port, apr_pool_t *mp) | |
| 1020 { | |
| 1021 apr_sockaddr_t *sa_in; | |
| 1022 apr_status_t status; | |
| 1023 apr_socket_t *sock = NULL; | |
| 1024 | |
| 1025 | |
| 1026 status = apr_sockaddr_info_get(&sa_in, hostname, APR_INET, port, 0, mp); | |
| 1027 | |
| 1028 if (status == APR_SUCCESS) | |
| 1029 status = apr_socket_create(&sock, sa_in->family, SOCK_STREAM, APR_PROTO_
TCP, mp); | |
| 1030 if (status == APR_SUCCESS) | |
| 1031 status = apr_socket_connect(sock, sa_in); | |
| 1032 | |
| 1033 if (status == APR_SUCCESS) | |
| 1034 return sock; | |
| 1035 return NULL; | |
| 1036 } | |
| 1037 | |
| 1038 | |
| 1039 /* Creates the request in a memory BIO in order to send it to the OCSP server. | |
| 1040 Most parts of this function are taken from mod_ssl support for OCSP (with som
e | |
| 1041 minor modifications | |
| 1042 */ | |
| 1043 static BIO *serialize_request(OCSP_REQUEST *req, char *host, int port, char *pat
h) | |
| 1044 { | |
| 1045 BIO *bio; | |
| 1046 int len; | |
| 1047 | |
| 1048 len = i2d_OCSP_REQUEST(req, NULL); | |
| 1049 | |
| 1050 bio = BIO_new(BIO_s_mem()); | |
| 1051 | |
| 1052 BIO_printf(bio, "POST %s HTTP/1.0\r\n" | |
| 1053 "Host: %s:%d\r\n" | |
| 1054 "Content-Type: application/ocsp-request\r\n" | |
| 1055 "Content-Length: %d\r\n" | |
| 1056 "\r\n", | |
| 1057 path, host, port, len); | |
| 1058 | |
| 1059 if (i2d_OCSP_REQUEST_bio(bio, req) != 1) { | |
| 1060 BIO_free(bio); | |
| 1061 return NULL; | |
| 1062 } | |
| 1063 | |
| 1064 return bio; | |
| 1065 } | |
| 1066 | |
| 1067 | |
| 1068 /* Send the OCSP request to the OCSP server. Taken from mod_ssl OCSP support */ | |
| 1069 static int ocsp_send_req(apr_socket_t *sock, BIO *req) | |
| 1070 { | |
| 1071 int len; | |
| 1072 char buf[TCN_BUFFER_SZ]; | |
| 1073 apr_status_t rv; | |
| 1074 int ok = 1; | |
| 1075 | |
| 1076 while ((len = BIO_read(req, buf, sizeof buf)) > 0) { | |
| 1077 char *wbuf = buf; | |
| 1078 apr_size_t remain = len; | |
| 1079 | |
| 1080 do { | |
| 1081 apr_size_t wlen = remain; | |
| 1082 rv = apr_socket_send(sock, wbuf, &wlen); | |
| 1083 wbuf += remain; | |
| 1084 remain -= wlen; | |
| 1085 } while (rv == APR_SUCCESS && remain > 0); | |
| 1086 | |
| 1087 if (rv != APR_SUCCESS) { | |
| 1088 apr_socket_close(sock); | |
| 1089 ok = 0; | |
| 1090 } | |
| 1091 } | |
| 1092 | |
| 1093 return ok; | |
| 1094 } | |
| 1095 | |
| 1096 | |
| 1097 | |
| 1098 /* Parses the buffer from the response and extracts the OCSP response. | |
| 1099 Taken from openssl library */ | |
| 1100 static OCSP_RESPONSE *parse_ocsp_resp(char *buf, int len) | |
| 1101 { | |
| 1102 BIO *mem = NULL; | |
| 1103 char tmpbuf[1024]; | |
| 1104 OCSP_RESPONSE *resp = NULL; | |
| 1105 char *p, *q, *r; | |
| 1106 int retcode; | |
| 1107 | |
| 1108 mem = BIO_new(BIO_s_mem()); | |
| 1109 if(mem == NULL) | |
| 1110 return NULL; | |
| 1111 | |
| 1112 BIO_write(mem, buf, len); /* write the buffer to the bio */ | |
| 1113 if (BIO_gets(mem, tmpbuf, 512) <= 0) { | |
| 1114 OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR); | |
| 1115 goto err; | |
| 1116 } | |
| 1117 /* Parse the HTTP response. This will look like this: | |
| 1118 * "HTTP/1.0 200 OK". We need to obtain the numeric code and | |
| 1119 * (optional) informational message. | |
| 1120 */ | |
| 1121 | |
| 1122 /* Skip to first white space (passed protocol info) */ | |
| 1123 for (p = tmpbuf; *p && !apr_isspace(*p); p++) | |
| 1124 continue; | |
| 1125 if (!*p) { | |
| 1126 goto err; | |
| 1127 } | |
| 1128 /* Skip past white space to start of response code */ | |
| 1129 while (apr_isspace(*p)) | |
| 1130 p++; | |
| 1131 if (!*p) { | |
| 1132 goto err; | |
| 1133 } | |
| 1134 /* Find end of response code: first whitespace after start of code */ | |
| 1135 for (q = p; *q && !apr_isspace(*q); q++) | |
| 1136 continue; | |
| 1137 if (!*q) { | |
| 1138 goto err; | |
| 1139 } | |
| 1140 /* Set end of response code and start of message */ | |
| 1141 *q++ = 0; | |
| 1142 /* Attempt to parse numeric code */ | |
| 1143 retcode = strtoul(p, &r, 10); | |
| 1144 if (*r) | |
| 1145 goto err; | |
| 1146 /* Skip over any leading white space in message */ | |
| 1147 while (apr_isspace(*q)) | |
| 1148 q++; | |
| 1149 if (*q) { | |
| 1150 /* Finally zap any trailing white space in message (include CRLF) */ | |
| 1151 /* We know q has a non white space character so this is OK */ | |
| 1152 for(r = q + strlen(q) - 1; apr_isspace(*r); r--) *r = 0; | |
| 1153 } | |
| 1154 if (retcode != 200) { | |
| 1155 goto err; | |
| 1156 } | |
| 1157 /* Find blank line marking beginning of content */ | |
| 1158 while (BIO_gets(mem, tmpbuf, 512) > 0) { | |
| 1159 for (p = tmpbuf; apr_isspace(*p); p++) | |
| 1160 continue; | |
| 1161 if (!*p) | |
| 1162 break; | |
| 1163 } | |
| 1164 if (*p) { | |
| 1165 goto err; | |
| 1166 } | |
| 1167 if (!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) { | |
| 1168 goto err; | |
| 1169 } | |
| 1170 err: | |
| 1171 BIO_free(mem); | |
| 1172 return resp; | |
| 1173 } | |
| 1174 | |
| 1175 | |
| 1176 /* Reads the respnse from the APR socket to a buffer, and parses the buffer to | |
| 1177 return the OCSP response */ | |
| 1178 #define ADDLEN 512 | |
| 1179 static OCSP_RESPONSE *ocsp_get_resp(apr_socket_t *sock) | |
| 1180 { | |
| 1181 int buflen; | |
| 1182 apr_size_t totalread = 0; | |
| 1183 apr_size_t readlen; | |
| 1184 char *buf, tmpbuf[ADDLEN]; | |
| 1185 apr_status_t rv = APR_SUCCESS; | |
| 1186 apr_pool_t *p; | |
| 1187 OCSP_RESPONSE *resp; | |
| 1188 | |
| 1189 apr_pool_create(&p, NULL); | |
| 1190 buflen = ADDLEN; | |
| 1191 buf = apr_palloc(p, buflen); | |
| 1192 if (buf == NULL) { | |
| 1193 apr_pool_destroy(p); | |
| 1194 return NULL; | |
| 1195 } | |
| 1196 | |
| 1197 while (rv == APR_SUCCESS ) { | |
| 1198 readlen = sizeof(tmpbuf); | |
| 1199 rv = apr_socket_recv(sock, tmpbuf, &readlen); | |
| 1200 if (rv == APR_SUCCESS) { /* if we have read something .. we can put it i
n the buffer*/ | |
| 1201 if ((totalread + readlen) >= buflen) { | |
| 1202 buf = apr_xrealloc(buf, buflen, buflen + ADDLEN, p); | |
| 1203 if (buf == NULL) { | |
| 1204 apr_pool_destroy(p); | |
| 1205 return NULL; | |
| 1206 } | |
| 1207 buflen += ADDLEN; /* if needed we enlarge the buffer */ | |
| 1208 } | |
| 1209 memcpy(buf + totalread, tmpbuf, readlen); /* the copy to the buffer
*/ | |
| 1210 totalread += readlen; /* update the total bytes read */ | |
| 1211 } | |
| 1212 else { | |
| 1213 if (rv == APR_EOF && readlen == 0) | |
| 1214 ; /* EOF, normal situation */ | |
| 1215 else if (readlen == 0) { | |
| 1216 /* Not success, and readlen == 0 .. some error */ | |
| 1217 apr_pool_destroy(p); | |
| 1218 return NULL; | |
| 1219 } | |
| 1220 } | |
| 1221 } | |
| 1222 | |
| 1223 resp = parse_ocsp_resp(buf, buflen); | |
| 1224 apr_pool_destroy(p); | |
| 1225 return resp; | |
| 1226 } | |
| 1227 | |
| 1228 /* Creates and OCSP request and returns the OCSP_RESPONSE */ | |
| 1229 static OCSP_RESPONSE *get_ocsp_response(X509 *cert, X509 *issuer, char *url) | |
| 1230 { | |
| 1231 OCSP_RESPONSE *ocsp_resp = NULL; | |
| 1232 OCSP_REQUEST *ocsp_req = NULL; | |
| 1233 BIO *bio_req; | |
| 1234 char *hostname, *path, *c_port; | |
| 1235 int port, use_ssl; | |
| 1236 STACK_OF(OCSP_CERTID) *ids = NULL; | |
| 1237 int ok = 0; | |
| 1238 apr_socket_t *apr_sock = NULL; | |
| 1239 apr_pool_t *mp; | |
| 1240 | |
| 1241 apr_pool_create(&mp, NULL); | |
| 1242 ids = sk_OCSP_CERTID_new_null(); | |
| 1243 | |
| 1244 /* problem parsing the URL */ | |
| 1245 if (OCSP_parse_url(url,&hostname, &c_port, &path, &use_ssl) == 0 ) { | |
| 1246 sk_OCSP_CERTID_free(ids); | |
| 1247 return NULL; | |
| 1248 } | |
| 1249 | |
| 1250 /* Create the OCSP request */ | |
| 1251 if (sscanf(c_port, "%d", &port) != 1) | |
| 1252 goto end; | |
| 1253 ocsp_req = OCSP_REQUEST_new(); | |
| 1254 if (ocsp_req == NULL) | |
| 1255 return NULL; | |
| 1256 if (add_ocsp_cert(&ocsp_req,cert,issuer,ids) == 0 ) | |
| 1257 goto free_req; | |
| 1258 | |
| 1259 /* create the BIO with the request to send */ | |
| 1260 bio_req = serialize_request(ocsp_req, hostname, port, path); | |
| 1261 if (bio_req == NULL) { | |
| 1262 goto free_req; | |
| 1263 } | |
| 1264 | |
| 1265 apr_sock = make_socket(hostname, port, mp); | |
| 1266 if (apr_sock == NULL) { | |
| 1267 ocsp_resp = NULL; | |
| 1268 goto free_bio; | |
| 1269 } | |
| 1270 | |
| 1271 ok = ocsp_send_req(apr_sock, bio_req); | |
| 1272 if (ok) | |
| 1273 ocsp_resp = ocsp_get_resp(apr_sock); | |
| 1274 | |
| 1275 free_bio: | |
| 1276 BIO_free(bio_req); | |
| 1277 | |
| 1278 free_req: | |
| 1279 if(apr_sock && ok) /* if ok == 0 we have already closed the socket */ | |
| 1280 apr_socket_close(apr_sock); | |
| 1281 | |
| 1282 apr_pool_destroy(mp); | |
| 1283 | |
| 1284 sk_OCSP_CERTID_free(ids); | |
| 1285 OCSP_REQUEST_free(ocsp_req); | |
| 1286 | |
| 1287 end: | |
| 1288 return ocsp_resp; | |
| 1289 } | |
| 1290 | |
| 1291 /* Process the OCSP_RESPONSE and returns the corresponding | |
| 1292 answert according to the status. | |
| 1293 */ | |
| 1294 static int process_ocsp_response(OCSP_RESPONSE *ocsp_resp) | |
| 1295 { | |
| 1296 int r, o = V_OCSP_CERTSTATUS_UNKNOWN, i; | |
| 1297 OCSP_BASICRESP *bs; | |
| 1298 OCSP_SINGLERESP *ss; | |
| 1299 | |
| 1300 r = OCSP_response_status(ocsp_resp); | |
| 1301 | |
| 1302 if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) { | |
| 1303 OCSP_RESPONSE_free(ocsp_resp); | |
| 1304 return OCSP_STATUS_UNKNOWN; | |
| 1305 } | |
| 1306 bs = OCSP_response_get1_basic(ocsp_resp); | |
| 1307 | |
| 1308 ss = OCSP_resp_get0(bs,0); /* we know we have only 1 request */ | |
| 1309 | |
| 1310 i = OCSP_single_get0_status(ss, NULL, NULL, NULL, NULL); | |
| 1311 if (i == V_OCSP_CERTSTATUS_GOOD) | |
| 1312 o = OCSP_STATUS_OK; | |
| 1313 else if (i == V_OCSP_CERTSTATUS_REVOKED) | |
| 1314 o = OCSP_STATUS_REVOKED; | |
| 1315 else if (i == V_OCSP_CERTSTATUS_UNKNOWN) | |
| 1316 o = OCSP_STATUS_UNKNOWN; | |
| 1317 | |
| 1318 /* we clean up */ | |
| 1319 OCSP_RESPONSE_free(ocsp_resp); | |
| 1320 return o; | |
| 1321 } | |
| 1322 | |
| 1323 static int ssl_ocsp_request(X509 *cert, X509 *issuer) | |
| 1324 { | |
| 1325 char **ocsp_urls = NULL; | |
| 1326 int nid; | |
| 1327 X509_EXTENSION *ext; | |
| 1328 ASN1_OCTET_STRING *os; | |
| 1329 apr_pool_t *p; | |
| 1330 | |
| 1331 apr_pool_create(&p, NULL); | |
| 1332 | |
| 1333 /* Get the proper extension */ | |
| 1334 nid = X509_get_ext_by_NID(cert,NID_info_access,-1); | |
| 1335 if (nid >= 0 ) { | |
| 1336 ext = X509_get_ext(cert,nid); | |
| 1337 os = X509_EXTENSION_get_data(ext); | |
| 1338 | |
| 1339 ocsp_urls = decode_OCSP_url(os, p); | |
| 1340 } | |
| 1341 | |
| 1342 /* if we find the extensions and we can parse it check | |
| 1343 the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */ | |
| 1344 if (ocsp_urls != NULL) { | |
| 1345 OCSP_RESPONSE *resp; | |
| 1346 /* for the time being just check for the fist response .. a better | |
| 1347 approach is to iterate for all the possible ocsp urls */ | |
| 1348 resp = get_ocsp_response(cert, issuer, ocsp_urls[0]); | |
| 1349 | |
| 1350 if (resp != NULL) { | |
| 1351 apr_pool_destroy(p); | |
| 1352 return process_ocsp_response(resp); | |
| 1353 } | |
| 1354 } | |
| 1355 apr_pool_destroy(p); | |
| 1356 return OCSP_STATUS_UNKNOWN; | |
| 1357 } | |
| 1358 | |
| 1359 #endif /* HAS_OCSP_ENABLED */ | |
| 1360 #endif /* HAVE_OPENSSL */ | |
| OLD | NEW |