x509_cert_create.c
Go to the documentation of this file.
1 /**
2  * @file x509_cert_create.c
3  * @brief X.509 certificate generation
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCrypto Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "pkix/x509_cert_create.h"
37 #include "pkix/x509_key_format.h"
38 #include "encoding/asn1.h"
39 #include "encoding/oid.h"
40 #include "pkc/rsa.h"
41 #include "pkc/dsa.h"
42 #include "ecc/ecdsa.h"
43 #include "ecc/eddsa.h"
44 #include "ecc/ed25519.h"
45 #include "ecc/ed448.h"
46 #include "hash/sha1.h"
47 #include "debug.h"
48 
49 //Check crypto library configuration
50 #if (X509_SUPPORT == ENABLED)
51 
52 
53 /**
54  * @brief Generate a X.509 certificate
55  * @param[in] prngAlgo PRNG algorithm
56  * @param[in] prngContext Pointer to the PRNG context
57  * @param[in] certReqInfo Certificate request information
58  * @param[in] subjectPublicKey Subject's public key (optional parameter)
59  * @param[in] issuerCertInfo Issuer's certificate (optional parameter)
60  * @param[in] serialNumber Serial number (optional parameter)
61  * @param[in] validity Validity period
62  * @param[in] signatureAlgo Signature algorithm
63  * @param[in] signerPrivateKey Pointer to the issuer's private key
64  * @param[out] output Buffer where to store the X.509 certificate
65  * @param[out] written Length of the resulting X.509 certificate
66  * @return Error code
67  **/
68 
69 error_t x509CreateCertificate(const PrngAlgo *prngAlgo, void *prngContext,
70  const X509CertRequestInfo *certReqInfo, const void *subjectPublicKey,
71  const X509CertificateInfo *issuerCertInfo, const X509SerialNumber *serialNumber,
72  const X509Validity *validity, const X509SignatureAlgoId *signatureAlgo,
73  const void *signerPrivateKey, uint8_t *output, size_t *written)
74 {
75  error_t error;
76  size_t n;
77  size_t length;
78  uint8_t *p;
79  uint8_t *tbsCert;
80  size_t tbsCertLen;
81  const X509Name *issuer;
82  const X509SubjectPublicKeyInfo *publicKeyInfo;
83  X509AuthorityKeyId authKeyId;
84  Asn1Tag tag;
85 
86  //Check parameters
87  if(certReqInfo == NULL || validity == NULL || signatureAlgo == NULL ||
88  signerPrivateKey == NULL || written == NULL)
89  {
91  }
92 
93  //Point to the buffer where to write the certificate
94  p = output;
95  //Length of the certificate
96  length = 0;
97 
98  //Self-signed certificate?
99  if(issuerCertInfo == NULL)
100  {
101  //Self-issued certificates are CA certificates in which the issuer
102  //and subject are the same entity
103  issuer = &certReqInfo->subject;
104 
105  //Where a CA distributes its public key in the form of a self-signed
106  //certificate, the authority key identifier may be omitted
107  authKeyId = certReqInfo->attributes.extensionReq.authKeyId;
108 
109  //Point to the subject's public key
110  publicKeyInfo = &certReqInfo->subjectPublicKeyInfo;
111  }
112  else
113  {
114  //Check issuer's certificate version
115  if(issuerCertInfo->tbsCert.version >= X509_VERSION_3)
116  {
117  const X509Extensions *extensions;
118 
119  //Point to the extensions of the issuer's certificate
120  extensions = &issuerCertInfo->tbsCert.extensions;
121 
122  //Make sure the cA boolean is asserted
123  if(!extensions->basicConstraints.cA)
124  return ERROR_BAD_CERTIFICATE;
125 
126  //Check if the KeyUsage extension is present
127  if(extensions->keyUsage.bitmap != 0)
128  {
129  //Make sure the keyCertSign is asserted
130  if((extensions->keyUsage.bitmap & X509_KEY_USAGE_KEY_CERT_SIGN) == 0)
131  return ERROR_BAD_CERTIFICATE;
132  }
133  }
134 
135  //The issuer field identifies the entity that has signed and issued
136  //the certificate
137  issuer = &issuerCertInfo->tbsCert.subject;
138 
139  //The KeyIdentifier field of the AuthorityKeyIdentifier extension must
140  //be included in all certificates generated by conforming CAs to
141  //facilitate certification path construction
142  authKeyId.critical = FALSE;
143  authKeyId.keyId = issuerCertInfo->tbsCert.extensions.subjectKeyId.value;
144  authKeyId.keyIdLen = issuerCertInfo->tbsCert.extensions.subjectKeyId.length;
145 
146  //Point to the issuer's public key
147  publicKeyInfo = &issuerCertInfo->tbsCert.subjectPublicKeyInfo;
148  }
149 
150  //Format TBSCertificate structure
151  error = x509FormatTbsCertificate(prngAlgo, prngContext, serialNumber,
152  signatureAlgo, issuer, validity, &certReqInfo->subject,
153  &certReqInfo->subjectPublicKeyInfo, subjectPublicKey,
154  &certReqInfo->attributes.extensionReq, &authKeyId, p, &n);
155  //Any error to report?
156  if(error)
157  return error;
158 
159  //The ASN.1 DER-encoded TBSCertificate is used as the input to the
160  //signature function
161  tbsCert = p;
162  tbsCertLen = n;
163 
164  //Advance data pointer
165  p += n;
166  length += n;
167 
168  //Format SignatureAlgorithm structure
169  error = x509FormatSignatureAlgo(signatureAlgo, p, &n);
170  //Any error to report?
171  if(error)
172  return error;
173 
174  //Advance data pointer
175  p += n;
176  length += n;
177 
178  //Format SignatureValue structure
179  error = x509FormatSignatureValue(prngAlgo, prngContext, tbsCert,
180  tbsCertLen, signatureAlgo, publicKeyInfo, signerPrivateKey, p, &n);
181  //Any error to report?
182  if(error)
183  return error;
184 
185  //Advance data pointer
186  p += n;
187  length += n;
188 
189  //The certificate is encapsulated within a sequence
190  tag.constructed = TRUE;
193  tag.length = length;
194  tag.value = output;
195 
196  //Write the corresponding ASN.1 tag
197  error = asn1WriteTag(&tag, FALSE, output, &n);
198  //Any error to report?
199  if(error)
200  return error;
201 
202  //Total number of bytes that have been written
203  *written = n;
204 
205  //Successful processing
206  return NO_ERROR;
207 }
208 
209 
210 /**
211  * @brief Format TBSCertificate structure
212  * @param[in] prngAlgo PRNG algorithm
213  * @param[in] prngContext Pointer to the PRNG context
214  * @param[in] serialNumber Serial number
215  * @param[in] signatureAlgo Signature algorithm
216  * @param[in] issuer Issuer's name
217  * @param[in] validity Validity period
218  * @param[in] subject Subject's name
219  * @param[in] subjectPublicKeyInfo Subject's public key information
220  * @param[in] publicKey Subject's public key
221  * @param[in] extensions X.509 certificates extensions
222  * @param[in] authKeyId AuthorityKeyIdentifier extension
223  * @param[out] output Buffer where to format the ASN.1 structure
224  * @param[out] written Length of the resulting ASN.1 structure
225  * @return Error code
226  **/
227 
228 error_t x509FormatTbsCertificate(const PrngAlgo *prngAlgo, void *prngContext,
229  const X509SerialNumber *serialNumber, const X509SignatureAlgoId *signatureAlgo,
230  const X509Name *issuer, const X509Validity *validity, const X509Name *subject,
231  const X509SubjectPublicKeyInfo *subjectPublicKeyInfo, const void *publicKey,
232  const X509Extensions *extensions, const X509AuthorityKeyId *authKeyId,
233  uint8_t *output, size_t *written)
234 {
235  error_t error;
236  size_t n;
237  size_t length;
238  uint8_t *p;
239  Asn1Tag tag;
240  X509SubjectKeyId subjectKeyId;
241  uint8_t digest[SHA1_DIGEST_SIZE];
242 
243  //Point to the buffer where to write the ASN.1 structure
244  p = output;
245  //Length of the ASN.1 structure
246  length = 0;
247 
248  //Format Version field
249  error = x509FormatVersion(X509_VERSION_3, p, &n);
250  //Any error to report?
251  if(error)
252  return error;
253 
254  //Advance data pointer
255  p += n;
256  length += n;
257 
258  //Format SerialNumber field
259  error = x509FormatSerialNumber(prngAlgo, prngContext, serialNumber, p, &n);
260  //Any error to report?
261  if(error)
262  return error;
263 
264  //Advance data pointer
265  p += n;
266  length += n;
267 
268  //Format Signature field
269  error = x509FormatSignatureAlgo(signatureAlgo, p, &n);
270  //Any error to report?
271  if(error)
272  return error;
273 
274  //Advance data pointer
275  p += n;
276  length += n;
277 
278  //Format Issuer field
279  error = x509FormatName(issuer, p, &n);
280  //Any error to report?
281  if(error)
282  return error;
283 
284  //Advance data pointer
285  p += n;
286  length += n;
287 
288  //Format Validity field
289  error = x509FormatValidity(validity, p, &n);
290  //Any error to report?
291  if(error)
292  return error;
293 
294  //Advance data pointer
295  p += n;
296  length += n;
297 
298  //Format Subject field
299  error = x509FormatName(subject, p, &n);
300  //Any error to report?
301  if(error)
302  return error;
303 
304  //Advance data pointer
305  p += n;
306  length += n;
307 
308  //Format SubjectPublicKeyInfo field
309  error = x509FormatSubjectPublicKeyInfo(subjectPublicKeyInfo, publicKey,
310  digest, p, &n);
311  //Any error to report?
312  if(error)
313  return error;
314 
315  //Advance data pointer
316  p += n;
317  length += n;
318 
319  //The SubjectKeyIdentifier extension provides a means of identifying
320  //certificates that contain a particular public key
321  subjectKeyId.critical = FALSE;
322  subjectKeyId.value = digest;
323  subjectKeyId.length = SHA1_DIGEST_SIZE;
324 
325  //The Extensions field must only appear if the version is 3
326  error = x509FormatExtensions(extensions, &subjectKeyId, authKeyId, p, &n);
327  //Any error to report?
328  if(error)
329  return error;
330 
331  //Advance data pointer
332  p += n;
333  length += n;
334 
335  //The TBSCertificate structure is encapsulated within a sequence
336  tag.constructed = TRUE;
339  tag.length = length;
340  tag.value = output;
341 
342  //Write the corresponding ASN.1 tag
343  error = asn1WriteTag(&tag, FALSE, output, &n);
344  //Any error to report?
345  if(error)
346  return error;
347 
348  //Total number of bytes that have been written
349  *written = n;
350 
351  //Successful processing
352  return NO_ERROR;
353 }
354 
355 
356 /**
357  * @brief Format Version field
358  * @param[in] version Version number
359  * @param[out] output Buffer where to format the ASN.1 structure
360  * @param[out] written Length of the resulting ASN.1 structure
361  * @return Error code
362  **/
363 
365  size_t *written)
366 {
367  error_t error;
368  size_t n;
369  Asn1Tag tag;
370 
371  //Encode the version number
372  error = asn1WriteInt32(version, FALSE, output, &n);
373  //Any error to report?
374  if(error)
375  return error;
376 
377  //Explicit tagging shall be used to encode version
378  tag.constructed = TRUE;
380  tag.objType = 0;
381  tag.length = n;
382  tag.value = output;
383 
384  //Write the corresponding ASN.1 tag
385  error = asn1WriteTag(&tag, FALSE, output, &n);
386  //Any error to report?
387  if(error)
388  return error;
389 
390  //Total number of bytes that have been written
391  *written = n;
392 
393  //Successful processing
394  return NO_ERROR;
395 }
396 
397 
398 /**
399  * @brief Format SerialNumber field
400  * @param[in] prngAlgo PRNG algorithm
401  * @param[in] prngContext Pointer to the PRNG context
402  * @param[in] serialNumber Pointer to the serial number (optional parameter)
403  * @param[out] output Buffer where to format the ASN.1 structure
404  * @param[out] written Length of the resulting ASN.1 structure
405  * @return Error code
406  **/
407 
408 error_t x509FormatSerialNumber(const PrngAlgo *prngAlgo, void *prngContext,
409  const X509SerialNumber *serialNumber, uint8_t *output, size_t *written)
410 {
411  error_t error;
412  size_t n;
413  Asn1Tag tag;
414 
415  //Valid serial number?
416  if(serialNumber != NULL)
417  {
418  //The serial number is a unique integer assigned by the CA to each
419  //certificate
420  tag.constructed = FALSE;
423  tag.length = serialNumber->length;
424  tag.value = serialNumber->data;
425  }
426  else
427  {
428  //Conforming CAs must not use serial number values longer than 20 octets
429  error = prngAlgo->read(prngContext, output, X509_SERIAL_NUMBER_SIZE);
430  //Any error to report?
431  if(error)
432  return error;
433 
434  //CAs must force the serial number to be a non-negative integer
435  output[0] = (output[0] & 0x3F) | 0x40;
436 
437  //The serial number is a unique integer assigned by the CA to each
438  //certificate
439  tag.constructed = FALSE;
443  tag.value = output;
444  }
445 
446  //Write the corresponding ASN.1 tag
447  error = asn1WriteTag(&tag, FALSE, output, &n);
448  //Any error to report?
449  if(error)
450  return error;
451 
452  //Total number of bytes that have been written
453  *written = n;
454 
455  //Successful processing
456  return NO_ERROR;
457 }
458 
459 
460 /**
461  * @brief Format Name structure
462  * @param[in] name Information about the name to be encoded
463  * @param[out] output Buffer where to format the ASN.1 structure
464  * @param[out] written Length of the resulting ASN.1 structure
465  * @return Error code
466  **/
467 
468 error_t x509FormatName(const X509Name *name, uint8_t *output,
469  size_t *written)
470 {
471  error_t error;
472  size_t n;
473  size_t length;
474  uint8_t *p;
475  Asn1Tag tag;
476 
477  //Initialize status code
478  error = NO_ERROR;
479 
480  //Raw ASN.1 sequence?
481  if(name->rawData != NULL && name->rawDataLen > 0)
482  {
483  //Copy raw ASN.1 sequence
484  cryptoMemcpy(output, name->rawData, name->rawDataLen);
485  //Total number of bytes that have been written
486  *written = name->rawDataLen;
487  }
488  else
489  {
490  //Point to the buffer where to write the Name structure
491  p = output;
492  //Length of the Name structure
493  length = 0;
494 
495  //Valid Country Name attribute?
496  if(name->countryName != NULL && name->countryNameLen > 0)
497  {
498  //Encode Country Name attribute
501  name->countryName, name->countryNameLen, p, &n);
502  //Any error to report?
503  if(error)
504  return error;
505 
506  //Advance data pointer
507  p += n;
508  length += n;
509  }
510 
511  //Valid State Or Province Name attribute?
512  if(name->stateOrProvinceName != NULL && name->stateOrProvinceNameLen > 0)
513  {
514  //Encode State Or Province Name attribute
517  name->stateOrProvinceName, name->stateOrProvinceNameLen, p, &n);
518  //Any error to report?
519  if(error)
520  return error;
521 
522  //Advance data pointer
523  p += n;
524  length += n;
525  }
526 
527  //Valid Locality Name attribute?
528  if(name->localityName != NULL && name->localityNameLen > 0)
529  {
530  //Encode Locality Name attribute
533  name->localityName, name->localityNameLen, p, &n);
534  //Any error to report?
535  if(error)
536  return error;
537 
538  //Advance data pointer
539  p += n;
540  length += n;
541  }
542 
543  //Valid Organization Name attribute?
544  if(name->organizationName != NULL && name->organizationNameLen > 0)
545  {
546  //Encode Organization Name attribute
549  name->organizationName, name->organizationNameLen, p, &n);
550  //Any error to report?
551  if(error)
552  return error;
553 
554  //Advance data pointer
555  p += n;
556  length += n;
557  }
558 
559  //Valid Organizational Unit Name attribute?
560  if(name->organizationalUnitName != NULL && name->organizationalUnitNameLen > 0)
561  {
562  //Encode Organizational Unit Name attribute
565  name->organizationalUnitName, name->organizationalUnitNameLen, p, &n);
566  //Any error to report?
567  if(error)
568  return error;
569 
570  //Advance data pointer
571  p += n;
572  length += n;
573  }
574 
575  //Valid Common Name attribute?
576  if(name->commonName != NULL && name->commonNameLen > 0)
577  {
578  //Encode Common Name attribute
581  name->commonName, name->commonNameLen, p, &n);
582  //Any error to report?
583  if(error)
584  return error;
585 
586  //Advance data pointer
587  p += n;
588  length += n;
589  }
590 
591  //The Name structure is encapsulated within a sequence
592  tag.constructed = TRUE;
595  tag.length = length;
596  tag.value = output;
597 
598  //Write the corresponding ASN.1 tag
599  error = asn1WriteTag(&tag, FALSE, output, &n);
600  //Any error to report?
601  if(error)
602  return error;
603 
604  //Total number of bytes that have been written
605  *written = n;
606  }
607 
608  //Successful processing
609  return NO_ERROR;
610 }
611 
612 
613 /**
614  * @brief Format Name attribute
615  * @param[in] type ASN.1 string type
616  * @param[in] oid Attribute OID
617  * @param[in] oidLen Length of the attribute OID, in bytes
618  * @param[in] value Attribute value
619  * @param[in] valueLen Length of the attribute value, in bytes
620  * @param[out] output Buffer where to format the ASN.1 structure
621  * @param[out] written Length of the resulting ASN.1 structure
622  * @return Error code
623  **/
624 
625 error_t x509FormatNameAttribute(uint_t type, const uint8_t *oid, size_t oidLen,
626  const char_t *value, size_t valueLen, uint8_t *output, size_t *written)
627 {
628  error_t error;
629  size_t n;
630  size_t length;
631  uint8_t *p;
632  Asn1Tag tag;
633 
634  //Point to the buffer where to write the ASN.1 structure
635  p = output;
636  //Length of the ASN.1 structure
637  length = 0;
638 
639  //Format AttributeType field
640  tag.constructed = FALSE;
643  tag.length = oidLen;
644  tag.value = oid;
645 
646  //Write the corresponding ASN.1 tag
647  error = asn1WriteTag(&tag, FALSE, p, &n);
648  //Any error to report?
649  if(error)
650  return error;
651 
652  //Advance data pointer
653  p += n;
654  length += n;
655 
656  //Format AttributeValue field
657  tag.constructed = FALSE;
659  tag.objType = type;
660  tag.length = valueLen;
661  tag.value = (uint8_t *) value;
662 
663  //Write the corresponding ASN.1 tag
664  error = asn1WriteTag(&tag, FALSE, p, &n);
665  //Any error to report?
666  if(error)
667  return error;
668 
669  //Advance data pointer
670  p += n;
671  length += n;
672 
673  //The attribute type and value are encapsulated within a sequence
674  tag.constructed = TRUE;
677  tag.length = length;
678  tag.value = output;
679 
680  //Write the corresponding ASN.1 tag
681  error = asn1WriteTag(&tag, FALSE, output, &n);
682  //Any error to report?
683  if(error)
684  return error;
685 
686  //The sequence is encapsulated within a set
687  tag.constructed = TRUE;
689  tag.objType = ASN1_TYPE_SET;
690  tag.length = n;
691  tag.value = output;
692 
693  //Write the corresponding ASN.1 tag
694  error = asn1WriteTag(&tag, FALSE, output, &n);
695  //Any error to report?
696  if(error)
697  return error;
698 
699  //Total number of bytes that have been written
700  *written = n;
701 
702  //Successful processing
703  return NO_ERROR;
704 }
705 
706 
707 /**
708  * @brief Format Validity structure
709  * @param[in] validity Validity period
710  * @param[out] output Buffer where to format the ASN.1 structure
711  * @param[out] written Length of the resulting ASN.1 structure
712  * @return Error code
713  **/
714 
715 error_t x509FormatValidity(const X509Validity *validity, uint8_t *output,
716  size_t *written)
717 {
718  error_t error;
719  size_t n;
720  size_t length;
721  uint8_t *p;
722  Asn1Tag tag;
723 
724  //Point to the buffer where to write the ASN.1 structure
725  p = output;
726  //Length of the ASN.1 structure
727  length = 0;
728 
729  //The NotBefore field may be encoded as UTCTime or GeneralizedTime
730  error = x509FormatTime(&validity->notBefore, p, &n);
731  //Any error to report?
732  if(error)
733  return error;
734 
735  //Advance data pointer
736  p += n;
737  length += n;
738 
739  //The NotAfter field may be encoded as UTCTime or GeneralizedTime
740  error = x509FormatTime(&validity->notAfter, p, &n);
741  //Any error to report?
742  if(error)
743  return error;
744 
745  //Advance data pointer
746  p += n;
747  length += n;
748 
749  //The Validity structure is encapsulated within a sequence
750  tag.constructed = TRUE;
753  tag.length = length;
754  tag.value = output;
755 
756  //Write the corresponding ASN.1 tag
757  error = asn1WriteTag(&tag, FALSE, output, &n);
758  //Any error to report?
759  if(error)
760  return error;
761 
762  //Total number of bytes that have been written
763  *written = n;
764 
765  //Successful processing
766  return NO_ERROR;
767 }
768 
769 
770 /**
771  * @brief Format UTCTime or GeneralizedTime field
772  * @param[in] dateTime Date to be encoded
773  * @param[out] output Buffer where to format the ASN.1 structure
774  * @param[out] written Length of the resulting ASN.1 structure
775  * @return Error code
776  **/
777 
778 error_t x509FormatTime(const DateTime *dateTime, uint8_t *output,
779  size_t *written)
780 {
781  error_t error;
782  uint_t type;
783  size_t n;
784  Asn1Tag tag;
785  char_t buffer[16];
786 
787  //UTCTime is limited to the period from 1950 to 2049
788  if(dateTime->year >= 1950 && dateTime->year <= 2049)
789  {
790  //Use UTCTime format
792 
793  //The UTCTime uses a 2-digit representation of the year. If YY is greater
794  //than or equal to 50, the year shall be interpreted as 19YY. If YY is
795  //less than 50, the year shall be interpreted as 20YY
796  sprintf(buffer, "%02" PRIu16 "%02" PRIu8 "%02" PRIu8
797  "%02" PRIu8 "%02" PRIu8 "%02" PRIu8 "Z",
798  dateTime->year % 100, dateTime->month, dateTime->day,
799  dateTime->hours, dateTime->minutes, dateTime->seconds);
800  }
801  else
802  {
803  //Use GeneralizedTime format
805 
806  //The GeneralizedTime uses a 4-digit representation of the year
807  sprintf(buffer, "%04" PRIu16 "%02" PRIu8 "%02" PRIu8
808  "%02" PRIu8 "%02" PRIu8 "%02" PRIu8 "Z",
809  dateTime->year, dateTime->month, dateTime->day,
810  dateTime->hours, dateTime->minutes, dateTime->seconds);
811  }
812 
813  //The date may be encoded as UTCTime or GeneralizedTime
814  tag.constructed = FALSE;
816  tag.objType = type;
817  tag.length = cryptoStrlen(buffer);
818  tag.value = (uint8_t *) buffer;
819 
820  //Write the corresponding ASN.1 tag
821  error = asn1WriteTag(&tag, FALSE, output, &n);
822  //Any error to report?
823  if(error)
824  return error;
825 
826  //Total number of bytes that have been written
827  *written = n;
828 
829  //Successful processing
830  return NO_ERROR;
831 }
832 
833 
834 /**
835  * @brief Format Extensions structure
836  * @param[in] extensions Pointer to the X.509 extensions
837  * @param[in] subjectKeyId SubjectKeyIdentifier extension
838  * @param[in] authKeyId AuthorityKeyIdentifier extension
839  * @param[out] output Buffer where to format the ASN.1 structure
840  * @param[out] written Length of the resulting ASN.1 structure
841  * @return Error code
842  **/
843 
845  const X509SubjectKeyId *subjectKeyId, const X509AuthorityKeyId *authKeyId,
846  uint8_t *output, size_t *written)
847 {
848  error_t error;
849  size_t n;
850  size_t length;
851  uint8_t *p;
852  Asn1Tag tag;
853 
854  //Point to the buffer where to write the ASN.1 structure
855  p = output;
856  //Length of the ASN.1 structure
857  length = 0;
858 
859  //Format NetscapeCertType extension
860  error = x509FormatNsCertType(&extensions->nsCertType, p, &n);
861  //Any error to report?
862  if(error)
863  return error;
864 
865  //Advance data pointer
866  p += n;
867  length += n;
868 
869  //Format BasicConstraints extension
870  error = x509FormatBasicConstraints(&extensions->basicConstraints, p, &n);
871  //Any error to report?
872  if(error)
873  return error;
874 
875  //Advance data pointer
876  p += n;
877  length += n;
878 
879  //Format KeyUsage extension
880  error = x509FormatKeyUsage(&extensions->keyUsage, p, &n);
881  //Any error to report?
882  if(error)
883  return error;
884 
885  //Advance data pointer
886  p += n;
887  length += n;
888 
889  //Format x509ParseSubjectKeyId extension
890  error = x509FormatSubjectKeyId(subjectKeyId, p, &n);
891  //Any error to report?
892  if(error)
893  return error;
894 
895  //Advance data pointer
896  p += n;
897  length += n;
898 
899  //Format AuthorityKeyId extension
900  error = x509FormatAuthorityKeyId(authKeyId, p, &n);
901  //Any error to report?
902  if(error)
903  return error;
904 
905  //Advance data pointer
906  p += n;
907  length += n;
908 
909  //Format SubjectAltName extension
910  error = x509FormatSubjectAltName(&extensions->subjectAltName, p, &n);
911  //Any error to report?
912  if(error)
913  return error;
914 
915  //Advance data pointer
916  p += n;
917  length += n;
918 
919  //Any extensions written?
920  if(length > 0)
921  {
922  //The extensions are encapsulated within a sequence
923  tag.constructed = TRUE;
926  tag.length = length;
927  tag.value = output;
928 
929  //Write the corresponding ASN.1 tag
930  error = asn1WriteTag(&tag, FALSE, output, &n);
931  //Any error to report?
932  if(error)
933  return error;
934 
935  //Explicit tagging shall be used to encode the Extensions structure
936  tag.constructed = TRUE;
938  tag.objType = 3;
939  tag.length = n;
940  tag.value = output;
941 
942  //Write the corresponding ASN.1 tag
943  error = asn1WriteTag(&tag, FALSE, output, &length);
944  //Any error to report?
945  if(error)
946  return error;
947  }
948 
949  //Total number of bytes that have been written
950  *written = length;
951 
952  //Successful processing
953  return NO_ERROR;
954 }
955 
956 
957 /**
958  * @brief Format BasicConstraints extension
959  * @param[in] basicConstraints Value of the extension
960  * @param[out] output Buffer where to format the ASN.1 structure
961  * @param[out] written Length of the resulting ASN.1 structure
962  * @return Error code
963  **/
964 
966  uint8_t *output, size_t *written)
967 {
968  error_t error;
969  uint32_t value;
970  size_t n;
971  size_t length;
972  uint8_t *p;
973  Asn1Tag tag;
974  uint8_t buffer[3];
975 
976  //Point to the buffer where to write the ASN.1 structure
977  p = output;
978  //Length of the ASN.1 structure
979  length = 0;
980 
981  //The basic constraints extension identifies whether the subject of the
982  //certificate is a CA and the maximum depth of valid certification paths
983  //that include this certificate
984  if(basicConstraints->cA || basicConstraints->critical)
985  {
986  //Format the extension identifier
987  tag.constructed = FALSE;
990  tag.length = sizeof(X509_BASIC_CONSTRAINTS_OID);
992 
993  //Write the corresponding ASN.1 tag
994  error = asn1WriteTag(&tag, FALSE, p, &n);
995  //Any error to report?
996  if(error)
997  return error;
998 
999  //Advance data pointer
1000  p += n;
1001  length += n;
1002 
1003  //An extension includes the critical flag, with a default value of FALSE
1004  if(basicConstraints->critical)
1005  {
1006  //Mark the extension as critical
1007  buffer[0] = 0xFF;
1008 
1009  //Format the critical field
1010  tag.constructed = FALSE;
1012  tag.objType = ASN1_TYPE_BOOLEAN;
1013  tag.length = 1;
1014  tag.value = buffer;
1015 
1016  //Write the corresponding ASN.1 tag
1017  error = asn1WriteTag(&tag, FALSE, p, &n);
1018  //Any error to report?
1019  if(error)
1020  return error;
1021 
1022  //Advance data pointer
1023  p += n;
1024  length += n;
1025  }
1026 
1027  //Total number of bytes that have been written
1028  *written = length;
1029 
1030  //Length of the extension value
1031  length = 0;
1032 
1033  //Check whether the cA boolean is set
1034  if(basicConstraints->cA)
1035  {
1036  //The cA boolean indicates whether the certified public key may be used
1037  //to verify certificate signatures
1038  buffer[0] = 0xFF;
1039 
1040  //Format the cA field
1041  tag.constructed = FALSE;
1043  tag.objType = ASN1_TYPE_BOOLEAN;
1044  tag.length = 1;
1045  tag.value = buffer;
1046 
1047  //Write the corresponding ASN.1 tag
1048  error = asn1WriteTag(&tag, FALSE, p, &length);
1049  //Any error to report?
1050  if(error)
1051  return error;
1052 
1053  //Where pathLenConstraint does not appear, no limit is imposed
1054  if(basicConstraints->pathLenConstraint >= 0)
1055  {
1056  //The pathLenConstraint field gives the maximum number of non-self-issued
1057  //intermediate certificates that may follow this certificate in a valid
1058  //certification path
1059  value = basicConstraints->pathLenConstraint;
1060 
1061  //Encode pathLenConstraint value
1062  error = asn1WriteInt32(value, FALSE, p + length, &n);
1063 
1064  //Update the length of the extension value
1065  length += n;
1066  }
1067  }
1068 
1069  //The BasicConstraints extension is encapsulated within a sequence
1070  tag.constructed = TRUE;
1073  tag.length = length;
1074  tag.value = p;
1075 
1076  //Write the corresponding ASN.1 tag
1077  error = asn1WriteTag(&tag, FALSE, p, &n);
1078  //Any error to report?
1079  if(error)
1080  return error;
1081 
1082  //The extension value is encapsulated in an octet string
1083  tag.constructed = FALSE;
1086  tag.length = n;
1087  tag.value = p;
1088 
1089  //Write the corresponding ASN.1 tag
1090  error = asn1WriteTag(&tag, FALSE, output + *written, &n);
1091  //Any error to report?
1092  if(error)
1093  return error;
1094 
1095  //Adjust the length of the extension
1096  *written += n;
1097 
1098  //The extension is encapsulated within a sequence
1099  tag.constructed = TRUE;
1102  tag.length = *written;
1103  tag.value = output;
1104 
1105  //Write the corresponding ASN.1 tag
1106  error = asn1WriteTag(&tag, FALSE, output, &length);
1107  //Any error to report?
1108  if(error)
1109  return error;
1110  }
1111 
1112  //Total number of bytes that have been written
1113  *written = length;
1114 
1115  //Successful processing
1116  return NO_ERROR;
1117 }
1118 
1119 
1120 /**
1121  * @brief Format KeyUsage extension
1122  * @param[in] keyUsage Value of the extension
1123  * @param[out] output Buffer where to format the ASN.1 structure
1124  * @param[out] written Length of the resulting ASN.1 structure
1125  * @return Error code
1126  **/
1127 
1128 error_t x509FormatKeyUsage(const X509KeyUsage *keyUsage, uint8_t *output,
1129  size_t *written)
1130 {
1131  error_t error;
1132  uint_t k;
1133  size_t n;
1134  size_t length;
1135  uint8_t *p;
1136  Asn1Tag tag;
1137  uint8_t buffer[3];
1138 
1139  //Initialize status code
1140  error = NO_ERROR;
1141 
1142  //Point to the buffer where to write the ASN.1 structure
1143  p = output;
1144  //Length of the ASN.1 structure
1145  length = 0;
1146 
1147  //The key usage extension defines the purpose of the key contained in the
1148  //certificate
1149  if(keyUsage->bitmap != 0 || keyUsage->critical)
1150  {
1151  //Format the extension identifier
1152  tag.constructed = FALSE;
1155  tag.length = sizeof(X509_KEY_USAGE_OID);
1156  tag.value = X509_KEY_USAGE_OID;
1157 
1158  //Write the corresponding ASN.1 tag
1159  error = asn1WriteTag(&tag, FALSE, p, &n);
1160  //Any error to report?
1161  if(error)
1162  return error;
1163 
1164  //Advance data pointer
1165  p += n;
1166  length += n;
1167 
1168  //An extension includes the critical flag, with a default value of FALSE
1169  if(keyUsage->critical)
1170  {
1171  //Mark the extension as critical
1172  buffer[0] = 0xFF;
1173 
1174  //Format the critical field
1175  tag.constructed = FALSE;
1177  tag.objType = ASN1_TYPE_BOOLEAN;
1178  tag.length = 1;
1179  tag.value = buffer;
1180 
1181  //Write the corresponding ASN.1 tag
1182  error = asn1WriteTag(&tag, FALSE, p, &n);
1183  //Any error to report?
1184  if(error)
1185  return error;
1186 
1187  //Advance data pointer
1188  p += n;
1189  length += n;
1190  }
1191 
1192  //Calculate the length, in bits, of the KeyUsage value
1193  for(k = 16; k > 0; k--)
1194  {
1195  if(keyUsage->bitmap & (1 << (k - 1)))
1196  break;
1197  }
1198 
1199  //Total number of bytes needed to encode the KeyUsage value
1200  n = 0;
1201 
1202  //Encode bit string value
1203  if(k <= 8)
1204  {
1205  buffer[n++] = 8 - k;
1206  buffer[n++] = reverseInt8(keyUsage->bitmap & 0xFF);
1207  }
1208  else
1209  {
1210  buffer[n++] = 16 - k;
1211  buffer[n++] = reverseInt8(keyUsage->bitmap & 0xFF);
1212  buffer[n++] = reverseInt8((keyUsage->bitmap >> 8) & 0xFF);
1213  }
1214 
1215  //Format the bit string using ASN.1
1216  tag.constructed = FALSE;
1219  tag.length = n;
1220  tag.value = buffer;
1221 
1222  //Write the corresponding ASN.1 tag
1223  error = asn1WriteTag(&tag, FALSE, p, &n);
1224  //Any error to report?
1225  if(error)
1226  return error;
1227 
1228  //The extension value is encapsulated in an octet string
1229  tag.constructed = FALSE;
1232  tag.length = n;
1233  tag.value = p;
1234 
1235  //Write the corresponding ASN.1 tag
1236  error = asn1WriteTag(&tag, FALSE, p, &n);
1237  //Any error to report?
1238  if(error)
1239  return error;
1240 
1241  //Adjust the length of the extension
1242  length += n;
1243 
1244  //The extension is encapsulated within a sequence
1245  tag.constructed = TRUE;
1248  tag.length = length;
1249  tag.value = output;
1250 
1251  //Write the corresponding ASN.1 tag
1252  error = asn1WriteTag(&tag, FALSE, output, &length);
1253  //Any error to report?
1254  if(error)
1255  return error;
1256  }
1257 
1258  //Total number of bytes that have been written
1259  *written = length;
1260 
1261  //Successful processing
1262  return NO_ERROR;
1263 }
1264 
1265 
1266 /**
1267  * @brief Format SubjectAltName extension
1268  * @param[in] subjectAltName Value of the extension
1269  * @param[out] output Buffer where to format the ASN.1 structure
1270  * @param[out] written Length of the resulting ASN.1 structure
1271  * @return Error code
1272  **/
1273 
1275  uint8_t *output, size_t *written)
1276 {
1277  error_t error;
1278  uint_t i;
1279  size_t n;
1280  size_t length;
1281  uint8_t *p;
1282  Asn1Tag tag;
1283 
1284  //Initialize status code
1285  error = NO_ERROR;
1286 
1287  //Point to the buffer where to write the ASN.1 structure
1288  p = output;
1289  //Length of the ASN.1 structure
1290  length = 0;
1291 
1292  //The subject alternative name extension allows identities to be bound to the
1293  //subject of the certificate. These identities may be included in addition
1294  //to or in place of the identity in the subject field of the certificate
1295  if(subjectAltName->numGeneralNames > 0)
1296  {
1297  //Format the extension identifier
1298  tag.constructed = FALSE;
1301  tag.length = sizeof(X509_SUBJECT_ALT_NAME_OID);
1303 
1304  //Write the corresponding ASN.1 tag
1305  error = asn1WriteTag(&tag, FALSE, p, &n);
1306  //Any error to report?
1307  if(error)
1308  return error;
1309 
1310  //Advance data pointer
1311  p += n;
1312  //Total number of bytes that have been written
1313  *written = n;
1314 
1315  //Loop through subject alternative names
1316  for(i = 0; i < subjectAltName->numGeneralNames; i++)
1317  {
1318  //Format the current name
1319  tag.constructed = FALSE;
1321  tag.objType = subjectAltName->generalNames[i].type;
1322  tag.length = subjectAltName->generalNames[i].length;
1323  tag.value = (uint8_t *) subjectAltName->generalNames[i].value;
1324 
1325  //Write the corresponding ASN.1 tag
1326  error = asn1WriteTag(&tag, FALSE, p, &n);
1327  //Any error to report?
1328  if(error)
1329  return error;
1330 
1331  //Advance data pointer
1332  p += n;
1333  length += n;
1334  }
1335 
1336  //Point to the first object
1337  p = output + *written;
1338 
1339  //The names are encapsulated within a sequence
1340  tag.constructed = TRUE;
1343  tag.length = length;
1344  tag.value = p;
1345 
1346  //Write the corresponding ASN.1 tag
1347  error = asn1WriteTag(&tag, FALSE, p, &n);
1348  //Any error to report?
1349  if(error)
1350  return error;
1351 
1352  //The extension value is encapsulated in an octet string
1353  tag.constructed = FALSE;
1356  tag.length = n;
1357  tag.value = p;
1358 
1359  //Write the corresponding ASN.1 tag
1360  error = asn1WriteTag(&tag, FALSE, p, &n);
1361  //Any error to report?
1362  if(error)
1363  return error;
1364 
1365  //Adjust the length of the extension
1366  *written += n;
1367 
1368  //The extension is encapsulated within a sequence
1369  tag.constructed = TRUE;
1372  tag.length = *written;
1373  tag.value = output;
1374 
1375  //Write the corresponding ASN.1 tag
1376  error = asn1WriteTag(&tag, FALSE, output, &length);
1377  //Any error to report?
1378  if(error)
1379  return error;
1380  }
1381 
1382  //Total number of bytes that have been written
1383  *written = length;
1384 
1385  //Successful processing
1386  return NO_ERROR;
1387 }
1388 
1389 
1390 /**
1391  * @brief Format SubjectKeyIdentifier extension
1392  * @param[in] subjectKeyId Value of the extension
1393  * @param[out] output Buffer where to format the ASN.1 structure
1394  * @param[out] written Length of the resulting ASN.1 structure
1395  * @return Error code
1396  **/
1397 
1399  uint8_t *output, size_t *written)
1400 {
1401  error_t error;
1402  size_t n;
1403  size_t length;
1404  uint8_t *p;
1405  Asn1Tag tag;
1406 
1407  //Initialize status code
1408  error = NO_ERROR;
1409 
1410  //Point to the buffer where to write the ASN.1 structure
1411  p = output;
1412  //Length of the ASN.1 structure
1413  length = 0;
1414 
1415  //The subject key identifier extension provides a means of identifying
1416  //certificates that contain a particular public key
1417  if(subjectKeyId->value != NULL && subjectKeyId->length > 0)
1418  {
1419  //Format the extension identifier
1420  tag.constructed = FALSE;
1423  tag.length = sizeof(X509_SUBJECT_KEY_ID_OID);
1425 
1426  //Write the corresponding ASN.1 tag
1427  error = asn1WriteTag(&tag, FALSE, p, &n);
1428  //Any error to report?
1429  if(error)
1430  return error;
1431 
1432  //Advance data pointer
1433  p += n;
1434  length += n;
1435 
1436  //Format the KeyIdentifier field
1437  tag.constructed = FALSE;
1440  tag.length = subjectKeyId->length;
1441  tag.value = subjectKeyId->value;
1442 
1443  //Write the corresponding ASN.1 tag
1444  error = asn1WriteTag(&tag, FALSE, p, &n);
1445  //Any error to report?
1446  if(error)
1447  return error;
1448 
1449  //The extension value is encapsulated in an octet string
1450  tag.constructed = FALSE;
1453  tag.length = n;
1454  tag.value = p;
1455 
1456  //Write the corresponding ASN.1 tag
1457  error = asn1WriteTag(&tag, FALSE, p, &n);
1458  //Any error to report?
1459  if(error)
1460  return error;
1461 
1462  //Adjust the length of the extension
1463  length += n;
1464 
1465  //The extension is encapsulated within a sequence
1466  tag.constructed = TRUE;
1469  tag.length = length;
1470  tag.value = output;
1471 
1472  //Write the corresponding ASN.1 tag
1473  error = asn1WriteTag(&tag, FALSE, output, &length);
1474  //Any error to report?
1475  if(error)
1476  return error;
1477  }
1478 
1479  //Total number of bytes that have been written
1480  *written = length;
1481 
1482  //Successful processing
1483  return NO_ERROR;
1484 }
1485 
1486 
1487 /**
1488  * @brief Format AuthorityKeyIdentifier extension
1489  * @param[in] authKeyId Value of the extension
1490  * @param[out] output Buffer where to format the ASN.1 structure
1491  * @param[out] written Length of the resulting ASN.1 structure
1492  * @return Error code
1493  **/
1494 
1496  uint8_t *output, size_t *written)
1497 {
1498  error_t error;
1499  size_t n;
1500  size_t length;
1501  uint8_t *p;
1502  Asn1Tag tag;
1503 
1504  //Initialize status code
1505  error = NO_ERROR;
1506 
1507  //Point to the buffer where to write the ASN.1 structure
1508  p = output;
1509  //Length of the ASN.1 structure
1510  length = 0;
1511 
1512  //The authority key identifier extension provides a means of identifying the
1513  //public key corresponding to the private key used to sign a certificate
1514  if(authKeyId->keyId != NULL && authKeyId->keyIdLen > 0)
1515  {
1516  //Format the extension identifier
1517  tag.constructed = FALSE;
1520  tag.length = sizeof(X509_AUTHORITY_KEY_ID_OID);
1522 
1523  //Write the corresponding ASN.1 tag
1524  error = asn1WriteTag(&tag, FALSE, p, &n);
1525  //Any error to report?
1526  if(error)
1527  return error;
1528 
1529  //Advance data pointer
1530  p += n;
1531  length += n;
1532 
1533  //Explicit tagging shall be used to encode the keyIdentifier field
1534  tag.constructed = FALSE;
1536  tag.objType = 0;
1537  tag.length = authKeyId->keyIdLen;
1538  tag.value = authKeyId->keyId;
1539 
1540  //Write the corresponding ASN.1 tag
1541  error = asn1WriteTag(&tag, FALSE, p, &n);
1542  //Any error to report?
1543  if(error)
1544  return error;
1545 
1546  //The KeyIdentifier field is encapsulated within a sequence
1547  tag.constructed = TRUE;
1550  tag.length = n;
1551  tag.value = p;
1552 
1553  //Write the corresponding ASN.1 tag
1554  error = asn1WriteTag(&tag, FALSE, p, &n);
1555  //Any error to report?
1556  if(error)
1557  return error;
1558 
1559  //The extension value is encapsulated in an octet string
1560  tag.constructed = FALSE;
1563  tag.length = n;
1564  tag.value = p;
1565 
1566  //Write the corresponding ASN.1 tag
1567  error = asn1WriteTag(&tag, FALSE, p, &n);
1568  //Any error to report?
1569  if(error)
1570  return error;
1571 
1572  //Adjust the length of the extension
1573  length += n;
1574 
1575  //The extension is encapsulated within a sequence
1576  tag.constructed = TRUE;
1579  tag.length = length;
1580  tag.value = output;
1581 
1582  //Write the corresponding ASN.1 tag
1583  error = asn1WriteTag(&tag, FALSE, output, &length);
1584  //Any error to report?
1585  if(error)
1586  return error;
1587  }
1588 
1589  //Total number of bytes that have been written
1590  *written = length;
1591 
1592  //Successful processing
1593  return NO_ERROR;
1594 }
1595 
1596 
1597 /**
1598  * @brief Format NetscapeCertType extension
1599  * @param[in] nsCertType Value of the extension
1600  * @param[out] output Buffer where to format the ASN.1 structure
1601  * @param[out] written Length of the resulting ASN.1 structure
1602  * @return Error code
1603  **/
1604 
1606  uint8_t *output, size_t *written)
1607 {
1608  error_t error;
1609  uint_t k;
1610  size_t n;
1611  size_t length;
1612  uint8_t *p;
1613  Asn1Tag tag;
1614  uint8_t buffer[2];
1615 
1616  //Initialize status code
1617  error = NO_ERROR;
1618 
1619  //Point to the buffer where to write the ASN.1 structure
1620  p = output;
1621  //Length of the ASN.1 structure
1622  length = 0;
1623 
1624  //The NetscapeCertType extension limit the use of a certificate
1625  if(nsCertType->bitmap != 0)
1626  {
1627  //Format the extension identifier
1628  tag.constructed = FALSE;
1631  tag.length = sizeof(X509_NS_CERT_TYPE_OID);
1633 
1634  //Write the corresponding ASN.1 tag
1635  error = asn1WriteTag(&tag, FALSE, p, &n);
1636  //Any error to report?
1637  if(error)
1638  return error;
1639 
1640  //Advance data pointer
1641  p += n;
1642  length += n;
1643 
1644  //Calculate the length, in bits, of the NetscapeCertType value
1645  for(k = 8; k > 0; k--)
1646  {
1647  if(nsCertType->bitmap & (1 << (k - 1)))
1648  break;
1649  }
1650 
1651  //Encode bit string value
1652  buffer[0] = 8 - k;
1653  buffer[1] = reverseInt8(nsCertType->bitmap);
1654 
1655  //Format the bit string using ASN.1
1656  tag.constructed = FALSE;
1659  tag.length = sizeof(buffer);
1660  tag.value = buffer;
1661 
1662  //Write the corresponding ASN.1 tag
1663  error = asn1WriteTag(&tag, FALSE, p, &n);
1664  //Any error to report?
1665  if(error)
1666  return error;
1667 
1668  //The extension value is encapsulated in an octet string
1669  tag.constructed = FALSE;
1672  tag.length = n;
1673  tag.value = p;
1674 
1675  //Write the corresponding ASN.1 tag
1676  error = asn1WriteTag(&tag, FALSE, p, &n);
1677  //Any error to report?
1678  if(error)
1679  return error;
1680 
1681  //Adjust the length of the extension
1682  length += n;
1683 
1684  //The extension is encapsulated within a sequence
1685  tag.constructed = TRUE;
1688  tag.length = length;
1689  tag.value = output;
1690 
1691  //Write the corresponding ASN.1 tag
1692  error = asn1WriteTag(&tag, FALSE, output, &length);
1693  //Any error to report?
1694  if(error)
1695  return error;
1696  }
1697 
1698  //Total number of bytes that have been written
1699  *written = length;
1700 
1701  //Successful processing
1702  return NO_ERROR;
1703 }
1704 
1705 
1706 /**
1707  * @brief Format SignatureAlgorithm structure
1708  * @param[in] signatureAlgo Pointer to the SignatureAlgorithm structure
1709  * @param[out] output Buffer where to format the ASN.1 structure
1710  * @param[out] written Length of the resulting ASN.1 structure
1711  * @return Error code
1712  **/
1713 
1715  uint8_t *output, size_t *written)
1716 {
1717  error_t error;
1718  size_t n;
1719  size_t length;
1720  uint8_t *p;
1721  Asn1Tag tag;
1722  X509SignatureAlgo signAlgo;
1723  const HashAlgo *hashAlgo;
1724 
1725  //Point to the buffer where to write the ASN.1 structure
1726  p = output;
1727  //Length of the ASN.1 structure
1728  length = 0;
1729 
1730  //Retrieve the signature algorithm that will be used to sign the certificate
1731  error = x509GetSignHashAlgo(signatureAlgo, &signAlgo, &hashAlgo);
1732  //Unsupported signature algorithm?
1733  if(error)
1734  return error;
1735 
1736  //The Algorithm field contains the OID for the algorithm used by the CA
1737  //to sign the certificate
1738  tag.constructed = FALSE;
1741  tag.length = signatureAlgo->oidLen;
1742  tag.value = signatureAlgo->oid;
1743 
1744  //Write the corresponding ASN.1 tag
1745  error = asn1WriteTag(&tag, FALSE, p, &n);
1746  //Any error to report?
1747  if(error)
1748  return error;
1749 
1750  //Advance data pointer
1751  p += n;
1752  length += n;
1753 
1754 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
1755  //RSA signature algorithm?
1756  if(signAlgo == X509_SIGN_ALGO_RSA)
1757  {
1758  //For RSA signature algorithm, the parameters component of that type
1759  //shall be the ASN.1 type NULL (refer to RFC 3279, section 2.2.1)
1760  tag.constructed = FALSE;
1762  tag.objType = ASN1_TYPE_NULL;
1763  tag.length = 0;
1764  tag.value = NULL;
1765 
1766  //Write the corresponding ASN.1 tag
1767  error = asn1WriteTag(&tag, FALSE, p, &n);
1768  }
1769  else
1770 #endif
1771 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
1772  //RSA-PSS signature algorithm?
1773  if(signAlgo == X509_SIGN_ALGO_RSA_PSS)
1774  {
1775  //The parameters must be present when used in the algorithm identifier
1776  //associated with a signature value (refer to RFC 4055, section 3.1)
1777  error = x509FormatRsaPssParameters(&signatureAlgo->rsaPssParams, p, &n);
1778  }
1779  else
1780 #endif
1781 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
1782  //DSA signature algorithm?
1783  if(signAlgo == X509_SIGN_ALGO_DSA)
1784  {
1785  //For DSA signature algorithm, the encoding shall omit the parameters
1786  //field (refer to RFC 3279, section 2.2.2)
1787  n = 0;
1788  }
1789  else
1790 #endif
1791 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
1792  //ECDSA signature algorithm?
1793  if(signAlgo == X509_SIGN_ALGO_ECDSA)
1794  {
1795  //For ECDSA signature algorithm, the encoding must omit the parameters
1796  //field (refer to RFC 3279, section 2.2.3)
1797  n = 0;
1798  }
1799  else
1800 #endif
1801 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
1802  //Ed25519 signature algorithm?
1803  if(signAlgo == X509_SIGN_ALGO_ED25519)
1804  {
1805  //The parameters must be absent (refer to RFC 8410, section 6)
1806  n = 0;
1807  }
1808  else
1809 #endif
1810 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
1811  //Ed448 signature algorithm?
1812  if(signAlgo == X509_SIGN_ALGO_ED448)
1813  {
1814  //The parameters must be absent (refer to RFC 8410, section 6)
1815  n = 0;
1816  }
1817  else
1818 #endif
1819  //Invalid signature algorithm?
1820  {
1821  //Report an error
1823  }
1824 
1825  //Check status code
1826  if(error)
1827  return error;
1828 
1829  //Advance data pointer
1830  p += n;
1831  length += n;
1832 
1833  //The Algorithm and Parameters fields are encapsulated within a sequence
1834  tag.constructed = TRUE;
1837  tag.length = length;
1838  tag.value = output;
1839 
1840  //Write the corresponding ASN.1 tag
1841  error = asn1WriteTag(&tag, FALSE, output, &length);
1842  //Any error to report?
1843  if(error)
1844  return error;
1845 
1846  //Total number of bytes that have been written
1847  *written = length;
1848 
1849  //Successful processing
1850  return NO_ERROR;
1851 }
1852 
1853 
1854 /**
1855  * @brief Format SignatureValue field
1856  * @param[in] prngAlgo PRNG algorithm
1857  * @param[in] prngContext Pointer to the PRNG context
1858  * @param[in] tbsCert Pointer to the TBSCertificate to be signed
1859  * @param[in] tbsCertLen Length of the TBSCertificate, in bytes
1860  * @param[in] signatureAlgoId Signature algorithm identifier
1861  * @param[in] publicKeyInfo Signer's public key information
1862  * @param[in] privateKey Signer's private key
1863  * @param[out] output Buffer where to format the ASN.1 structure
1864  * @param[out] written Length of the resulting ASN.1 structure
1865  * @return Error code
1866  **/
1867 
1868 error_t x509FormatSignatureValue(const PrngAlgo *prngAlgo, void *prngContext,
1869  const uint8_t *tbsCert, size_t tbsCertLen, const X509SignatureAlgoId *signatureAlgoId,
1870  const X509SubjectPublicKeyInfo *publicKeyInfo, const void *privateKey,
1871  uint8_t *output, size_t *written)
1872 {
1873  error_t error;
1874  size_t n;
1875  Asn1Tag tag;
1876 
1877  //The bit string shall contain an initial octet which encodes the number
1878  //of unused bits in the final subsequent octet
1879  output[0] = 0;
1880 
1881  //The ASN.1 DER-encoded tbsCertificate is used as the input to the signature
1882  //function
1883  error = x509GenerateSignature(prngAlgo, prngContext, tbsCert, tbsCertLen,
1884  signatureAlgoId, publicKeyInfo, privateKey, output + 1, &n);
1885  //Any error to report?
1886  if(error)
1887  return error;
1888 
1889  //The signature is encapsulated within a bit string
1890  tag.constructed = FALSE;
1893  tag.length = n + 1;
1894  tag.value = output;
1895 
1896  //Write the corresponding ASN.1 tag
1897  error = asn1WriteTag(&tag, FALSE, output, &n);
1898  //Any error to report?
1899  if(error)
1900  return error;
1901 
1902  //Total number of bytes that have been written
1903  *written = n;
1904 
1905  //Successful processing
1906  return NO_ERROR;
1907 }
1908 
1909 
1910 /**
1911  * @brief Certificate signature generation
1912  * @param[in] prngAlgo PRNG algorithm
1913  * @param[in] prngContext Pointer to the PRNG context
1914  * @param[in] tbsCert Pointer to the TBSCertificate to be signed
1915  * @param[in] tbsCertLen Length of the TBSCertificate, in bytes
1916  * @param[in] signatureAlgoId Signature algorithm identifier
1917  * @param[in] publicKeyInfo Signer's public key information
1918  * @param[in] privateKey Signer's private key
1919  * @param[out] output Resulting signature
1920  * @param[out] written Length of the resulting signature
1921  * @return Error code
1922  **/
1923 
1924 error_t x509GenerateSignature(const PrngAlgo *prngAlgo, void *prngContext,
1925  const uint8_t *tbsCert, size_t tbsCertLen, const X509SignatureAlgoId *signatureAlgoId,
1926  const X509SubjectPublicKeyInfo *publicKeyInfo, const void *privateKey,
1927  uint8_t *output, size_t *written)
1928 {
1929  error_t error;
1930  X509SignatureAlgo signAlgo;
1931  const HashAlgo *hashAlgo;
1932  uint8_t digest[X509_MAX_HASH_DIGEST_SIZE];
1933 
1934  //Retrieve the signature algorithm that will be used to sign the certificate
1935  error = x509GetSignHashAlgo(signatureAlgoId, &signAlgo, &hashAlgo);
1936  //Unsupported signature algorithm?
1937  if(error)
1938  return error;
1939 
1940  //Ed25519 and Ed448 are used in PureEdDSA mode, without pre-hashing
1941  if(hashAlgo != NULL)
1942  {
1943  //Digest the TBSCertificate structure using the specified hash algorithm
1944  error = hashAlgo->compute(tbsCert, tbsCertLen, digest);
1945  //Any error to report?
1946  if(error)
1947  return error;
1948 
1949 #if (X509_RSA_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
1950  //RSA signature algorithm?
1951  if(signAlgo == X509_SIGN_ALGO_RSA)
1952  {
1953  //Generate RSA signature
1954  error = rsassaPkcs1v15Sign(privateKey, hashAlgo, digest, output,
1955  written);
1956  }
1957  else
1958 #endif
1959 #if (X509_RSA_PSS_SUPPORT == ENABLED && RSA_SUPPORT == ENABLED)
1960  //RSA-PSS signature algorithm?
1961  if(signAlgo == X509_SIGN_ALGO_RSA_PSS)
1962  {
1963  //Generate RSA-PSS signature
1964  error = rsassaPssSign(prngAlgo, prngContext, privateKey, hashAlgo,
1965  signatureAlgoId->rsaPssParams.saltLen, digest, output, written);
1966  }
1967  else
1968 #endif
1969 #if (X509_DSA_SUPPORT == ENABLED && DSA_SUPPORT == ENABLED)
1970  //DSA signature algorithm?
1971  if(signAlgo == X509_SIGN_ALGO_DSA)
1972  {
1974 
1975  //Initialize DSA signature
1977 
1978  //Generate DSA signature
1979  error = dsaGenerateSignature(prngAlgo, prngContext, privateKey,
1980  digest, hashAlgo->digestSize, &signature);
1981 
1982  //Check status code
1983  if(!error)
1984  {
1985  //Encode DSA signature using ASN.1
1986  error = dsaWriteSignature(&signature, output, written);
1987  }
1988 
1989  //Release previously allocated resources
1991  }
1992  else
1993 #endif
1994 #if (X509_ECDSA_SUPPORT == ENABLED && ECDSA_SUPPORT == ENABLED)
1995  //ECDSA signature algorithm?
1996  if(signAlgo == X509_SIGN_ALGO_ECDSA)
1997  {
1998  const EcCurveInfo *curveInfo;
1999  EcDomainParameters params;
2001 
2002  //Initialize EC domain parameters
2003  ecInitDomainParameters(&params);
2004  //Initialize ECDSA signature
2006 
2007  //Retrieve EC domain parameters
2008  curveInfo = x509GetCurveInfo(publicKeyInfo->ecParams.namedCurve,
2009  publicKeyInfo->ecParams.namedCurveLen);
2010 
2011  //Make sure the specified elliptic curve is supported
2012  if(curveInfo != NULL)
2013  {
2014  //Load EC domain parameters
2015  error = ecLoadDomainParameters(&params, curveInfo);
2016  }
2017  else
2018  {
2019  //Invalid EC domain parameters
2020  error = ERROR_BAD_CERTIFICATE;
2021  }
2022 
2023  //Check status code
2024  if(!error)
2025  {
2026  //Generate ECDSA signature
2027  error = ecdsaGenerateSignature(prngAlgo, prngContext, &params,
2028  privateKey, digest, hashAlgo->digestSize, &signature);
2029  }
2030 
2031  //Check status code
2032  if(!error)
2033  {
2034  //Encode ECDSA signature using ASN.1
2035  error = ecdsaWriteSignature(&signature, output, written);
2036  }
2037 
2038  //Release previously allocated resources
2039  ecFreeDomainParameters(&params);
2041  }
2042  else
2043 #endif
2044  //Invalid signature algorithm?
2045  {
2046  //Report an error
2048  }
2049  }
2050  else
2051  {
2052 #if (X509_ED25519_SUPPORT == ENABLED && ED25519_SUPPORT == ENABLED)
2053  //Ed25519 signature algorithm?
2054  if(signAlgo == X509_SIGN_ALGO_ED25519)
2055  {
2056  const EddsaPrivateKey *eddsaPrivateKey;
2057 
2058  //Point to the EdDSA private key
2059  eddsaPrivateKey = (const EddsaPrivateKey *) privateKey;
2060 
2061  //Check the length of the EdDSA private key
2062  if(mpiGetByteLength(&eddsaPrivateKey->d) == ED25519_PRIVATE_KEY_LEN)
2063  {
2064  uint8_t d[ED25519_PRIVATE_KEY_LEN];
2065 
2066  //Retrieve private key
2067  error = mpiExport(&eddsaPrivateKey->d, d, ED25519_PRIVATE_KEY_LEN,
2069 
2070  //Check status code
2071  if(!error)
2072  {
2073  //Generate Ed25519 signature (PureEdDSA mode)
2074  error = ed25519GenerateSignature(d, NULL, tbsCert, tbsCertLen,
2075  NULL, 0, 0, output);
2076  }
2077 
2078  //Length of the resulting EdDSA signature
2079  *written = ED25519_SIGNATURE_LEN;
2080  }
2081  else
2082  {
2083  //The length of the EdDSA private key is not valid
2084  error = ERROR_INVALID_KEY;
2085  }
2086  }
2087  else
2088 #endif
2089 #if (X509_ED448_SUPPORT == ENABLED && ED448_SUPPORT == ENABLED)
2090  //Ed448 signature algorithm?
2091  if(signAlgo == X509_SIGN_ALGO_ED448)
2092  {
2093  const EddsaPrivateKey *eddsaPrivateKey;
2094 
2095  //Point to the EdDSA private key
2096  eddsaPrivateKey = (const EddsaPrivateKey *) privateKey;
2097 
2098  //Check the length of the EdDSA private key
2099  if(mpiGetByteLength(&eddsaPrivateKey->d) == ED448_PRIVATE_KEY_LEN)
2100  {
2101  uint8_t d[ED448_PRIVATE_KEY_LEN];
2102 
2103  //Retrieve private key
2104  error = mpiExport(&eddsaPrivateKey->d, d, ED448_PRIVATE_KEY_LEN,
2106 
2107  //Check status code
2108  if(!error)
2109  {
2110  //Generate Ed448 signature (PureEdDSA mode)
2111  error = ed448GenerateSignature(d, NULL, tbsCert, tbsCertLen,
2112  NULL, 0, 0, output);
2113  }
2114 
2115  //Length of the resulting EdDSA signature
2116  *written = ED448_SIGNATURE_LEN;
2117  }
2118  else
2119  {
2120  //The length of the EdDSA private key is not valid
2121  error = ERROR_INVALID_KEY;
2122  }
2123  }
2124  else
2125 #endif
2126  //Invalid signature algorithm?
2127  {
2128  //Report an error
2130  }
2131  }
2132 
2133  //Return status code
2134  return error;
2135 }
2136 
2137 #endif
ECDSA signature.
Definition: ecdsa.h:48
uint8_t length
Definition: dtls_misc.h:149
Ed25519 elliptic curve (constant-time implementation)
error_t x509FormatVersion(X509Version version, uint8_t *output, size_t *written)
Format Version field.
X509AuthorityKeyId authKeyId
Definition: x509_common.h:851
const uint8_t * oid
Definition: x509_common.h:878
X509GeneralNameType type
Definition: x509_common.h:768
const EcCurveInfo * x509GetCurveInfo(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: x509_common.c:860
Common interface for pseudo-random number generators.
Definition: crypto.h:1168
const uint8_t X509_SUBJECT_ALT_NAME_OID[3]
Definition: x509_common.c:104
Signature algorithm identifier.
Definition: x509_common.h:876
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:55
X509Extensions extensions
Definition: x509_common.h:912
PrngAlgoRead read
Definition: crypto.h:1176
const uint8_t X509_ORGANIZATION_NAME_OID[3]
Definition: x509_common.c:79
OID (Object Identifier)
ECDSA (Elliptic Curve Digital Signature Algorithm)
SHA-1 (Secure Hash Algorithm 1)
uint8_t p
Definition: ndp.h:298
Validity.
Definition: x509_common.h:622
const uint8_t * keyId
Definition: x509_common.h:807
uint16_t year
Definition: date_time.h:48
#define TRUE
Definition: os_port.h:50
error_t x509FormatExtensions(const X509Extensions *extensions, const X509SubjectKeyId *subjectKeyId, const X509AuthorityKeyId *authKeyId, uint8_t *output, size_t *written)
Format Extensions structure.
X509RsaPssParameters rsaPssParams
Definition: x509_common.h:881
size_t digestSize
Definition: crypto.h:1135
X.509 certificate.
Definition: x509_common.h:920
uint8_t signature
Definition: tls.h:1370
uint16_t version
Definition: dtls_misc.h:172
X509EcParameters ecParams
Definition: x509_common.h:708
#define ED448_SIGNATURE_LEN
Definition: ed448.h:43
const uint8_t X509_KEY_USAGE_OID[3]
Definition: x509_common.c:102
X509Extensions extensionReq
Definition: x509_common.h:1123
error_t x509GetSignHashAlgo(const X509SignatureAlgoId *signAlgoId, X509SignatureAlgo *signAlgo, const HashAlgo **hashAlgo)
Get the signature and hash algorithms that match the specified identifier.
Definition: x509_common.c:337
char_t name[]
#define ED25519_SIGNATURE_LEN
Definition: ed25519.h:43
const uint8_t X509_COUNTRY_NAME_OID[3]
Definition: x509_common.c:73
EC domain parameters.
Definition: ec.h:63
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:75
#define ED25519_PRIVATE_KEY_LEN
Definition: ed25519.h:39
Subject key identifier.
Definition: x509_common.h:792
uint8_t day
Definition: date_time.h:50
error_t x509FormatSubjectPublicKeyInfo(const X509SubjectPublicKeyInfo *publicKeyInfo, const void *publicKey, uint8_t *keyId, uint8_t *output, size_t *written)
Format SubjectPublicKeyInfo structure.
const uint8_t X509_BASIC_CONSTRAINTS_OID[3]
Definition: x509_common.c:108
error_t x509FormatRsaPssParameters(const X509RsaPssParameters *rsaPssParams, uint8_t *output, size_t *written)
Format RSASSA-PSS parameters.
void ecdsaFreeSignature(EcdsaSignature *signature)
Release an ECDSA signature.
Definition: ecdsa.c:82
size_t length
Definition: asn1.h:102
error_t x509FormatSignatureValue(const PrngAlgo *prngAlgo, void *prngContext, const uint8_t *tbsCert, size_t tbsCertLen, const X509SignatureAlgoId *signatureAlgoId, const X509SubjectPublicKeyInfo *publicKeyInfo, const void *privateKey, uint8_t *output, size_t *written)
Format SignatureValue field.
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:93
X509SubjectPublicKeyInfo subjectPublicKeyInfo
Definition: x509_common.h:1137
error_t x509FormatSignatureAlgo(const X509SignatureAlgoId *signatureAlgo, uint8_t *output, size_t *written)
Format SignatureAlgorithm structure.
DateTime notAfter
Definition: x509_common.h:625
#define FALSE
Definition: os_port.h:46
X509SignatureAlgo
Signature algorithms.
Definition: x509_common.h:521
Elliptic curve parameters.
Definition: ec_curves.h:292
error_t ed25519GenerateSignature(const uint8_t *privateKey, const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed25519.c:185
bool_t critical
Definition: x509_common.h:746
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:618
Invalid parameter.
Definition: error.h:47
#define cryptoStrlen(s)
Definition: crypto.h:660
X.509 certificate generation.
char_t type
error_t x509FormatSerialNumber(const PrngAlgo *prngAlgo, void *prngContext, const X509SerialNumber *serialNumber, uint8_t *output, size_t *written)
Format SerialNumber field.
uint8_t minutes
Definition: date_time.h:53
error_t
Error codes.
Definition: error.h:42
void dsaInitSignature(DsaSignature *signature)
Initialize a DSA signature.
Definition: dsa.c:137
HashAlgoCompute compute
Definition: crypto.h:1138
#define X509_MAX_HASH_DIGEST_SIZE
Definition: x509_common.h:359
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:48
X509Version
X.509 versions.
Definition: x509_common.h:390
X509Version version
Definition: x509_common.h:905
ASN.1 tag.
Definition: asn1.h:97
error_t rsassaPssSign(const PrngAlgo *prngAlgo, void *prngContext, const RsaPrivateKey *key, const HashAlgo *hash, size_t saltLen, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PSS signature generation operation.
Definition: rsa.c:920
void ecdsaInitSignature(EcdsaSignature *signature)
Initialize an ECDSA signature.
Definition: ecdsa.c:69
const uint8_t X509_LOCALITY_NAME_OID[3]
Definition: x509_common.c:75
error_t dsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const DsaPrivateKey *key, const uint8_t *digest, size_t digestLen, DsaSignature *signature)
DSA signature generation.
Definition: dsa.c:457
EdDSA (Edwards-Curve Digital Signature Algorithm)
const uint8_t X509_AUTHORITY_KEY_ID_OID[3]
Definition: x509_common.c:130
const uint8_t X509_COMMON_NAME_OID[3]
Definition: x509_common.c:67
error_t x509FormatValidity(const X509Validity *validity, uint8_t *output, size_t *written)
Format Validity structure.
General definitions for cryptographic algorithms.
RSA public-key cryptography standard.
uint8_t oid[1]
Definition: mib_common.h:186
error_t x509CreateCertificate(const PrngAlgo *prngAlgo, void *prngContext, const X509CertRequestInfo *certReqInfo, const void *subjectPublicKey, const X509CertificateInfo *issuerCertInfo, const X509SerialNumber *serialNumber, const X509Validity *validity, const X509SignatureAlgoId *signatureAlgo, const void *signerPrivateKey, uint8_t *output, size_t *written)
Generate a X.509 certificate.
error_t x509GenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const uint8_t *tbsCert, size_t tbsCertLen, const X509SignatureAlgoId *signatureAlgoId, const X509SubjectPublicKeyInfo *publicKeyInfo, const void *privateKey, uint8_t *output, size_t *written)
Certificate signature generation.
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:377
DSA (Digital Signature Algorithm)
uint8_t hours
Definition: date_time.h:52
Date and time representation.
Definition: date_time.h:46
uint_t objClass
Definition: asn1.h:100
size_t namedCurveLen
Definition: x509_common.h:675
uint16_t bitmap
Definition: x509_common.h:747
CertificationRequestInfo structure.
Definition: x509_common.h:1131
Subject alternative name.
Definition: x509_common.h:778
uint8_t seconds
Definition: date_time.h:54
error_t dsaWriteSignature(const DsaSignature *signature, uint8_t *data, size_t *length)
Encode DSA signature using ASN.1.
Definition: dsa.c:166
__weak error_t ecdsaGenerateSignature(const PrngAlgo *prngAlgo, void *prngContext, const EcDomainParameters *params, const Mpi *privateKey, const uint8_t *digest, size_t digestLen, EcdsaSignature *signature)
ECDSA signature generation.
Definition: ecdsa.c:447
EdDSA private key.
Definition: eddsa.h:58
Netscape certificate type.
Definition: x509_common.h:816
const char_t * value
Definition: x509_common.h:769
error_t x509FormatNameAttribute(uint_t type, const uint8_t *oid, size_t oidLen, const char_t *value, size_t valueLen, uint8_t *output, size_t *written)
Format Name attribute.
#define ED448_PRIVATE_KEY_LEN
Definition: ed448.h:39
error_t x509FormatKeyUsage(const X509KeyUsage *keyUsage, uint8_t *output, size_t *written)
Format KeyUsage extension.
const uint8_t * data
Definition: x509_common.h:559
error_t ecdsaWriteSignature(const EcdsaSignature *signature, uint8_t *data, size_t *length)
Encode ECDSA signature using ASN.1.
Definition: ecdsa.c:98
uint8_t month
Definition: date_time.h:49
char char_t
Definition: compiler_port.h:43
Formatting of ASN.1 encoded keys.
#define SHA1_DIGEST_SIZE
Definition: sha1.h:40
DateTime notBefore
Definition: x509_common.h:624
Mpi d
Private key.
Definition: eddsa.h:60
uint8_t n
Issuer or subject name.
Definition: x509_common.h:568
uint8_t extensions[]
Definition: tls13_misc.h:327
Subject public key information.
Definition: x509_common.h:694
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:50
#define cryptoMemcpy(dest, src, length)
Definition: crypto.h:642
const uint8_t X509_NS_CERT_TYPE_OID[9]
Definition: x509_common.c:141
#define X509_SERIAL_NUMBER_SIZE
Definition: x509_common.h:338
error_t x509FormatSubjectAltName(const X509SubjectAltName *subjectAltName, uint8_t *output, size_t *written)
Format SubjectAltName extension.
void dsaFreeSignature(DsaSignature *signature)
Release a DSA signature.
Definition: dsa.c:150
error_t x509FormatName(const X509Name *name, uint8_t *output, size_t *written)
Format Name structure.
Basic constraints.
Definition: x509_common.h:718
uint8_t reverseInt8(uint8_t value)
Reverse bit order in a byte.
Definition: cpu_endian.c:90
bool_t constructed
Definition: asn1.h:99
error_t x509FormatSubjectKeyId(const X509SubjectKeyId *subjectKeyId, uint8_t *output, size_t *written)
Format SubjectKeyIdentifier extension.
const uint8_t X509_ORGANIZATIONAL_UNIT_NAME_OID[3]
Definition: x509_common.c:81
X.509 certificate extensions.
Definition: x509_common.h:841
const uint8_t X509_SUBJECT_KEY_ID_OID[3]
Definition: x509_common.c:100
Common interface for hash algorithms.
Definition: crypto.h:1128
error_t x509FormatAuthorityKeyId(const X509AuthorityKeyId *authKeyId, uint8_t *output, size_t *written)
Format AuthorityKeyIdentifier extension.
error_t rsassaPkcs1v15Sign(const RsaPrivateKey *key, const HashAlgo *hash, const uint8_t *digest, uint8_t *signature, size_t *signatureLen)
RSASSA-PKCS1-v1_5 signature generation operation.
Definition: rsa.c:678
const uint8_t * value
Definition: x509_common.h:795
error_t x509FormatTbsCertificate(const PrngAlgo *prngAlgo, void *prngContext, const X509SerialNumber *serialNumber, const X509SignatureAlgoId *signatureAlgo, const X509Name *issuer, const X509Validity *validity, const X509Name *subject, const X509SubjectPublicKeyInfo *subjectPublicKeyInfo, const void *publicKey, const X509Extensions *extensions, const X509AuthorityKeyId *authKeyId, uint8_t *output, size_t *written)
Format TBSCertificate structure.
DSA signature.
Definition: dsa.h:86
error_t x509FormatTime(const DateTime *dateTime, uint8_t *output, size_t *written)
Format UTCTime or GeneralizedTime field.
Serial number.
Definition: x509_common.h:557
uint8_t value[]
Definition: dtls_misc.h:150
unsigned int uint_t
Definition: compiler_port.h:45
uint8_t bitmap
Definition: x509_common.h:819
error_t x509FormatBasicConstraints(const X509BasicConstraints *basicConstraints, uint8_t *output, size_t *written)
Format BasicConstraints extension.
X509SubjectPublicKeyInfo subjectPublicKeyInfo
Definition: x509_common.h:911
error_t asn1WriteInt32(int32_t value, bool_t reverse, uint8_t *data, size_t *written)
Write a 32-bit integer to the output stream.
Definition: asn1.c:516
X509SubjectKeyId subjectKeyId
Definition: x509_common.h:850
error_t x509FormatNsCertType(const X509NsCertType *nsCertType, uint8_t *output, size_t *written)
Format NetscapeCertType extension.
X509Attributes attributes
Definition: x509_common.h:1138
X509GeneralName generalNames[X509_MAX_SUBJECT_ALT_NAMES]
Definition: x509_common.h:784
Ed448 elliptic curve (constant-time implementation)
const uint8_t X509_STATE_OR_PROVINCE_NAME_OID[]
Definition: x509_common.c:77
Authority key identifier.
Definition: x509_common.h:804
const uint8_t * namedCurve
Definition: x509_common.h:674
error_t ed448GenerateSignature(const uint8_t *privateKey, const uint8_t *publicKey, const void *message, size_t messageLen, const void *context, uint8_t contextLen, uint8_t flag, uint8_t *signature)
EdDSA signature generation.
Definition: ed448.c:172
const uint8_t * value
Definition: asn1.h:103
X509TbsCertificate tbsCert
Definition: x509_common.h:922
Success.
Definition: error.h:44
Debugging facilities.
uint_t objType
Definition: asn1.h:101
ASN.1 (Abstract Syntax Notation One)
Key usage.
Definition: x509_common.h:744
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:156