x509_key_format.c
Go to the documentation of this file.
1 /**
2  * @file x509_key_format.c
3  * @brief Formatting of ASN.1 encoded keys
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 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 2.4.0
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_key_format.h"
37 #include "encoding/asn1.h"
38 #include "encoding/oid.h"
39 #include "ecc/eddsa.h"
40 #include "hash/sha1.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (X509_SUPPORT == ENABLED || PEM_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Format SubjectPublicKeyInfo structure
49  * @param[in] publicKeyInfo Subject's public key information
50  * @param[in] publicKey Pointer to the public key (RSA, DSA, ECDSA or EdDSA)
51  * @param[out] keyId Subject's key identifier (optional parameter)
52  * @param[out] output Buffer where to format the ASN.1 structure
53  * @param[out] written Length of the resulting ASN.1 structure
54  * @return Error code
55  **/
56 
58  const void *publicKey, uint8_t *keyId, uint8_t *output, size_t *written)
59 {
60  error_t error;
61  size_t n;
62  size_t length;
63  uint8_t *p;
64  size_t oidLen;
65  const uint8_t *oid;
66  Asn1Tag tag;
67 
68  //Get the public key identifier
69  oid = publicKeyInfo->oid.value;
70  oidLen = publicKeyInfo->oid.length;
71 
72  //Point to the buffer where to write the ASN.1 structure
73  p = output;
74  //Length of the ASN.1 structure
75  length = 0;
76 
77 #if (DSA_SUPPORT == ENABLED)
78  //Valid DSA public key?
79  if(publicKey != NULL && !oidComp(oid, oidLen, DSA_OID, sizeof(DSA_OID)))
80  {
81  const DsaPublicKey *dsaPublicKey;
82 
83  //Point to the DSA public key
84  dsaPublicKey = (DsaPublicKey *) publicKey;
85 
86  //Format AlgorithmIdentifier field
87  error = x509FormatAlgoId(publicKeyInfo,
88  &dsaPublicKey->params, p, &n);
89  }
90  else
91 #endif
92  {
93  //Format AlgorithmIdentifier field
94  error = x509FormatAlgoId(publicKeyInfo, NULL, p, &n);
95  }
96 
97  //Any error to report?
98  if(error)
99  return error;
100 
101  //Advance data pointer
102  p += n;
103  length += n;
104 
105  //The bit string shall contain an initial octet which encodes the number
106  //of unused bits in the final subsequent octet
107  p[0] = 0;
108 
109 #if (RSA_SUPPORT == ENABLED)
110  //RSA or RSA-PSS algorithm identifier?
113  {
114  //Valid RSA public key?
115  if(publicKey != NULL)
116  {
117  //Export the RSA public key to ASN.1 format
118  error = x509ExportRsaPublicKey(publicKey, p + 1, &n);
119  }
120  else
121  {
122  //Format RSAPublicKey structure
123  error = x509FormatRsaPublicKey(&publicKeyInfo->rsaPublicKey,
124  p + 1, &n);
125  }
126  }
127  else
128 #endif
129 #if (DSA_SUPPORT == ENABLED)
130  //DSA algorithm identifier?
131  if(!oidComp(oid, oidLen, DSA_OID, sizeof(DSA_OID)))
132  {
133  //Valid DSA public key?
134  if(publicKey != NULL)
135  {
136  //Export the DSA public key to ASN.1 format
137  error = x509ExportDsaPublicKey(publicKey, p + 1, &n);
138  }
139  else
140  {
141  //Format DSAPublicKey structure
142  error = x509FormatDsaPublicKey(&publicKeyInfo->dsaPublicKey,
143  p + 1, &n);
144  }
145  }
146  else
147 #endif
148 #if (EC_SUPPORT == ENABLED)
149  //EC public key identifier?
151  {
152  //Valid EC public key?
153  if(publicKey != NULL)
154  {
155  //Export the EC public key to ASN.1 format
156  error = x509ExportEcPublicKey(publicKeyInfo, publicKey,
157  p + 1, &n);
158  }
159  else
160  {
161  //Format ECPublicKey structure
162  error = x509FormatEcPublicKey(&publicKeyInfo->ecPublicKey,
163  p + 1, &n);
164  }
165  }
166  else
167 #endif
168 #if (ED25519_SUPPORT == ENABLED)
169  //Ed25519 algorithm identifier?
170  if(!oidComp(oid, oidLen, ED25519_OID, sizeof(ED25519_OID)))
171  {
172  //Valid EdDSA public key?
173  if(publicKey != NULL)
174  {
175  //Export the EdDSA public key to ASN.1 format
177  p + 1, &n);
178  }
179  else
180  {
181  //The SubjectPublicKey contains the byte stream of the public key
182  error = x509FormatEcPublicKey(&publicKeyInfo->ecPublicKey,
183  p + 1, &n);
184  }
185  }
186  else
187 #endif
188 #if (ED448_SUPPORT == ENABLED)
189  //Ed448 algorithm identifier?
190  if(!oidComp(oid, oidLen, ED448_OID, sizeof(ED448_OID)))
191  {
192  //Valid EdDSA public key?
193  if(publicKey != NULL)
194  {
195  //Export the EdDSA public key to ASN.1 format
197  p + 1, &n);
198  }
199  else
200  {
201  //The SubjectPublicKey contains the byte stream of the public key
202  error = x509FormatEcPublicKey(&publicKeyInfo->ecPublicKey,
203  p + 1, &n);
204  }
205  }
206  else
207 #endif
208  //Unknown algorithm identifier?
209  {
210  //Report an error
211  error = ERROR_INVALID_PARAMETER;
212  }
213 
214  //Any error to report?
215  if(error)
216  return error;
217 
218  //The keyIdentifier parameter is optional
219  if(keyId != NULL)
220  {
221  //The keyIdentifier is composed of the 160-bit SHA-1 hash of the value
222  //of the bit string subjectPublicKey (excluding the tag, length, and
223  //number of unused bits)
224  error = sha1Compute(p + 1, n, keyId);
225  //Any error to report?
226  if(error)
227  return error;
228  }
229 
230  //The public key is encapsulated within a bit string
231  tag.constructed = FALSE;
234  tag.length = n + 1;
235  tag.value = p;
236 
237  //Write the corresponding ASN.1 tag
238  error = asn1WriteTag(&tag, FALSE, p, &n);
239  //Any error to report?
240  if(error)
241  return error;
242 
243  //Advance data pointer
244  p += n;
245  length += n;
246 
247  //The SubjectPublicKeyInfo structure is encapsulated within a sequence
248  tag.constructed = TRUE;
251  tag.length = length;
252  tag.value = output;
253 
254  //Write the corresponding ASN.1 tag
255  error = asn1WriteTag(&tag, FALSE, output, &n);
256  //Any error to report?
257  if(error)
258  return error;
259 
260  //Total number of bytes that have been written
261  *written = n;
262 
263  //Successful processing
264  return NO_ERROR;
265 }
266 
267 
268 /**
269  * @brief Format AlgorithmIdentifier structure
270  * @param[in] publicKeyInfo Subject's public key information
271  * @param[in] params Pointer to the domain parameters (DSA or ECDSA)
272  * @param[out] output Buffer where to format the ASN.1 structure
273  * @param[out] written Length of the resulting ASN.1 structure
274  * @return Error code
275  **/
276 
278  const void *params, uint8_t *output, size_t *written)
279 {
280  error_t error;
281  size_t n;
282  size_t length;
283  uint8_t *p;
284  size_t oidLen;
285  const uint8_t *oid;
286  Asn1Tag tag;
287 
288  //Get the public key identifier
289  oid = publicKeyInfo->oid.value;
290  oidLen = publicKeyInfo->oid.length;
291 
292  //Point to the buffer where to write the ASN.1 structure
293  p = output;
294  //Length of the ASN.1 structure
295  length = 0;
296 
297  //Format algorithm OID
298  tag.constructed = FALSE;
301  tag.length = oidLen;
302  tag.value = oid;
303 
304  //Write the corresponding ASN.1 tag
305  error = asn1WriteTag(&tag, FALSE, p, &n);
306  //Any error to report?
307  if(error)
308  return error;
309 
310  //Advance data pointer
311  p += n;
312  length += n;
313 
314 #if (RSA_SUPPORT == ENABLED)
315  //RSA algorithm identifier?
317  {
318  //The parameters field must have ASN.1 type NULL for this algorithm
319  //identifier (refer to RFC 3279, section 2.3.1)
320  tag.constructed = FALSE;
322  tag.objType = ASN1_TYPE_NULL;
323  tag.length = 0;
324  tag.value = NULL;
325 
326  //Write the corresponding ASN.1 tag
327  error = asn1WriteTag(&tag, FALSE, p, &n);
328  }
329  //RSA-PSS algorithm identifier?
330  else if(!oidComp(oid, oidLen, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
331  {
332  //The parameters may be either absent or present when used as subject
333  //public key information (refer to RFC 4055, section 3.1)
334  n = 0;
335  }
336  else
337 #endif
338 #if (DSA_SUPPORT == ENABLED)
339  //DSA algorithm identifier?
340  if(!oidComp(oid, oidLen, DSA_OID, sizeof(DSA_OID)))
341  {
342  //Valid DSA domain parameters?
343  if(params != NULL)
344  {
345  //Export the DSA domain parameters to ASN.1 format
346  error = x509ExportDsaParameters(params, p, &n);
347  }
348  else
349  {
350  //Format DSAParameters structure
351  error = x509FormatDsaParameters(&publicKeyInfo->dsaParams, p, &n);
352  }
353  }
354  else
355 #endif
356 #if (EC_SUPPORT == ENABLED)
357  //EC public key identifier?
359  {
360  //Format ECParameters structure
361  error = x509FormatEcParameters(&publicKeyInfo->ecParams, p, &n);
362  }
363  else
364 #endif
365 #if (ED25519_SUPPORT == ENABLED)
366  //X25519 or Ed25519 algorithm identifier?
367  if(!oidComp(oid, oidLen, X25519_OID, sizeof(X25519_OID)) ||
369  {
370  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
371  //section 3)
372  n = 0;
373  }
374  else
375 #endif
376 #if (ED448_SUPPORT == ENABLED)
377  //X448 or Ed448 algorithm identifier?
378  if(!oidComp(oid, oidLen, X448_OID, sizeof(X448_OID)) ||
379  !oidComp(oid, oidLen, ED448_OID, sizeof(ED448_OID)))
380  {
381  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
382  //section 3)
383  n = 0;
384  }
385  else
386 #endif
387  //Unknown algorithm identifier?
388  {
389  //Report an error
390  error = ERROR_INVALID_PARAMETER;
391  }
392 
393  //Any error to report?
394  if(error)
395  return error;
396 
397  //Advance data pointer
398  p += n;
399  length += n;
400 
401  //The AlgorithmIdentifier structure is encapsulated within a sequence
402  tag.constructed = TRUE;
405  tag.length = length;
406  tag.value = output;
407 
408  //Write the corresponding ASN.1 tag
409  error = asn1WriteTag(&tag, FALSE, output, &n);
410  //Any error to report?
411  if(error)
412  return error;
413 
414  //Total number of bytes that have been written
415  *written = n;
416 
417  //Successful processing
418  return NO_ERROR;
419 }
420 
421 
422 /**
423  * @brief Format RSAPublicKey structure
424  * @param[in] rsaPublicKey Pointer to the RSA public key
425  * @param[out] output Buffer where to format the ASN.1 structure
426  * @param[out] written Length of the resulting ASN.1 structure
427  * @return Error code
428  **/
429 
431  uint8_t *output, size_t *written)
432 {
433  error_t error;
434  size_t n;
435  size_t length;
436  uint8_t *p;
437  Asn1Tag tag;
438 
439  //Point to the buffer where to write the ASN.1 structure
440  p = output;
441  //Length of the ASN.1 structure
442  length = 0;
443 
444  //Write Modulus field
445  tag.constructed = FALSE;
448  tag.length = rsaPublicKey->n.length;
449  tag.value = rsaPublicKey->n.value;
450 
451  //Write the corresponding ASN.1 tag
452  error = asn1WriteTag(&tag, FALSE, p, &n);
453  //Any error to report?
454  if(error)
455  return error;
456 
457  //Advance data pointer
458  p += n;
459  length += n;
460 
461  //Write PublicExponent field
462  tag.constructed = FALSE;
465  tag.length = rsaPublicKey->e.length;
466  tag.value = rsaPublicKey->e.value;
467 
468  //Write the corresponding ASN.1 tag
469  error = asn1WriteTag(&tag, FALSE, p, &n);
470  //Any error to report?
471  if(error)
472  return error;
473 
474  //Advance data pointer
475  p += n;
476  length += n;
477 
478  //The public key is encapsulated within a sequence
479  tag.constructed = TRUE;
482  tag.length = length;
483  tag.value = output;
484 
485  //Write RSAPublicKey structure
486  error = asn1WriteTag(&tag, FALSE, output, &n);
487  //Any error to report?
488  if(error)
489  return error;
490 
491  //Total number of bytes that have been written
492  *written = n;
493 
494  //Successful processing
495  return NO_ERROR;
496 }
497 
498 
499 /**
500  * @brief Format DSAPublicKey structure
501  * @param[in] dsaPublicKey Pointer to the DSA public key
502  * @param[out] output Buffer where to format the DSAPublicKey structure
503  * @param[out] written Length of the DSAPublicKey structure
504  * @return Error code
505  **/
506 
508  uint8_t *output, size_t *written)
509 {
510  error_t error;
511  size_t n;
512  Asn1Tag tag;
513 
514  //Write public key
515  tag.constructed = FALSE;
518  tag.length = dsaPublicKey->y.length;
519  tag.value = dsaPublicKey->y.value;
520 
521  //Write the corresponding ASN.1 tag
522  error = asn1WriteTag(&tag, FALSE, output, &n);
523  //Any error to report?
524  if(error)
525  return error;
526 
527  //Total number of bytes that have been written
528  *written = n;
529 
530  //Successful processing
531  return NO_ERROR;
532 }
533 
534 
535 /**
536  * @brief Format DSA domain parameters
537  * @param[in] dsaParams Pointer to the DSA domain parameters
538  * @param[out] output Buffer where to format the ASN.1 structure
539  * @param[out] written Length of the resulting ASN.1 structure
540  * @return Error code
541  **/
542 
544  uint8_t *output, size_t *written)
545 {
546  error_t error;
547  size_t n;
548  size_t length;
549  uint8_t *p;
550  Asn1Tag tag;
551 
552  //Point to the buffer where to write the ASN.1 structure
553  p = output;
554  //Length of the ASN.1 structure
555  length = 0;
556 
557  //Write parameter p
558  tag.constructed = FALSE;
561  tag.length = dsaParams->p.length;
562  tag.value = dsaParams->p.value;
563 
564  //Write the corresponding ASN.1 tag
565  error = asn1WriteTag(&tag, FALSE, 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  //Write parameter q
575  tag.constructed = FALSE;
578  tag.length = dsaParams->q.length;
579  tag.value = dsaParams->q.value;
580 
581  //Write the corresponding ASN.1 tag
582  error = asn1WriteTag(&tag, FALSE, p, &n);
583  //Any error to report?
584  if(error)
585  return error;
586 
587  //Advance data pointer
588  p += n;
589  length += n;
590 
591  //Write parameter g
592  tag.constructed = FALSE;
595  tag.length = dsaParams->g.length;
596  tag.value = dsaParams->g.value;
597 
598  //Write the corresponding ASN.1 tag
599  error = asn1WriteTag(&tag, FALSE, p, &n);
600  //Any error to report?
601  if(error)
602  return error;
603 
604  //Advance data pointer
605  p += n;
606  length += n;
607 
608  //The DSA domain parameters are encapsulated within a sequence
609  tag.constructed = TRUE;
612  tag.length = length;
613  tag.value = output;
614 
615  //Write DSAParameters structure
616  error = asn1WriteTag(&tag, FALSE, output, &n);
617  //Any error to report?
618  if(error)
619  return error;
620 
621  //Total number of bytes that have been written
622  *written = n;
623 
624  //Successful processing
625  return NO_ERROR;
626 }
627 
628 
629 /**
630  * @brief Format ECPublicKey structure
631  * @param[in] ecPublicKey Pointer to the EC public key
632  * @param[out] output Buffer where to format the ASN.1 structure
633  * @param[out] written Length of the resulting ASN.1 structure
634  * @return Error code
635  **/
636 
638  uint8_t *output, size_t *written)
639 {
640  //Copy the EC public key
641  osMemcpy(output, ecPublicKey->q.value, ecPublicKey->q.length);
642 
643  //Total number of bytes that have been written
644  *written = ecPublicKey->q.length;
645 
646  //Successful processing
647  return NO_ERROR;
648 }
649 
650 
651 /**
652  * @brief Format ECParameters structure
653  * @param[in] ecParams Pointer to the EC parameters
654  * @param[out] output Buffer where to format the ECParameters structure
655  * @param[out] written Length of the ECParameters structure
656  * @return Error code
657  **/
658 
660  uint8_t *output, size_t *written)
661 {
662  error_t error;
663  size_t n;
664  Asn1Tag tag;
665 
666  //The namedCurve field identifies all the required values for a particular
667  //set of elliptic curve domain parameters to be represented by an object
668  //identifier
669  tag.constructed = FALSE;
672  tag.length = ecParams->namedCurve.length;
673  tag.value = ecParams->namedCurve.value;
674 
675  //Write the corresponding ASN.1 tag
676  error = asn1WriteTag(&tag, FALSE, output, &n);
677  //Any error to report?
678  if(error)
679  return error;
680 
681  //Total number of bytes that have been written
682  *written = n;
683 
684  //Successful processing
685  return NO_ERROR;
686 }
687 
688 
689 /**
690  * @brief Export an RSA public key to ASN.1 format
691  * @param[in] publicKey Pointer to the RSA public key
692  * @param[out] output Buffer where to store the ASN.1 structure
693  * @param[out] written Length of the resulting ASN.1 structure
694  * @return Error code
695  **/
696 
698  uint8_t *output, size_t *written)
699 {
700  error_t error;
701  size_t n;
702  size_t length;
703  uint8_t *p;
704  Asn1Tag tag;
705 
706  //Point to the buffer where to write the ASN.1 structure
707  p = output;
708  //Length of the ASN.1 structure
709  length = 0;
710 
711  //Write Modulus field
712  error = asn1WriteMpi(&publicKey->n, FALSE, p, &n);
713  //Any error to report?
714  if(error)
715  return error;
716 
717  //Advance data pointer
718  p += n;
719  length += n;
720 
721  //Write PublicExponent field
722  error = asn1WriteMpi(&publicKey->e, FALSE, p, &n);
723  //Any error to report?
724  if(error)
725  return error;
726 
727  //Advance data pointer
728  p += n;
729  length += n;
730 
731  //The public key is encapsulated within a sequence
732  tag.constructed = TRUE;
735  tag.length = length;
736  tag.value = output;
737 
738  //Write RSAPublicKey structure
739  error = asn1WriteTag(&tag, FALSE, output, &n);
740  //Any error to report?
741  if(error)
742  return error;
743 
744  //Total number of bytes that have been written
745  *written = n;
746 
747  //Successful processing
748  return NO_ERROR;
749 }
750 
751 
752 /**
753  * @brief Export an RSA private key to ASN.1 format
754  * @param[in] privateKey Pointer to the RSA private key
755  * @param[out] output Buffer where to store the ASN.1 structure
756  * @param[out] written Length of the resulting ASN.1 structure
757  * @return Error code
758  **/
759 
761  uint8_t *output, size_t *written)
762 {
763  error_t error;
764  size_t n;
765  size_t length;
766  uint8_t *p;
767  Asn1Tag tag;
768 
769  //Point to the buffer where to write the ASN.1 structure
770  p = output;
771  //Length of the ASN.1 structure
772  length = 0;
773 
774  //Write Version field
775  error = asn1WriteInt32(PKCS1_VERSION_1, FALSE, p, &n);
776  //Any error to report?
777  if(error)
778  return error;
779 
780  //Update the length of the RSAPrivateKey structure
781  length += n;
782 
783  //Advance data pointer
784  if(output != NULL)
785  {
786  p += n;
787  }
788 
789  //Write Modulus field
790  error = asn1WriteMpi(&privateKey->n, FALSE, p, &n);
791  //Any error to report?
792  if(error)
793  return error;
794 
795  //Update the length of the RSAPrivateKey structure
796  length += n;
797 
798  //Advance data pointer
799  if(output != NULL)
800  {
801  p += n;
802  }
803 
804  //Write PublicExponent field
805  error = asn1WriteMpi(&privateKey->e, FALSE, p, &n);
806  //Any error to report?
807  if(error)
808  return error;
809 
810  //Update the length of the RSAPrivateKey structure
811  length += n;
812 
813  //Advance data pointer
814  if(output != NULL)
815  {
816  p += n;
817  }
818 
819  //Write PrivateExponent field
820  error = asn1WriteMpi(&privateKey->d, FALSE, p, &n);
821  //Any error to report?
822  if(error)
823  return error;
824 
825  //Update the length of the RSAPrivateKey structure
826  length += n;
827 
828  //Advance data pointer
829  if(output != NULL)
830  {
831  p += n;
832  }
833 
834  //Write Prime1 field
835  error = asn1WriteMpi(&privateKey->p, FALSE, p, &n);
836  //Any error to report?
837  if(error)
838  return error;
839 
840  //Update the length of the RSAPrivateKey structure
841  length += n;
842 
843  //Advance data pointer
844  if(output != NULL)
845  {
846  p += n;
847  }
848 
849  //Write Prime2 field
850  error = asn1WriteMpi(&privateKey->q, FALSE, p, &n);
851  //Any error to report?
852  if(error)
853  return error;
854 
855  //Update the length of the RSAPrivateKey structure
856  length += n;
857 
858  //Advance data pointer
859  if(output != NULL)
860  {
861  p += n;
862  }
863 
864  //Write Exponent1 field
865  error = asn1WriteMpi(&privateKey->dp, FALSE, p, &n);
866  //Any error to report?
867  if(error)
868  return error;
869 
870  //Update the length of the RSAPrivateKey structure
871  length += n;
872 
873  //Advance data pointer
874  if(output != NULL)
875  {
876  p += n;
877  }
878 
879  //Write Exponent2 field
880  error = asn1WriteMpi(&privateKey->dq, FALSE, p, &n);
881  //Any error to report?
882  if(error)
883  return error;
884 
885  //Update the length of the RSAPrivateKey structure
886  length += n;
887 
888  //Advance data pointer
889  if(output != NULL)
890  {
891  p += n;
892  }
893 
894  //Write Coefficient field
895  error = asn1WriteMpi(&privateKey->qinv, FALSE, p, &n);
896  //Any error to report?
897  if(error)
898  return error;
899 
900  //Update the length of the RSAPrivateKey structure
901  length += n;
902 
903  //Advance data pointer
904  if(output != NULL)
905  {
906  p += n;
907  }
908 
909  //The private key is encapsulated within a sequence
910  tag.constructed = TRUE;
913  tag.length = length;
914  tag.value = output;
915 
916  //Write RSAPrivateKey structure
917  error = asn1WriteTag(&tag, FALSE, output, &n);
918  //Any error to report?
919  if(error)
920  return error;
921 
922  //Total number of bytes that have been written
923  *written = tag.totalLength;
924 
925  //Successful processing
926  return NO_ERROR;
927 }
928 
929 
930 /**
931  * @brief Export a DSA public key to ASN.1 format
932  * @param[in] publicKey Pointer to the DSA public key
933  * @param[out] output Buffer where to store the ASN.1 structure
934  * @param[out] written Length of the resulting ASN.1 structure
935  * @return Error code
936  **/
937 
939  uint8_t *output, size_t *written)
940 {
941  error_t error;
942  size_t n;
943 
944  //Write public key
945  error = asn1WriteMpi(&publicKey->y, FALSE, output, &n);
946  //Any error to report?
947  if(error)
948  return error;
949 
950  //Total number of bytes that have been written
951  *written = n;
952 
953  //Successful processing
954  return NO_ERROR;
955 }
956 
957 
958 /**
959  * @brief Export a DSA private key to ASN.1 format
960  * @param[in] privateKey Pointer to the DSA private key
961  * @param[out] output Buffer where to store the ASN.1 structure
962  * @param[out] written Length of the resulting ASN.1 structure
963  * @return Error code
964  **/
965 
967  uint8_t *output, size_t *written)
968 {
969  error_t error;
970  size_t n;
971 
972  //Write private key
973  error = asn1WriteMpi(&privateKey->x, FALSE, output, &n);
974  //Any error to report?
975  if(error)
976  return error;
977 
978  //Total number of bytes that have been written
979  *written = n;
980 
981  //Successful processing
982  return NO_ERROR;
983 }
984 
985 
986 /**
987  * @brief Export DSA domain parameters to ASN.1 format
988  * @param[in] params Pointer to the DSA domain parameters
989  * @param[out] output Buffer where to store the ASN.1 structure
990  * @param[out] written Length of the resulting ASN.1 structure
991  * @return Error code
992  **/
993 
995  uint8_t *output, size_t *written)
996 {
997  error_t error;
998  size_t n;
999  size_t length;
1000  uint8_t *p;
1001  Asn1Tag tag;
1002 
1003  //Point to the buffer where to write the ASN.1 structure
1004  p = output;
1005  //Length of the ASN.1 structure
1006  length = 0;
1007 
1008  //Write parameter p
1009  error = asn1WriteMpi(&params->p, FALSE, p, &n);
1010  //Any error to report?
1011  if(error)
1012  return error;
1013 
1014  //Advance data pointer
1015  p += n;
1016  length += n;
1017 
1018  //Write parameter q
1019  error = asn1WriteMpi(&params->q, FALSE, p, &n);
1020  //Any error to report?
1021  if(error)
1022  return error;
1023 
1024  //Advance data pointer
1025  p += n;
1026  length += n;
1027 
1028  //Write parameter g
1029  error = asn1WriteMpi(&params->g, FALSE, p, &n);
1030  //Any error to report?
1031  if(error)
1032  return error;
1033 
1034  //Advance data pointer
1035  p += n;
1036  length += n;
1037 
1038  //The DSA domain parameters are encapsulated within a sequence
1039  tag.constructed = TRUE;
1042  tag.length = length;
1043  tag.value = output;
1044 
1045  //Write DSAParameters structure
1046  error = asn1WriteTag(&tag, FALSE, output, &n);
1047  //Any error to report?
1048  if(error)
1049  return error;
1050 
1051  //Total number of bytes that have been written
1052  *written = n;
1053 
1054  //Successful processing
1055  return NO_ERROR;
1056 }
1057 
1058 
1059 /**
1060  * @brief Export an EC public key to ASN.1 format
1061  * @param[in] publicKeyInfo Public key information
1062  * @param[in] publicKey Pointer to the EC public key
1063  * @param[out] output Buffer where to store the ASN.1 structure
1064  * @param[out] written Length of the resulting ASN.1 structure
1065  * @return Error code
1066  **/
1067 
1069  const EcPoint *publicKey, uint8_t *output, size_t *written)
1070 {
1071 #if (EC_SUPPORT == ENABLED)
1072  error_t error;
1073  const EcCurveInfo *curveInfo;
1074  EcDomainParameters params;
1075 
1076  //Initialize EC domain parameters
1077  ecInitDomainParameters(&params);
1078 
1079  //Retrieve EC domain parameters
1080  curveInfo = x509GetCurveInfo(publicKeyInfo->ecParams.namedCurve.value,
1081  publicKeyInfo->ecParams.namedCurve.length);
1082 
1083  //Make sure the specified elliptic curve is supported
1084  if(curveInfo != NULL)
1085  {
1086  //Load EC domain parameters
1087  error = ecLoadDomainParameters(&params, curveInfo);
1088  }
1089  else
1090  {
1091  //Invalid EC domain parameters
1092  error = ERROR_WRONG_IDENTIFIER;
1093  }
1094 
1095  //Check status code
1096  if(!error)
1097  {
1098  //Format ECPublicKey structure
1099  error = ecExport(&params, publicKey, output, written);
1100  }
1101 
1102  //Release EC domain parameters
1103  ecFreeDomainParameters(&params);
1104 
1105  //Return status code
1106  return error;
1107 #else
1108  //Not implemented
1109  return ERROR_NOT_IMPLEMENTED;
1110 #endif
1111 }
1112 
1113 
1114 /**
1115  * @brief Export an EdDSA public key to ASN.1 format
1116  * @param[in] publicKey Pointer to the EdDSA public key
1117  * @param[in] publicKeyLen Length of the EdDSA public key, in bytes
1118  * @param[out] output Buffer where to store the ASN.1 structure
1119  * @param[out] written Length of the resulting ASN.1 structure
1120  * @return Error code
1121  **/
1122 
1124  size_t publicKeyLen, uint8_t *output, size_t *written)
1125 {
1126  error_t error;
1127 
1128  //The SubjectPublicKey contains the byte stream of the public key
1129  error = mpiExport(&publicKey->q, output, publicKeyLen,
1131  //Any error to report?
1132  if(error)
1133  return error;
1134 
1135  //Total number of bytes that have been written
1136  *written = publicKeyLen;
1137 
1138  //Successful processing
1139  return NO_ERROR;
1140 }
1141 
1142 
1143 /**
1144  * @brief Export an EdDSA private key to ASN.1 format
1145  * @param[in] privateKey Pointer to the EdDSA private key
1146  * @param[in] privateKeyLen Length of the EdDSA private key, in bytes
1147  * @param[out] output Buffer where to store the ASN.1 structure
1148  * @param[out] written Length of the resulting ASN.1 structure
1149  * @return Error code
1150  **/
1151 
1153  size_t privateKeyLen, uint8_t *output, size_t *written)
1154 {
1155  error_t error;
1156  size_t n;
1157  Asn1Tag tag;
1158 
1159  //The private key is always an opaque byte sequence
1160  error = mpiExport(&privateKey->d, output, privateKeyLen,
1162  //Any error to report?
1163  if(error)
1164  return error;
1165 
1166  //The private key is encapsulated within an octet string
1167  tag.constructed = FALSE;
1170  tag.length = privateKeyLen;
1171  tag.value = output;
1172 
1173  //Write CurvePrivateKey structure
1174  error = asn1WriteTag(&tag, FALSE, output, &n);
1175  //Any error to report?
1176  if(error)
1177  return error;
1178 
1179  //Total number of bytes that have been written
1180  *written = tag.totalLength;
1181 
1182  //Successful processing
1183  return NO_ERROR;
1184 }
1185 
1186 #endif
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:495
error_t asn1WriteMpi(const Mpi *value, bool_t reverse, uint8_t *data, size_t *written)
Write a multiple-precision integer from the output stream.
Definition: asn1.c:591
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:334
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_OBJECT_IDENTIFIER
Definition: asn1.h:74
@ ASN1_TYPE_BIT_STRING
Definition: asn1.h:71
@ ASN1_TYPE_NULL
Definition: asn1.h:73
@ ASN1_TYPE_OCTET_STRING
Definition: asn1.h:72
@ ASN1_TYPE_INTEGER
Definition: asn1.h:70
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:80
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
General definitions for cryptographic algorithms.
Debugging facilities.
uint8_t n
const uint8_t DSA_OID[7]
Definition: dsa.c:51
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:72
error_t ecExport(const EcDomainParameters *params, const EcPoint *a, uint8_t *data, size_t *length)
Convert an EC point to an octet string.
Definition: ec.c:438
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:51
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:43
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:90
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:98
const uint8_t X448_OID[3]
Definition: ec_curves.c:96
const uint8_t X25519_OID[3]
Definition: ec_curves.c:94
const uint8_t ED448_OID[3]
Definition: ec_curves.c:100
#define ED25519_PUBLIC_KEY_LEN
Definition: ed25519.h:42
#define ED448_PUBLIC_KEY_LEN
Definition: ed448.h:42
EdDSA (Edwards-Curve Digital Signature Algorithm)
error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-1.
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
error_t mpiExport(const Mpi *a, uint8_t *data, uint_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:709
@ MPI_FORMAT_LITTLE_ENDIAN
Definition: mpi.h:70
uint8_t p
Definition: ndp.h:300
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:103
OID (Object Identifier)
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define TRUE
Definition: os_port.h:50
#define FALSE
Definition: os_port.h:46
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:57
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:88
SHA-1 (Secure Hash Algorithm 1)
ASN.1 tag.
Definition: asn1.h:102
size_t totalLength
Definition: asn1.h:108
const uint8_t * value
Definition: asn1.h:107
uint_t objClass
Definition: asn1.h:104
uint_t objType
Definition: asn1.h:105
bool_t constructed
Definition: asn1.h:103
size_t length
Definition: asn1.h:106
DSA domain parameters.
Definition: dsa.h:49
Mpi p
Prime modulus.
Definition: dsa.h:50
Mpi q
Group order.
Definition: dsa.h:51
Mpi g
Group generator.
Definition: dsa.h:52
DSA private key.
Definition: dsa.h:72
Mpi x
Secret exponent.
Definition: dsa.h:74
DSA public key.
Definition: dsa.h:61
Mpi y
Public key value.
Definition: dsa.h:63
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:62
Elliptic curve parameters.
Definition: ec_curves.h:295
EC domain parameters.
Definition: ec.h:76
EC point.
Definition: ec.h:64
EdDSA private key.
Definition: eddsa.h:59
Mpi d
Private key.
Definition: eddsa.h:60
EdDSA public key.
Definition: eddsa.h:49
Mpi q
Public key.
Definition: eddsa.h:50
RSA private key.
Definition: rsa.h:68
Mpi p
First factor.
Definition: rsa.h:72
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
Mpi e
Public exponent.
Definition: rsa.h:70
Mpi q
Second factor.
Definition: rsa.h:73
Mpi d
Private exponent.
Definition: rsa.h:71
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
Mpi n
Modulus.
Definition: rsa.h:69
RSA public key.
Definition: rsa.h:57
Mpi e
Public exponent.
Definition: rsa.h:59
Mpi n
Modulus.
Definition: rsa.h:58
DSA domain parameters.
Definition: x509_common.h:741
X509OctetString p
Definition: x509_common.h:742
X509OctetString q
Definition: x509_common.h:743
X509OctetString g
Definition: x509_common.h:744
DSA public key.
Definition: x509_common.h:753
X509OctetString y
Definition: x509_common.h:754
EC parameters.
Definition: x509_common.h:763
X509OctetString namedCurve
Definition: x509_common.h:764
EC public key.
Definition: x509_common.h:773
X509OctetString q
Definition: x509_common.h:774
const uint8_t * value
Definition: x509_common.h:647
RSA public key.
Definition: x509_common.h:730
X509OctetString n
Definition: x509_common.h:731
X509OctetString e
Definition: x509_common.h:732
Subject Public Key Information extension.
Definition: x509_common.h:783
X509RsaPublicKey rsaPublicKey
Definition: x509_common.h:788
X509DsaPublicKey dsaPublicKey
Definition: x509_common.h:792
X509EcPublicKey ecPublicKey
Definition: x509_common.h:796
X509OctetString oid
Definition: x509_common.h:785
X509DsaParameters dsaParams
Definition: x509_common.h:791
X509EcParameters ecParams
Definition: x509_common.h:795
uint8_t length
Definition: tcp.h:368
const EcCurveInfo * x509GetCurveInfo(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: x509_common.c:910
@ PKCS1_VERSION_1
Definition: x509_common.h:438
error_t x509ExportEcPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, const EcPoint *publicKey, uint8_t *output, size_t *written)
Export an EC public key to ASN.1 format.
error_t x509FormatDsaPublicKey(const X509DsaPublicKey *dsaPublicKey, uint8_t *output, size_t *written)
Format DSAPublicKey structure.
error_t x509ExportRsaPublicKey(const RsaPublicKey *publicKey, uint8_t *output, size_t *written)
Export an RSA public key to ASN.1 format.
error_t x509FormatRsaPublicKey(const X509RsaPublicKey *rsaPublicKey, uint8_t *output, size_t *written)
Format RSAPublicKey structure.
error_t x509FormatDsaParameters(const X509DsaParameters *dsaParams, uint8_t *output, size_t *written)
Format DSA domain parameters.
error_t x509ExportEddsaPublicKey(const EddsaPublicKey *publicKey, size_t publicKeyLen, uint8_t *output, size_t *written)
Export an EdDSA public key to ASN.1 format.
error_t x509ExportDsaPrivateKey(const DsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export a DSA private key to ASN.1 format.
error_t x509FormatAlgoId(const X509SubjectPublicKeyInfo *publicKeyInfo, const void *params, uint8_t *output, size_t *written)
Format AlgorithmIdentifier structure.
error_t x509ExportDsaParameters(const DsaDomainParameters *params, uint8_t *output, size_t *written)
Export DSA domain parameters to ASN.1 format.
error_t x509FormatSubjectPublicKeyInfo(const X509SubjectPublicKeyInfo *publicKeyInfo, const void *publicKey, uint8_t *keyId, uint8_t *output, size_t *written)
Format SubjectPublicKeyInfo structure.
error_t x509ExportEddsaPrivateKey(const EddsaPrivateKey *privateKey, size_t privateKeyLen, uint8_t *output, size_t *written)
Export an EdDSA private key to ASN.1 format.
error_t x509ExportDsaPublicKey(const DsaPublicKey *publicKey, uint8_t *output, size_t *written)
Export a DSA public key to ASN.1 format.
error_t x509ExportRsaPrivateKey(const RsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export an RSA private key to ASN.1 format.
error_t x509FormatEcPublicKey(const X509EcPublicKey *ecPublicKey, uint8_t *output, size_t *written)
Format ECPublicKey structure.
error_t x509FormatEcParameters(const X509EcParameters *ecParams, uint8_t *output, size_t *written)
Format ECParameters structure.
Formatting of ASN.1 encoded keys.