1/*
2 * Copyright (c) 2007-2016, Cameron Rich
3 *
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright notice,
12 * this list of conditions and the following disclaimer in the documentation
13 * and/or other materials provided with the distribution.
14 * * Neither the name of the axTLS project nor the names of its contributors
15 * may be used to endorse or promote products derived from this software
16 * without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31/**
32 * @file x509.c
33 *
34 * Certificate processing.
35 */
36
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40#include <time.h>
41#include "os_port.h"
42#include "crypto_misc.h"
43
44#ifdef CONFIG_SSL_CERT_VERIFICATION
45static int x509_v3_subject_alt_name(const uint8_t *cert, int offset,
46 X509_CTX *x509_ctx);
47static int x509_v3_basic_constraints(const uint8_t *cert, int offset,
48 X509_CTX *x509_ctx);
49static int x509_v3_key_usage(const uint8_t *cert, int offset,
50 X509_CTX *x509_ctx);
51
52/**
53 * Retrieve the signature from a certificate.
54 */
55static const uint8_t *get_signature(const uint8_t *asn1_sig, int *len)
56{
57 int offset = 0;
58 const uint8_t *ptr = NULL;
59
60 if (asn1_next_obj(asn1_sig, &offset, ASN1_SEQUENCE) < 0 ||
61 asn1_skip_obj(asn1_sig, &offset, ASN1_SEQUENCE))
62 goto end_get_sig;
63
64 if (asn1_sig[offset++] != ASN1_OCTET_STRING)
65 goto end_get_sig;
66 *len = get_asn1_length(asn1_sig, &offset);
67 ptr = &asn1_sig[offset]; /* all ok */
68
69end_get_sig:
70 return ptr;
71}
72
73#endif
74
75/**
76 * Construct a new x509 object.
77 * @return 0 if ok. < 0 if there was a problem.
78 */
79int x509_new(const uint8_t *cert, int *len, X509_CTX **ctx)
80{
81 int begin_tbs, end_tbs;
82 int ret = X509_NOT_OK, offset = 0, cert_size = 0;
83 int version = 0;
84 X509_CTX *x509_ctx;
85#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
86 BI_CTX *bi_ctx;
87#endif
88
89 *ctx = (X509_CTX *)calloc(1, sizeof(X509_CTX));
90 x509_ctx = *ctx;
91
92 /* get the certificate size */
93 asn1_skip_obj(cert, &cert_size, ASN1_SEQUENCE);
94
95 if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
96 goto end_cert;
97
98 begin_tbs = offset; /* start of the tbs */
99 end_tbs = begin_tbs; /* work out the end of the tbs */
100 asn1_skip_obj(cert, &end_tbs, ASN1_SEQUENCE);
101
102 if (asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
103 goto end_cert;
104
105 /* optional version */
106 if (cert[offset] == ASN1_EXPLICIT_TAG &&
107 asn1_version(cert, &offset, &version) == X509_NOT_OK)
108 goto end_cert;
109
110 if (asn1_skip_obj(cert, &offset, ASN1_INTEGER) || /* serial number */
111 asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0)
112 goto end_cert;
113
114 /* make sure the signature is ok */
115 if (asn1_signature_type(cert, &offset, x509_ctx))
116 {
117 ret = X509_VFY_ERROR_UNSUPPORTED_DIGEST;
118 goto end_cert;
119 }
120
121 if (asn1_name(cert, &offset, x509_ctx->ca_cert_dn) ||
122 asn1_validity(cert, &offset, x509_ctx) ||
123 asn1_name(cert, &offset, x509_ctx->cert_dn) ||
124 asn1_public_key(cert, &offset, x509_ctx))
125 {
126 goto end_cert;
127 }
128
129#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
130 bi_ctx = x509_ctx->rsa_ctx->bi_ctx;
131
132 /* use the appropriate signature algorithm */
133 switch (x509_ctx->sig_type)
134 {
135 case SIG_TYPE_MD5:
136 {
137 MD5_CTX md5_ctx;
138 uint8_t md5_dgst[MD5_SIZE];
139 MD5_Init(&md5_ctx);
140 MD5_Update(&md5_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
141 MD5_Final(md5_dgst, &md5_ctx);
142 x509_ctx->digest = bi_import(bi_ctx, md5_dgst, MD5_SIZE);
143 }
144 break;
145
146 case SIG_TYPE_SHA1:
147 {
148 SHA1_CTX sha_ctx;
149 uint8_t sha_dgst[SHA1_SIZE];
150 SHA1_Init(&sha_ctx);
151 SHA1_Update(&sha_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
152 SHA1_Final(sha_dgst, &sha_ctx);
153 x509_ctx->digest = bi_import(bi_ctx, sha_dgst, SHA1_SIZE);
154 }
155 break;
156
157 case SIG_TYPE_SHA256:
158 {
159 SHA256_CTX sha256_ctx;
160 uint8_t sha256_dgst[SHA256_SIZE];
161 SHA256_Init(&sha256_ctx);
162 SHA256_Update(&sha256_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
163 SHA256_Final(sha256_dgst, &sha256_ctx);
164 x509_ctx->digest = bi_import(bi_ctx, sha256_dgst, SHA256_SIZE);
165 }
166 break;
167
168 case SIG_TYPE_SHA384:
169 {
170 SHA384_CTX sha384_ctx;
171 uint8_t sha384_dgst[SHA384_SIZE];
172 SHA384_Init(&sha384_ctx);
173 SHA384_Update(&sha384_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
174 SHA384_Final(sha384_dgst, &sha384_ctx);
175 x509_ctx->digest = bi_import(bi_ctx, sha384_dgst, SHA384_SIZE);
176 }
177 break;
178
179 case SIG_TYPE_SHA512:
180 {
181 SHA512_CTX sha512_ctx;
182 uint8_t sha512_dgst[SHA512_SIZE];
183 SHA512_Init(&sha512_ctx);
184 SHA512_Update(&sha512_ctx, &cert[begin_tbs], end_tbs-begin_tbs);
185 SHA512_Final(sha512_dgst, &sha512_ctx);
186 x509_ctx->digest = bi_import(bi_ctx, sha512_dgst, SHA512_SIZE);
187 }
188 break;
189 }
190
191 if (version == 2 && asn1_next_obj(cert, &offset, ASN1_V3_DATA) > 0)
192 {
193 x509_v3_subject_alt_name(cert, offset, x509_ctx);
194 x509_v3_basic_constraints(cert, offset, x509_ctx);
195 x509_v3_key_usage(cert, offset, x509_ctx);
196 }
197
198 offset = end_tbs; /* skip the rest of v3 data */
199 if (asn1_skip_obj(cert, &offset, ASN1_SEQUENCE) ||
200 asn1_signature(cert, &offset, x509_ctx))
201 goto end_cert;
202#endif
203 ret = X509_OK;
204end_cert:
205 if (len)
206 {
207 *len = cert_size;
208 }
209
210 if (ret)
211 {
212#ifdef CONFIG_SSL_FULL_MODE
213 printf("Error: Invalid X509 ASN.1 file (%s)\n",
214 x509_display_error(ret));
215#endif
216 x509_free(x509_ctx);
217 *ctx = NULL;
218 }
219
220 return ret;
221}
222
223#ifdef CONFIG_SSL_CERT_VERIFICATION /* only care if doing verification */
224static int x509_v3_subject_alt_name(const uint8_t *cert, int offset,
225 X509_CTX *x509_ctx)
226{
227 if ((offset = asn1_is_subject_alt_name(cert, offset)) > 0)
228 {
229 x509_ctx->subject_alt_name_present = true;
230 x509_ctx->subject_alt_name_is_critical =
231 asn1_is_critical_ext(cert, &offset);
232
233 if (asn1_next_obj(cert, &offset, ASN1_OCTET_STRING) > 0)
234 {
235 int altlen;
236
237 if ((altlen = asn1_next_obj(cert, &offset, ASN1_SEQUENCE)) > 0)
238 {
239 int endalt = offset + altlen;
240 int totalnames = 0;
241
242 while (offset < endalt)
243 {
244 int type = cert[offset++];
245 int dnslen = get_asn1_length(cert, &offset);
246
247 if (type == ASN1_CONTEXT_DNSNAME)
248 {
249 x509_ctx->subject_alt_dnsnames = (char**)
250 realloc(x509_ctx->subject_alt_dnsnames,
251 (totalnames + 2) * sizeof(char*));
252 x509_ctx->subject_alt_dnsnames[totalnames] =
253 (char*)malloc(dnslen + 1);
254 x509_ctx->subject_alt_dnsnames[totalnames+1] = NULL;
255 memcpy(x509_ctx->subject_alt_dnsnames[totalnames],
256 cert + offset, dnslen);
257 x509_ctx->subject_alt_dnsnames[totalnames][dnslen] = 0;
258 totalnames++;
259 }
260
261 offset += dnslen;
262 }
263 }
264 }
265 }
266
267 return X509_OK;
268}
269
270/**
271 * Basic constraints - see https://tools.ietf.org/html/rfc5280#page-39
272 */
273static int x509_v3_basic_constraints(const uint8_t *cert, int offset,
274 X509_CTX *x509_ctx)
275{
276 int ret = X509_OK;
277
278 if ((offset = asn1_is_basic_constraints(cert, offset)) == 0)
279 goto end_contraints;
280
281 x509_ctx->basic_constraint_present = true;
282 x509_ctx->basic_constraint_is_critical =
283 asn1_is_critical_ext(cert, &offset);
284
285 if (asn1_next_obj(cert, &offset, ASN1_OCTET_STRING) < 0 ||
286 asn1_next_obj(cert, &offset, ASN1_SEQUENCE) < 0 ||
287 asn1_get_bool(cert, &offset, &x509_ctx->basic_constraint_cA) < 0 ||
288 asn1_get_int(cert, &offset,
289 &x509_ctx->basic_constraint_pathLenConstraint) < 0)
290 {
291 ret = X509_NOT_OK;
292 }
293
294end_contraints:
295 return ret;
296}
297
298/*
299 * Key usage - see https://tools.ietf.org/html/rfc5280#section-4.2.1.3
300 */
301static int x509_v3_key_usage(const uint8_t *cert, int offset,
302 X509_CTX *x509_ctx)
303{
304 int ret = X509_OK;
305
306 if ((offset = asn1_is_key_usage(cert, offset)) == 0)
307 goto end_key_usage;
308
309 x509_ctx->key_usage_present = true;
310 x509_ctx->key_usage_is_critical = asn1_is_critical_ext(cert, &offset);
311
312 if (asn1_next_obj(cert, &offset, ASN1_OCTET_STRING) < 0 ||
313 asn1_get_bit_string_as_int(cert, &offset, &x509_ctx->key_usage))
314 {
315 ret = X509_NOT_OK;
316 }
317
318end_key_usage:
319 return ret;
320}
321#endif
322
323/**
324 * Free an X.509 object's resources.
325 */
326void x509_free(X509_CTX *x509_ctx)
327{
328 X509_CTX *next;
329 int i;
330
331 if (x509_ctx == NULL) /* if already null, then don't bother */
332 return;
333
334 for (i = 0; i < X509_NUM_DN_TYPES; i++)
335 {
336 free(x509_ctx->ca_cert_dn[i]);
337 free(x509_ctx->cert_dn[i]);
338 }
339
340 free(x509_ctx->signature);
341
342#ifdef CONFIG_SSL_CERT_VERIFICATION
343 if (x509_ctx->digest)
344 {
345 bi_free(x509_ctx->rsa_ctx->bi_ctx, x509_ctx->digest);
346 }
347
348 if (x509_ctx->subject_alt_dnsnames)
349 {
350 for (i = 0; x509_ctx->subject_alt_dnsnames[i]; ++i)
351 free(x509_ctx->subject_alt_dnsnames[i]);
352
353 free(x509_ctx->subject_alt_dnsnames);
354 }
355#endif
356
357 RSA_free(x509_ctx->rsa_ctx);
358 next = x509_ctx->next;
359 free(x509_ctx);
360 x509_free(next); /* clear the chain */
361}
362
363#ifdef CONFIG_SSL_CERT_VERIFICATION
364/**
365 * Take a signature and decrypt it.
366 */
367static bigint *sig_verify(BI_CTX *ctx, const uint8_t *sig, int sig_len,
368 bigint *modulus, bigint *pub_exp)
369{
370 int i, size;
371 bigint *decrypted_bi, *dat_bi;
372 bigint *bir = NULL;
373 uint8_t *block = (uint8_t *)alloca(sig_len);
374
375 /* decrypt */
376 dat_bi = bi_import(ctx, sig, sig_len);
377 ctx->mod_offset = BIGINT_M_OFFSET;
378
379 /* convert to a normal block */
380 decrypted_bi = bi_mod_power2(ctx, dat_bi, modulus, pub_exp);
381
382 bi_export(ctx, decrypted_bi, block, sig_len);
383 ctx->mod_offset = BIGINT_M_OFFSET;
384
385 i = 10; /* start at the first possible non-padded byte */
386 while (block[i++] && i < sig_len);
387 size = sig_len - i;
388
389 /* get only the bit we want */
390 if (size > 0)
391 {
392 int len;
393 const uint8_t *sig_ptr = get_signature(&block[i], &len);
394
395 if (sig_ptr)
396 {
397 bir = bi_import(ctx, sig_ptr, len);
398 }
399 }
400
401 /* save a few bytes of memory */
402 bi_clear_cache(ctx);
403 return bir;
404}
405
406/**
407 * Do some basic checks on the certificate chain.
408 *
409 * Certificate verification consists of a number of checks:
410 * - The date of the certificate is after the start date.
411 * - The date of the certificate is before the finish date.
412 * - A root certificate exists in the certificate store.
413 * - That the certificate(s) are not self-signed.
414 * - The certificate chain is valid.
415 * - The signature of the certificate is valid.
416 * - Basic constraints
417 */
418int x509_verify(const CA_CERT_CTX *ca_cert_ctx, const X509_CTX *cert,
419 int *pathLenConstraint)
420{
421 int ret = X509_OK, i = 0;
422 bigint *cert_sig;
423 X509_CTX *next_cert = NULL;
424 BI_CTX *ctx = NULL;
425 bigint *mod = NULL, *expn = NULL;
426 int match_ca_cert = 0;
427 struct timeval tv;
428 uint8_t is_self_signed = 0;
429
430 if (cert == NULL)
431 {
432 ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
433 goto end_verify;
434 }
435
436 /* a self-signed certificate that is not in the CA store - use this
437 to check the signature */
438 if (asn1_compare_dn(cert->ca_cert_dn, cert->cert_dn) == 0)
439 {
440 is_self_signed = 1;
441 ctx = cert->rsa_ctx->bi_ctx;
442 mod = cert->rsa_ctx->m;
443 expn = cert->rsa_ctx->e;
444 }
445
446 gettimeofday(&tv, NULL);
447
448 /* check the not before date */
449 if (tv.tv_sec < cert->not_before)
450 {
451 ret = X509_VFY_ERROR_NOT_YET_VALID;
452 goto end_verify;
453 }
454
455 /* check the not after date */
456 if (tv.tv_sec > cert->not_after)
457 {
458 ret = X509_VFY_ERROR_EXPIRED;
459 goto end_verify;
460 }
461
462 if (cert->basic_constraint_present)
463 {
464 /* If the cA boolean is not asserted,
465 then the keyCertSign bit in the key usage extension MUST NOT be
466 asserted. */
467 if (!cert->basic_constraint_cA &&
468 IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_CERT_SIGN))
469 {
470 ret = X509_VFY_ERROR_BASIC_CONSTRAINT;
471 goto end_verify;
472 }
473
474 /* The pathLenConstraint field is meaningful only if the cA boolean is
475 asserted and the key usage extension, if present, asserts the
476 keyCertSign bit. In this case, it gives the maximum number of
477 non-self-issued intermediate certificates that may follow this
478 certificate in a valid certification path. */
479 if (cert->basic_constraint_cA &&
480 (!cert->key_usage_present ||
481 IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_CERT_SIGN)) &&
482 (cert->basic_constraint_pathLenConstraint+1) < *pathLenConstraint)
483 {
484 ret = X509_VFY_ERROR_BASIC_CONSTRAINT;
485 goto end_verify;
486 }
487 }
488
489 next_cert = cert->next;
490
491 /* last cert in the chain - look for a trusted cert */
492 if (next_cert == NULL)
493 {
494 if (ca_cert_ctx != NULL)
495 {
496 /* go thru the CA store */
497 while (i < CONFIG_X509_MAX_CA_CERTS && ca_cert_ctx->cert[i])
498 {
499 /* the extension is present but the cA boolean is not
500 asserted, then the certified public key MUST NOT be used
501 to verify certificate signatures. */
502 if (cert->basic_constraint_present &&
503 !ca_cert_ctx->cert[i]->basic_constraint_cA)
504 continue;
505
506 if (asn1_compare_dn(cert->ca_cert_dn,
507 ca_cert_ctx->cert[i]->cert_dn) == 0)
508 {
509 /* use this CA certificate for signature verification */
510 match_ca_cert = true;
511 ctx = ca_cert_ctx->cert[i]->rsa_ctx->bi_ctx;
512 mod = ca_cert_ctx->cert[i]->rsa_ctx->m;
513 expn = ca_cert_ctx->cert[i]->rsa_ctx->e;
514
515
516 break;
517 }
518
519 i++;
520 }
521 }
522
523 /* couldn't find a trusted cert (& let self-signed errors
524 be returned) */
525 if (!match_ca_cert && !is_self_signed)
526 {
527 ret = X509_VFY_ERROR_NO_TRUSTED_CERT;
528 goto end_verify;
529 }
530 }
531 else if (asn1_compare_dn(cert->ca_cert_dn, next_cert->cert_dn) != 0)
532 {
533 /* check the chain */
534 ret = X509_VFY_ERROR_INVALID_CHAIN;
535 goto end_verify;
536 }
537 else /* use the next certificate in the chain for signature verify */
538 {
539 ctx = next_cert->rsa_ctx->bi_ctx;
540 mod = next_cert->rsa_ctx->m;
541 expn = next_cert->rsa_ctx->e;
542 }
543
544 /* cert is self signed */
545 if (!match_ca_cert && is_self_signed)
546 {
547 ret = X509_VFY_ERROR_SELF_SIGNED;
548 goto end_verify;
549 }
550
551 /* check the signature */
552 cert_sig = sig_verify(ctx, cert->signature, cert->sig_len,
553 bi_clone(ctx, mod), bi_clone(ctx, expn));
554
555 if (cert_sig && cert->digest)
556 {
557 if (bi_compare(cert_sig, cert->digest) != 0)
558 ret = X509_VFY_ERROR_BAD_SIGNATURE;
559
560
561 bi_free(ctx, cert_sig);
562 }
563 else
564 {
565 ret = X509_VFY_ERROR_BAD_SIGNATURE;
566 }
567
568 if (ret)
569 goto end_verify;
570
571 /* go down the certificate chain using recursion. */
572 if (next_cert != NULL)
573 {
574 (*pathLenConstraint)++; /* don't include last certificate */
575 ret = x509_verify(ca_cert_ctx, next_cert, pathLenConstraint);
576 }
577
578end_verify:
579 return ret;
580}
581#endif
582
583#if defined (CONFIG_SSL_FULL_MODE)
584/**
585 * Used for diagnostics.
586 */
587static const char *not_part_of_cert = "<Not Part Of Certificate>";
588void x509_print(const X509_CTX *cert, CA_CERT_CTX *ca_cert_ctx)
589{
590 if (cert == NULL)
591 return;
592
593 printf("=== CERTIFICATE ISSUED TO ===\n");
594 printf("Common Name (CN):\t\t");
595 printf("%s\n", cert->cert_dn[X509_COMMON_NAME] ?
596 cert->cert_dn[X509_COMMON_NAME] : not_part_of_cert);
597
598 printf("Organization (O):\t\t");
599 printf("%s\n", cert->cert_dn[X509_ORGANIZATION] ?
600 cert->cert_dn[X509_ORGANIZATION] : not_part_of_cert);
601
602 if (cert->cert_dn[X509_ORGANIZATIONAL_UNIT])
603 {
604 printf("Organizational Unit (OU):\t");
605 printf("%s\n", cert->cert_dn[X509_ORGANIZATIONAL_UNIT]);
606 }
607
608 if (cert->cert_dn[X509_LOCATION])
609 {
610 printf("Location (L):\t\t\t");
611 printf("%s\n", cert->cert_dn[X509_LOCATION]);
612 }
613
614 if (cert->cert_dn[X509_COUNTRY])
615 {
616 printf("Country (C):\t\t\t");
617 printf("%s\n", cert->cert_dn[X509_COUNTRY]);
618 }
619
620 if (cert->cert_dn[X509_STATE])
621 {
622 printf("State (ST):\t\t\t");
623 printf("%s\n", cert->cert_dn[X509_STATE]);
624 }
625
626 if (cert->basic_constraint_present)
627 {
628 printf("Basic Constraints:\t\t%sCA:%s, pathlen:%d\n",
629 cert->basic_constraint_is_critical ?
630 "critical, " : "",
631 cert->basic_constraint_cA? "TRUE" : "FALSE",
632 cert->basic_constraint_pathLenConstraint);
633 }
634
635 if (cert->key_usage_present)
636 {
637 printf("Key Usage:\t\t\t%s", cert->key_usage_is_critical ?
638 "critical, " : "");
639 bool has_started = false;
640
641 if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_DIGITAL_SIGNATURE))
642 {
643 printf("Digital Signature");
644 has_started = true;
645 }
646
647 if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_NON_REPUDIATION))
648 {
649 if (has_started)
650 printf(", ");
651
652 printf("Non Repudiation");
653 has_started = true;
654 }
655
656 if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_ENCIPHERMENT))
657 {
658 if (has_started)
659 printf(", ");
660
661 printf("Key Encipherment");
662 has_started = true;
663 }
664
665 if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_DATA_ENCIPHERMENT))
666 {
667 if (has_started)
668 printf(", ");
669
670 printf("Data Encipherment");
671 has_started = true;
672 }
673
674 if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_AGREEMENT))
675 {
676 if (has_started)
677 printf(", ");
678
679 printf("Key Agreement");
680 has_started = true;
681 }
682
683 if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_KEY_CERT_SIGN))
684 {
685 if (has_started)
686 printf(", ");
687
688 printf("Key Cert Sign");
689 has_started = true;
690 }
691
692 if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_CRL_SIGN))
693 {
694 if (has_started)
695 printf(", ");
696
697 printf("CRL Sign");
698 has_started = true;
699 }
700
701 if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_ENCIPHER_ONLY))
702 {
703 if (has_started)
704 printf(", ");
705
706 printf("Encipher Only");
707 has_started = true;
708 }
709
710 if (IS_SET_KEY_USAGE_FLAG(cert, KEY_USAGE_DECIPHER_ONLY))
711 {
712 if (has_started)
713 printf(", ");
714
715 printf("Decipher Only");
716 has_started = true;
717 }
718
719 printf("\n");
720 }
721
722 if (cert->subject_alt_name_present)
723 {
724 printf("Subject Alt Name:\t\t%s", cert->subject_alt_name_is_critical
725 ? "critical, " : "");
726 if (cert->subject_alt_dnsnames)
727 {
728 int i = 0;
729
730 while (cert->subject_alt_dnsnames[i])
731 printf("%s ", cert->subject_alt_dnsnames[i++]);
732 }
733 printf("\n");
734
735 }
736
737 printf("=== CERTIFICATE ISSUED BY ===\n");
738 printf("Common Name (CN):\t\t");
739 printf("%s\n", cert->ca_cert_dn[X509_COMMON_NAME] ?
740 cert->ca_cert_dn[X509_COMMON_NAME] : not_part_of_cert);
741
742 printf("Organization (O):\t\t");
743 printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATION] ?
744 cert->ca_cert_dn[X509_ORGANIZATION] : not_part_of_cert);
745
746 if (cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT])
747 {
748 printf("Organizational Unit (OU):\t");
749 printf("%s\n", cert->ca_cert_dn[X509_ORGANIZATIONAL_UNIT]);
750 }
751
752 if (cert->ca_cert_dn[X509_LOCATION])
753 {
754 printf("Location (L):\t\t\t");
755 printf("%s\n", cert->ca_cert_dn[X509_LOCATION]);
756 }
757
758 if (cert->ca_cert_dn[X509_COUNTRY])
759 {
760 printf("Country (C):\t\t\t");
761 printf("%s\n", cert->ca_cert_dn[X509_COUNTRY]);
762 }
763
764 if (cert->ca_cert_dn[X509_STATE])
765 {
766 printf("State (ST):\t\t\t");
767 printf("%s\n", cert->ca_cert_dn[X509_STATE]);
768 }
769
770 printf("Not Before:\t\t\t%s", ctime(&cert->not_before));
771 printf("Not After:\t\t\t%s", ctime(&cert->not_after));
772 printf("RSA bitsize:\t\t\t%d\n", cert->rsa_ctx->num_octets*8);
773 printf("Sig Type:\t\t\t");
774 switch (cert->sig_type)
775 {
776 case SIG_TYPE_MD5:
777 printf("MD5\n");
778 break;
779 case SIG_TYPE_SHA1:
780 printf("SHA1\n");
781 break;
782 case SIG_TYPE_SHA256:
783 printf("SHA256\n");
784 break;
785 case SIG_TYPE_SHA384:
786 printf("SHA384\n");
787 break;
788 case SIG_TYPE_SHA512:
789 printf("SHA512\n");
790 break;
791 default:
792 printf("Unrecognized: %d\n", cert->sig_type);
793 break;
794 }
795
796 if (ca_cert_ctx)
797 {
798 int pathLenConstraint = 0;
799 printf("Verify:\t\t\t\t%s\n",
800 x509_display_error(x509_verify(ca_cert_ctx, cert,
801 &pathLenConstraint)));
802 }
803
804#if 0
805 print_blob("Signature", cert->signature, cert->sig_len);
806 bi_print("Modulus", cert->rsa_ctx->m);
807 bi_print("Pub Exp", cert->rsa_ctx->e);
808#endif
809
810 if (ca_cert_ctx)
811 {
812 x509_print(cert->next, ca_cert_ctx);
813 }
814
815 TTY_FLUSH();
816}
817#endif
818
819const char * x509_display_error(int error)
820{
821 switch (error)
822 {
823 case X509_OK:
824 return "Certificate verify successful";
825
826 case X509_NOT_OK:
827 return "X509 not ok";
828
829 case X509_VFY_ERROR_NO_TRUSTED_CERT:
830 return "No trusted cert is available";
831
832 case X509_VFY_ERROR_BAD_SIGNATURE:
833 return "Bad signature";
834
835 case X509_VFY_ERROR_NOT_YET_VALID:
836 return "Cert is not yet valid";
837
838 case X509_VFY_ERROR_EXPIRED:
839 return "Cert has expired";
840
841 case X509_VFY_ERROR_SELF_SIGNED:
842 return "Cert is self-signed";
843
844 case X509_VFY_ERROR_INVALID_CHAIN:
845 return "Chain is invalid (check order of certs)";
846
847 case X509_VFY_ERROR_UNSUPPORTED_DIGEST:
848 return "Unsupported digest";
849
850 case X509_INVALID_PRIV_KEY:
851 return "Invalid private key";
852
853 case X509_VFY_ERROR_BASIC_CONSTRAINT:
854 return "Basic constraint invalid";
855
856 default:
857 return "Unknown";
858 }
859}
860//#endif /* CONFIG_SSL_FULL_MODE */
861
862