1 /*
2  *  OpenVPN -- An application to securely tunnel IP networks
3  *             over a single TCP/UDP port, with support for SSL/TLS-based
4  *             session authentication and key exchange,
5  *             packet encryption, packet authentication, and
6  *             packet compression.
7  *
8  *  Copyright (C) 2002-2018 OpenVPN Inc <sales@openvpn.net>
9  *  Copyright (C) 2010-2018 Fox Crypto B.V. <openvpn@fox-it.com>
10  *
11  *  This program is free software; you can redistribute it and/or modify
12  *  it under the terms of the GNU General Public License version 2
13  *  as published by the Free Software Foundation.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License along
21  *  with this program; if not, write to the Free Software Foundation, Inc.,
22  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
25 /**
26  * @file Control Channel Verification Module OpenSSL implementation
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #elif defined(_MSC_VER)
32 #include "config-msvc.h"
33 #endif
34 
35 #include "syshead.h"
36 
37 #if defined(ENABLE_CRYPTO_OPENSSL)
38 
39 #include "ssl_verify_openssl.h"
40 
41 #include "error.h"
42 #include "ssl_openssl.h"
43 #include "ssl_verify.h"
44 #include "ssl_verify_backend.h"
45 #include "openssl_compat.h"
46 
47 #include <openssl/bn.h>
48 #include <openssl/err.h>
49 #include <openssl/x509v3.h>
50 
51 int
verify_callback(int preverify_ok,X509_STORE_CTX * ctx)52 verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
53 {
54     int ret = 0;
55     struct tls_session *session;
56     SSL *ssl;
57     struct gc_arena gc = gc_new();
58 
59     /* get the tls_session pointer */
60     ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
61     ASSERT(ssl);
62     session = (struct tls_session *) SSL_get_ex_data(ssl, mydata_index);
63     ASSERT(session);
64 
65     X509 *current_cert = X509_STORE_CTX_get_current_cert(ctx);
66     struct buffer cert_hash = x509_get_sha256_fingerprint(current_cert, &gc);
67     cert_hash_remember(session, X509_STORE_CTX_get_error_depth(ctx), &cert_hash);
68 
69     /* did peer present cert which was signed by our root cert? */
70     if (!preverify_ok && !session->opt->verify_hash_no_ca)
71     {
72         /* get the X509 name */
73         char *subject = x509_get_subject(current_cert, &gc);
74         char *serial = backend_x509_get_serial(current_cert, &gc);
75 
76         if (!subject)
77         {
78             subject = "(Failed to retrieve certificate subject)";
79         }
80 
81         /* Log and ignore missing CRL errors */
82         if (X509_STORE_CTX_get_error(ctx) == X509_V_ERR_UNABLE_TO_GET_CRL)
83         {
84             msg(D_TLS_DEBUG_LOW, "VERIFY WARNING: depth=%d, %s: %s",
85                 X509_STORE_CTX_get_error_depth(ctx),
86                 X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)),
87                 subject);
88             ret = 1;
89             goto cleanup;
90         }
91 
92         /* Remote site specified a certificate, but it's not correct */
93         msg(D_TLS_ERRORS, "VERIFY ERROR: depth=%d, error=%s: %s, serial=%s",
94             X509_STORE_CTX_get_error_depth(ctx),
95             X509_verify_cert_error_string(X509_STORE_CTX_get_error(ctx)),
96             subject, serial ? serial : "<not available>");
97 
98         ERR_clear_error();
99 
100         session->verified = false;
101         goto cleanup;
102     }
103 
104     if (SUCCESS != verify_cert(session, current_cert, X509_STORE_CTX_get_error_depth(ctx)))
105     {
106         goto cleanup;
107     }
108 
109     ret = 1;
110 
111 cleanup:
112     gc_free(&gc);
113 
114     return ret;
115 }
116 
117 #ifdef ENABLE_X509ALTUSERNAME
118 bool
x509_username_field_ext_supported(const char * fieldname)119 x509_username_field_ext_supported(const char *fieldname)
120 {
121     int nid = OBJ_txt2nid(fieldname);
122     return nid == NID_subject_alt_name || nid == NID_issuer_alt_name;
123 }
124 
125 static
126 bool
extract_x509_extension(X509 * cert,char * fieldname,char * out,int size)127 extract_x509_extension(X509 *cert, char *fieldname, char *out, int size)
128 {
129     bool retval = false;
130     char *buf = 0;
131 
132     if (!x509_username_field_ext_supported(fieldname))
133     {
134         msg(D_TLS_ERRORS,
135             "ERROR: --x509-username-field 'ext:%s' not supported", fieldname);
136         return false;
137     }
138 
139     int nid = OBJ_txt2nid(fieldname);
140     GENERAL_NAMES *extensions = X509_get_ext_d2i(cert, nid, NULL, NULL);
141     if (extensions)
142     {
143         int numalts;
144         int i;
145         /* get amount of alternatives,
146          * RFC2459 claims there MUST be at least
147          * one, but we don't depend on it...
148          */
149 
150         numalts = sk_GENERAL_NAME_num(extensions);
151 
152         /* loop through all alternatives */
153         for (i = 0; i<numalts; i++)
154         {
155             /* get a handle to alternative name number i */
156             const GENERAL_NAME *name = sk_GENERAL_NAME_value(extensions, i );
157 
158             switch (name->type)
159             {
160                 case GEN_EMAIL:
161                     if (ASN1_STRING_to_UTF8((unsigned char **)&buf, name->d.ia5) < 0)
162                     {
163                         continue;
164                     }
165                     if (strlen(buf) != name->d.ia5->length)
166                     {
167                         msg(D_TLS_ERRORS, "ASN1 ERROR: string contained terminating zero");
168                         OPENSSL_free(buf);
169                     }
170                     else
171                     {
172                         strncpynt(out, buf, size);
173                         OPENSSL_free(buf);
174                         retval = true;
175                     }
176                     break;
177 
178                 default:
179                     msg(D_TLS_DEBUG, "%s: ignoring general name field type %i",
180                         __func__, name->type);
181                     break;
182             }
183         }
184         GENERAL_NAMES_free(extensions);
185     }
186     return retval;
187 }
188 #endif /* ENABLE_X509ALTUSERNAME */
189 
190 /*
191  * Extract a field from an X509 subject name.
192  *
193  * Example:
194  *
195  * /C=US/ST=CO/L=Denver/O=ORG/CN=First-CN/CN=Test-CA/Email=jim@yonan.net
196  *
197  * The common name is 'Test-CA'
198  *
199  * Return true on success, false on error (insufficient buffer size in 'out'
200  * to contain result is grounds for error).
201  */
202 static result_t
extract_x509_field_ssl(X509_NAME * x509,const char * field_name,char * out,int size)203 extract_x509_field_ssl(X509_NAME *x509, const char *field_name, char *out,
204                        int size)
205 {
206     int lastpos = -1;
207     int tmp = -1;
208     X509_NAME_ENTRY *x509ne = NULL;
209     ASN1_STRING *asn1 = NULL;
210     unsigned char *buf = NULL;
211     ASN1_OBJECT *field_name_obj = OBJ_txt2obj(field_name, 0);
212 
213     if (field_name_obj == NULL)
214     {
215         msg(D_TLS_ERRORS, "Invalid X509 attribute name '%s'", field_name);
216         return FAILURE;
217     }
218 
219     ASSERT(size > 0);
220     *out = '\0';
221     do
222     {
223         lastpos = tmp;
224         tmp = X509_NAME_get_index_by_OBJ(x509, field_name_obj, lastpos);
225     } while (tmp > -1);
226 
227     ASN1_OBJECT_free(field_name_obj);
228 
229     /* Nothing found */
230     if (lastpos == -1)
231     {
232         return FAILURE;
233     }
234 
235     x509ne = X509_NAME_get_entry(x509, lastpos);
236     if (!x509ne)
237     {
238         return FAILURE;
239     }
240 
241     asn1 = X509_NAME_ENTRY_get_data(x509ne);
242     if (!asn1)
243     {
244         return FAILURE;
245     }
246     if (ASN1_STRING_to_UTF8(&buf, asn1) < 0)
247     {
248         return FAILURE;
249     }
250 
251     strncpynt(out, (char *)buf, size);
252 
253     {
254         const result_t ret = (strlen((char *)buf) < size) ? SUCCESS : FAILURE;
255         OPENSSL_free(buf);
256         return ret;
257     }
258 }
259 
260 result_t
backend_x509_get_username(char * common_name,int cn_len,char * x509_username_field,X509 * peer_cert)261 backend_x509_get_username(char *common_name, int cn_len,
262                           char *x509_username_field, X509 *peer_cert)
263 {
264 #ifdef ENABLE_X509ALTUSERNAME
265     if (strncmp("ext:",x509_username_field,4) == 0)
266     {
267         if (!extract_x509_extension(peer_cert, x509_username_field+4, common_name, cn_len))
268         {
269             return FAILURE;
270         }
271     }
272     else if (strcmp(LN_serialNumber, x509_username_field) == 0)
273     {
274         ASN1_INTEGER *asn1_i = X509_get_serialNumber(peer_cert);
275         struct gc_arena gc = gc_new();
276         char *serial = format_hex_ex(asn1_i->data, asn1_i->length,
277                                      0, 1 | FHE_CAPS, NULL, &gc);
278 
279         if (!serial || cn_len <= strlen(serial)+2)
280         {
281             gc_free(&gc);
282             return FAILURE;
283         }
284         openvpn_snprintf(common_name, cn_len, "0x%s", serial);
285         gc_free(&gc);
286     }
287     else
288 #endif
289     if (FAILURE == extract_x509_field_ssl(X509_get_subject_name(peer_cert),
290                                           x509_username_field, common_name, cn_len))
291     {
292         return FAILURE;
293     }
294 
295     return SUCCESS;
296 }
297 
298 char *
backend_x509_get_serial(openvpn_x509_cert_t * cert,struct gc_arena * gc)299 backend_x509_get_serial(openvpn_x509_cert_t *cert, struct gc_arena *gc)
300 {
301     ASN1_INTEGER *asn1_i;
302     BIGNUM *bignum;
303     char *openssl_serial, *serial;
304 
305     asn1_i = X509_get_serialNumber(cert);
306     bignum = ASN1_INTEGER_to_BN(asn1_i, NULL);
307     openssl_serial = BN_bn2dec(bignum);
308 
309     serial = string_alloc(openssl_serial, gc);
310 
311     BN_free(bignum);
312     OPENSSL_free(openssl_serial);
313 
314     return serial;
315 }
316 
317 char *
backend_x509_get_serial_hex(openvpn_x509_cert_t * cert,struct gc_arena * gc)318 backend_x509_get_serial_hex(openvpn_x509_cert_t *cert, struct gc_arena *gc)
319 {
320     const ASN1_INTEGER *asn1_i = X509_get_serialNumber(cert);
321 
322     return format_hex_ex(asn1_i->data, asn1_i->length, 0, 1, ":", gc);
323 }
324 
325 struct buffer
x509_get_sha1_fingerprint(X509 * cert,struct gc_arena * gc)326 x509_get_sha1_fingerprint(X509 *cert, struct gc_arena *gc)
327 {
328     const EVP_MD *sha1 = EVP_sha1();
329     struct buffer hash = alloc_buf_gc(EVP_MD_size(sha1), gc);
330     X509_digest(cert, EVP_sha1(), BPTR(&hash), NULL);
331     ASSERT(buf_inc_len(&hash, EVP_MD_size(sha1)));
332     return hash;
333 }
334 
335 struct buffer
x509_get_sha256_fingerprint(X509 * cert,struct gc_arena * gc)336 x509_get_sha256_fingerprint(X509 *cert, struct gc_arena *gc)
337 {
338     const EVP_MD *sha256 = EVP_sha256();
339     struct buffer hash = alloc_buf_gc(EVP_MD_size(sha256), gc);
340     X509_digest(cert, EVP_sha256(), BPTR(&hash), NULL);
341     ASSERT(buf_inc_len(&hash, EVP_MD_size(sha256)));
342     return hash;
343 }
344 
345 char *
x509_get_subject(X509 * cert,struct gc_arena * gc)346 x509_get_subject(X509 *cert, struct gc_arena *gc)
347 {
348     BIO *subject_bio = NULL;
349     BUF_MEM *subject_mem;
350     char *subject = NULL;
351 
352     subject_bio = BIO_new(BIO_s_mem());
353     if (subject_bio == NULL)
354     {
355         goto err;
356     }
357 
358     X509_NAME_print_ex(subject_bio, X509_get_subject_name(cert),
359                        0, XN_FLAG_SEP_CPLUS_SPC | XN_FLAG_FN_SN
360                        |ASN1_STRFLGS_UTF8_CONVERT | ASN1_STRFLGS_ESC_CTRL);
361 
362     if (BIO_eof(subject_bio))
363     {
364         goto err;
365     }
366 
367     BIO_get_mem_ptr(subject_bio, &subject_mem);
368 
369     subject = gc_malloc(subject_mem->length + 1, false, gc);
370 
371     memcpy(subject, subject_mem->data, subject_mem->length);
372     subject[subject_mem->length] = '\0';
373 
374 err:
375     BIO_free(subject_bio);
376     return subject;
377 }
378 
379 
380 /*
381  * x509-track implementation -- save X509 fields to environment,
382  * using the naming convention:
383  *
384  *  X509_{cert_depth}_{name}={value}
385  *
386  * This function differs from x509_setenv below in the following ways:
387  *
388  * (1) Only explicitly named attributes in xt are saved, per usage
389  *     of "x509-track" program options.
390  * (2) Only the level 0 cert info is saved unless the XT_FULL_CHAIN
391  *     flag is set in xt->flags (corresponds with prepending a '+'
392  *     to the name when specified by "x509-track" program option).
393  * (3) This function supports both X509 subject name fields as
394  *     well as X509 V3 extensions.
395  * (4) This function can return the SHA1 fingerprint of a cert, e.g.
396  *       x509-track "+SHA1"
397  *     will return the SHA1 fingerprint for each certificate in the
398  *     peer chain.
399  */
400 
401 void
x509_track_add(const struct x509_track ** ll_head,const char * name,int msglevel,struct gc_arena * gc)402 x509_track_add(const struct x509_track **ll_head, const char *name, int msglevel, struct gc_arena *gc)
403 {
404     struct x509_track *xt;
405     ALLOC_OBJ_CLEAR_GC(xt, struct x509_track, gc);
406     if (*name == '+')
407     {
408         xt->flags |= XT_FULL_CHAIN;
409         ++name;
410     }
411     xt->name = name;
412     xt->nid = OBJ_txt2nid(name);
413     if (xt->nid != NID_undef)
414     {
415         xt->next = *ll_head;
416         *ll_head = xt;
417     }
418     else
419     {
420         msg(msglevel, "x509_track: no such attribute '%s'", name);
421     }
422 }
423 
424 /* worker method for setenv_x509_track */
425 static void
do_setenv_x509(struct env_set * es,const char * name,char * value,int depth)426 do_setenv_x509(struct env_set *es, const char *name, char *value, int depth)
427 {
428     char *name_expand;
429     size_t name_expand_size;
430 
431     string_mod(value, CC_ANY, CC_CRLF, '?');
432     msg(D_X509_ATTR, "X509 ATTRIBUTE name='%s' value='%s' depth=%d", name, value, depth);
433     name_expand_size = 64 + strlen(name);
434     name_expand = (char *) malloc(name_expand_size);
435     check_malloc_return(name_expand);
436     openvpn_snprintf(name_expand, name_expand_size, "X509_%d_%s", depth, name);
437     setenv_str(es, name_expand, value);
438     free(name_expand);
439 }
440 
441 void
x509_setenv_track(const struct x509_track * xt,struct env_set * es,const int depth,X509 * x509)442 x509_setenv_track(const struct x509_track *xt, struct env_set *es, const int depth, X509 *x509)
443 {
444     struct gc_arena gc = gc_new();
445     X509_NAME *x509_name = X509_get_subject_name(x509);
446     const char nullc = '\0';
447 
448     while (xt)
449     {
450         if (depth == 0 || (xt->flags & XT_FULL_CHAIN))
451         {
452             switch (xt->nid)
453             {
454                 case NID_sha1:
455                 case NID_sha256:
456                 {
457                     struct buffer fp_buf;
458                     char *fp_str = NULL;
459 
460                     if (xt->nid == NID_sha1)
461                     {
462                         fp_buf = x509_get_sha1_fingerprint(x509, &gc);
463                     }
464                     else
465                     {
466                         fp_buf = x509_get_sha256_fingerprint(x509, &gc);
467                     }
468 
469                     fp_str = format_hex_ex(BPTR(&fp_buf), BLEN(&fp_buf), 0,
470                                            1 | FHE_CAPS, ":", &gc);
471                     do_setenv_x509(es, xt->name, fp_str, depth);
472                 }
473                 break;
474 
475                 default:
476                 {
477                     int i = X509_NAME_get_index_by_NID(x509_name, xt->nid, -1);
478                     if (i >= 0)
479                     {
480                         X509_NAME_ENTRY *ent = X509_NAME_get_entry(x509_name, i);
481                         if (ent)
482                         {
483                             ASN1_STRING *val = X509_NAME_ENTRY_get_data(ent);
484                             unsigned char *buf = NULL;
485                             if (ASN1_STRING_to_UTF8(&buf, val) >= 0)
486                             {
487                                 do_setenv_x509(es, xt->name, (char *)buf, depth);
488                                 OPENSSL_free(buf);
489                             }
490                         }
491                     }
492                     else
493                     {
494                         i = X509_get_ext_by_NID(x509, xt->nid, -1);
495                         if (i >= 0)
496                         {
497                             X509_EXTENSION *ext = X509_get_ext(x509, i);
498                             if (ext)
499                             {
500                                 BIO *bio = BIO_new(BIO_s_mem());
501                                 if (bio)
502                                 {
503                                     if (X509V3_EXT_print(bio, ext, 0, 0))
504                                     {
505                                         if (BIO_write(bio, &nullc, 1) == 1)
506                                         {
507                                             char *str;
508                                             BIO_get_mem_data(bio, &str);
509                                             do_setenv_x509(es, xt->name, str, depth);
510                                         }
511                                     }
512                                     BIO_free(bio);
513                                 }
514                             }
515                         }
516                     }
517                 }
518             }
519         }
520         xt = xt->next;
521     }
522     gc_free(&gc);
523 }
524 
525 /*
526  * Save X509 fields to environment, using the naming convention:
527  *
528  *  X509_{cert_depth}_{name}={value}
529  */
530 void
x509_setenv(struct env_set * es,int cert_depth,openvpn_x509_cert_t * peer_cert)531 x509_setenv(struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert)
532 {
533     int i, n;
534     int fn_nid;
535     ASN1_OBJECT *fn;
536     ASN1_STRING *val;
537     X509_NAME_ENTRY *ent;
538     const char *objbuf;
539     unsigned char *buf = NULL;
540     char *name_expand;
541     size_t name_expand_size;
542     X509_NAME *x509 = X509_get_subject_name(peer_cert);
543 
544     n = X509_NAME_entry_count(x509);
545     for (i = 0; i < n; ++i)
546     {
547         ent = X509_NAME_get_entry(x509, i);
548         if (!ent)
549         {
550             continue;
551         }
552         fn = X509_NAME_ENTRY_get_object(ent);
553         if (!fn)
554         {
555             continue;
556         }
557         val = X509_NAME_ENTRY_get_data(ent);
558         if (!val)
559         {
560             continue;
561         }
562         fn_nid = OBJ_obj2nid(fn);
563         if (fn_nid == NID_undef)
564         {
565             continue;
566         }
567         objbuf = OBJ_nid2sn(fn_nid);
568         if (!objbuf)
569         {
570             continue;
571         }
572         if (ASN1_STRING_to_UTF8(&buf, val) < 0)
573         {
574             continue;
575         }
576         name_expand_size = 64 + strlen(objbuf);
577         name_expand = (char *) malloc(name_expand_size);
578         check_malloc_return(name_expand);
579         openvpn_snprintf(name_expand, name_expand_size, "X509_%d_%s", cert_depth,
580                          objbuf);
581         string_mod(name_expand, CC_PRINT, CC_CRLF, '_');
582         string_mod((char *)buf, CC_PRINT, CC_CRLF, '_');
583         setenv_str_incr(es, name_expand, (char *)buf);
584         free(name_expand);
585         OPENSSL_free(buf);
586     }
587 }
588 
589 result_t
x509_verify_ns_cert_type(openvpn_x509_cert_t * peer_cert,const int usage)590 x509_verify_ns_cert_type(openvpn_x509_cert_t *peer_cert, const int usage)
591 {
592     if (usage == NS_CERT_CHECK_NONE)
593     {
594         return SUCCESS;
595     }
596     if (usage == NS_CERT_CHECK_CLIENT)
597     {
598         /*
599          * Unfortunately, X509_check_purpose() does some weird thing that
600          * prevent it to take a const argument
601          */
602         result_t result = X509_check_purpose(peer_cert, X509_PURPOSE_SSL_CLIENT, 0) ?
603                           SUCCESS : FAILURE;
604 
605         /*
606          * old versions of OpenSSL allow us to make the less strict check we used to
607          * do. If this less strict check pass, warn user that this might not be the
608          * case when its distribution will update to OpenSSL 1.1
609          */
610         if (result == FAILURE)
611         {
612             ASN1_BIT_STRING *ns;
613             ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
614             result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_CLIENT)) ? SUCCESS : FAILURE;
615             if (result == SUCCESS)
616             {
617                 msg(M_WARN, "X509: Certificate is a client certificate yet it's purpose "
618                     "cannot be verified (check may fail in the future)");
619             }
620             ASN1_BIT_STRING_free(ns);
621         }
622         return result;
623     }
624     if (usage == NS_CERT_CHECK_SERVER)
625     {
626         /*
627          * Unfortunately, X509_check_purpose() does some weird thing that
628          * prevent it to take a const argument
629          */
630         result_t result = X509_check_purpose(peer_cert, X509_PURPOSE_SSL_SERVER, 0) ?
631                           SUCCESS : FAILURE;
632 
633         /*
634          * old versions of OpenSSL allow us to make the less strict check we used to
635          * do. If this less strict check pass, warn user that this might not be the
636          * case when its distribution will update to OpenSSL 1.1
637          */
638         if (result == FAILURE)
639         {
640             ASN1_BIT_STRING *ns;
641             ns = X509_get_ext_d2i(peer_cert, NID_netscape_cert_type, NULL, NULL);
642             result = (ns && ns->length > 0 && (ns->data[0] & NS_SSL_SERVER)) ? SUCCESS : FAILURE;
643             if (result == SUCCESS)
644             {
645                 msg(M_WARN, "X509: Certificate is a server certificate yet it's purpose "
646                     "cannot be verified (check may fail in the future)");
647             }
648             ASN1_BIT_STRING_free(ns);
649         }
650         return result;
651     }
652 
653     return FAILURE;
654 }
655 
656 result_t
x509_verify_cert_ku(X509 * x509,const unsigned * const expected_ku,int expected_len)657 x509_verify_cert_ku(X509 *x509, const unsigned *const expected_ku,
658                     int expected_len)
659 {
660     ASN1_BIT_STRING *ku = X509_get_ext_d2i(x509, NID_key_usage, NULL, NULL);
661 
662     if (ku == NULL)
663     {
664         msg(D_TLS_ERRORS, "Certificate does not have key usage extension");
665         return FAILURE;
666     }
667 
668     if (expected_ku[0] == OPENVPN_KU_REQUIRED)
669     {
670         /* Extension required, value checked by TLS library */
671         ASN1_BIT_STRING_free(ku);
672         return SUCCESS;
673     }
674 
675     unsigned nku = 0;
676     for (size_t i = 0; i < 8; i++)
677     {
678         if (ASN1_BIT_STRING_get_bit(ku, i))
679         {
680             nku |= 1 << (7 - i);
681         }
682     }
683 
684     /*
685      * Fixup if no LSB bits
686      */
687     if ((nku & 0xff) == 0)
688     {
689         nku >>= 8;
690     }
691 
692     msg(D_HANDSHAKE, "Validating certificate key usage");
693     result_t fFound = FAILURE;
694     for (size_t i = 0; fFound != SUCCESS && i < expected_len; i++)
695     {
696         if (expected_ku[i] != 0 && (nku & expected_ku[i]) == expected_ku[i])
697         {
698             fFound = SUCCESS;
699         }
700     }
701 
702     if (fFound != SUCCESS)
703     {
704         msg(D_TLS_ERRORS,
705             "ERROR: Certificate has key usage %04x, expected one of:", nku);
706         for (size_t i = 0; i < expected_len && expected_ku[i]; i++)
707         {
708             msg(D_TLS_ERRORS, " * %04x", expected_ku[i]);
709         }
710     }
711 
712     ASN1_BIT_STRING_free(ku);
713 
714     return fFound;
715 }
716 
717 result_t
x509_verify_cert_eku(X509 * x509,const char * const expected_oid)718 x509_verify_cert_eku(X509 *x509, const char *const expected_oid)
719 {
720     EXTENDED_KEY_USAGE *eku = NULL;
721     result_t fFound = FAILURE;
722 
723     if ((eku = (EXTENDED_KEY_USAGE *) X509_get_ext_d2i(x509, NID_ext_key_usage,
724                                                        NULL, NULL)) == NULL)
725     {
726         msg(D_HANDSHAKE, "Certificate does not have extended key usage extension");
727     }
728     else
729     {
730         int i;
731 
732         msg(D_HANDSHAKE, "Validating certificate extended key usage");
733         for (i = 0; SUCCESS != fFound && i < sk_ASN1_OBJECT_num(eku); i++)
734         {
735             ASN1_OBJECT *oid = sk_ASN1_OBJECT_value(eku, i);
736             char szOid[1024];
737 
738             if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 0) != -1)
739             {
740                 msg(D_HANDSHAKE, "++ Certificate has EKU (str) %s, expects %s",
741                     szOid, expected_oid);
742                 if (!strcmp(expected_oid, szOid))
743                 {
744                     fFound = SUCCESS;
745                 }
746             }
747             if (SUCCESS != fFound && OBJ_obj2txt(szOid, sizeof(szOid), oid, 1) != -1)
748             {
749                 msg(D_HANDSHAKE, "++ Certificate has EKU (oid) %s, expects %s",
750                     szOid, expected_oid);
751                 if (!strcmp(expected_oid, szOid))
752                 {
753                     fFound = SUCCESS;
754                 }
755             }
756         }
757     }
758 
759     if (eku != NULL)
760     {
761         sk_ASN1_OBJECT_pop_free(eku, ASN1_OBJECT_free);
762     }
763 
764     return fFound;
765 }
766 
767 result_t
x509_write_pem(FILE * peercert_file,X509 * peercert)768 x509_write_pem(FILE *peercert_file, X509 *peercert)
769 {
770     if (PEM_write_X509(peercert_file, peercert) < 0)
771     {
772         msg(M_NONFATAL, "Failed to write peer certificate in PEM format");
773         return FAILURE;
774     }
775     return SUCCESS;
776 }
777 
778 bool
tls_verify_crl_missing(const struct tls_options * opt)779 tls_verify_crl_missing(const struct tls_options *opt)
780 {
781     if (!opt->crl_file || (opt->ssl_flags & SSLF_CRL_VERIFY_DIR))
782     {
783         return false;
784     }
785 
786     X509_STORE *store = SSL_CTX_get_cert_store(opt->ssl_ctx.ctx);
787     if (!store)
788     {
789         crypto_msg(M_FATAL, "Cannot get certificate store");
790     }
791 
792     STACK_OF(X509_OBJECT) *objs = X509_STORE_get0_objects(store);
793     for (int i = 0; i < sk_X509_OBJECT_num(objs); i++)
794     {
795         X509_OBJECT *obj = sk_X509_OBJECT_value(objs, i);
796         ASSERT(obj);
797         if (X509_OBJECT_get_type(obj) == X509_LU_CRL)
798         {
799             return false;
800         }
801     }
802     return true;
803 }
804 
805 #endif /* defined(ENABLE_CRYPTO_OPENSSL) */
806