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