1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * 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
6 * 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,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /** SSL Utilities
18 */
19
20 #include "tcn.h"
21
22 #ifdef HAVE_OPENSSL
23 #include "apr_poll.h"
24 #include "ssl_private.h"
25
26 #ifdef WIN32
27 extern int WIN32_SSL_password_prompt(tcn_pass_cb_t *data);
28 #endif
29
30 #ifdef HAVE_OCSP_STAPLING
31 #include <openssl/bio.h>
32 #include <openssl/ocsp.h>
33 /* defines with the values as seen by the asn1parse -dump openssl command */
34 #define ASN1_SEQUENCE 0x30
35 #define ASN1_OID 0x06
36 #define ASN1_STRING 0x86
37 static int ssl_verify_OCSP(X509_STORE_CTX *ctx);
38 static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx);
39 #endif
40
41 /* _________________________________________________________________
42 **
43 ** Additional High-Level Functions for OpenSSL
44 ** _________________________________________________________________
45 */
46
47 /* we initialize this index at startup time
48 * and never write to it at request time,
49 * so this static is thread safe.
50 * also note that OpenSSL increments at static variable when
51 * SSL_get_ex_new_index() is called, so we _must_ do this at startup.
52 */
53 static int SSL_app_data2_idx = -1;
54 static int SSL_app_data3_idx = -1;
55 static int SSL_app_data4_idx = -1;
56
SSL_init_app_data_idx(void)57 void SSL_init_app_data_idx(void)
58 {
59 int i;
60
61 if (SSL_app_data2_idx > -1) {
62 return;
63 }
64
65 /* we _do_ need to call this twice */
66 for (i = 0; i <= 1; i++) {
67 SSL_app_data2_idx =
68 SSL_get_ex_new_index(0,
69 "Second Application Data for SSL",
70 NULL, NULL, NULL);
71 }
72
73 if (SSL_app_data3_idx > -1) {
74 return;
75 }
76
77 SSL_app_data3_idx =
78 SSL_get_ex_new_index(0,
79 "Third Application Data for SSL",
80 NULL, NULL, NULL);
81
82 if (SSL_app_data4_idx > -1) {
83 return;
84 }
85
86 SSL_app_data4_idx =
87 SSL_get_ex_new_index(0,
88 "Fourth Application Data for SSL",
89 NULL, NULL, NULL);
90
91 }
92
SSL_get_app_data2(SSL * ssl)93 void *SSL_get_app_data2(SSL *ssl)
94 {
95 return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx);
96 }
97
SSL_set_app_data2(SSL * ssl,void * arg)98 void SSL_set_app_data2(SSL *ssl, void *arg)
99 {
100 SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg);
101 return;
102 }
103
104
SSL_get_app_data3(const SSL * ssl)105 void *SSL_get_app_data3(const SSL *ssl)
106 {
107 return SSL_get_ex_data(ssl, SSL_app_data3_idx);
108 }
109
SSL_set_app_data3(SSL * ssl,void * arg)110 void SSL_set_app_data3(SSL *ssl, void *arg)
111 {
112 SSL_set_ex_data(ssl, SSL_app_data3_idx, arg);
113 }
114
SSL_get_app_data4(const SSL * ssl)115 void *SSL_get_app_data4(const SSL *ssl)
116 {
117 return SSL_get_ex_data(ssl, SSL_app_data4_idx);
118 }
119
SSL_set_app_data4(SSL * ssl,void * arg)120 void SSL_set_app_data4(SSL *ssl, void *arg)
121 {
122 SSL_set_ex_data(ssl, SSL_app_data4_idx, arg);
123 }
124
125 /* Simple echo password prompting */
SSL_password_prompt(tcn_pass_cb_t * data)126 int SSL_password_prompt(tcn_pass_cb_t *data)
127 {
128 int rv = 0;
129 data->password[0] = '\0';
130 if (data->cb.obj) {
131 JNIEnv *e;
132 jobject o;
133 jstring prompt;
134 tcn_get_java_env(&e);
135 prompt = AJP_TO_JSTRING(data->prompt);
136 if ((o = (*e)->CallObjectMethod(e, data->cb.obj,
137 data->cb.mid[0], prompt))) {
138 TCN_ALLOC_CSTRING(o);
139 if (J2S(o)) {
140 strncpy(data->password, J2S(o), SSL_MAX_PASSWORD_LEN);
141 data->password[SSL_MAX_PASSWORD_LEN-1] = '\0';
142 rv = (int)strlen(data->password);
143 }
144 TCN_FREE_CSTRING(o);
145 }
146 }
147 else {
148 #ifdef WIN32
149 rv = WIN32_SSL_password_prompt(data);
150 #else
151 EVP_read_pw_string(data->password, SSL_MAX_PASSWORD_LEN,
152 data->prompt, 0);
153 #endif
154 rv = (int)strlen(data->password);
155 }
156 if (rv > 0) {
157 /* Remove LF char if present */
158 char *r = strchr(data->password, '\n');
159 if (r) {
160 *r = '\0';
161 rv--;
162 }
163 #ifdef WIN32
164 if ((r = strchr(data->password, '\r'))) {
165 *r = '\0';
166 rv--;
167 }
168 #endif
169 }
170 return rv;
171 }
172
SSL_password_callback(char * buf,int bufsiz,int verify,void * cb)173 int SSL_password_callback(char *buf, int bufsiz, int verify,
174 void *cb)
175 {
176 tcn_pass_cb_t *cb_data = (tcn_pass_cb_t *)cb;
177
178 if (buf == NULL)
179 return 0;
180 *buf = '\0';
181 if (cb_data == NULL)
182 cb_data = &tcn_password_callback;
183 if (!cb_data->prompt)
184 cb_data->prompt = SSL_DEFAULT_PASS_PROMPT;
185 if (cb_data->password[0]) {
186 /* Return already obtained password */
187 strncpy(buf, cb_data->password, bufsiz);
188 buf[bufsiz - 1] = '\0';
189 return (int)strlen(buf);
190 }
191 else {
192 if (SSL_password_prompt(cb_data) > 0)
193 strncpy(buf, cb_data->password, bufsiz);
194 }
195 buf[bufsiz - 1] = '\0';
196 return (int)strlen(buf);
197 }
198
199 /* _________________________________________________________________
200 **
201 ** Custom (EC)DH parameter support
202 ** _________________________________________________________________
203 */
SSL_dh_GetParamFromFile(const char * file)204 DH *SSL_dh_GetParamFromFile(const char *file)
205 {
206 DH *dh = NULL;
207 BIO *bio;
208
209 if ((bio = BIO_new_file(file, "r")) == NULL)
210 return NULL;
211 dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
212 BIO_free(bio);
213 return dh;
214 }
215
216 #ifdef HAVE_ECC
SSL_ec_GetParamFromFile(const char * file)217 EC_GROUP *SSL_ec_GetParamFromFile(const char *file)
218 {
219 EC_GROUP *group = NULL;
220 BIO *bio;
221
222 if ((bio = BIO_new_file(file, "r")) == NULL)
223 return NULL;
224 group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL);
225 BIO_free(bio);
226 return (group);
227 }
228 #endif
229
230 /*
231 * Hand out standard DH parameters, based on the authentication strength
232 */
SSL_callback_tmp_DH(SSL * ssl,int export,int keylen)233 DH *SSL_callback_tmp_DH(SSL *ssl, int export, int keylen)
234 {
235 EVP_PKEY *pkey = SSL_get_privatekey(ssl);
236 int type = pkey != NULL ? EVP_PKEY_base_id(pkey) : EVP_PKEY_NONE;
237
238 /*
239 * OpenSSL will call us with either keylen == 512 or keylen == 1024
240 * (see the definition of SSL_EXPORT_PKEYLENGTH in ssl_locl.h).
241 * Adjust the DH parameter length according to the size of the
242 * RSA/DSA private key used for the current connection, and always
243 * use at least 1024-bit parameters.
244 * Note: This may cause interoperability issues with implementations
245 * which limit their DH support to 1024 bit - e.g. Java 7 and earlier.
246 * In this case, SSLCertificateFile can be used to specify fixed
247 * 1024-bit DH parameters (with the effect that OpenSSL skips this
248 * callback).
249 */
250 if ((type == EVP_PKEY_RSA) || (type == EVP_PKEY_DSA)) {
251 keylen = EVP_PKEY_bits(pkey);
252 }
253 return SSL_get_dh_params(keylen);
254 }
255
256 /*
257 * Read a file that optionally contains the server certificate in PEM
258 * format, possibly followed by a sequence of CA certificates that
259 * should be sent to the peer in the SSL Certificate message.
260 */
SSL_CTX_use_certificate_chain(SSL_CTX * ctx,const char * file,int skipfirst)261 int SSL_CTX_use_certificate_chain(SSL_CTX *ctx, const char *file,
262 int skipfirst)
263 {
264 BIO *bio;
265 X509 *x509;
266 unsigned long err;
267 int n;
268
269 if ((bio = BIO_new(BIO_s_file())) == NULL)
270 return -1;
271 if (BIO_read_filename(bio, file) <= 0) {
272 BIO_free(bio);
273 return -1;
274 }
275 /* optionally skip a leading server certificate */
276 if (skipfirst) {
277 if ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) == NULL) {
278 BIO_free(bio);
279 return -1;
280 }
281 X509_free(x509);
282 }
283
284 /* free a perhaps already configured extra chain */
285 SSL_CTX_clear_extra_chain_certs(ctx);
286
287 /* create new extra chain by loading the certs */
288 n = 0;
289 while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
290 if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
291 X509_free(x509);
292 BIO_free(bio);
293 return -1;
294 }
295 n++;
296 }
297 /* Make sure that only the error is just an EOF */
298 if ((err = ERR_peek_error()) > 0) {
299 if (!( ERR_GET_LIB(err) == ERR_LIB_PEM
300 && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
301 BIO_free(bio);
302 return -1;
303 }
304 while (SSL_ERR_get() > 0) ;
305 }
306 BIO_free(bio);
307 return n;
308 }
309
310 /*
311 * This OpenSSL callback function is called when OpenSSL
312 * does client authentication and verifies the certificate chain.
313 */
314
315
SSL_callback_SSL_verify(int ok,X509_STORE_CTX * ctx)316 int SSL_callback_SSL_verify(int ok, X509_STORE_CTX *ctx)
317 {
318 /* Get Apache context back through OpenSSL context */
319 SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
320 SSL_get_ex_data_X509_STORE_CTX_idx());
321 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
322 /* Get verify ingredients */
323 int errnum = X509_STORE_CTX_get_error(ctx);
324 int errdepth = X509_STORE_CTX_get_error_depth(ctx);
325 int verify = con->ctx->verify_mode;
326 int depth = con->ctx->verify_depth;
327
328 #if defined(SSL_OP_NO_TLSv1_3)
329 con->pha_state = PHA_COMPLETE;
330 #endif
331
332 if (verify == SSL_CVERIFY_UNSET ||
333 verify == SSL_CVERIFY_NONE) {
334 return 1;
335 }
336
337 if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum) &&
338 (verify == SSL_CVERIFY_OPTIONAL_NO_CA)) {
339 ok = 1;
340 SSL_set_verify_result(ssl, X509_V_OK);
341 }
342
343 /*
344 * Expired certificates vs. "expired" CRLs: by default, OpenSSL
345 * turns X509_V_ERR_CRL_HAS_EXPIRED into a "certificate_expired(45)"
346 * SSL alert, but that's not really the message we should convey to the
347 * peer (at the very least, it's confusing, and in many cases, it's also
348 * inaccurate, as the certificate itself may very well not have expired
349 * yet). We set the X509_STORE_CTX error to something which OpenSSL's
350 * s3_both.c:ssl_verify_alarm_type() maps to SSL_AD_CERTIFICATE_UNKNOWN,
351 * i.e. the peer will receive a "certificate_unknown(46)" alert.
352 * We do not touch errnum, though, so that later on we will still log
353 * the "real" error, as returned by OpenSSL.
354 */
355 if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
356 X509_STORE_CTX_set_error(ctx, -1);
357 }
358
359 #ifdef HAVE_OCSP_STAPLING
360 /* First perform OCSP validation if possible */
361 if (ok) {
362 /* If there was an optional verification error, it's not
363 * possible to perform OCSP validation since the issuer may be
364 * missing/untrusted. Fail in that case.
365 */
366 if (SSL_VERIFY_ERROR_IS_OPTIONAL(errnum)) {
367 X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
368 errnum = X509_V_ERR_APPLICATION_VERIFICATION;
369 ok = 0;
370 }
371 else {
372 int ocsp_response = ssl_verify_OCSP(ctx);
373 if (ocsp_response == OCSP_STATUS_REVOKED) {
374 ok = 0 ;
375 errnum = X509_STORE_CTX_get_error(ctx);
376 }
377 else if (ocsp_response == OCSP_STATUS_UNKNOWN) {
378 /* TODO: do nothing for time being */
379 ;
380 }
381 }
382 }
383 #endif
384 /*
385 * If we already know it's not ok, log the real reason
386 */
387 if (!ok) {
388 /* TODO: Some logging
389 * Certificate Verification: Error
390 */
391 if (con->peer) {
392 X509_free(con->peer);
393 con->peer = NULL;
394 }
395 }
396 if (errdepth > depth) {
397 /* TODO: Some logging
398 * Certificate Verification: Certificate Chain too long
399 */
400 ok = 0;
401 }
402 return ok;
403 }
404
405 /*
406 * This callback function is executed while OpenSSL processes the SSL
407 * handshake and does SSL record layer stuff. It's used to trap
408 * client-initiated renegotiations, and for dumping everything to the
409 * log.
410 */
SSL_callback_handshake(const SSL * ssl,int where,int rc)411 void SSL_callback_handshake(const SSL *ssl, int where, int rc)
412 {
413 tcn_ssl_conn_t *con = (tcn_ssl_conn_t *)SSL_get_app_data(ssl);
414 #ifdef HAVE_TLSV1_3
415 const SSL_SESSION *session = SSL_get_session(ssl);
416 #endif
417
418 /* Retrieve the conn_rec and the associated SSLConnRec. */
419 if (con == NULL) {
420 return;
421 }
422
423 #ifdef HAVE_TLSV1_3
424 /* TLS 1.3 does not use renegotiation so do not update the renegotiation
425 * state once we know we are using TLS 1.3. */
426 if (session != NULL) {
427 if (SSL_SESSION_get_protocol_version(session) == TLS1_3_VERSION) {
428 return;
429 }
430 }
431 #endif
432
433 /* If the reneg state is to reject renegotiations, check the SSL
434 * state machine and move to ABORT if a Client Hello is being
435 * read. */
436 if ((where & SSL_CB_HANDSHAKE_START) &&
437 con->reneg_state == RENEG_REJECT) {
438 con->reneg_state = RENEG_ABORT;
439 }
440 /* If the first handshake is complete, change state to reject any
441 * subsequent client-initated renegotiation. */
442 else if ((where & SSL_CB_HANDSHAKE_DONE) && con->reneg_state == RENEG_INIT) {
443 con->reneg_state = RENEG_REJECT;
444 }
445 }
446
SSL_callback_next_protos(SSL * ssl,const unsigned char ** data,unsigned int * len,void * arg)447 int SSL_callback_next_protos(SSL *ssl, const unsigned char **data,
448 unsigned int *len, void *arg)
449 {
450 tcn_ssl_ctxt_t *ssl_ctxt = arg;
451
452 *data = ssl_ctxt->next_proto_data;
453 *len = ssl_ctxt->next_proto_len;
454
455 return SSL_TLSEXT_ERR_OK;
456 }
457
458 /* The code here is inspired by nghttp2
459 *
460 * See https://github.com/tatsuhiro-t/nghttp2/blob/ae0100a9abfcf3149b8d9e62aae216e946b517fb/src/shrpx_ssl.cc#L244 */
select_next_proto(SSL * ssl,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,unsigned char * supported_protos,unsigned int supported_protos_len,int failure_behavior)461 int select_next_proto(SSL *ssl, const unsigned char **out, unsigned char *outlen,
462 const unsigned char *in, unsigned int inlen, unsigned char *supported_protos,
463 unsigned int supported_protos_len, int failure_behavior) {
464
465 unsigned int i = 0;
466 unsigned char target_proto_len;
467 const unsigned char *p;
468 const unsigned char *end;
469 const unsigned char *proto;
470 unsigned char proto_len = '\0';
471
472 while (i < supported_protos_len) {
473 target_proto_len = *supported_protos;
474 ++supported_protos;
475
476 p = in;
477 end = in + inlen;
478
479 while (p < end) {
480 proto_len = *p;
481 proto = ++p;
482
483 if (proto + proto_len <= end && target_proto_len == proto_len &&
484 memcmp(supported_protos, proto, proto_len) == 0) {
485
486 // We found a match, so set the output and return with OK!
487 *out = proto;
488 *outlen = proto_len;
489
490 return SSL_TLSEXT_ERR_OK;
491 }
492 // Move on to the next protocol.
493 p += proto_len;
494 }
495
496 // increment len and pointers.
497 i += target_proto_len;
498 supported_protos += target_proto_len;
499 }
500
501 if (supported_protos_len > 0 && inlen > 0 && failure_behavior == SSL_SELECTOR_FAILURE_CHOOSE_MY_LAST_PROTOCOL) {
502 // There were no match but we just select our last protocol and hope the other peer support it.
503 //
504 // decrement the pointer again so the pointer points to the start of the protocol.
505 p -= proto_len;
506 *out = p;
507 *outlen = proto_len;
508 return SSL_TLSEXT_ERR_OK;
509 }
510 // TODO: OpenSSL currently not support to fail with fatal error. Once this changes we can also support it here.
511 // Issue https://github.com/openssl/openssl/issues/188 has been created for this.
512 // Nothing matched so not select anything and just accept.
513 return SSL_TLSEXT_ERR_NOACK;
514 }
515
SSL_callback_select_next_proto(SSL * ssl,unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)516 int SSL_callback_select_next_proto(SSL *ssl, unsigned char **out, unsigned char *outlen,
517 const unsigned char *in, unsigned int inlen,
518 void *arg) {
519 tcn_ssl_ctxt_t *ssl_ctxt = arg;
520 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_failure_behavior);
521 }
522
SSL_callback_alpn_select_proto(SSL * ssl,const unsigned char ** out,unsigned char * outlen,const unsigned char * in,unsigned int inlen,void * arg)523 int SSL_callback_alpn_select_proto(SSL* ssl, const unsigned char **out, unsigned char *outlen,
524 const unsigned char *in, unsigned int inlen, void *arg) {
525 tcn_ssl_ctxt_t *ssl_ctxt = arg;
526 return select_next_proto(ssl, out, outlen, in, inlen, ssl_ctxt->alpn_proto_data, ssl_ctxt->alpn_proto_len, ssl_ctxt->alpn_selector_failure_behavior);
527 }
528 #ifdef HAVE_OCSP_STAPLING
529
530 /* Function that is used to do the OCSP verification */
ssl_verify_OCSP(X509_STORE_CTX * ctx)531 static int ssl_verify_OCSP(X509_STORE_CTX *ctx)
532 {
533 X509 *cert, *issuer;
534 int r = OCSP_STATUS_UNKNOWN;
535
536 cert = X509_STORE_CTX_get_current_cert(ctx);
537
538 if (!cert) {
539 /* starting with OpenSSL 1.0, X509_STORE_CTX_get_current_cert()
540 * may yield NULL. Return early, but leave the ctx error as is. */
541 return OCSP_STATUS_UNKNOWN;
542 }
543 #if OPENSSL_VERSION_NUMBER < 0x10100000L
544 else if (cert->valid && X509_check_issued(cert,cert) == X509_V_OK) {
545 #else
546 /* No need to check cert->valid, because ssl_verify_OCSP() only
547 * is called if OpenSSL already successfully verified the certificate
548 * (parameter "ok" in SSL_callback_SSL_verify() must be true).
549 */
550 else if (X509_check_issued(cert,cert) == X509_V_OK) {
551 #endif
552 /* don't do OCSP checking for valid self-issued certs */
553 X509_STORE_CTX_set_error(ctx, X509_V_OK);
554 return OCSP_STATUS_UNKNOWN;
555 }
556
557 /* if we can't get the issuer, we cannot perform OCSP verification */
558 issuer = X509_STORE_CTX_get0_current_issuer(ctx);
559 if (issuer != NULL) {
560 r = ssl_ocsp_request(cert, issuer, ctx);
561 switch (r) {
562 case OCSP_STATUS_OK:
563 X509_STORE_CTX_set_error(ctx, X509_V_OK);
564 break;
565 case OCSP_STATUS_REVOKED:
566 /* we set the error if we know that it is revoked */
567 X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
568 break;
569 case OCSP_STATUS_UNKNOWN:
570 /* ssl_ocsp_request() sets the error correctly already. */
571 break;
572 }
573 }
574 return r;
575 }
576
577
578 /* Helps with error handling or realloc */
579 static void *apr_xrealloc(void *buf, size_t oldlen, size_t len, apr_pool_t *p)
580 {
581 void *newp = apr_palloc(p, len);
582
583 if(newp)
584 memcpy(newp, buf, oldlen);
585 return newp;
586 }
587
588 /* Parses an ASN.1 length.
589 * On entry, asn1 points to the current tag.
590 * Updates the pointer to the ASN.1 structure to point to the start of the data.
591 * Returns 0 on success, 1 on failure.
592 */
593 static int parse_asn1_length(unsigned char **asn1, int *len) {
594
595 /* Length immediately follows tag so increment before reading first (and
596 * possibly only) length byte.
597 */
598 (*asn1)++;
599
600 if (**asn1 & 0x80) {
601 // MSB set. Remaining bits are number of bytes used to store the length.
602 int i, l;
603
604 // How many bytes for this length?
605 i = **asn1 & 0x7F;
606
607 if (i == 0) {
608 /* This is the indefinite form of length. Since certificates use DER
609 * this should never happen and is therefore an error.
610 */
611 return 1;
612 }
613 if (i > 3) {
614 /* Three bytes for length gives a maximum of 16MB which should be
615 * far more than is required. (2 bytes is 64K which is probably more
616 * than enough but play safe.)
617 */
618 return 1;
619 }
620
621 // Most significant byte is first
622 l = 0;
623 while (i > 0) {
624 l <<= 8;
625 (*asn1)++;
626 l += **asn1;
627 i--;
628 }
629 *len = l;
630 } else {
631 // Single byte length
632 *len = **asn1;
633 }
634
635 (*asn1)++;
636
637 return 0;
638 }
639
640 /* parses the ocsp url and updates the ocsp_urls and nocsp_urls variables
641 returns 0 on success, 1 on failure */
642 static int parse_ocsp_url(unsigned char *asn1, char ***ocsp_urls,
643 int *nocsp_urls, apr_pool_t *p)
644 {
645 char **new_ocsp_urls, *ocsp_url;
646 int len, err = 0, new_nocsp_urls;
647
648 if (*asn1 == ASN1_STRING) {
649 err = parse_asn1_length(&asn1, &len);
650
651 if (!err) {
652 new_nocsp_urls = *nocsp_urls+1;
653 if ((new_ocsp_urls = apr_xrealloc(*ocsp_urls,*nocsp_urls, new_nocsp_urls, p)) == NULL)
654 err = 1;
655 }
656 if (!err) {
657 *ocsp_urls = new_ocsp_urls;
658 *nocsp_urls = new_nocsp_urls;
659 *(*ocsp_urls + *nocsp_urls) = NULL;
660 if ((ocsp_url = apr_palloc(p, len + 1)) == NULL) {
661 err = 1;
662 }
663 else {
664 memcpy(ocsp_url, asn1, len);
665 ocsp_url[len] = '\0';
666 *(*ocsp_urls + *nocsp_urls - 1) = ocsp_url;
667 }
668 }
669 }
670 return err;
671
672 }
673
674 /* parses the ANS1 OID and if it is an OCSP OID then calls the parse_ocsp_url function */
675 static int parse_ASN1_OID(unsigned char *asn1, char ***ocsp_urls, int *nocsp_urls, apr_pool_t *p)
676 {
677 int len, err = 0 ;
678 const unsigned char OCSP_OID[] = {0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01};
679
680 err = parse_asn1_length(&asn1, &len);
681
682 if (!err && len == 8 && memcmp(asn1, OCSP_OID, 8) == 0) {
683 asn1+=len;
684 err = parse_ocsp_url(asn1, ocsp_urls, nocsp_urls, p);
685 }
686 return err;
687 }
688
689
690 /* Parses an ASN1 Sequence. It is a recursive function, since if it finds a sequence
691 within the sequence it calls recursively itself. This function stops when it finds
692 the end of the ASN1 sequence (marked by '\0'), so if there are other sequences within
693 the same sequence the while loop parses the sequences */
694
695 /* This algo was developed with AIA in mind so it was tested only with this extension */
696 static int parse_ASN1_Sequence(unsigned char *asn1, char ***ocsp_urls,
697 int *nocsp_urls, apr_pool_t *p)
698 {
699 int len = 0 , err = 0;
700
701 while (!err && *asn1 != '\0') {
702 switch(*asn1) {
703 case ASN1_SEQUENCE:
704 err = parse_asn1_length(&asn1, &len);
705 if (!err) {
706 err = parse_ASN1_Sequence(asn1, ocsp_urls, nocsp_urls, p);
707 }
708 break;
709 case ASN1_OID:
710 err = parse_ASN1_OID(asn1,ocsp_urls,nocsp_urls, p);
711 return err;
712 break;
713 default:
714 err = 1; /* we shouldn't have any errors */
715 break;
716 }
717 asn1+=len;
718 }
719 return err;
720 }
721
722 /* the main function that gets the ASN1 encoding string and returns
723 a pointer to a NULL terminated "array" of char *, that contains
724 the ocsp_urls */
725 static char **decode_OCSP_url(ASN1_OCTET_STRING *os, apr_pool_t *p)
726 {
727 char **response = NULL;
728 unsigned char *ocsp_urls;
729 int len, numofresponses = 0 ;
730
731 len = ASN1_STRING_length(os);
732
733 ocsp_urls = apr_palloc(p, len + 1);
734 memcpy(ocsp_urls,os->data, len);
735 ocsp_urls[len] = '\0';
736
737 if ((response = apr_pcalloc(p, sizeof(char *))) == NULL) {
738 return NULL;
739 }
740 if (parse_ASN1_Sequence(ocsp_urls, &response, &numofresponses, p) ||
741 numofresponses ==0) {
742 response = NULL;
743 }
744 return response;
745 }
746
747
748 /* stolen from openssl ocsp command */
749 static int add_ocsp_cert(OCSP_REQUEST *req, X509 *cert, X509 *issuer)
750 {
751 OCSP_CERTID *id;
752
753 if (!issuer)
754 return 0;
755 id = OCSP_cert_to_id(NULL, cert, issuer);
756 if (!id)
757 return 0;
758 if (!OCSP_request_add0_id(req, id)) {
759 OCSP_CERTID_free(id);
760 return 0;
761 } else {
762 /* id will be freed by OCSP_REQUEST_free() */
763 return 1;
764 }
765 }
766
767
768 /* Creates the APR socket and connect to the hostname. Returns the
769 socket or NULL if there is an error.
770 */
771 static apr_socket_t *make_socket(char *hostname, int port, apr_pool_t *mp)
772 {
773 apr_sockaddr_t *sa_in;
774 apr_status_t status;
775 apr_socket_t *sock = NULL;
776
777
778 status = apr_sockaddr_info_get(&sa_in, hostname, APR_INET, port, 0, mp);
779
780 if (status == APR_SUCCESS)
781 status = apr_socket_create(&sock, sa_in->family, SOCK_STREAM, APR_PROTO_TCP, mp);
782 if (status == APR_SUCCESS)
783 status = apr_socket_connect(sock, sa_in);
784
785 if (status == APR_SUCCESS)
786 return sock;
787 return NULL;
788 }
789
790
791 /* Creates the request in a memory BIO in order to send it to the OCSP server.
792 Most parts of this function are taken from mod_ssl support for OCSP (with some
793 minor modifications
794 */
795 static BIO *serialize_request(OCSP_REQUEST *req, char *host, int port, char *path)
796 {
797 BIO *bio;
798 int len;
799
800 len = i2d_OCSP_REQUEST(req, NULL);
801
802 bio = BIO_new(BIO_s_mem());
803
804 BIO_printf(bio, "POST %s HTTP/1.0\r\n"
805 "Host: %s:%d\r\n"
806 "Content-Type: application/ocsp-request\r\n"
807 "Content-Length: %d\r\n"
808 "\r\n",
809 path, host, port, len);
810
811 if (i2d_OCSP_REQUEST_bio(bio, req) != 1) {
812 BIO_free(bio);
813 return NULL;
814 }
815
816 return bio;
817 }
818
819
820 /* Send the OCSP request to the OCSP server. Taken from mod_ssl OCSP support */
821 static int ocsp_send_req(apr_socket_t *sock, BIO *req)
822 {
823 int len;
824 char buf[TCN_BUFFER_SZ];
825 apr_status_t rv;
826
827 while ((len = BIO_read(req, buf, sizeof buf)) > 0) {
828 char *wbuf = buf;
829 apr_size_t remain = len;
830
831 do {
832 apr_size_t wlen = remain;
833 rv = apr_socket_send(sock, wbuf, &wlen);
834 wbuf += remain;
835 remain -= wlen;
836 } while (rv == APR_SUCCESS && remain > 0);
837
838 if (rv != APR_SUCCESS) {
839 return 0;
840 }
841 }
842
843 return 1;
844 }
845
846
847
848 /* Parses the buffer from the response and extracts the OCSP response.
849 Taken from openssl library */
850 static OCSP_RESPONSE *parse_ocsp_resp(char *buf, int len)
851 {
852 BIO *mem = NULL;
853 char tmpbuf[1024];
854 OCSP_RESPONSE *resp = NULL;
855 char *p, *q, *r;
856 int retcode;
857
858 mem = BIO_new(BIO_s_mem());
859 if(mem == NULL)
860 return NULL;
861
862 BIO_write(mem, buf, len); /* write the buffer to the bio */
863 if (BIO_gets(mem, tmpbuf, 512) <= 0) {
864 #if OPENSSL_VERSION_NUMBER < 0x10100000L
865 OCSPerr(OCSP_F_OCSP_SENDREQ_BIO,OCSP_R_SERVER_RESPONSE_PARSE_ERROR);
866 #endif
867 goto err;
868 }
869 /* Parse the HTTP response. This will look like this:
870 * "HTTP/1.0 200 OK". We need to obtain the numeric code and
871 * (optional) informational message.
872 */
873
874 /* Skip to first white space (passed protocol info) */
875 for (p = tmpbuf; *p && !apr_isspace(*p); p++)
876 continue;
877 if (!*p) {
878 goto err;
879 }
880 /* Skip past white space to start of response code */
881 while (apr_isspace(*p))
882 p++;
883 if (!*p) {
884 goto err;
885 }
886 /* Find end of response code: first whitespace after start of code */
887 for (q = p; *q && !apr_isspace(*q); q++)
888 continue;
889 if (!*q) {
890 goto err;
891 }
892 /* Set end of response code and start of message */
893 *q++ = 0;
894 /* Attempt to parse numeric code */
895 retcode = strtoul(p, &r, 10);
896 if (*r)
897 goto err;
898 /* Skip over any leading white space in message */
899 while (apr_isspace(*q))
900 q++;
901 if (*q) {
902 /* Finally zap any trailing white space in message (include CRLF) */
903 /* We know q has a non white space character so this is OK */
904 for(r = q + strlen(q) - 1; apr_isspace(*r); r--) *r = 0;
905 }
906 if (retcode != 200) {
907 goto err;
908 }
909 /* Find blank line marking beginning of content */
910 while (BIO_gets(mem, tmpbuf, 512) > 0) {
911 for (p = tmpbuf; apr_isspace(*p); p++)
912 continue;
913 if (!*p)
914 break;
915 }
916 if (*p) {
917 goto err;
918 }
919 if (!(resp = d2i_OCSP_RESPONSE_bio(mem, NULL))) {
920 goto err;
921 }
922 err:
923 /* XXX No error logging? */
924 BIO_free(mem);
925 return resp;
926 }
927
928
929 /* Reads the response from the APR socket to a buffer, and parses the buffer to
930 return the OCSP response */
931 #define ADDLEN 512
932 static OCSP_RESPONSE *ocsp_get_resp(apr_pool_t *mp, apr_socket_t *sock)
933 {
934 int buflen;
935 apr_size_t totalread = 0;
936 apr_size_t readlen;
937 char *buf, tmpbuf[ADDLEN];
938 apr_status_t rv = APR_SUCCESS;
939 apr_pool_t *p;
940 OCSP_RESPONSE *resp;
941
942 apr_pool_create(&p, mp);
943 buflen = ADDLEN;
944 buf = apr_palloc(p, buflen);
945 if (buf == NULL) {
946 apr_pool_destroy(p);
947 return NULL;
948 }
949
950 while (rv == APR_SUCCESS ) {
951 readlen = sizeof(tmpbuf);
952 rv = apr_socket_recv(sock, tmpbuf, &readlen);
953 if (rv == APR_SUCCESS) { /* if we have read something .. we can put it in the buffer*/
954 if ((totalread + readlen) >= buflen) {
955 buf = apr_xrealloc(buf, buflen, buflen + ADDLEN, p);
956 if (buf == NULL) {
957 apr_pool_destroy(p);
958 return NULL;
959 }
960 buflen += ADDLEN; /* if needed we enlarge the buffer */
961 }
962 memcpy(buf + totalread, tmpbuf, readlen); /* the copy to the buffer */
963 totalread += readlen; /* update the total bytes read */
964 }
965 else {
966 if (rv == APR_EOF && readlen == 0)
967 ; /* EOF, normal situation */
968 else if (readlen == 0) {
969 /* Not success, and readlen == 0 .. some error */
970 apr_pool_destroy(p);
971 return NULL;
972 }
973 }
974 }
975
976 resp = parse_ocsp_resp(buf, buflen);
977 apr_pool_destroy(p);
978 return resp;
979 }
980
981 /* Creates and OCSP request and returns the OCSP_RESPONSE */
982 static OCSP_RESPONSE *get_ocsp_response(apr_pool_t *p, X509 *cert, X509 *issuer, char *url)
983 {
984 OCSP_RESPONSE *ocsp_resp = NULL;
985 OCSP_REQUEST *ocsp_req = NULL;
986 BIO *bio_req;
987 char *hostname, *path, *c_port;
988 int port, use_ssl;
989 int ok = 0;
990 apr_socket_t *apr_sock = NULL;
991 apr_pool_t *mp;
992
993 if (OCSP_parse_url(url,&hostname, &c_port, &path, &use_ssl) == 0 )
994 goto end;
995
996 if (sscanf(c_port, "%d", &port) != 1)
997 goto end;
998
999 /* Create the OCSP request */
1000 ocsp_req = OCSP_REQUEST_new();
1001 if (ocsp_req == NULL)
1002 goto end;
1003
1004 if (add_ocsp_cert(ocsp_req,cert,issuer) == 0 )
1005 goto free_req;
1006
1007 /* create the BIO with the request to send */
1008 bio_req = serialize_request(ocsp_req, hostname, port, path);
1009 if (bio_req == NULL) {
1010 goto free_req;
1011 }
1012
1013 apr_pool_create(&mp, p);
1014 apr_sock = make_socket(hostname, port, mp);
1015 if (apr_sock == NULL) {
1016 goto free_bio;
1017 }
1018
1019 ok = ocsp_send_req(apr_sock, bio_req);
1020 if (ok) {
1021 ocsp_resp = ocsp_get_resp(mp, apr_sock);
1022 }
1023 apr_socket_close(apr_sock);
1024
1025 free_bio:
1026 BIO_free(bio_req);
1027 apr_pool_destroy(mp);
1028
1029 free_req:
1030 OCSP_REQUEST_free(ocsp_req);
1031
1032 end:
1033 OPENSSL_free(hostname);
1034 OPENSSL_free(c_port);
1035 OPENSSL_free(path);
1036
1037 return ocsp_resp;
1038 }
1039
1040 /* Process the OCSP_RESPONSE and returns the corresponding
1041 answert according to the status.
1042 */
1043 static int process_ocsp_response(OCSP_RESPONSE *ocsp_resp, X509 *cert, X509 *issuer)
1044 {
1045 int r, o = V_OCSP_CERTSTATUS_UNKNOWN, i;
1046 OCSP_BASICRESP *bs;
1047 OCSP_SINGLERESP *ss;
1048 OCSP_CERTID *certid;
1049
1050 r = OCSP_response_status(ocsp_resp);
1051
1052 if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
1053 return OCSP_STATUS_UNKNOWN;
1054 }
1055 bs = OCSP_response_get1_basic(ocsp_resp);
1056
1057 certid = OCSP_cert_to_id(NULL, cert, issuer);
1058 if (certid == NULL) {
1059 return OCSP_STATUS_UNKNOWN;
1060 }
1061 ss = OCSP_resp_get0(bs, OCSP_resp_find(bs, certid, -1)); /* find by serial number and get the matching response */
1062
1063
1064 i = OCSP_single_get0_status(ss, NULL, NULL, NULL, NULL);
1065 if (i == V_OCSP_CERTSTATUS_GOOD)
1066 o = OCSP_STATUS_OK;
1067 else if (i == V_OCSP_CERTSTATUS_REVOKED)
1068 o = OCSP_STATUS_REVOKED;
1069 else if (i == V_OCSP_CERTSTATUS_UNKNOWN)
1070 o = OCSP_STATUS_UNKNOWN;
1071
1072 /* we clean up */
1073 OCSP_CERTID_free(certid);
1074 OCSP_BASICRESP_free(bs);
1075 return o;
1076 }
1077
1078 static int ssl_ocsp_request(X509 *cert, X509 *issuer, X509_STORE_CTX *ctx)
1079 {
1080 char **ocsp_urls = NULL;
1081 int nid;
1082 X509_EXTENSION *ext;
1083 ASN1_OCTET_STRING *os;
1084 apr_pool_t *p;
1085
1086 apr_pool_create(&p, NULL);
1087
1088 /* Get the proper extension */
1089 nid = X509_get_ext_by_NID(cert,NID_info_access,-1);
1090 if (nid >= 0 ) {
1091 ext = X509_get_ext(cert,nid);
1092 os = X509_EXTENSION_get_data(ext);
1093
1094 ocsp_urls = decode_OCSP_url(os, p);
1095 }
1096
1097 /* if we find the extensions and we can parse it check
1098 the ocsp status. Otherwise, return OCSP_STATUS_UNKNOWN */
1099 if (ocsp_urls != NULL) {
1100 OCSP_RESPONSE *resp;
1101 int rv = OCSP_STATUS_UNKNOWN;
1102 /* for the time being just check for the fist response .. a better
1103 approach is to iterate for all the possible ocsp urls */
1104 resp = get_ocsp_response(p, cert, issuer, ocsp_urls[0]);
1105 if (resp != NULL) {
1106 rv = process_ocsp_response(resp, cert, issuer);
1107 } else {
1108 /* correct error code for application errors? */
1109 X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
1110 }
1111
1112 if (resp != NULL) {
1113 OCSP_RESPONSE_free(resp);
1114 apr_pool_destroy(p);
1115 return rv;
1116 }
1117 }
1118 apr_pool_destroy(p);
1119 return OCSP_STATUS_UNKNOWN;
1120 }
1121
1122 #endif /* HAVE_OCSP_STAPLING */
1123 #endif /* HAVE_OPENSSL */
1124