]> granicus.if.org Git - apache/blob - modules/ssl/ssl_util_ssl.c
Further clarify the naming of the entity that originates the request by
[apache] / modules / ssl / ssl_util_ssl.c
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 /*                      _             _
18  *  _ __ ___   ___   __| |    ___ ___| |  mod_ssl
19  * | '_ ` _ \ / _ \ / _` |   / __/ __| |  Apache Interface to OpenSSL
20  * | | | | | | (_) | (_| |   \__ \__ \ |
21  * |_| |_| |_|\___/ \__,_|___|___/___/_|
22  *                      |_____|
23  *  ssl_util_ssl.c
24  *  Additional Utility Functions for OpenSSL
25  */
26
27 #include "ssl_private.h"
28
29 /*  _________________________________________________________________
30 **
31 **  Additional High-Level Functions for OpenSSL
32 **  _________________________________________________________________
33 */
34
35 /* we initialize this index at startup time
36  * and never write to it at request time,
37  * so this static is thread safe.
38  * also note that OpenSSL increments at static variable when
39  * SSL_get_ex_new_index() is called, so we _must_ do this at startup.
40  */
41 static int SSL_app_data2_idx = -1;
42
43 void SSL_init_app_data2_idx(void)
44 {
45     int i;
46
47     if (SSL_app_data2_idx > -1) {
48         return;
49     }
50
51     /* we _do_ need to call this twice */
52     for (i=0; i<=1; i++) {
53         SSL_app_data2_idx =
54             SSL_get_ex_new_index(0,
55                                  "Second Application Data for SSL",
56                                  NULL, NULL, NULL);
57     }
58 }
59
60 void *SSL_get_app_data2(SSL *ssl)
61 {
62     return (void *)SSL_get_ex_data(ssl, SSL_app_data2_idx);
63 }
64
65 void SSL_set_app_data2(SSL *ssl, void *arg)
66 {
67     SSL_set_ex_data(ssl, SSL_app_data2_idx, (char *)arg);
68     return;
69 }
70
71 /*  _________________________________________________________________
72 **
73 **  High-Level Certificate / Private Key Loading
74 **  _________________________________________________________________
75 */
76
77 X509 *SSL_read_X509(char* filename, X509 **x509, pem_password_cb *cb)
78 {
79     X509 *rc;
80     BIO *bioS;
81     BIO *bioF;
82
83     /* 1. try PEM (= DER+Base64+headers) */
84     if ((bioS=BIO_new_file(filename, "r")) == NULL)
85         return NULL;
86     rc = PEM_read_bio_X509 (bioS, x509, cb, NULL);
87     BIO_free(bioS);
88
89     if (rc == NULL) {
90         /* 2. try DER+Base64 */
91         if ((bioS=BIO_new_file(filename, "r")) == NULL)
92             return NULL;
93
94         if ((bioF = BIO_new(BIO_f_base64())) == NULL) {
95             BIO_free(bioS);
96             return NULL;
97         }
98         bioS = BIO_push(bioF, bioS);
99         rc = d2i_X509_bio(bioS, NULL);
100         BIO_free_all(bioS);
101
102         if (rc == NULL) {
103             /* 3. try plain DER */
104             if ((bioS=BIO_new_file(filename, "r")) == NULL)
105                 return NULL;
106             rc = d2i_X509_bio(bioS, NULL);
107             BIO_free(bioS);
108         }
109     }
110     if (rc != NULL && x509 != NULL) {
111         if (*x509 != NULL)
112             X509_free(*x509);
113         *x509 = rc;
114     }
115     return rc;
116 }
117
118 EVP_PKEY *SSL_read_PrivateKey(char* filename, EVP_PKEY **key, pem_password_cb *cb, void *s)
119 {
120     EVP_PKEY *rc;
121     BIO *bioS;
122     BIO *bioF;
123
124     /* 1. try PEM (= DER+Base64+headers) */
125     if ((bioS=BIO_new_file(filename, "r")) == NULL)
126         return NULL;
127     rc = PEM_read_bio_PrivateKey(bioS, key, cb, s);
128     BIO_free(bioS);
129
130     if (rc == NULL) {
131         /* 2. try DER+Base64 */
132         if ((bioS = BIO_new_file(filename, "r")) == NULL)
133             return NULL;
134
135         if ((bioF = BIO_new(BIO_f_base64())) == NULL) {
136             BIO_free(bioS);
137             return NULL;
138         }
139         bioS = BIO_push(bioF, bioS);
140         rc = d2i_PrivateKey_bio(bioS, NULL);
141         BIO_free_all(bioS);
142
143         if (rc == NULL) {
144             /* 3. try plain DER */
145             if ((bioS = BIO_new_file(filename, "r")) == NULL)
146                 return NULL;
147             rc = d2i_PrivateKey_bio(bioS, NULL);
148             BIO_free(bioS);
149         }
150     }
151     if (rc != NULL && key != NULL) {
152         if (*key != NULL)
153             EVP_PKEY_free(*key);
154         *key = rc;
155     }
156     return rc;
157 }
158
159 /*  _________________________________________________________________
160 **
161 **  Smart shutdown
162 **  _________________________________________________________________
163 */
164
165 int SSL_smart_shutdown(SSL *ssl)
166 {
167     int i;
168     int rc;
169
170     /*
171      * Repeat the calls, because SSL_shutdown internally dispatches through a
172      * little state machine. Usually only one or two interation should be
173      * needed, so we restrict the total number of restrictions in order to
174      * avoid process hangs in case the client played bad with the socket
175      * connection and OpenSSL cannot recognize it.
176      */
177     rc = 0;
178     for (i = 0; i < 4 /* max 2x pending + 2x data = 4 */; i++) {
179         if ((rc = SSL_shutdown(ssl)))
180             break;
181     }
182     return rc;
183 }
184
185 /*  _________________________________________________________________
186 **
187 **  Cipher Suite Spec String Creation
188 **  _________________________________________________________________
189 */
190
191 char *SSL_make_ciphersuite(apr_pool_t *p, SSL *ssl)
192 {
193     STACK_OF(SSL_CIPHER) *sk;
194     SSL_CIPHER *c;
195     int i;
196     int l;
197     char *cpCipherSuite;
198     char *cp;
199
200     if (ssl == NULL)
201         return "";
202     if ((sk = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl)) == NULL)
203         return "";
204     l = 0;
205     for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
206         c = sk_SSL_CIPHER_value(sk, i);
207         l += strlen(SSL_CIPHER_get_name(c))+2+1;
208     }
209     if (l == 0)
210         return "";
211     cpCipherSuite = (char *)apr_palloc(p, l+1);
212     cp = cpCipherSuite;
213     for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
214         c = sk_SSL_CIPHER_value(sk, i);
215         l = strlen(SSL_CIPHER_get_name(c));
216         memcpy(cp, SSL_CIPHER_get_name(c), l);
217         cp += l;
218         *cp++ = '/';
219         *cp++ = (c->valid == 1 ? '1' : '0');
220         *cp++ = ':';
221     }
222     *(cp-1) = NUL;
223     return cpCipherSuite;
224 }
225
226 /*  _________________________________________________________________
227 **
228 **  Certificate Checks
229 **  _________________________________________________________________
230 */
231
232 /* check whether cert contains extended key usage with a SGC tag */
233 BOOL SSL_X509_isSGC(X509 *cert)
234 {
235     int ext_nid;
236     EXTENDED_KEY_USAGE *sk;
237     BOOL is_sgc;
238     int i;
239
240     is_sgc = FALSE;
241     sk = X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL);
242     if (sk) {
243         for (i = 0; i < sk_ASN1_OBJECT_num(sk); i++) {
244             ext_nid = OBJ_obj2nid(sk_ASN1_OBJECT_value(sk, i));
245             if (ext_nid == NID_ms_sgc || ext_nid == NID_ns_sgc) {
246                 is_sgc = TRUE;
247                 break;
248             }
249         }
250     EXTENDED_KEY_USAGE_free(sk);
251     }
252     return is_sgc;
253 }
254
255 /* retrieve basic constraints ingredients */
256 BOOL SSL_X509_getBC(X509 *cert, int *ca, int *pathlen)
257 {
258     BASIC_CONSTRAINTS *bc;
259     BIGNUM *bn = NULL;
260     char *cp;
261
262     bc = X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL);
263     if (bc == NULL)
264         return FALSE;
265     *ca = bc->ca;
266     *pathlen = -1 /* unlimited */;
267     if (bc->pathlen != NULL) {
268         if ((bn = ASN1_INTEGER_to_BN(bc->pathlen, NULL)) == NULL)
269             return FALSE;
270         if ((cp = BN_bn2dec(bn)) == NULL)
271             return FALSE;
272         *pathlen = atoi(cp);
273         free(cp);
274         BN_free(bn);
275     }
276     BASIC_CONSTRAINTS_free(bc);
277     return TRUE;
278 }
279
280 /* convert a NAME_ENTRY to UTF8 string */
281 char *SSL_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne)
282 {
283     char *result = NULL;
284     BIO* bio;
285     int len;
286
287     if ((bio = BIO_new(BIO_s_mem())) == NULL)
288         return NULL;
289     ASN1_STRING_print_ex(bio, X509_NAME_ENTRY_get_data(xsne),
290                          ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_UTF8_CONVERT);
291     len = BIO_pending(bio);
292     result = apr_palloc(p, len+1);
293     len = BIO_read(bio, result, len);
294     result[len] = NUL;
295     BIO_free(bio);
296     ap_xlate_proto_from_ascii(result, len);
297     return result;
298 }
299
300 /*
301  * convert an X509_NAME to an RFC 2253 formatted string, optionally truncated
302  * to maxlen characters (specify a maxlen of 0 for no length limit)
303  */
304 char *SSL_X509_NAME_to_string(apr_pool_t *p, X509_NAME *dn, unsigned int maxlen)
305 {
306     char *result = NULL;
307     BIO *bio;
308     int len;
309
310     if ((bio = BIO_new(BIO_s_mem())) == NULL)
311         return NULL;
312     X509_NAME_print_ex(bio, dn, 0, XN_FLAG_RFC2253);
313     len = BIO_pending(bio);
314     if (len > 0) {
315         result = apr_palloc(p, maxlen ? maxlen+1 : len+1);
316         if (maxlen && maxlen < len) {
317             len = BIO_read(bio, result, maxlen);
318             if (maxlen > 2) {
319                 /* insert trailing ellipsis if there's enough space */
320                 apr_snprintf(result + maxlen - 3, 4, "...");
321             }
322         } else {
323             len = BIO_read(bio, result, len);
324         }
325         result[len] = NUL;
326     }
327     BIO_free(bio);
328
329     return result;
330 }
331
332 /* return an array of (RFC 6125 coined) DNS-IDs and CN-IDs in a certificate */
333 BOOL SSL_X509_getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids)
334 {
335     STACK_OF(GENERAL_NAME) *names;
336     BIO *bio;
337     X509_NAME *subj;
338     char **cpp;
339     int i, n;
340
341     if (!x509 || !(*ids = apr_array_make(p, 0, sizeof(char *)))) {
342         *ids = NULL;
343         return FALSE;
344     }
345
346     /* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */
347     if ((names = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL)) &&
348         (bio = BIO_new(BIO_s_mem()))) {
349         GENERAL_NAME *name;
350
351         for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
352             name = sk_GENERAL_NAME_value(names, i);
353             if (name->type == GEN_DNS) {
354                 ASN1_STRING_print_ex(bio, name->d.ia5, ASN1_STRFLGS_ESC_CTRL|
355                                      ASN1_STRFLGS_UTF8_CONVERT);
356                 n = BIO_pending(bio);
357                 if (n > 0) {
358                     cpp = (char **)apr_array_push(*ids);
359                     *cpp = apr_palloc(p, n+1);
360                     n = BIO_read(bio, *cpp, n);
361                     (*cpp)[n] = NUL;
362                 }
363             }
364         }
365         BIO_free(bio);
366     }
367
368     if (names)
369         sk_GENERAL_NAME_free(names);
370
371     /* Second, the CN-IDs (commonName attributes in the subject DN) */
372     subj = X509_get_subject_name(x509);
373     i = -1;
374     while ((i = X509_NAME_get_index_by_NID(subj, NID_commonName, i)) != -1) {
375         cpp = (char **)apr_array_push(*ids);
376         *cpp = SSL_X509_NAME_ENTRY_to_string(p, X509_NAME_get_entry(subj, i));
377     }
378
379     return apr_is_empty_array(*ids) ? FALSE : TRUE;
380 }
381
382 /*  _________________________________________________________________
383 **
384 **  Low-Level CA Certificate Loading
385 **  _________________________________________________________________
386 */
387
388 BOOL SSL_X509_INFO_load_file(apr_pool_t *ptemp,
389                              STACK_OF(X509_INFO) *sk,
390                              const char *filename)
391 {
392     BIO *in;
393
394     if (!(in = BIO_new(BIO_s_file()))) {
395         return FALSE;
396     }
397
398     if (BIO_read_filename(in, filename) <= 0) {
399         BIO_free(in);
400         return FALSE;
401     }
402
403     ERR_clear_error();
404
405     PEM_X509_INFO_read_bio(in, sk, NULL, NULL);
406
407     BIO_free(in);
408
409     return TRUE;
410 }
411
412 BOOL SSL_X509_INFO_load_path(apr_pool_t *ptemp,
413                              STACK_OF(X509_INFO) *sk,
414                              const char *pathname)
415 {
416     /* XXX: this dir read code is exactly the same as that in
417      * ssl_engine_init.c, only the call to handle the fullname is different,
418      * should fold the duplication.
419      */
420     apr_dir_t *dir;
421     apr_finfo_t dirent;
422     apr_int32_t finfo_flags = APR_FINFO_TYPE|APR_FINFO_NAME;
423     const char *fullname;
424     BOOL ok = FALSE;
425
426     if (apr_dir_open(&dir, pathname, ptemp) != APR_SUCCESS) {
427         return FALSE;
428     }
429
430     while ((apr_dir_read(&dirent, finfo_flags, dir)) == APR_SUCCESS) {
431         if (dirent.filetype == APR_DIR) {
432             continue; /* don't try to load directories */
433         }
434
435         fullname = apr_pstrcat(ptemp,
436                                pathname, "/", dirent.name,
437                                NULL);
438
439         if (SSL_X509_INFO_load_file(ptemp, sk, fullname)) {
440             ok = TRUE;
441         }
442     }
443
444     apr_dir_close(dir);
445
446     return ok;
447 }
448
449 /*  _________________________________________________________________
450 **
451 **  Extra Server Certificate Chain Support
452 **  _________________________________________________________________
453 */
454
455 /*
456  * Read a file that optionally contains the server certificate in PEM
457  * format, possibly followed by a sequence of CA certificates that
458  * should be sent to the peer in the SSL Certificate message.
459  */
460 int SSL_CTX_use_certificate_chain(
461     SSL_CTX *ctx, char *file, int skipfirst, pem_password_cb *cb)
462 {
463     BIO *bio;
464     X509 *x509;
465     unsigned long err;
466     int n;
467     STACK_OF(X509) *extra_certs;
468
469     if ((bio = BIO_new(BIO_s_file_internal())) == NULL)
470         return -1;
471     if (BIO_read_filename(bio, file) <= 0) {
472         BIO_free(bio);
473         return -1;
474     }
475     /* optionally skip a leading server certificate */
476     if (skipfirst) {
477         if ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) == NULL) {
478             BIO_free(bio);
479             return -1;
480         }
481         X509_free(x509);
482     }
483     /* free a perhaps already configured extra chain */
484     extra_certs = ctx->extra_certs;
485     if (extra_certs != NULL) {
486         sk_X509_pop_free((STACK_OF(X509) *)extra_certs, X509_free);
487         ctx->extra_certs = NULL;
488     }
489     /* create new extra chain by loading the certs */
490     n = 0;
491     while ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) != NULL) {
492         if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
493             X509_free(x509);
494             BIO_free(bio);
495             return -1;
496         }
497         n++;
498     }
499     /* Make sure that only the error is just an EOF */
500     if ((err = ERR_peek_error()) > 0) {
501         if (!(   ERR_GET_LIB(err) == ERR_LIB_PEM
502               && ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
503             BIO_free(bio);
504             return -1;
505         }
506         while (ERR_get_error() > 0) ;
507     }
508     BIO_free(bio);
509     return n;
510 }
511
512 /*  _________________________________________________________________
513 **
514 **  Session Stuff
515 **  _________________________________________________________________
516 */
517
518 char *SSL_SESSION_id2sz(unsigned char *id, int idlen,
519                         char *str, int strsize)
520 {
521     char *cp;
522     int n;
523
524     cp = str;
525     for (n = 0; n < idlen && n < SSL_MAX_SSL_SESSION_ID_LENGTH; n++) {
526         apr_snprintf(cp, strsize - (cp-str), "%02X", id[n]);
527         cp += 2;
528     }
529     *cp = NUL;
530     return str;
531 }