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-2025 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.5.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 && OID_COMP(oid, oidLen, DSA_OID) == 0)
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?
111  if(OID_COMP(oid, oidLen, RSA_ENCRYPTION_OID) == 0 ||
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(OID_COMP(oid, oidLen, DSA_OID) == 0)
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
156  error = ecExportPublicKey(publicKey, 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(OID_COMP(oid, oidLen, ED25519_OID) == 0)
171  {
172  //Valid EdDSA public key?
173  if(publicKey != NULL)
174  {
175  //Export the EdDSA public key
176  error = eddsaExportPublicKey(publicKey, p + 1, &n);
177  }
178  else
179  {
180  //The SubjectPublicKey contains the byte stream of the public key
181  error = x509FormatEcPublicKey(&publicKeyInfo->ecPublicKey,
182  p + 1, &n);
183  }
184  }
185  else
186 #endif
187 #if (ED448_SUPPORT == ENABLED)
188  //Ed448 algorithm identifier?
189  if(OID_COMP(oid, oidLen, ED448_OID) == 0)
190  {
191  //Valid EdDSA public key?
192  if(publicKey != NULL)
193  {
194  //Export the EdDSA public key
195  error = eddsaExportPublicKey(publicKey, p + 1, &n);
196  }
197  else
198  {
199  //The SubjectPublicKey contains the byte stream of the public key
200  error = x509FormatEcPublicKey(&publicKeyInfo->ecPublicKey,
201  p + 1, &n);
202  }
203  }
204  else
205 #endif
206  //Unknown algorithm identifier?
207  {
208  //Report an error
209  error = ERROR_INVALID_PARAMETER;
210  }
211 
212  //Any error to report?
213  if(error)
214  return error;
215 
216  //The keyIdentifier parameter is optional
217  if(keyId != NULL)
218  {
219  //The keyIdentifier is composed of the 160-bit SHA-1 hash of the value
220  //of the bit string subjectPublicKey (excluding the tag, length, and
221  //number of unused bits)
222  error = sha1Compute(p + 1, n, keyId);
223  //Any error to report?
224  if(error)
225  return error;
226  }
227 
228  //The public key is encapsulated within a bit string
229  tag.constructed = FALSE;
232  tag.length = n + 1;
233  tag.value = p;
234 
235  //Write the corresponding ASN.1 tag
236  error = asn1WriteTag(&tag, FALSE, p, &n);
237  //Any error to report?
238  if(error)
239  return error;
240 
241  //Advance data pointer
242  p += n;
243  length += n;
244 
245  //The SubjectPublicKeyInfo structure is encapsulated within a sequence
246  tag.constructed = TRUE;
249  tag.length = length;
250  tag.value = output;
251 
252  //Write the corresponding ASN.1 tag
253  error = asn1WriteTag(&tag, FALSE, output, &n);
254  //Any error to report?
255  if(error)
256  return error;
257 
258  //Total number of bytes that have been written
259  *written = n;
260 
261  //Successful processing
262  return NO_ERROR;
263 }
264 
265 
266 /**
267  * @brief Format AlgorithmIdentifier structure
268  * @param[in] publicKeyInfo Subject's public key information
269  * @param[in] params Pointer to the domain parameters (DSA or ECDSA)
270  * @param[out] output Buffer where to format the ASN.1 structure
271  * @param[out] written Length of the resulting ASN.1 structure
272  * @return Error code
273  **/
274 
276  const void *params, uint8_t *output, size_t *written)
277 {
278  error_t error;
279  size_t n;
280  size_t length;
281  uint8_t *p;
282  size_t oidLen;
283  const uint8_t *oid;
284  Asn1Tag tag;
285 
286  //Get the public key identifier
287  oid = publicKeyInfo->oid.value;
288  oidLen = publicKeyInfo->oid.length;
289 
290  //Point to the buffer where to write the ASN.1 structure
291  p = output;
292  //Length of the ASN.1 structure
293  length = 0;
294 
295  //Format algorithm OID
296  tag.constructed = FALSE;
299  tag.length = oidLen;
300  tag.value = oid;
301 
302  //Write the corresponding ASN.1 tag
303  error = asn1WriteTag(&tag, FALSE, p, &n);
304  //Any error to report?
305  if(error)
306  return error;
307 
308  //Advance data pointer
309  p += n;
310  length += n;
311 
312 #if (RSA_SUPPORT == ENABLED)
313  //RSA algorithm identifier?
315  {
316  //The parameters field must have ASN.1 type NULL for this algorithm
317  //identifier (refer to RFC 3279, section 2.3.1)
318  tag.constructed = FALSE;
320  tag.objType = ASN1_TYPE_NULL;
321  tag.length = 0;
322  tag.value = NULL;
323 
324  //Write the corresponding ASN.1 tag
325  error = asn1WriteTag(&tag, FALSE, p, &n);
326  }
327  //RSA-PSS algorithm identifier?
328  else if(OID_COMP(oid, oidLen, RSASSA_PSS_OID) == 0)
329  {
330  //The parameters may be either absent or present when used as subject
331  //public key information (refer to RFC 4055, section 3.1)
332  n = 0;
333  }
334  else
335 #endif
336 #if (DSA_SUPPORT == ENABLED)
337  //DSA algorithm identifier?
338  if(OID_COMP(oid, oidLen, DSA_OID) == 0)
339  {
340  //Valid DSA domain parameters?
341  if(params != NULL)
342  {
343  //Export the DSA domain parameters to ASN.1 format
344  error = x509ExportDsaParameters(params, p, &n);
345  }
346  else
347  {
348  //Format DSAParameters structure
349  error = x509FormatDsaParameters(&publicKeyInfo->dsaParams, p, &n);
350  }
351  }
352  else
353 #endif
354 #if (EC_SUPPORT == ENABLED)
355  //EC public key identifier?
357  {
358  //Format ECParameters structure
359  error = x509FormatEcParameters(&publicKeyInfo->ecParams, p, &n);
360  }
361  else
362 #endif
363 #if (ED25519_SUPPORT == ENABLED)
364  //X25519 or Ed25519 algorithm identifier?
365  if(OID_COMP(oid, oidLen, X25519_OID) == 0 ||
366  OID_COMP(oid, oidLen, ED25519_OID) == 0)
367  {
368  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
369  //section 3)
370  n = 0;
371  }
372  else
373 #endif
374 #if (ED448_SUPPORT == ENABLED)
375  //X448 or Ed448 algorithm identifier?
376  if(OID_COMP(oid, oidLen, X448_OID) == 0 ||
377  OID_COMP(oid, oidLen, ED448_OID) == 0)
378  {
379  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
380  //section 3)
381  n = 0;
382  }
383  else
384 #endif
385  //Unknown algorithm identifier?
386  {
387  //Report an error
388  error = ERROR_INVALID_PARAMETER;
389  }
390 
391  //Any error to report?
392  if(error)
393  return error;
394 
395  //Advance data pointer
396  p += n;
397  length += n;
398 
399  //The AlgorithmIdentifier structure is encapsulated within a sequence
400  tag.constructed = TRUE;
403  tag.length = length;
404  tag.value = output;
405 
406  //Write the corresponding ASN.1 tag
407  error = asn1WriteTag(&tag, FALSE, output, &n);
408  //Any error to report?
409  if(error)
410  return error;
411 
412  //Total number of bytes that have been written
413  *written = n;
414 
415  //Successful processing
416  return NO_ERROR;
417 }
418 
419 
420 /**
421  * @brief Format RSAPublicKey structure
422  * @param[in] rsaPublicKey Pointer to the RSA public key
423  * @param[out] output Buffer where to format the ASN.1 structure
424  * @param[out] written Length of the resulting ASN.1 structure
425  * @return Error code
426  **/
427 
429  uint8_t *output, size_t *written)
430 {
431  error_t error;
432  size_t n;
433  size_t length;
434  uint8_t *p;
435  Asn1Tag tag;
436 
437  //Point to the buffer where to write the ASN.1 structure
438  p = output;
439  //Length of the ASN.1 structure
440  length = 0;
441 
442  //Write Modulus field
443  tag.constructed = FALSE;
446  tag.length = rsaPublicKey->n.length;
447  tag.value = rsaPublicKey->n.value;
448 
449  //Write the corresponding ASN.1 tag
450  error = asn1WriteTag(&tag, FALSE, p, &n);
451  //Any error to report?
452  if(error)
453  return error;
454 
455  //Advance data pointer
456  p += n;
457  length += n;
458 
459  //Write PublicExponent field
460  tag.constructed = FALSE;
463  tag.length = rsaPublicKey->e.length;
464  tag.value = rsaPublicKey->e.value;
465 
466  //Write the corresponding ASN.1 tag
467  error = asn1WriteTag(&tag, FALSE, p, &n);
468  //Any error to report?
469  if(error)
470  return error;
471 
472  //Advance data pointer
473  p += n;
474  length += n;
475 
476  //The public key is encapsulated within a sequence
477  tag.constructed = TRUE;
480  tag.length = length;
481  tag.value = output;
482 
483  //Write RSAPublicKey structure
484  error = asn1WriteTag(&tag, FALSE, output, &n);
485  //Any error to report?
486  if(error)
487  return error;
488 
489  //Total number of bytes that have been written
490  *written = n;
491 
492  //Successful processing
493  return NO_ERROR;
494 }
495 
496 
497 /**
498  * @brief Format DSAPublicKey structure
499  * @param[in] dsaPublicKey Pointer to the DSA public key
500  * @param[out] output Buffer where to format the DSAPublicKey structure
501  * @param[out] written Length of the DSAPublicKey structure
502  * @return Error code
503  **/
504 
506  uint8_t *output, size_t *written)
507 {
508  error_t error;
509  size_t n;
510  Asn1Tag tag;
511 
512  //Write public key
513  tag.constructed = FALSE;
516  tag.length = dsaPublicKey->y.length;
517  tag.value = dsaPublicKey->y.value;
518 
519  //Write the corresponding ASN.1 tag
520  error = asn1WriteTag(&tag, FALSE, output, &n);
521  //Any error to report?
522  if(error)
523  return error;
524 
525  //Total number of bytes that have been written
526  *written = n;
527 
528  //Successful processing
529  return NO_ERROR;
530 }
531 
532 
533 /**
534  * @brief Format DSA domain parameters
535  * @param[in] dsaParams Pointer to the DSA domain parameters
536  * @param[out] output Buffer where to format the ASN.1 structure
537  * @param[out] written Length of the resulting ASN.1 structure
538  * @return Error code
539  **/
540 
542  uint8_t *output, size_t *written)
543 {
544  error_t error;
545  size_t n;
546  size_t length;
547  uint8_t *p;
548  Asn1Tag tag;
549 
550  //Point to the buffer where to write the ASN.1 structure
551  p = output;
552  //Length of the ASN.1 structure
553  length = 0;
554 
555  //Write parameter p
556  tag.constructed = FALSE;
559  tag.length = dsaParams->p.length;
560  tag.value = dsaParams->p.value;
561 
562  //Write the corresponding ASN.1 tag
563  error = asn1WriteTag(&tag, FALSE, p, &n);
564  //Any error to report?
565  if(error)
566  return error;
567 
568  //Advance data pointer
569  p += n;
570  length += n;
571 
572  //Write parameter q
573  tag.constructed = FALSE;
576  tag.length = dsaParams->q.length;
577  tag.value = dsaParams->q.value;
578 
579  //Write the corresponding ASN.1 tag
580  error = asn1WriteTag(&tag, FALSE, p, &n);
581  //Any error to report?
582  if(error)
583  return error;
584 
585  //Advance data pointer
586  p += n;
587  length += n;
588 
589  //Write parameter g
590  tag.constructed = FALSE;
593  tag.length = dsaParams->g.length;
594  tag.value = dsaParams->g.value;
595 
596  //Write the corresponding ASN.1 tag
597  error = asn1WriteTag(&tag, FALSE, p, &n);
598  //Any error to report?
599  if(error)
600  return error;
601 
602  //Advance data pointer
603  p += n;
604  length += n;
605 
606  //The DSA domain parameters are encapsulated within a sequence
607  tag.constructed = TRUE;
610  tag.length = length;
611  tag.value = output;
612 
613  //Write DSAParameters structure
614  error = asn1WriteTag(&tag, FALSE, output, &n);
615  //Any error to report?
616  if(error)
617  return error;
618 
619  //Total number of bytes that have been written
620  *written = n;
621 
622  //Successful processing
623  return NO_ERROR;
624 }
625 
626 
627 /**
628  * @brief Format ECPublicKey structure
629  * @param[in] ecPublicKey Pointer to the EC public key
630  * @param[out] output Buffer where to format the ASN.1 structure
631  * @param[out] written Length of the resulting ASN.1 structure
632  * @return Error code
633  **/
634 
636  uint8_t *output, size_t *written)
637 {
638  //Copy the EC public key
639  osMemcpy(output, ecPublicKey->q.value, ecPublicKey->q.length);
640 
641  //Total number of bytes that have been written
642  *written = ecPublicKey->q.length;
643 
644  //Successful processing
645  return NO_ERROR;
646 }
647 
648 
649 /**
650  * @brief Format ECParameters structure
651  * @param[in] ecParams Pointer to the EC parameters
652  * @param[out] output Buffer where to format the ECParameters structure
653  * @param[out] written Length of the ECParameters structure
654  * @return Error code
655  **/
656 
658  uint8_t *output, size_t *written)
659 {
660  error_t error;
661  size_t n;
662  Asn1Tag tag;
663 
664  //The namedCurve field identifies all the required values for a particular
665  //set of elliptic curve domain parameters to be represented by an object
666  //identifier
667  tag.constructed = FALSE;
670  tag.length = ecParams->namedCurve.length;
671  tag.value = ecParams->namedCurve.value;
672 
673  //Write the corresponding ASN.1 tag
674  error = asn1WriteTag(&tag, FALSE, output, &n);
675  //Any error to report?
676  if(error)
677  return error;
678 
679  //Total number of bytes that have been written
680  *written = n;
681 
682  //Successful processing
683  return NO_ERROR;
684 }
685 
686 
687 /**
688  * @brief Export an RSA public key to ASN.1 format
689  * @param[in] publicKey Pointer to the RSA public key
690  * @param[out] output Buffer where to store the ASN.1 structure
691  * @param[out] written Length of the resulting ASN.1 structure
692  * @return Error code
693  **/
694 
696  uint8_t *output, size_t *written)
697 {
698  error_t error;
699  size_t n;
700  size_t length;
701  uint8_t *p;
702  Asn1Tag tag;
703 
704  //Point to the buffer where to write the ASN.1 structure
705  p = output;
706  //Length of the ASN.1 structure
707  length = 0;
708 
709  //Write Modulus field
710  error = asn1WriteMpi(&publicKey->n, FALSE, p, &n);
711  //Any error to report?
712  if(error)
713  return error;
714 
715  //Advance data pointer
716  p += n;
717  length += n;
718 
719  //Write PublicExponent field
720  error = asn1WriteMpi(&publicKey->e, FALSE, p, &n);
721  //Any error to report?
722  if(error)
723  return error;
724 
725  //Advance data pointer
726  p += n;
727  length += n;
728 
729  //The public key is encapsulated within a sequence
730  tag.constructed = TRUE;
733  tag.length = length;
734  tag.value = output;
735 
736  //Write RSAPublicKey structure
737  error = asn1WriteTag(&tag, FALSE, output, &n);
738  //Any error to report?
739  if(error)
740  return error;
741 
742  //Total number of bytes that have been written
743  *written = n;
744 
745  //Successful processing
746  return NO_ERROR;
747 }
748 
749 
750 /**
751  * @brief Export an RSA private key to ASN.1 format
752  * @param[in] privateKey Pointer to the RSA private key
753  * @param[out] output Buffer where to store the ASN.1 structure
754  * @param[out] written Length of the resulting ASN.1 structure
755  * @return Error code
756  **/
757 
759  uint8_t *output, size_t *written)
760 {
761  error_t error;
762  size_t n;
763  size_t length;
764  uint8_t *p;
765  Asn1Tag tag;
766 
767  //Point to the buffer where to write the ASN.1 structure
768  p = output;
769  //Length of the ASN.1 structure
770  length = 0;
771 
772  //Write Version field
773  error = asn1WriteInt32(PKCS1_VERSION_1, FALSE, p, &n);
774  //Any error to report?
775  if(error)
776  return error;
777 
778  //Update the length of the RSAPrivateKey structure
779  length += n;
780 
781  //Advance data pointer
782  if(output != NULL)
783  {
784  p += n;
785  }
786 
787  //Write Modulus field
788  error = asn1WriteMpi(&privateKey->n, FALSE, p, &n);
789  //Any error to report?
790  if(error)
791  return error;
792 
793  //Update the length of the RSAPrivateKey structure
794  length += n;
795 
796  //Advance data pointer
797  if(output != NULL)
798  {
799  p += n;
800  }
801 
802  //Write PublicExponent field
803  error = asn1WriteMpi(&privateKey->e, FALSE, p, &n);
804  //Any error to report?
805  if(error)
806  return error;
807 
808  //Update the length of the RSAPrivateKey structure
809  length += n;
810 
811  //Advance data pointer
812  if(output != NULL)
813  {
814  p += n;
815  }
816 
817  //Write PrivateExponent field
818  error = asn1WriteMpi(&privateKey->d, FALSE, p, &n);
819  //Any error to report?
820  if(error)
821  return error;
822 
823  //Update the length of the RSAPrivateKey structure
824  length += n;
825 
826  //Advance data pointer
827  if(output != NULL)
828  {
829  p += n;
830  }
831 
832  //Write Prime1 field
833  error = asn1WriteMpi(&privateKey->p, FALSE, p, &n);
834  //Any error to report?
835  if(error)
836  return error;
837 
838  //Update the length of the RSAPrivateKey structure
839  length += n;
840 
841  //Advance data pointer
842  if(output != NULL)
843  {
844  p += n;
845  }
846 
847  //Write Prime2 field
848  error = asn1WriteMpi(&privateKey->q, FALSE, p, &n);
849  //Any error to report?
850  if(error)
851  return error;
852 
853  //Update the length of the RSAPrivateKey structure
854  length += n;
855 
856  //Advance data pointer
857  if(output != NULL)
858  {
859  p += n;
860  }
861 
862  //Write Exponent1 field
863  error = asn1WriteMpi(&privateKey->dp, FALSE, p, &n);
864  //Any error to report?
865  if(error)
866  return error;
867 
868  //Update the length of the RSAPrivateKey structure
869  length += n;
870 
871  //Advance data pointer
872  if(output != NULL)
873  {
874  p += n;
875  }
876 
877  //Write Exponent2 field
878  error = asn1WriteMpi(&privateKey->dq, FALSE, p, &n);
879  //Any error to report?
880  if(error)
881  return error;
882 
883  //Update the length of the RSAPrivateKey structure
884  length += n;
885 
886  //Advance data pointer
887  if(output != NULL)
888  {
889  p += n;
890  }
891 
892  //Write Coefficient field
893  error = asn1WriteMpi(&privateKey->qinv, FALSE, p, &n);
894  //Any error to report?
895  if(error)
896  return error;
897 
898  //Update the length of the RSAPrivateKey structure
899  length += n;
900 
901  //Advance data pointer
902  if(output != NULL)
903  {
904  p += n;
905  }
906 
907  //The private key is encapsulated within a sequence
908  tag.constructed = TRUE;
911  tag.length = length;
912  tag.value = output;
913 
914  //Write RSAPrivateKey structure
915  error = asn1WriteTag(&tag, FALSE, output, &n);
916  //Any error to report?
917  if(error)
918  return error;
919 
920  //Total number of bytes that have been written
921  *written = tag.totalLength;
922 
923  //Successful processing
924  return NO_ERROR;
925 }
926 
927 
928 /**
929  * @brief Export a DSA public key to ASN.1 format
930  * @param[in] publicKey Pointer to the DSA public key
931  * @param[out] output Buffer where to store the ASN.1 structure
932  * @param[out] written Length of the resulting ASN.1 structure
933  * @return Error code
934  **/
935 
937  uint8_t *output, size_t *written)
938 {
939  error_t error;
940  size_t n;
941 
942  //Write public key
943  error = asn1WriteMpi(&publicKey->y, FALSE, output, &n);
944  //Any error to report?
945  if(error)
946  return error;
947 
948  //Total number of bytes that have been written
949  *written = n;
950 
951  //Successful processing
952  return NO_ERROR;
953 }
954 
955 
956 /**
957  * @brief Export a DSA private key to ASN.1 format
958  * @param[in] privateKey Pointer to the DSA private key
959  * @param[out] output Buffer where to store the ASN.1 structure
960  * @param[out] written Length of the resulting ASN.1 structure
961  * @return Error code
962  **/
963 
965  uint8_t *output, size_t *written)
966 {
967  error_t error;
968  size_t n;
969 
970  //Write private key
971  error = asn1WriteMpi(&privateKey->x, FALSE, output, &n);
972  //Any error to report?
973  if(error)
974  return error;
975 
976  //Total number of bytes that have been written
977  *written = n;
978 
979  //Successful processing
980  return NO_ERROR;
981 }
982 
983 
984 /**
985  * @brief Export DSA domain parameters to ASN.1 format
986  * @param[in] params Pointer to the DSA domain parameters
987  * @param[out] output Buffer where to store the ASN.1 structure
988  * @param[out] written Length of the resulting ASN.1 structure
989  * @return Error code
990  **/
991 
993  uint8_t *output, size_t *written)
994 {
995  error_t error;
996  size_t n;
997  size_t length;
998  uint8_t *p;
999  Asn1Tag tag;
1000 
1001  //Point to the buffer where to write the ASN.1 structure
1002  p = output;
1003  //Length of the ASN.1 structure
1004  length = 0;
1005 
1006  //Write parameter p
1007  error = asn1WriteMpi(&params->p, FALSE, p, &n);
1008  //Any error to report?
1009  if(error)
1010  return error;
1011 
1012  //Advance data pointer
1013  p += n;
1014  length += n;
1015 
1016  //Write parameter q
1017  error = asn1WriteMpi(&params->q, 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  //Write parameter g
1027  error = asn1WriteMpi(&params->g, FALSE, p, &n);
1028  //Any error to report?
1029  if(error)
1030  return error;
1031 
1032  //Advance data pointer
1033  p += n;
1034  length += n;
1035 
1036  //The DSA domain parameters are encapsulated within a sequence
1037  tag.constructed = TRUE;
1040  tag.length = length;
1041  tag.value = output;
1042 
1043  //Write DSAParameters structure
1044  error = asn1WriteTag(&tag, FALSE, output, &n);
1045  //Any error to report?
1046  if(error)
1047  return error;
1048 
1049  //Total number of bytes that have been written
1050  *written = n;
1051 
1052  //Successful processing
1053  return NO_ERROR;
1054 }
1055 
1056 
1057 /**
1058  * @brief Export an EdDSA private key to ASN.1 format
1059  * @param[in] privateKey Pointer to the EdDSA private key
1060  * @param[out] output Buffer where to store the ASN.1 structure
1061  * @param[out] written Length of the resulting ASN.1 structure
1062  * @return Error code
1063  **/
1064 
1066  uint8_t *output, size_t *written)
1067 {
1068 #if (ED25519_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
1069  error_t error;
1070  size_t n;
1071  Asn1Tag tag;
1072 
1073  //The private key is always an opaque byte sequence
1074  error = eddsaExportPrivateKey(privateKey, output, &n);
1075 
1076  //Check status code
1077  if(!error)
1078  {
1079  //The private key is encapsulated within an octet string
1080  tag.constructed = FALSE;
1083  tag.length = n;
1084  tag.value = output;
1085 
1086  //Write CurvePrivateKey structure
1087  error = asn1WriteTag(&tag, FALSE, output, written);
1088  }
1089 
1090  //Return status code
1091  return error;
1092 #else
1093  //Not implemented
1094  return ERROR_NOT_IMPLEMENTED;
1095 #endif
1096 }
1097 
1098 #endif
error_t x509FormatEcParameters(const X509EcParameters *ecParams, uint8_t *output, size_t *written)
Format ECParameters structure.
error_t x509ExportEddsaPrivateKey(const EddsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export an EdDSA private key to ASN.1 format.
Mpi p
First factor.
Definition: rsa.h:72
error_t eddsaExportPrivateKey(const EddsaPrivateKey *key, uint8_t *data, size_t *length)
Export an EdDSA private key.
Definition: eddsa.c:424
const uint8_t X25519_OID[3]
Definition: ec_curves.c:108
X509OctetString g
Definition: x509_common.h:799
X509OctetString p
Definition: x509_common.h:797
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
error_t eddsaExportPublicKey(const EddsaPublicKey *key, uint8_t *data, size_t *length)
Export an EdDSA public key.
Definition: eddsa.c:327
X509DsaPublicKey dsaPublicKey
Definition: x509_common.h:847
OID (Object Identifier)
SHA-1 (Secure Hash Algorithm 1)
uint8_t p
Definition: ndp.h:300
Mpi q
Group order.
Definition: dsa.h:51
X509OctetString oid
Definition: x509_common.h:840
#define TRUE
Definition: os_port.h:50
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:44
Mpi n
Modulus.
Definition: rsa.h:69
X509EcParameters ecParams
Definition: x509_common.h:850
@ EC_PUBLIC_KEY_FORMAT_X963
Definition: ec.h:386
Mpi e
Public exponent.
Definition: rsa.h:59
Mpi p
Prime modulus.
Definition: dsa.h:50
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:85
uint8_t oid[]
Definition: lldp_tlv.h:300
Mpi d
Private exponent.
Definition: rsa.h:71
Mpi n
Modulus.
Definition: rsa.h:58
X509OctetString q
Definition: x509_common.h:798
EC public key.
Definition: x509_common.h:828
error_t x509FormatSubjectPublicKeyInfo(const X509SubjectPublicKeyInfo *publicKeyInfo, const void *publicKey, uint8_t *keyId, uint8_t *output, size_t *written)
Format SubjectPublicKeyInfo structure.
const uint8_t DSA_OID[7]
Definition: dsa.c:51
@ PKCS1_VERSION_1
Definition: x509_common.h:493
error_t sha1Compute(const void *data, size_t length, uint8_t *digest)
Digest a message using SHA-1.
size_t totalLength
Definition: asn1.h:108
size_t length
Definition: asn1.h:106
X509OctetString y
Definition: x509_common.h:809
#define FALSE
Definition: os_port.h:46
DSA public key.
Definition: dsa.h:61
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
#define osMemcpy(dest, src, length)
Definition: os_port.h:144
error_t x509FormatDsaPublicKey(const X509DsaPublicKey *dsaPublicKey, uint8_t *output, size_t *written)
Format DSAPublicKey structure.
error_t
Error codes.
Definition: error.h:43
Mpi g
Group generator.
Definition: dsa.h:52
error_t x509ExportDsaPublicKey(const DsaPublicKey *publicKey, uint8_t *output, size_t *written)
Export a DSA public key to ASN.1 format.
EC parameters.
Definition: x509_common.h:818
error_t x509ExportDsaPrivateKey(const DsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export a DSA private key to ASN.1 format.
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
RSA public key.
Definition: x509_common.h:785
error_t x509FormatAlgoId(const X509SubjectPublicKeyInfo *publicKeyInfo, const void *params, uint8_t *output, size_t *written)
Format AlgorithmIdentifier structure.
ASN.1 tag.
Definition: asn1.h:102
Mpi q
Second factor.
Definition: rsa.h:73
error_t x509ExportRsaPublicKey(const RsaPublicKey *publicKey, uint8_t *output, size_t *written)
Export an RSA public key to ASN.1 format.
RSA public key.
Definition: rsa.h:57
X509RsaPublicKey rsaPublicKey
Definition: x509_common.h:843
DSA domain parameters.
Definition: dsa.h:49
EdDSA (Edwards-Curve Digital Signature Algorithm)
General definitions for cryptographic algorithms.
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:741
error_t asn1WriteTag(Asn1Tag *tag, bool_t reverse, uint8_t *data, size_t *written)
Write an ASN.1 tag.
Definition: asn1.c:334
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:62
DSA private key.
Definition: dsa.h:72
X509DsaParameters dsaParams
Definition: x509_common.h:846
uint_t objClass
Definition: asn1.h:104
uint8_t length
Definition: tcp.h:375
Mpi e
Public exponent.
Definition: rsa.h:70
error_t x509FormatRsaPublicKey(const X509RsaPublicKey *rsaPublicKey, uint8_t *output, size_t *written)
Format RSAPublicKey structure.
error_t x509ExportRsaPrivateKey(const RsaPrivateKey *privateKey, uint8_t *output, size_t *written)
Export an RSA private key to ASN.1 format.
X509OctetString namedCurve
Definition: x509_common.h:819
const uint8_t ED448_OID[3]
Definition: ec_curves.c:114
Mpi qinv
CRT coefficient.
Definition: rsa.h:76
error_t ecExportPublicKey(const EcPublicKey *key, uint8_t *data, size_t *length, EcPublicKeyFormat format)
Export an EC public key.
Definition: ec.c:378
EdDSA private key.
Definition: eddsa.h:75
Mpi dq
Second factor's CRT exponent.
Definition: rsa.h:75
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:112
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:54
const uint8_t X448_OID[3]
Definition: ec_curves.c:110
@ ASN1_TYPE_OCTET_STRING
Definition: asn1.h:72
@ ASN1_TYPE_INTEGER
Definition: asn1.h:70
Formatting of ASN.1 encoded keys.
error_t x509FormatEcPublicKey(const X509EcPublicKey *ecPublicKey, uint8_t *output, size_t *written)
Format ECPublicKey structure.
X509OctetString q
Definition: x509_common.h:829
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
uint8_t n
RSA private key.
Definition: rsa.h:68
X509OctetString n
Definition: x509_common.h:786
X509OctetString e
Definition: x509_common.h:787
Subject Public Key Information extension.
Definition: x509_common.h:838
DSA domain parameters.
Definition: x509_common.h:796
error_t x509FormatDsaParameters(const X509DsaParameters *dsaParams, uint8_t *output, size_t *written)
Format DSA domain parameters.
error_t x509ExportDsaParameters(const DsaDomainParameters *params, uint8_t *output, size_t *written)
Export DSA domain parameters to ASN.1 format.
Mpi x
Secret exponent.
Definition: dsa.h:74
uint8_t oidLen
Definition: lldp_tlv.h:299
bool_t constructed
Definition: asn1.h:103
Mpi y
Public key value.
Definition: dsa.h:63
@ ASN1_TYPE_OBJECT_IDENTIFIER
Definition: asn1.h:74
@ ASN1_TYPE_SEQUENCE
Definition: asn1.h:80
const uint8_t * value
Definition: x509_common.h:702
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
@ ASN1_TYPE_BIT_STRING
Definition: asn1.h:71
X509EcPublicKey ecPublicKey
Definition: x509_common.h:851
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:645
DSA public key.
Definition: x509_common.h:808
const uint8_t * value
Definition: asn1.h:107
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
uint_t objType
Definition: asn1.h:105
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_NULL
Definition: asn1.h:73