NCBI C++ ToolKit
x509.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /*
2  * X.509 common functions for parsing and verification
3  *
4  * Copyright The Mbed TLS Contributors
5  * SPDX-License-Identifier: Apache-2.0
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may
8  * not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 /*
20  * The ITU-T X.509 standard defines a certificate format for PKI.
21  *
22  * http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
23  * http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
24  * http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
25  *
26  * http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
27  * http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
28  */
29 
30 #include "common.h"
31 
32 #if defined(MBEDTLS_X509_USE_C)
33 
34 #include "mbedtls/x509.h"
35 #include "mbedtls/asn1.h"
36 #include "mbedtls/error.h"
37 #include "mbedtls/oid.h"
38 
39 #include <stdio.h>
40 #include <string.h>
41 
42 #if defined(MBEDTLS_PEM_PARSE_C)
43 #include "mbedtls/pem.h"
44 #endif
45 
46 #include "mbedtls/platform.h"
47 
48 #if defined(MBEDTLS_HAVE_TIME)
49 #include "mbedtls/platform_time.h"
50 #endif
51 #if defined(MBEDTLS_HAVE_TIME_DATE)
52 #include "mbedtls/platform_util.h"
53 #include <time.h>
54 #endif
55 
56 #define CHECK(code) if ((ret = (code)) != 0) { return ret; }
57 #define CHECK_RANGE(min, max, val) \
58  do \
59  { \
60  if ((val) < (min) || (val) > (max)) \
61  { \
62  return ret; \
63  } \
64  } while (0)
65 
66 /*
67  * CertificateSerialNumber ::= INTEGER
68  */
69 int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end,
70  mbedtls_x509_buf *serial)
71 {
73 
74  if ((end - *p) < 1) {
77  }
78 
80  **p != MBEDTLS_ASN1_INTEGER) {
83  }
84 
85  serial->tag = *(*p)++;
86 
87  if ((ret = mbedtls_asn1_get_len(p, end, &serial->len)) != 0) {
89  }
90 
91  serial->p = *p;
92  *p += serial->len;
93 
94  return 0;
95 }
96 
97 /* Get an algorithm identifier without parameters (eg for signatures)
98  *
99  * AlgorithmIdentifier ::= SEQUENCE {
100  * algorithm OBJECT IDENTIFIER,
101  * parameters ANY DEFINED BY algorithm OPTIONAL }
102  */
103 int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end,
104  mbedtls_x509_buf *alg)
105 {
107 
108  if ((ret = mbedtls_asn1_get_alg_null(p, end, alg)) != 0) {
110  }
111 
112  return 0;
113 }
114 
115 /*
116  * Parse an algorithm identifier with (optional) parameters
117  */
118 int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end,
119  mbedtls_x509_buf *alg, mbedtls_x509_buf *params)
120 {
122 
123  if ((ret = mbedtls_asn1_get_alg(p, end, alg, params)) != 0) {
125  }
126 
127  return 0;
128 }
129 
130 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
131 /*
132  * HashAlgorithm ::= AlgorithmIdentifier
133  *
134  * AlgorithmIdentifier ::= SEQUENCE {
135  * algorithm OBJECT IDENTIFIER,
136  * parameters ANY DEFINED BY algorithm OPTIONAL }
137  *
138  * For HashAlgorithm, parameters MUST be NULL or absent.
139  */
140 static int x509_get_hash_alg(const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg)
141 {
143  unsigned char *p;
144  const unsigned char *end;
145  mbedtls_x509_buf md_oid;
146  size_t len;
147 
148  /* Make sure we got a SEQUENCE and setup bounds */
152  }
153 
154  p = alg->p;
155  end = p + alg->len;
156 
157  if (p >= end) {
160  }
161 
162  /* Parse md_oid */
163  md_oid.tag = *p;
164 
165  if ((ret = mbedtls_asn1_get_tag(&p, end, &md_oid.len, MBEDTLS_ASN1_OID)) != 0) {
167  }
168 
169  md_oid.p = p;
170  p += md_oid.len;
171 
172  /* Get md_alg from md_oid */
173  if ((ret = mbedtls_oid_get_md_alg(&md_oid, md_alg)) != 0) {
175  }
176 
177  /* Make sure params is absent of NULL */
178  if (p == end) {
179  return 0;
180  }
181 
182  if ((ret = mbedtls_asn1_get_tag(&p, end, &len, MBEDTLS_ASN1_NULL)) != 0 || len != 0) {
184  }
185 
186  if (p != end) {
189  }
190 
191  return 0;
192 }
193 
194 /*
195  * RSASSA-PSS-params ::= SEQUENCE {
196  * hashAlgorithm [0] HashAlgorithm DEFAULT sha1Identifier,
197  * maskGenAlgorithm [1] MaskGenAlgorithm DEFAULT mgf1SHA1Identifier,
198  * saltLength [2] INTEGER DEFAULT 20,
199  * trailerField [3] INTEGER DEFAULT 1 }
200  * -- Note that the tags in this Sequence are explicit.
201  *
202  * RFC 4055 (which defines use of RSASSA-PSS in PKIX) states that the value
203  * of trailerField MUST be 1, and PKCS#1 v2.2 doesn't even define any other
204  * option. Enforce this at parsing time.
205  */
207  mbedtls_md_type_t *md_alg, mbedtls_md_type_t *mgf_md,
208  int *salt_len)
209 {
211  unsigned char *p;
212  const unsigned char *end, *end2;
213  size_t len;
214  mbedtls_x509_buf alg_id, alg_params;
215 
216  /* First set everything to defaults */
217  *md_alg = MBEDTLS_MD_SHA1;
218  *mgf_md = MBEDTLS_MD_SHA1;
219  *salt_len = 20;
220 
221  /* Make sure params is a SEQUENCE and setup bounds */
225  }
226 
227  p = (unsigned char *) params->p;
228  end = p + params->len;
229 
230  if (p == end) {
231  return 0;
232  }
233 
234  /*
235  * HashAlgorithm
236  */
237  if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
239  0)) == 0) {
240  end2 = p + len;
241 
242  /* HashAlgorithm ::= AlgorithmIdentifier (without parameters) */
243  if ((ret = mbedtls_x509_get_alg_null(&p, end2, &alg_id)) != 0) {
244  return ret;
245  }
246 
247  if ((ret = mbedtls_oid_get_md_alg(&alg_id, md_alg)) != 0) {
249  }
250 
251  if (p != end2) {
254  }
255  } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
257  }
258 
259  if (p == end) {
260  return 0;
261  }
262 
263  /*
264  * MaskGenAlgorithm
265  */
266  if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
268  1)) == 0) {
269  end2 = p + len;
270 
271  /* MaskGenAlgorithm ::= AlgorithmIdentifier (params = HashAlgorithm) */
272  if ((ret = mbedtls_x509_get_alg(&p, end2, &alg_id, &alg_params)) != 0) {
273  return ret;
274  }
275 
276  /* Only MFG1 is recognised for now */
277  if (MBEDTLS_OID_CMP(MBEDTLS_OID_MGF1, &alg_id) != 0) {
280  }
281 
282  /* Parse HashAlgorithm */
283  if ((ret = x509_get_hash_alg(&alg_params, mgf_md)) != 0) {
284  return ret;
285  }
286 
287  if (p != end2) {
290  }
291  } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
293  }
294 
295  if (p == end) {
296  return 0;
297  }
298 
299  /*
300  * salt_len
301  */
302  if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
304  2)) == 0) {
305  end2 = p + len;
306 
307  if ((ret = mbedtls_asn1_get_int(&p, end2, salt_len)) != 0) {
309  }
310 
311  if (p != end2) {
314  }
315  } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
317  }
318 
319  if (p == end) {
320  return 0;
321  }
322 
323  /*
324  * trailer_field (if present, must be 1)
325  */
326  if ((ret = mbedtls_asn1_get_tag(&p, end, &len,
328  3)) == 0) {
329  int trailer_field;
330 
331  end2 = p + len;
332 
333  if ((ret = mbedtls_asn1_get_int(&p, end2, &trailer_field)) != 0) {
335  }
336 
337  if (p != end2) {
340  }
341 
342  if (trailer_field != 1) {
344  }
345  } else if (ret != MBEDTLS_ERR_ASN1_UNEXPECTED_TAG) {
347  }
348 
349  if (p != end) {
352  }
353 
354  return 0;
355 }
356 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
357 
358 /*
359  * AttributeTypeAndValue ::= SEQUENCE {
360  * type AttributeType,
361  * value AttributeValue }
362  *
363  * AttributeType ::= OBJECT IDENTIFIER
364  *
365  * AttributeValue ::= ANY DEFINED BY AttributeType
366  */
367 static int x509_get_attr_type_value(unsigned char **p,
368  const unsigned char *end,
369  mbedtls_x509_name *cur)
370 {
372  size_t len;
373  mbedtls_x509_buf *oid;
375 
376  if ((ret = mbedtls_asn1_get_tag(p, end, &len,
379  }
380 
381  end = *p + len;
382 
383  if ((end - *p) < 1) {
386  }
387 
388  oid = &cur->oid;
389  oid->tag = **p;
390 
391  if ((ret = mbedtls_asn1_get_tag(p, end, &oid->len, MBEDTLS_ASN1_OID)) != 0) {
393  }
394 
395  oid->p = *p;
396  *p += oid->len;
397 
398  if ((end - *p) < 1) {
401  }
402 
403  if (**p != MBEDTLS_ASN1_BMP_STRING && **p != MBEDTLS_ASN1_UTF8_STRING &&
406  **p != MBEDTLS_ASN1_BIT_STRING) {
409  }
410 
411  val = &cur->val;
412  val->tag = *(*p)++;
413 
414  if ((ret = mbedtls_asn1_get_len(p, end, &val->len)) != 0) {
416  }
417 
418  val->p = *p;
419  *p += val->len;
420 
421  if (*p != end) {
424  }
425 
426  cur->next = NULL;
427 
428  return 0;
429 }
430 
431 /*
432  * Name ::= CHOICE { -- only one possibility for now --
433  * rdnSequence RDNSequence }
434  *
435  * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
436  *
437  * RelativeDistinguishedName ::=
438  * SET OF AttributeTypeAndValue
439  *
440  * AttributeTypeAndValue ::= SEQUENCE {
441  * type AttributeType,
442  * value AttributeValue }
443  *
444  * AttributeType ::= OBJECT IDENTIFIER
445  *
446  * AttributeValue ::= ANY DEFINED BY AttributeType
447  *
448  * The data structure is optimized for the common case where each RDN has only
449  * one element, which is represented as a list of AttributeTypeAndValue.
450  * For the general case we still use a flat list, but we mark elements of the
451  * same set so that they are "merged" together in the functions that consume
452  * this list, eg mbedtls_x509_dn_gets().
453  *
454  * On success, this function may allocate a linked list starting at cur->next
455  * that must later be free'd by the caller using mbedtls_free(). In error
456  * cases, this function frees all allocated memory internally and the caller
457  * has no freeing responsibilities.
458  */
459 int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end,
460  mbedtls_x509_name *cur)
461 {
463  size_t set_len;
464  const unsigned char *end_set;
465  mbedtls_x509_name *head = cur;
466  mbedtls_x509_name *prev, *allocated;
467 
468  /* don't use recursion, we'd risk stack overflow if not optimized */
469  while (1) {
470  /*
471  * parse SET
472  */
473  if ((ret = mbedtls_asn1_get_tag(p, end, &set_len,
476  goto error;
477  }
478 
479  end_set = *p + set_len;
480 
481  while (1) {
482  if ((ret = x509_get_attr_type_value(p, end_set, cur)) != 0) {
483  goto error;
484  }
485 
486  if (*p == end_set) {
487  break;
488  }
489 
490  /* Mark this item as being no the only one in a set */
491  cur->next_merged = 1;
492 
493  cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
494 
495  if (cur->next == NULL) {
497  goto error;
498  }
499 
500  cur = cur->next;
501  }
502 
503  /*
504  * continue until end of SEQUENCE is reached
505  */
506  if (*p == end) {
507  return 0;
508  }
509 
510  cur->next = mbedtls_calloc(1, sizeof(mbedtls_x509_name));
511 
512  if (cur->next == NULL) {
514  goto error;
515  }
516 
517  cur = cur->next;
518  }
519 
520 error:
521  /* Skip the first element as we did not allocate it */
522  allocated = head->next;
523 
524  while (allocated != NULL) {
525  prev = allocated;
526  allocated = allocated->next;
527 
530  }
531 
533 
534  return ret;
535 }
536 
537 static int x509_parse_int(unsigned char **p, size_t n, int *res)
538 {
539  *res = 0;
540 
541  for (; n > 0; --n) {
542  if ((**p < '0') || (**p > '9')) {
544  }
545 
546  *res *= 10;
547  *res += (*(*p)++ - '0');
548  }
549 
550  return 0;
551 }
552 
554 {
556  int month_len;
557 
558  CHECK_RANGE(0, 9999, t->year);
559  CHECK_RANGE(0, 23, t->hour);
560  CHECK_RANGE(0, 59, t->min);
561  CHECK_RANGE(0, 59, t->sec);
562 
563  switch (t->mon) {
564  case 1: case 3: case 5: case 7: case 8: case 10: case 12:
565  month_len = 31;
566  break;
567  case 4: case 6: case 9: case 11:
568  month_len = 30;
569  break;
570  case 2:
571  if ((!(t->year % 4) && t->year % 100) ||
572  !(t->year % 400)) {
573  month_len = 29;
574  } else {
575  month_len = 28;
576  }
577  break;
578  default:
579  return ret;
580  }
581  CHECK_RANGE(1, month_len, t->day);
582 
583  return 0;
584 }
585 
586 /*
587  * Parse an ASN1_UTC_TIME (yearlen=2) or ASN1_GENERALIZED_TIME (yearlen=4)
588  * field.
589  */
590 static int x509_parse_time(unsigned char **p, size_t len, size_t yearlen,
591  mbedtls_x509_time *tm)
592 {
594 
595  /*
596  * Minimum length is 10 or 12 depending on yearlen
597  */
598  if (len < yearlen + 8) {
600  }
601  len -= yearlen + 8;
602 
603  /*
604  * Parse year, month, day, hour, minute
605  */
606  CHECK(x509_parse_int(p, yearlen, &tm->year));
607  if (2 == yearlen) {
608  if (tm->year < 50) {
609  tm->year += 100;
610  }
611 
612  tm->year += 1900;
613  }
614 
615  CHECK(x509_parse_int(p, 2, &tm->mon));
616  CHECK(x509_parse_int(p, 2, &tm->day));
617  CHECK(x509_parse_int(p, 2, &tm->hour));
618  CHECK(x509_parse_int(p, 2, &tm->min));
619 
620  /*
621  * Parse seconds if present
622  */
623  if (len >= 2) {
624  CHECK(x509_parse_int(p, 2, &tm->sec));
625  len -= 2;
626  } else {
628  }
629 
630  /*
631  * Parse trailing 'Z' if present
632  */
633  if (1 == len && 'Z' == **p) {
634  (*p)++;
635  len--;
636  }
637 
638  /*
639  * We should have parsed all characters at this point
640  */
641  if (0 != len) {
643  }
644 
646 
647  return 0;
648 }
649 
650 /*
651  * Time ::= CHOICE {
652  * utcTime UTCTime,
653  * generalTime GeneralizedTime }
654  */
655 int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end,
656  mbedtls_x509_time *tm)
657 {
659  size_t len, year_len;
660  unsigned char tag;
661 
662  if ((end - *p) < 1) {
665  }
666 
667  tag = **p;
668 
669  if (tag == MBEDTLS_ASN1_UTC_TIME) {
670  year_len = 2;
671  } else if (tag == MBEDTLS_ASN1_GENERALIZED_TIME) {
672  year_len = 4;
673  } else {
676  }
677 
678  (*p)++;
679  ret = mbedtls_asn1_get_len(p, end, &len);
680 
681  if (ret != 0) {
683  }
684 
685  return x509_parse_time(p, len, year_len, tm);
686 }
687 
688 int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig)
689 {
691  size_t len;
692  int tag_type;
693 
694  if ((end - *p) < 1) {
697  }
698 
699  tag_type = **p;
700 
701  if ((ret = mbedtls_asn1_get_bitstring_null(p, end, &len)) != 0) {
703  }
704 
705  sig->tag = tag_type;
706  sig->len = len;
707  sig->p = *p;
708 
709  *p += len;
710 
711  return 0;
712 }
713 
714 /*
715  * Get signature algorithm from alg OID and optional parameters
716  */
717 int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params,
718  mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg,
719  void **sig_opts)
720 {
722 
723  if (*sig_opts != NULL) {
725  }
726 
727  if ((ret = mbedtls_oid_get_sig_alg(sig_oid, md_alg, pk_alg)) != 0) {
729  }
730 
731 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
732  if (*pk_alg == MBEDTLS_PK_RSASSA_PSS) {
734 
735  pss_opts = mbedtls_calloc(1, sizeof(mbedtls_pk_rsassa_pss_options));
736  if (pss_opts == NULL) {
738  }
739 
740  ret = mbedtls_x509_get_rsassa_pss_params(sig_params,
741  md_alg,
742  &pss_opts->mgf1_hash_id,
743  &pss_opts->expected_salt_len);
744  if (ret != 0) {
745  mbedtls_free(pss_opts);
746  return ret;
747  }
748 
749  *sig_opts = (void *) pss_opts;
750  } else
751 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
752  {
753  /* Make sure parameters are absent or NULL */
754  if ((sig_params->tag != MBEDTLS_ASN1_NULL && sig_params->tag != 0) ||
755  sig_params->len != 0) {
757  }
758  }
759 
760  return 0;
761 }
762 
763 /*
764  * X.509 Extensions (No parsing of extensions, pointer should
765  * be either manually updated or extensions should be parsed!)
766  */
767 int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end,
768  mbedtls_x509_buf *ext, int tag)
769 {
771  size_t len;
772 
773  /* Extension structure use EXPLICIT tagging. That is, the actual
774  * `Extensions` structure is wrapped by a tag-length pair using
775  * the respective context-specific tag. */
776  ret = mbedtls_asn1_get_tag(p, end, &ext->len,
778  if (ret != 0) {
780  }
781 
783  ext->p = *p;
784  end = *p + ext->len;
785 
786  /*
787  * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension
788  */
789  if ((ret = mbedtls_asn1_get_tag(p, end, &len,
792  }
793 
794  if (end != *p + len) {
797  }
798 
799  return 0;
800 }
801 
802 /*
803  * Store the name in printable form into buf; no more
804  * than size characters will be written
805  */
806 int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
807 {
809  size_t i, j, n;
810  unsigned char c, merge = 0;
811  const mbedtls_x509_name *name;
812  const char *short_name = NULL;
813  char s[MBEDTLS_X509_MAX_DN_NAME_SIZE], *p;
814 
815  memset(s, 0, sizeof(s));
816 
817  name = dn;
818  p = buf;
819  n = size;
820 
821  while (name != NULL) {
822  if (!name->oid.p) {
823  name = name->next;
824  continue;
825  }
826 
827  if (name != dn) {
828  ret = mbedtls_snprintf(p, n, merge ? " + " : ", ");
830  }
831 
832  ret = mbedtls_oid_get_attr_short_name(&name->oid, &short_name);
833 
834  if (ret == 0) {
835  ret = mbedtls_snprintf(p, n, "%s=", short_name);
836  } else {
837  ret = mbedtls_snprintf(p, n, "\?\?=");
838  }
840 
841  for (i = 0, j = 0; i < name->val.len; i++, j++) {
842  if (j >= sizeof(s) - 1) {
844  }
845 
846  c = name->val.p[i];
847  // Special characters requiring escaping, RFC 1779
848  if (c && strchr(",=+<>#;\"\\", c)) {
849  if (j + 1 >= sizeof(s) - 1) {
851  }
852  s[j++] = '\\';
853  }
854  if (c < 32 || c >= 127) {
855  s[j] = '?';
856  } else {
857  s[j] = c;
858  }
859  }
860  s[j] = '\0';
861  ret = mbedtls_snprintf(p, n, "%s", s);
863 
864  merge = name->next_merged;
865  name = name->next;
866  }
867 
868  return (int) (size - n);
869 }
870 
871 /*
872  * Store the serial in printable form into buf; no more
873  * than size characters will be written
874  */
875 int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial)
876 {
878  size_t i, n, nr;
879  char *p;
880 
881  p = buf;
882  n = size;
883 
884  nr = (serial->len <= 32)
885  ? serial->len : 28;
886 
887  for (i = 0; i < nr; i++) {
888  if (i == 0 && nr > 1 && serial->p[i] == 0x0) {
889  continue;
890  }
891 
892  ret = mbedtls_snprintf(p, n, "%02X%s",
893  serial->p[i], (i < nr - 1) ? ":" : "");
895  }
896 
897  if (nr != serial->len) {
898  ret = mbedtls_snprintf(p, n, "....");
900  }
901 
902  return (int) (size - n);
903 }
904 
905 /*
906  * Helper for writing signature algorithms
907  */
908 int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid,
909  mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg,
910  const void *sig_opts)
911 {
913  char *p = buf;
914  size_t n = size;
915  const char *desc = NULL;
916 
917  ret = mbedtls_oid_get_sig_alg_desc(sig_oid, &desc);
918  if (ret != 0) {
919  ret = mbedtls_snprintf(p, n, "???");
920  } else {
921  ret = mbedtls_snprintf(p, n, "%s", desc);
922  }
924 
925 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
926  if (pk_alg == MBEDTLS_PK_RSASSA_PSS) {
927  const mbedtls_pk_rsassa_pss_options *pss_opts;
928  const mbedtls_md_info_t *md_info, *mgf_md_info;
929 
930  pss_opts = (const mbedtls_pk_rsassa_pss_options *) sig_opts;
931 
932  md_info = mbedtls_md_info_from_type(md_alg);
933  mgf_md_info = mbedtls_md_info_from_type(pss_opts->mgf1_hash_id);
934 
935  ret = mbedtls_snprintf(p, n, " (%s, MGF1-%s, 0x%02X)",
936  md_info ? mbedtls_md_get_name(md_info) : "???",
937  mgf_md_info ? mbedtls_md_get_name(mgf_md_info) : "???",
938  (unsigned int) pss_opts->expected_salt_len);
940  }
941 #else
942  ((void) pk_alg);
943  ((void) md_alg);
944  ((void) sig_opts);
945 #endif /* MBEDTLS_X509_RSASSA_PSS_SUPPORT */
946 
947  return (int) (size - n);
948 }
949 
950 /*
951  * Helper for writing "RSA key size", "EC key size", etc
952  */
953 int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name)
954 {
955  char *p = buf;
956  size_t n = buf_size;
958 
959  ret = mbedtls_snprintf(p, n, "%s key size", name);
961 
962  return 0;
963 }
964 
965 #if defined(MBEDTLS_HAVE_TIME_DATE)
966 /*
967  * Set the time structure to the current time.
968  * Return 0 on success, non-zero on failure.
969  */
971 {
972  struct tm *lt, tm_buf;
973  mbedtls_time_t tt;
974  int ret = 0;
975 
976  tt = mbedtls_time(NULL);
977  lt = mbedtls_platform_gmtime_r(&tt, &tm_buf);
978 
979  if (lt == NULL) {
980  ret = -1;
981  } else {
982  now->year = lt->tm_year + 1900;
983  now->mon = lt->tm_mon + 1;
984  now->day = lt->tm_mday;
985  now->hour = lt->tm_hour;
986  now->min = lt->tm_min;
987  now->sec = lt->tm_sec;
988  }
989 
990  return ret;
991 }
992 
993 /*
994  * Return 0 if before <= after, 1 otherwise
995  */
996 static int x509_check_time(const mbedtls_x509_time *before, const mbedtls_x509_time *after)
997 {
998  if (before->year > after->year) {
999  return 1;
1000  }
1001 
1002  if (before->year == after->year &&
1003  before->mon > after->mon) {
1004  return 1;
1005  }
1006 
1007  if (before->year == after->year &&
1008  before->mon == after->mon &&
1009  before->day > after->day) {
1010  return 1;
1011  }
1012 
1013  if (before->year == after->year &&
1014  before->mon == after->mon &&
1015  before->day == after->day &&
1016  before->hour > after->hour) {
1017  return 1;
1018  }
1019 
1020  if (before->year == after->year &&
1021  before->mon == after->mon &&
1022  before->day == after->day &&
1023  before->hour == after->hour &&
1024  before->min > after->min) {
1025  return 1;
1026  }
1027 
1028  if (before->year == after->year &&
1029  before->mon == after->mon &&
1030  before->day == after->day &&
1031  before->hour == after->hour &&
1032  before->min == after->min &&
1033  before->sec > after->sec) {
1034  return 1;
1035  }
1036 
1037  return 0;
1038 }
1039 
1041 {
1042  mbedtls_x509_time now;
1043 
1044  if (x509_get_current_time(&now) != 0) {
1045  return 1;
1046  }
1047 
1048  return x509_check_time(&now, to);
1049 }
1050 
1052 {
1053  mbedtls_x509_time now;
1054 
1055  if (x509_get_current_time(&now) != 0) {
1056  return 1;
1057  }
1058 
1059  return x509_check_time(from, &now);
1060 }
1061 
1062 #else /* MBEDTLS_HAVE_TIME_DATE */
1063 
1065 {
1066  ((void) to);
1067  return 0;
1068 }
1069 
1071 {
1072  ((void) from);
1073  return 0;
1074 }
1075 #endif /* MBEDTLS_HAVE_TIME_DATE */
1076 
1077 #if defined(MBEDTLS_SELF_TEST)
1078 
1079 #include "mbedtls/x509_crt.h"
1080 #include "mbedtls/certs.h"
1081 
1082 /*
1083  * Checkup routine
1084  */
1085 int mbedtls_x509_self_test(int verbose)
1086 {
1087  int ret = 0;
1088 #if defined(MBEDTLS_CERTS_C) && defined(MBEDTLS_SHA256_C)
1089  uint32_t flags;
1090  mbedtls_x509_crt cacert;
1091  mbedtls_x509_crt clicert;
1092 
1093  if (verbose != 0) {
1094  mbedtls_printf(" X.509 certificate load: ");
1095  }
1096 
1097  mbedtls_x509_crt_init(&cacert);
1098  mbedtls_x509_crt_init(&clicert);
1099 
1100  ret = mbedtls_x509_crt_parse(&clicert, (const unsigned char *) mbedtls_test_cli_crt,
1102  if (ret != 0) {
1103  if (verbose != 0) {
1104  mbedtls_printf("failed\n");
1105  }
1106 
1107  goto cleanup;
1108  }
1109 
1110  ret = mbedtls_x509_crt_parse(&cacert, (const unsigned char *) mbedtls_test_ca_crt,
1112  if (ret != 0) {
1113  if (verbose != 0) {
1114  mbedtls_printf("failed\n");
1115  }
1116 
1117  goto cleanup;
1118  }
1119 
1120  if (verbose != 0) {
1121  mbedtls_printf("passed\n X.509 signature verify: ");
1122  }
1123 
1124  ret = mbedtls_x509_crt_verify(&clicert, &cacert, NULL, NULL, &flags, NULL, NULL);
1125  if (ret != 0) {
1126  if (verbose != 0) {
1127  mbedtls_printf("failed\n");
1128  }
1129 
1130  goto cleanup;
1131  }
1132 
1133  if (verbose != 0) {
1134  mbedtls_printf("passed\n\n");
1135  }
1136 
1137 cleanup:
1138  mbedtls_x509_crt_free(&cacert);
1139  mbedtls_x509_crt_free(&clicert);
1140 #else
1141  ((void) verbose);
1142 #endif /* MBEDTLS_CERTS_C && MBEDTLS_SHA256_C */
1143  return ret;
1144 }
1145 
1146 #endif /* MBEDTLS_SELF_TEST */
1147 
1148 #endif /* MBEDTLS_X509_USE_C */
Generic ASN.1 parsing.
Sample certificates and DHM parameters for testing.
const size_t mbedtls_test_cli_crt_len
const char * mbedtls_test_ca_crt
const size_t mbedtls_test_ca_crt_len
const char * mbedtls_test_cli_crt
static void cleanup(void)
Definition: ct_dynamic.c:30
#define head
Definition: ct_nlmzip_i.h:138
static uch flags
static DLIST_TYPE *DLIST_NAME() prev(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:61
#define NULL
Definition: ncbistd.hpp:225
#define MBEDTLS_OID_CMP(oid_str, oid_buf)
Compares an mbedtls_asn1_buf structure to a reference OID.
Definition: asn1.h:135
int mbedtls_asn1_get_bitstring_null(unsigned char **p, const unsigned char *end, size_t *len)
Retrieve a bitstring ASN.1 tag without unused bits and its value.
#define MBEDTLS_ERR_ASN1_OUT_OF_DATA
Out of data when parsing an ASN1 data structure.
Definition: asn1.h:50
#define MBEDTLS_ASN1_GENERALIZED_TIME
Definition: asn1.h:91
#define MBEDTLS_ASN1_IA5_STRING
Definition: asn1.h:89
#define MBEDTLS_ASN1_BMP_STRING
Definition: asn1.h:93
#define MBEDTLS_ASN1_PRINTABLE_STRING
Definition: asn1.h:87
#define MBEDTLS_ASN1_SEQUENCE
Definition: asn1.h:85
#define MBEDTLS_ASN1_SET
Definition: asn1.h:86
#define MBEDTLS_ASN1_INTEGER
Definition: asn1.h:78
int mbedtls_asn1_get_int(unsigned char **p, const unsigned char *end, int *val)
Retrieve an integer ASN.1 tag and its value.
#define MBEDTLS_ASN1_PRIMITIVE
Definition: asn1.h:94
#define MBEDTLS_ASN1_CONTEXT_SPECIFIC
Definition: asn1.h:96
#define MBEDTLS_ASN1_CONSTRUCTED
Definition: asn1.h:95
#define MBEDTLS_ERR_ASN1_UNEXPECTED_TAG
ASN1 tag was of an unexpected value.
Definition: asn1.h:52
#define MBEDTLS_ASN1_T61_STRING
Definition: asn1.h:88
#define MBEDTLS_ASN1_UTC_TIME
Definition: asn1.h:90
#define MBEDTLS_ASN1_UNIVERSAL_STRING
Definition: asn1.h:92
#define MBEDTLS_ERR_ASN1_LENGTH_MISMATCH
Actual length differs from expected length.
Definition: asn1.h:56
int mbedtls_asn1_get_len(unsigned char **p, const unsigned char *end, size_t *len)
Get the length of an ASN.1 element.
#define MBEDTLS_ASN1_OID
Definition: asn1.h:82
int mbedtls_asn1_get_alg_null(unsigned char **p, const unsigned char *end, mbedtls_asn1_buf *alg)
Retrieve an AlgorithmIdentifier ASN.1 sequence with NULL or no params.
int mbedtls_asn1_get_alg(unsigned char **p, const unsigned char *end, mbedtls_asn1_buf *alg, mbedtls_asn1_buf *params)
Retrieve an AlgorithmIdentifier ASN.1 sequence.
#define MBEDTLS_ASN1_NULL
Definition: asn1.h:81
int mbedtls_asn1_get_tag(unsigned char **p, const unsigned char *end, size_t *len, int tag)
Get the tag and length of the element.
#define MBEDTLS_ASN1_UTF8_STRING
Definition: asn1.h:84
#define MBEDTLS_ASN1_BIT_STRING
Definition: asn1.h:79
#define MBEDTLS_ERR_X509_INVALID_SIGNATURE
The signature tag or value invalid.
Definition: x509.h:76
int mbedtls_x509_time_is_past(const mbedtls_x509_time *to)
Check a given mbedtls_x509_time against the system time and tell if it's in the past.
int mbedtls_x509_time_is_future(const mbedtls_x509_time *from)
Check a given mbedtls_x509_time against the system time and tell if it's in the future.
#define MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE
Unavailable feature, e.g.
Definition: x509.h:60
#define MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG
Signature algorithm (oid) is unsupported.
Definition: x509.h:82
int mbedtls_x509_dn_gets(char *buf, size_t size, const mbedtls_x509_name *dn)
Store the certificate DN in printable form into buf; no more than size characters will be written.
#define MBEDTLS_ERR_X509_INVALID_SERIAL
The serial tag or value is invalid.
Definition: x509.h:68
#define MBEDTLS_ERR_X509_INVALID_NAME
The name tag or value is invalid.
Definition: x509.h:72
#define MBEDTLS_ERR_X509_INVALID_EXTENSIONS
The extension tag or value is invalid.
Definition: x509.h:78
#define MBEDTLS_ERR_X509_BUFFER_TOO_SMALL
Destination buffer is too small.
Definition: x509.h:96
#define MBEDTLS_ERR_X509_INVALID_DATE
The date tag or value is invalid.
Definition: x509.h:74
#define MBEDTLS_ERR_X509_ALLOC_FAILED
Allocation of memory failed.
Definition: x509.h:92
#define MBEDTLS_ERR_X509_INVALID_ALG
The algorithm tag or value is invalid.
Definition: x509.h:70
#define MBEDTLS_ERR_X509_BAD_INPUT_DATA
Input invalid.
Definition: x509.h:90
int mbedtls_x509_serial_gets(char *buf, size_t size, const mbedtls_x509_buf *serial)
Store the certificate serial in printable form into buf; no more than size characters will be written...
for(len=0;yy_str[len];++len)
char * buf
int i
if(yy_accept[yy_current_state])
yy_size_t n
int len
mbedtls_md_type_t
Supported message digests.
Definition: md.h:62
@ MBEDTLS_MD_SHA1
The SHA-1 message digest.
Definition: md.h:67
const char * mbedtls_md_get_name(const mbedtls_md_info_t *md_info)
This function extracts the message-digest name from the message-digest information structure.
const mbedtls_md_info_t * mbedtls_md_info_from_type(mbedtls_md_type_t md_type)
This function returns the message-digest information associated with the given digest type.
const struct ncbi::grid::netcache::search::fields::SIZE size
EIPRangeType t
Definition: ncbi_localip.c:101
const char * tag
#define mbedtls_oid_get_sig_alg
#define mbedtls_x509_get_rsassa_pss_params
#define mbedtls_platform_gmtime_r
#define mbedtls_oid_get_sig_alg_desc
#define mbedtls_snprintf
#define mbedtls_x509_crt_init
#define mbedtls_x509_crt_free
#define mbedtls_x509_crt_parse
#define mbedtls_x509_crt_verify
#define mbedtls_oid_get_md_alg
Object Identifier (OID) database.
int mbedtls_oid_get_attr_short_name(const mbedtls_asn1_buf *oid, const char **short_name)
Translate an X.509 attribute type OID into the short name (e.g.
#define MBEDTLS_OID_MGF1
id-mgf1 ::= { pkcs-1 8 }
Definition: oid.h:253
#define MBEDTLS_ERR_OID_NOT_FOUND
OID is not found.
Definition: oid.h:45
Privacy Enhanced Mail (PEM) decoding.
mbedtls_pk_type_t
Public key types.
Definition: pk.h:95
@ MBEDTLS_PK_RSASSA_PSS
Definition: pk.h:102
This file contains the definitions and functions of the Mbed TLS platform abstraction layer.
#define mbedtls_free
Definition: platform.h:168
#define mbedtls_calloc
Definition: platform.h:169
#define mbedtls_printf
Definition: platform.h:219
mbed TLS Platform time abstraction
#define mbedtls_time
Definition: platform_time.h:64
time_t mbedtls_time_t
Definition: platform_time.h:43
Common and shared functions used by multiple modules in the Mbed TLS library.
void mbedtls_platform_zeroize(void *buf, size_t len)
Securely zeroize a buffer.
true_type verbose
Definition: processing.cpp:889
Error to string translation.
#define MBEDTLS_ERROR_ADD(high, low)
Combines a high-level and low-level error code together.
Definition: error.h:130
#define MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED
This is a bug in the library.
Definition: error.h:122
unsigned int uint32_t
Definition: stdint.h:126
Type-length-value structure that allows for ASN1 using DER.
Definition: asn1.h:155
size_t len
ASN1 length, in octets.
Definition: asn1.h:157
unsigned char * p
ASN1 data, e.g.
Definition: asn1.h:158
int tag
ASN1 type, e.g.
Definition: asn1.h:156
Container for a sequence or list of 'named' ASN.1 data items.
Definition: asn1.h:184
mbedtls_asn1_buf oid
The object identifier.
Definition: asn1.h:185
struct mbedtls_asn1_named_data * next
The next entry in the sequence.
Definition: asn1.h:187
mbedtls_asn1_buf val
The named value.
Definition: asn1.h:186
unsigned char next_merged
Merge next item into the current one?
Definition: asn1.h:188
Message digest information.
Definition: md_internal.h:45
Options for RSASSA-PSS signature verification.
Definition: pk.h:110
mbedtls_md_type_t mgf1_hash_id
Definition: pk.h:111
Container for an X.509 certificate.
Definition: x509_crt.h:52
Container for date and time (precision in seconds).
Definition: x509.h:250
int day
Date.
Definition: x509.h:251
int sec
Time.
Definition: x509.h:252
static int x509_get_attr_type_value(unsigned char **p, const unsigned char *end, mbedtls_x509_name *cur)
Definition: x509.c:367
static int x509_date_is_valid(const mbedtls_x509_time *t)
Definition: x509.c:553
static int x509_parse_int(unsigned char **p, size_t n, int *res)
Definition: x509.c:537
static int x509_get_hash_alg(const mbedtls_x509_buf *alg, mbedtls_md_type_t *md_alg)
Definition: x509.c:140
static int x509_get_current_time(mbedtls_x509_time *now)
Definition: x509.c:970
static int x509_check_time(const mbedtls_x509_time *before, const mbedtls_x509_time *after)
Definition: x509.c:996
#define CHECK(code)
Definition: x509.c:56
#define CHECK_RANGE(min, max, val)
Definition: x509.c:57
static int x509_parse_time(unsigned char **p, size_t len, size_t yearlen, mbedtls_x509_time *tm)
Definition: x509.c:590
X.509 generic defines and structures.
int mbedtls_x509_get_name(unsigned char **p, const unsigned char *end, mbedtls_x509_name *cur)
int mbedtls_x509_get_alg_null(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *alg)
#define MBEDTLS_X509_SAFE_SNPRINTF
Definition: x509.h:366
int mbedtls_x509_get_sig_alg(const mbedtls_x509_buf *sig_oid, const mbedtls_x509_buf *sig_params, mbedtls_md_type_t *md_alg, mbedtls_pk_type_t *pk_alg, void **sig_opts)
int mbedtls_x509_get_alg(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *alg, mbedtls_x509_buf *params)
int mbedtls_x509_get_ext(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *ext, int tag)
int mbedtls_x509_key_size_helper(char *buf, size_t buf_size, const char *name)
int mbedtls_x509_sig_alg_gets(char *buf, size_t size, const mbedtls_x509_buf *sig_oid, mbedtls_pk_type_t pk_alg, mbedtls_md_type_t md_alg, const void *sig_opts)
int mbedtls_x509_get_serial(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *serial)
int mbedtls_x509_get_sig(unsigned char **p, const unsigned char *end, mbedtls_x509_buf *sig)
int mbedtls_x509_get_time(unsigned char **p, const unsigned char *end, mbedtls_x509_time *t)
#define MBEDTLS_X509_MAX_DN_NAME_SIZE
Maximum value size of a DN entry.
Definition: x509.h:213
X.509 certificate parsing and writing.
Modified on Sat Dec 09 04:46:59 2023 by modify_doxy.py rev. 669887