pkcs8_key_parse.c
Go to the documentation of this file.
1 /**
2  * @file pkcs8_key_parse.c
3  * @brief PKCS #8 key parsing
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.2
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/pkcs8_key_parse.h"
37 #include "pkix/x509_key_parse.h"
38 #include "ecc/ec_misc.h"
39 #include "encoding/asn1.h"
40 #include "encoding/oid.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (PEM_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Parse PrivateKeyInfo structure
49  * @param[in] data Pointer to the ASN.1 structure to parse
50  * @param[in] length Length of the ASN.1 structure
51  * @param[out] privateKeyInfo Information resulting from the parsing process
52  * @return Error code
53  **/
54 
56  Pkcs8PrivateKeyInfo *privateKeyInfo)
57 {
58  error_t error;
59  size_t n;
60  size_t oidLen;
61  const uint8_t *oid;
62  Asn1Tag tag;
63 
64  //Clear the PrivateKeyInfo structure
65  osMemset(privateKeyInfo, 0, sizeof(Pkcs8PrivateKeyInfo));
66 
67  //The private key information is encapsulated within a sequence
68  error = asn1ReadSequence(data, length, &tag);
69  //Failed to decode ASN.1 tag?
70  if(error)
71  return error;
72 
73  //Point to the first field of the sequence
74  data = tag.value;
75  length = tag.length;
76 
77  //The Version field identifies the version of OneAsymmetricKey
78  error = asn1ReadInt32(data, length, &tag, &privateKeyInfo->version);
79  //Failed to decode ASN.1 tag?
80  if(error)
81  return error;
82 
83  //Check version
84  if(privateKeyInfo->version != PKCS8_VERSION_1 &&
85  privateKeyInfo->version != PKCS8_VERSION_2)
86  {
87  return ERROR_INVALID_VERSION;
88  }
89 
90  //Point to the next field
91  data += tag.totalLength;
92  length -= tag.totalLength;
93 
94  //Read PrivateKeyAlgorithm field
95  error = pkcs8ParsePrivateKeyAlgo(data, length, &n, privateKeyInfo);
96  //Failed to decode ASN.1 tag?
97  if(error)
98  return error;
99 
100  //Point to the next field
101  data += n;
102  length -= n;
103 
104  //The PrivateKey is encapsulated within an octet string
105  error = asn1ReadOctetString(data, length, &tag);
106  //Failed to decode ASN.1 tag?
107  if(error)
108  return error;
109 
110  //Get the private key algorithm identifier
111  oid = privateKeyInfo->oid.value;
112  oidLen = privateKeyInfo->oid.length;
113 
114 #if (RSA_SUPPORT == ENABLED)
115  //RSA or RSA-PSS algorithm identifier?
116  if(OID_COMP(oid, oidLen, RSA_ENCRYPTION_OID) == 0 ||
118  {
119  //Read RSAPrivateKey structure
120  error = pkcs8ParseRsaPrivateKey(tag.value, tag.length,
121  &privateKeyInfo->rsaPrivateKey);
122  }
123  else
124 #endif
125 #if (DSA_SUPPORT == ENABLED)
126  //DSA algorithm identifier?
127  if(OID_COMP(oid, oidLen, DSA_OID) == 0)
128  {
129  //Read DSAPrivateKey structure
130  error = pkcs8ParseDsaPrivateKey(tag.value, tag.length, NULL,
131  &privateKeyInfo->dsaPrivateKey, NULL);
132  }
133  else
134 #endif
135 #if (EC_SUPPORT == ENABLED)
136  //EC public key identifier?
138  {
139  //Read ECPrivateKey structure
140  error = pkcs8ParseEcPrivateKey(tag.value, tag.length,
141  &privateKeyInfo->ecParams, &privateKeyInfo->ecPrivateKey,
142  &privateKeyInfo->ecPublicKey);
143  }
144  else
145 #endif
146 #if (ED25519_SUPPORT == ENABLED)
147  //X25519 or Ed25519 algorithm identifier?
148  if(OID_COMP(oid, oidLen, X25519_OID) == 0 ||
149  OID_COMP(oid, oidLen, ED25519_OID) == 0)
150  {
151  //Read CurvePrivateKey structure
152  error = pkcs8ParseEddsaPrivateKey(tag.value, tag.length,
153  &privateKeyInfo->eddsaPrivateKey);
154  }
155  else
156 #endif
157 #if (ED448_SUPPORT == ENABLED)
158  //X448 or Ed448 algorithm identifier?
159  if(OID_COMP(oid, oidLen, X448_OID) == 0 ||
160  OID_COMP(oid, oidLen, ED448_OID) == 0)
161  {
162  //Read CurvePrivateKey structure
163  error = pkcs8ParseEddsaPrivateKey(tag.value, tag.length,
164  &privateKeyInfo->eddsaPrivateKey);
165  }
166  else
167 #endif
168  //Unknown algorithm identifier?
169  {
170  //Report an error
171  error = ERROR_WRONG_IDENTIFIER;
172  }
173 
174  //Any error to report?
175  if(error)
176  return error;
177 
178  //Point to the next field
179  data += tag.totalLength;
180  length -= tag.totalLength;
181 
182  //Check version
183  if(privateKeyInfo->version == PKCS8_VERSION_2)
184  {
185  //The OneAsymmetricKey structure allows for the public key and additional
186  //attributes about the key to be included as well (refer to RFC 8410,
187  //section 7)
188  while(length > 0)
189  {
190  //Read current attribute
191  error = asn1ReadTag(data, length, &tag);
192  //Failed to decode ASN.1 tag?
193  if(error)
194  return error;
195 
196  //Explicit tagging shall be used to encode each optional attribute
198  return ERROR_INVALID_CLASS;
199 
200  //Check attribute type
201  if(tag.objType == 1)
202  {
203 #if (ED25519_SUPPORT == ENABLED)
204  //X25519 or Ed25519 algorithm identifier?
205  if(OID_COMP(oid, oidLen, X25519_OID) == 0 ||
206  OID_COMP(oid, oidLen, ED25519_OID) == 0)
207  {
208  //The publicKey field contains the elliptic curve public key
209  //associated with the private key in question
210  error = pkcs8ParseEddsaPublicKey(tag.value, tag.length,
211  &privateKeyInfo->eddsaPublicKey);
212  //Any error to report?
213  if(error)
214  return error;
215  }
216  else
217 #endif
218 #if (ED448_SUPPORT == ENABLED)
219  //X448 or Ed448 algorithm identifier?
220  if(OID_COMP(oid, oidLen, X448_OID) == 0 ||
221  OID_COMP(oid, oidLen, ED448_OID) == 0)
222  {
223  //The publicKey field contains the elliptic curve public key
224  //associated with the private key in question
225  error = pkcs8ParseEddsaPublicKey(tag.value, tag.length,
226  &privateKeyInfo->eddsaPublicKey);
227  //Any error to report?
228  if(error)
229  return error;
230  }
231  else
232 #endif
233  //Unknown algorithm identifier?
234  {
235  //Just for sanity
236  }
237  }
238 
239  //Next attribute
240  data += tag.totalLength;
241  length -= tag.totalLength;
242  }
243  }
244 
245  //Successful processing
246  return NO_ERROR;
247 }
248 
249 
250 /**
251  * @brief Parse PrivateKeyAlgorithm structure
252  * @param[in] data Pointer to the ASN.1 structure to parse
253  * @param[in] length Length of the ASN.1 structure
254  * @param[out] totalLength Number of bytes that have been parsed
255  * @param[out] privateKeyInfo Information resulting from the parsing process
256  * @return Error code
257  **/
258 
260  size_t *totalLength, Pkcs8PrivateKeyInfo *privateKeyInfo)
261 {
262  error_t error;
263  Asn1Tag tag;
264 
265  //Read the contents of the PrivateKeyAlgorithm structure
266  error = asn1ReadSequence(data, length, &tag);
267  //Failed to decode ASN.1 tag?
268  if(error)
269  return error;
270 
271  //Save the total length of the sequence
272  *totalLength = tag.totalLength;
273 
274  //Point to the first field of the sequence
275  data = tag.value;
276  length = tag.length;
277 
278  //Read the private key algorithm identifier
279  error = asn1ReadOid(data, length, &tag);
280  //Failed to decode ASN.1 tag?
281  if(error)
282  return error;
283 
284  //Save the private key algorithm identifier
285  privateKeyInfo->oid.value = tag.value;
286  privateKeyInfo->oid.length = tag.length;
287 
288  //Point to the next field (if any)
289  data += tag.totalLength;
290  length -= tag.totalLength;
291 
292 #if (RSA_SUPPORT == ENABLED)
293  //RSA algorithm identifier?
295  {
296  //The parameters field must have ASN.1 type NULL for this algorithm
297  //identifier (refer to RFC 3279, section 2.3.1)
298  error = NO_ERROR;
299  }
300  //RSA-PSS algorithm identifier?
301  else if(!asn1CheckOid(&tag, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
302  {
303  //The parameters may be either absent or present when used as subject
304  //public key information (refer to RFC 4055, section 3.1)
305  error = NO_ERROR;
306  }
307  else
308 #endif
309 #if (DSA_SUPPORT == ENABLED)
310  //DSA algorithm identifier?
311  if(!asn1CheckOid(&tag, DSA_OID, sizeof(DSA_OID)))
312  {
313  //Read DsaParameters structure
314  error = x509ParseDsaParameters(data, length, &privateKeyInfo->dsaParams);
315  }
316  else
317 #endif
318 #if (EC_SUPPORT == ENABLED)
319  //EC public key identifier?
321  {
322  //Read ECParameters structure
323  error = x509ParseEcParameters(data, length, &privateKeyInfo->ecParams);
324  }
325  else
326 #endif
327 #if (ED25519_SUPPORT == ENABLED)
328  //X25519 or Ed25519 algorithm identifier?
329  if(!asn1CheckOid(&tag, X25519_OID, sizeof(X25519_OID)) ||
330  !asn1CheckOid(&tag, ED25519_OID, sizeof(ED25519_OID)))
331  {
332  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
333  //section 3)
334  error = NO_ERROR;
335  }
336  else
337 #endif
338 #if (ED448_SUPPORT == ENABLED)
339  //X448 or Ed448 algorithm identifier?
340  if(!asn1CheckOid(&tag, X448_OID, sizeof(X448_OID)) ||
341  !asn1CheckOid(&tag, ED448_OID, sizeof(ED448_OID)))
342  {
343  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
344  //section 3)
345  error = NO_ERROR;
346  }
347  else
348 #endif
349  //Unknown algorithm identifier?
350  {
351  //Report an error
352  error = ERROR_WRONG_IDENTIFIER;
353  }
354 
355  //Return status code
356  return error;
357 }
358 
359 
360 /**
361  * @brief Parse RSAPrivateKey structure
362  * @param[in] data Pointer to the ASN.1 structure to parse
363  * @param[in] length Length of the ASN.1 structure
364  * @param[out] rsaPrivateKey Information resulting from the parsing process
365  * @return Error code
366  **/
367 
369  Pkcs8RsaPrivateKey *rsaPrivateKey)
370 {
371  error_t error;
372  Asn1Tag tag;
373 
374  //Read RSAPrivateKey structure
375  error = asn1ReadSequence(data, length, &tag);
376  //Failed to decode ASN.1 tag?
377  if(error)
378  return error;
379 
380  //Point to the first field
381  data = tag.value;
382  length = tag.length;
383 
384  //Read Version field
385  error = asn1ReadInt32(data, length, &tag, &rsaPrivateKey->version);
386  //Failed to decode ASN.1 tag?
387  if(error)
388  return error;
389 
390  //Point to the next field
391  data += tag.totalLength;
392  length -= tag.totalLength;
393 
394  //Read Modulus field
395  error = asn1ReadTag(data, length, &tag);
396  //Failed to decode ASN.1 tag?
397  if(error)
398  return error;
399 
400  //Enforce encoding, class and type
402  //Invalid tag?
403  if(error)
404  return error;
405 
406  //Save the modulus
407  rsaPrivateKey->n.value = tag.value;
408  rsaPrivateKey->n.length = tag.length;
409 
410  //Point to the next field
411  data += tag.totalLength;
412  length -= tag.totalLength;
413 
414  //Read PublicExponent field
415  error = asn1ReadTag(data, length, &tag);
416  //Failed to decode ASN.1 tag?
417  if(error)
418  return error;
419 
420  //Enforce encoding, class and type
422  //Invalid tag?
423  if(error)
424  return error;
425 
426  //Save the public exponent
427  rsaPrivateKey->e.value = tag.value;
428  rsaPrivateKey->e.length = tag.length;
429 
430  //Point to the next field
431  data += tag.totalLength;
432  length -= tag.totalLength;
433 
434  //Read PrivateExponent field
435  error = asn1ReadTag(data, length, &tag);
436  //Failed to decode ASN.1 tag?
437  if(error)
438  return error;
439 
440  //Enforce encoding, class and type
442  //Invalid tag?
443  if(error)
444  return error;
445 
446  //Save the private exponent
447  rsaPrivateKey->d.value = tag.value;
448  rsaPrivateKey->d.length = tag.length;
449 
450  //Point to the next field
451  data += tag.totalLength;
452  length -= tag.totalLength;
453 
454  //Read Prime1 field
455  error = asn1ReadTag(data, length, &tag);
456  //Failed to decode ASN.1 tag?
457  if(error)
458  return error;
459 
460  //Enforce encoding, class and type
462  //Invalid tag?
463  if(error)
464  return error;
465 
466  //Save the first factor
467  rsaPrivateKey->p.value = tag.value;
468  rsaPrivateKey->p.length = tag.length;
469 
470  //Point to the next field
471  data += tag.totalLength;
472  length -= tag.totalLength;
473 
474  //Read Prime2 field
475  error = asn1ReadTag(data, length, &tag);
476  //Failed to decode ASN.1 tag?
477  if(error)
478  return error;
479 
480  //Enforce encoding, class and type
482  //Invalid tag?
483  if(error)
484  return error;
485 
486  //Save the second factor
487  rsaPrivateKey->q.value = tag.value;
488  rsaPrivateKey->q.length = tag.length;
489 
490  //Point to the next field
491  data += tag.totalLength;
492  length -= tag.totalLength;
493 
494  //Read Exponent1 field
495  error = asn1ReadTag(data, length, &tag);
496  //Failed to decode ASN.1 tag?
497  if(error)
498  return error;
499 
500  //Enforce encoding, class and type
502  //Invalid tag?
503  if(error)
504  return error;
505 
506  //Save the first exponent
507  rsaPrivateKey->dp.value = tag.value;
508  rsaPrivateKey->dp.length = tag.length;
509 
510  //Point to the next field
511  data += tag.totalLength;
512  length -= tag.totalLength;
513 
514  //Read Exponent2 field
515  error = asn1ReadTag(data, length, &tag);
516  //Failed to decode ASN.1 tag?
517  if(error)
518  return error;
519 
520  //Enforce encoding, class and type
522  //Invalid tag?
523  if(error)
524  return error;
525 
526  //Save the second exponent
527  rsaPrivateKey->dq.value = tag.value;
528  rsaPrivateKey->dq.length = tag.length;
529 
530  //Point to the next field
531  data += tag.totalLength;
532  length -= tag.totalLength;
533 
534  //Read Coefficient field
535  error = asn1ReadTag(data, length, &tag);
536  //Failed to decode ASN.1 tag?
537  if(error)
538  return error;
539 
540  //Enforce encoding, class and type
542  //Invalid tag?
543  if(error)
544  return error;
545 
546  //Save the coefficient
547  rsaPrivateKey->qinv.value = tag.value;
548  rsaPrivateKey->qinv.length = tag.length;
549 
550  //Successful processing
551  return NO_ERROR;
552 }
553 
554 
555 /**
556  * @brief Parse DSAPrivateKey structure
557  * @param[in] data Pointer to the ASN.1 structure to parse
558  * @param[in] length Length of the ASN.1 structure
559  * @param[out] dsaParams DSA domain parameters
560  * @param[out] dsaPrivateKey DSA private key
561  * @param[out] dsaPublicKey DSA public key
562  * @return Error code
563  **/
564 
566  X509DsaParameters *dsaParams, Pkcs8DsaPrivateKey *dsaPrivateKey,
567  X509DsaPublicKey *dsaPublicKey)
568 {
569  error_t error;
570  int32_t version;
571  Asn1Tag tag;
572 
573  //The DSA domain parameters can be optionally parsed
574  if(dsaParams != NULL && dsaPublicKey != NULL)
575  {
576  //Read DSAPrivateKey structure
577  error = asn1ReadSequence(data, length, &tag);
578  //Failed to decode ASN.1 tag?
579  if(error)
580  return error;
581 
582  //Point to the first field of the sequence
583  data = tag.value;
584  length = tag.length;
585 
586  //Read version
587  error = asn1ReadInt32(data, length, &tag, &version);
588  //Failed to decode ASN.1 tag?
589  if(error)
590  return error;
591 
592  //Point to the next field
593  data += tag.totalLength;
594  length -= tag.totalLength;
595 
596  //Read the parameter p
597  error = asn1ReadTag(data, length, &tag);
598  //Failed to decode ASN.1 tag?
599  if(error)
600  return error;
601 
602  //Enforce encoding, class and type
603  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
605  //Invalid tag?
606  if(error)
607  return error;
608 
609  //Save the parameter p
610  dsaParams->p.value = tag.value;
611  dsaParams->p.length = tag.length;
612 
613  //Point to the next field
614  data += tag.totalLength;
615  length -= tag.totalLength;
616 
617  //Read the parameter q
618  error = asn1ReadTag(data, length, &tag);
619  //Failed to decode ASN.1 tag?
620  if(error)
621  return error;
622 
623  //Enforce encoding, class and type
624  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
626  //Invalid tag?
627  if(error)
628  return error;
629 
630  //Save the parameter q
631  dsaParams->q.value = tag.value;
632  dsaParams->q.length = tag.length;
633 
634  //Point to the next field
635  data += tag.totalLength;
636  length -= tag.totalLength;
637 
638  //Read the parameter g
639  error = asn1ReadTag(data, length, &tag);
640  //Failed to decode ASN.1 tag?
641  if(error)
642  return error;
643 
644  //Enforce encoding, class and type
645  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
647  //Invalid tag?
648  if(error)
649  return error;
650 
651  //Save the parameter g
652  dsaParams->g.value = tag.value;
653  dsaParams->g.length = tag.length;
654 
655  //Point to the next field
656  data += tag.totalLength;
657  length -= tag.totalLength;
658 
659  //Read the public value y
660  error = asn1ReadTag(data, length, &tag);
661  //Failed to decode ASN.1 tag?
662  if(error)
663  return error;
664 
665  //Enforce encoding, class and type
666  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
668  //Invalid tag?
669  if(error)
670  return error;
671 
672  //Save the public value y
673  dsaPublicKey->y.value = tag.value;
674  dsaPublicKey->y.length = tag.length;
675 
676  //Point to the next field
677  data += tag.totalLength;
678  length -= tag.totalLength;
679  }
680 
681  //Read the private value x
682  error = asn1ReadTag(data, length, &tag);
683  //Failed to decode ASN.1 tag?
684  if(error)
685  return error;
686 
687  //Enforce encoding, class and type
689  //Invalid tag?
690  if(error)
691  return error;
692 
693  //Save the private value x
694  dsaPrivateKey->x.value = tag.value;
695  dsaPrivateKey->x.length = tag.length;
696 
697  //Successful processing
698  return NO_ERROR;
699 }
700 
701 
702 /**
703  * @brief Parse ECPrivateKey structure
704  * @param[in] data Pointer to the ASN.1 structure to parse
705  * @param[in] length Length of the ASN.1 structure
706  * @param[out] ecParams EC domain parameters
707  * @param[out] ecPrivateKey EC private key
708  * @param[out] ecPublicKey EC public key
709  * @return Error code
710  **/
711 
712 error_t pkcs8ParseEcPrivateKey(const uint8_t *data, size_t length,
713  X509EcParameters *ecParams, Pkcs8EcPrivateKey *ecPrivateKey,
714  X509EcPublicKey *ecPublicKey)
715 {
716  error_t error;
717  Asn1Tag tag;
718 
719  //Read ECPrivateKey structure
720  error = asn1ReadSequence(data, length, &tag);
721  //Failed to decode ASN.1 tag?
722  if(error)
723  return error;
724 
725  //Point to the first field
726  data = tag.value;
727  length = tag.length;
728 
729  //Read Version field
730  error = asn1ReadInt32(data, length, &tag, &ecPrivateKey->version);
731  //Failed to decode ASN.1 tag?
732  if(error)
733  return error;
734 
735  //Point to the next field
736  data += tag.totalLength;
737  length -= tag.totalLength;
738 
739  //Read PrivateKey field
740  error = asn1ReadOctetString(data, length, &tag);
741  //Failed to decode ASN.1 tag?
742  if(error)
743  return error;
744 
745  //Save the EC private key
746  ecPrivateKey->d.value = tag.value;
747  ecPrivateKey->d.length = tag.length;
748 
749  //Point to the next field
750  data += tag.totalLength;
751  length -= tag.totalLength;
752 
753  //Loop through optional attributes
754  while(length > 0)
755  {
756  //Read current attribute
757  error = asn1ReadTag(data, length, &tag);
758  //Failed to decode ASN.1 tag?
759  if(error)
760  return error;
761 
762  //Explicit tagging shall be used to encode each optional attribute
764  return ERROR_INVALID_CLASS;
765 
766  //Check attribute type
767  if(tag.objType == 0)
768  {
769  //The parameters field specifies the elliptic curve domain parameters
770  //associated to the private key
771  error = x509ParseEcParameters(tag.value, tag.length, ecParams);
772  //Any error to report?
773  if(error)
774  return error;
775  }
776  else if(tag.objType == 1)
777  {
778  //The publicKey field contains the elliptic curve public key associated
779  //with the private key in question
780  error = pkcs8ParseEcPublicKey(tag.value, tag.length, ecPublicKey);
781  //Any error to report?
782  if(error)
783  return error;
784  }
785  else
786  {
787  //Ignore unknown attribute
788  }
789 
790  //Next attribute
791  data += tag.totalLength;
792  length -= tag.totalLength;
793  }
794 
795  //Successful processing
796  return NO_ERROR;
797 }
798 
799 
800 /**
801  * @brief Parse publicKey structure
802  * @param[in] data Pointer to the ASN.1 structure to parse
803  * @param[in] length Length of the ASN.1 structure
804  * @param[out] ecPublicKey EC public key
805  * @return Error code
806  **/
807 
808 error_t pkcs8ParseEcPublicKey(const uint8_t *data, size_t length,
809  X509EcPublicKey *ecPublicKey)
810 {
811  error_t error;
812  Asn1Tag tag;
813 
814  //The public key is encapsulated within a bit string
815  error = asn1ReadTag(data, length, &tag);
816  //Failed to decode ASN.1 tag?
817  if(error)
818  return error;
819 
820  //Enforce encoding, class and type
821  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
823  //Failed to decode ASN.1 tag?
824  if(error)
825  return error;
826 
827  //The bit string shall contain an initial octet which encodes the number
828  //of unused bits in the final subsequent octet
829  if(tag.length < 1 || tag.value[0] != 0)
830  return ERROR_INVALID_SYNTAX;
831 
832  //Save the EC public key
833  ecPublicKey->q.value = tag.value + 1;
834  ecPublicKey->q.length = tag.length - 1;
835 
836  //Successful processing
837  return NO_ERROR;
838 }
839 
840 
841 /**
842  * @brief Parse CurvePrivateKey structure
843  * @param[in] data Pointer to the ASN.1 structure to parse
844  * @param[in] length Length of the ASN.1 structure
845  * @param[out] eddsaPrivateKey EdDSA private key
846  * @return Error code
847  **/
848 
850  Pkcs8EddsaPrivateKey *eddsaPrivateKey)
851 {
852  error_t error;
853  Asn1Tag tag;
854 
855  //The CurvePrivateKey structure is encapsulated within an octet string
856  error = asn1ReadOctetString(data, length, &tag);
857  //Failed to decode ASN.1 tag?
858  if(error)
859  return error;
860 
861  //Save the EdDSA private key
862  eddsaPrivateKey->d.value = tag.value;
863  eddsaPrivateKey->d.length = tag.length;
864 
865  //Successful processing
866  return NO_ERROR;
867 }
868 
869 
870 /**
871  * @brief Parse publicKey structure
872  * @param[in] data Pointer to the ASN.1 structure to parse
873  * @param[in] length Length of the ASN.1 structure
874  * @param[out] eddsaPublicKey EdDSA public key
875  * @return Error code
876  **/
877 
879  Pkcs8EddsaPublicKey *eddsaPublicKey)
880 {
881  //The bit string shall contain an initial octet which encodes the number
882  //of unused bits in the final subsequent octet
883  if(length < 1 || data[0] != 0)
884  return ERROR_INVALID_SYNTAX;
885 
886  //Save the EdDSA public key
887  eddsaPublicKey->q.value = data + 1;
888  eddsaPublicKey->q.length = length - 1;
889 
890  //Successful processing
891  return NO_ERROR;
892 }
893 
894 
895 /**
896  * @brief Parse EncryptedPrivateKeyInfo structure
897  * @param[in] data Pointer to the ASN.1 structure to parse
898  * @param[in] length Length of the ASN.1 structure
899  * @param[out] encryptedPrivateKeyInfo Information resulting from the parsing process
900  * @return Error code
901  **/
902 
904  Pkcs8EncryptedPrivateKeyInfo *encryptedPrivateKeyInfo)
905 {
906  error_t error;
907  size_t n;
908  Asn1Tag tag;
909 
910  //Read EncryptedPrivateKeyInfo structure
911  error = asn1ReadSequence(data, length, &tag);
912  //Failed to decode ASN.1 tag?
913  if(error)
914  return error;
915 
916  //Point to the first field
917  data = tag.value;
918  length = tag.length;
919 
920  //Parse EncryptionAlgorithmIdentifier structure
922  &encryptedPrivateKeyInfo->encryptionAlgo);
923  //Any error to report?
924  if(error)
925  return error;
926 
927  //Point to the next field
928  data += n;
929  length -= n;
930 
931  //The EncryptedData is encapsulated within an octet string
932  error = asn1ReadOctetString(data, length, &tag);
933  //Failed to decode ASN.1 tag?
934  if(error)
935  return error;
936 
937  //The EncryptedData is the result of encrypting the private-key information
938  encryptedPrivateKeyInfo->encryptedData.value = tag.value;
939  encryptedPrivateKeyInfo->encryptedData.length = tag.length;
940 
941  //Successful processing
942  return NO_ERROR;
943 }
944 
945 
946 /**
947  * @brief Parse EncryptionAlgorithmIdentifier structure
948  * @param[in] data Pointer to the ASN.1 structure to parse
949  * @param[in] length Length of the ASN.1 structure
950  * @param[out] totalLength Number of bytes that have been parsed
951  * @param[out] encryptionAlgoId Information resulting from the parsing process
952  * @return Error code
953  **/
954 
956  size_t *totalLength, X509AlgoId *encryptionAlgoId)
957 {
958  error_t error;
959  Asn1Tag tag;
960 
961  //Read the contents of the EncryptionAlgorithmIdentifier structure
962  error = asn1ReadSequence(data, length, &tag);
963  //Failed to decode ASN.1 tag?
964  if(error)
965  return error;
966 
967  //Save the total length of the sequence
968  *totalLength = tag.totalLength;
969 
970  //Point to the first field of the sequence
971  data = tag.value;
972  length = tag.length;
973 
974  //Read the encryption algorithm identifier
975  error = asn1ReadOid(data, length, &tag);
976  //Failed to decode ASN.1 tag?
977  if(error)
978  return error;
979 
980  //Save the encryption algorithm identifier
981  encryptionAlgoId->oid.value = tag.value;
982  encryptionAlgoId->oid.length = tag.length;
983 
984  //Point to the next field (if any)
985  data += tag.totalLength;
986  length -= tag.totalLength;
987 
988  //The contents of the optional parameters field will vary according to the
989  //algorithm identified
990  encryptionAlgoId->params.value = data;
991  encryptionAlgoId->params.length = length;
992 
993  //Return status code
994  return error;
995 }
996 
997 
998 /**
999  * @brief Import an RSA private key
1000  * @param[out] privateKey RSA private key
1001  * @param[in] privateKeyInfo Private key information
1002  * @return Error code
1003  **/
1004 
1006  const Pkcs8PrivateKeyInfo *privateKeyInfo)
1007 {
1008  error_t error;
1009 
1010 #if (RSA_SUPPORT == ENABLED)
1011  const uint8_t *oid;
1012  size_t oidLen;
1013 
1014  //Get the private key algorithm identifier
1015  oid = privateKeyInfo->oid.value;
1016  oidLen = privateKeyInfo->oid.length;
1017 
1018  //RSA or RSA-PSS algorithm identifier?
1019  if(OID_COMP(oid, oidLen, RSA_ENCRYPTION_OID) == 0 ||
1021  {
1022  //Sanity check
1023  if(privateKeyInfo->rsaPrivateKey.n.value != NULL &&
1024  privateKeyInfo->rsaPrivateKey.e.value != NULL &&
1025  privateKeyInfo->rsaPrivateKey.d.value != NULL &&
1026  privateKeyInfo->rsaPrivateKey.p.value != NULL &&
1027  privateKeyInfo->rsaPrivateKey.q.value != NULL &&
1028  privateKeyInfo->rsaPrivateKey.dp.value != NULL &&
1029  privateKeyInfo->rsaPrivateKey.dq.value != NULL &&
1030  privateKeyInfo->rsaPrivateKey.qinv.value != NULL)
1031  {
1032  //Read modulus
1033  error = mpiImport(&privateKey->n,
1034  privateKeyInfo->rsaPrivateKey.n.value,
1035  privateKeyInfo->rsaPrivateKey.n.length, MPI_FORMAT_BIG_ENDIAN);
1036 
1037  //Check status code
1038  if(!error)
1039  {
1040  //Read public exponent
1041  error = mpiImport(&privateKey->e,
1042  privateKeyInfo->rsaPrivateKey.e.value,
1043  privateKeyInfo->rsaPrivateKey.e.length, MPI_FORMAT_BIG_ENDIAN);
1044  }
1045 
1046  //Check status code
1047  if(!error)
1048  {
1049  //Read private exponent
1050  error = mpiImport(&privateKey->d,
1051  privateKeyInfo->rsaPrivateKey.d.value,
1052  privateKeyInfo->rsaPrivateKey.d.length, MPI_FORMAT_BIG_ENDIAN);
1053  }
1054 
1055  //Check status code
1056  if(!error)
1057  {
1058  //Read first factor
1059  error = mpiImport(&privateKey->p,
1060  privateKeyInfo->rsaPrivateKey.p.value,
1061  privateKeyInfo->rsaPrivateKey.p.length, MPI_FORMAT_BIG_ENDIAN);
1062  }
1063 
1064  //Check status code
1065  if(!error)
1066  {
1067  //Read second factor
1068  error = mpiImport(&privateKey->q,
1069  privateKeyInfo->rsaPrivateKey.q.value,
1070  privateKeyInfo->rsaPrivateKey.q.length, MPI_FORMAT_BIG_ENDIAN);
1071  }
1072 
1073  //Check status code
1074  if(!error)
1075  {
1076  //Read first exponent
1077  error = mpiImport(&privateKey->dp,
1078  privateKeyInfo->rsaPrivateKey.dp.value,
1079  privateKeyInfo->rsaPrivateKey.dp.length, MPI_FORMAT_BIG_ENDIAN);
1080  }
1081 
1082  //Check status code
1083  if(!error)
1084  {
1085  //Read second exponent
1086  error = mpiImport(&privateKey->dq,
1087  privateKeyInfo->rsaPrivateKey.dq.value,
1088  privateKeyInfo->rsaPrivateKey.dq.length, MPI_FORMAT_BIG_ENDIAN);
1089  }
1090 
1091  //Check status code
1092  if(!error)
1093  {
1094  //Read coefficient
1095  error = mpiImport(&privateKey->qinv,
1096  privateKeyInfo->rsaPrivateKey.qinv.value,
1097  privateKeyInfo->rsaPrivateKey.qinv.length, MPI_FORMAT_BIG_ENDIAN);
1098  }
1099 
1100  //Check status code
1101  if(!error)
1102  {
1103  //Dump RSA private key
1104  TRACE_DEBUG("RSA private key:\r\n");
1105  TRACE_DEBUG(" Modulus:\r\n");
1106  TRACE_DEBUG_MPI(" ", &privateKey->n);
1107  TRACE_DEBUG(" Public exponent:\r\n");
1108  TRACE_DEBUG_MPI(" ", &privateKey->e);
1109  TRACE_DEBUG(" Private exponent:\r\n");
1110  TRACE_DEBUG_MPI(" ", &privateKey->d);
1111  TRACE_DEBUG(" Prime 1:\r\n");
1112  TRACE_DEBUG_MPI(" ", &privateKey->p);
1113  TRACE_DEBUG(" Prime 2:\r\n");
1114  TRACE_DEBUG_MPI(" ", &privateKey->q);
1115  TRACE_DEBUG(" Prime exponent 1:\r\n");
1116  TRACE_DEBUG_MPI(" ", &privateKey->dp);
1117  TRACE_DEBUG(" Prime exponent 2:\r\n");
1118  TRACE_DEBUG_MPI(" ", &privateKey->dq);
1119  TRACE_DEBUG(" Coefficient:\r\n");
1120  TRACE_DEBUG_MPI(" ", &privateKey->qinv);
1121  }
1122  }
1123  else
1124  {
1125  //The private key is not valid
1126  error = ERROR_INVALID_KEY;
1127  }
1128  }
1129  else
1130 #endif
1131  //Invalid algorithm identifier?
1132  {
1133  //Report an error
1134  error = ERROR_WRONG_IDENTIFIER;
1135  }
1136 
1137  //Return status code
1138  return error;
1139 }
1140 
1141 
1142 /**
1143  * @brief Import a DSA private key
1144  * @param[out] privateKey DSA private key
1145  * @param[in] privateKeyInfo Private key information
1146  * @return Error code
1147  **/
1148 
1150  const Pkcs8PrivateKeyInfo *privateKeyInfo)
1151 {
1152  error_t error;
1153 
1154 #if (DSA_SUPPORT == ENABLED)
1155  //DSA algorithm identifier?
1156  if(OID_COMP(privateKeyInfo->oid.value, privateKeyInfo->oid.length,
1157  DSA_OID) == 0)
1158  {
1159  //Sanity check
1160  if(privateKeyInfo->dsaParams.p.value != NULL &&
1161  privateKeyInfo->dsaParams.q.value != NULL &&
1162  privateKeyInfo->dsaParams.g.value != NULL &&
1163  privateKeyInfo->dsaPrivateKey.x.value != NULL)
1164  {
1165  //Read parameter p
1166  error = mpiImport(&privateKey->params.p,
1167  privateKeyInfo->dsaParams.p.value,
1168  privateKeyInfo->dsaParams.p.length, MPI_FORMAT_BIG_ENDIAN);
1169 
1170  //Check status code
1171  if(!error)
1172  {
1173  //Read parameter q
1174  error = mpiImport(&privateKey->params.q,
1175  privateKeyInfo->dsaParams.q.value,
1176  privateKeyInfo->dsaParams.q.length, MPI_FORMAT_BIG_ENDIAN);
1177  }
1178 
1179  //Check status code
1180  if(!error)
1181  {
1182  //Read parameter g
1183  error = mpiImport(&privateKey->params.g,
1184  privateKeyInfo->dsaParams.g.value,
1185  privateKeyInfo->dsaParams.g.length, MPI_FORMAT_BIG_ENDIAN);
1186  }
1187 
1188  //Check status code
1189  if(!error)
1190  {
1191  //Read private value
1192  error = mpiImport(&privateKey->x,
1193  privateKeyInfo->dsaPrivateKey.x.value,
1194  privateKeyInfo->dsaPrivateKey.x.length, MPI_FORMAT_BIG_ENDIAN);
1195  }
1196 
1197  //Check status code
1198  if(!error)
1199  {
1200  //The public key is optional
1201  if(privateKeyInfo->dsaPublicKey.y.value != NULL)
1202  {
1203  //Read public value
1204  error = mpiImport(&privateKey->y,
1205  privateKeyInfo->dsaPublicKey.y.value,
1206  privateKeyInfo->dsaPublicKey.y.length, MPI_FORMAT_BIG_ENDIAN);
1207  }
1208  else
1209  {
1210  //The public key is not present
1211  mpiFree(&privateKey->y);
1212  mpiInit(&privateKey->y);
1213  }
1214  }
1215 
1216  //Check status code
1217  if(!error)
1218  {
1219  //Dump DSA private key
1220  TRACE_DEBUG("DSA private key:\r\n");
1221  TRACE_DEBUG(" Parameter p:\r\n");
1222  TRACE_DEBUG_MPI(" ", &privateKey->params.p);
1223  TRACE_DEBUG(" Parameter q:\r\n");
1224  TRACE_DEBUG_MPI(" ", &privateKey->params.q);
1225  TRACE_DEBUG(" Parameter g:\r\n");
1226  TRACE_DEBUG_MPI(" ", &privateKey->params.g);
1227  TRACE_DEBUG(" Private value x:\r\n");
1228  TRACE_DEBUG_MPI(" ", &privateKey->x);
1229  TRACE_DEBUG(" Public value y:\r\n");
1230  TRACE_DEBUG_MPI(" ", &privateKey->y);
1231  }
1232  }
1233  else
1234  {
1235  //The private key is not valid
1236  error = ERROR_INVALID_KEY;
1237  }
1238  }
1239  else
1240 #endif
1241  //Invalid algorithm identifier?
1242  {
1243  //Report an error
1244  error = ERROR_WRONG_IDENTIFIER;
1245  }
1246 
1247  //Return status code
1248  return error;
1249 }
1250 
1251 
1252 /**
1253  * @brief Import an EC private key
1254  * @param[out] privateKey EC private key
1255  * @param[in] privateKeyInfo Private key information
1256  * @return Error code
1257  **/
1258 
1260  const Pkcs8PrivateKeyInfo *privateKeyInfo)
1261 {
1262  error_t error;
1263 
1264 #if (EC_SUPPORT == ENABLED)
1265  //EC public key algorithm identifier?
1266  if(OID_COMP(privateKeyInfo->oid.value, privateKeyInfo->oid.length,
1267  EC_PUBLIC_KEY_OID) == 0)
1268  {
1269  //Sanity check
1270  if(privateKeyInfo->ecParams.namedCurve.value != NULL &&
1271  privateKeyInfo->ecPrivateKey.d.value != NULL)
1272  {
1273  const EcCurve *curve;
1274 
1275  //Get the elliptic curve that matches the OID
1276  curve = ecGetCurve(privateKeyInfo->ecParams.namedCurve.value,
1277  privateKeyInfo->ecParams.namedCurve.length);
1278 
1279  //Make sure the specified elliptic curve is supported
1280  if(curve != NULL)
1281  {
1282  //Read the EC private key
1283  error = ecImportPrivateKey(privateKey, curve,
1284  privateKeyInfo->ecPrivateKey.d.value,
1285  privateKeyInfo->ecPrivateKey.d.length);
1286 
1287  //Check status code
1288  if(!error)
1289  {
1290  //The public key is optional
1291  if(privateKeyInfo->ecPublicKey.q.value != NULL)
1292  {
1293  //Read the EC public key
1294  error = ecImportPublicKey(&privateKey->q, curve,
1295  privateKeyInfo->ecPublicKey.q.value,
1296  privateKeyInfo->ecPublicKey.q.length,
1298  }
1299  else
1300  {
1301  //The EC public key is not present
1302  ecInitPublicKey(&privateKey->q);
1303  }
1304  }
1305  }
1306  else
1307  {
1308  //Invalid elliptic curve
1309  error = ERROR_WRONG_IDENTIFIER;
1310  }
1311 
1312  //Check status code
1313  if(!error)
1314  {
1315  //Dump EC private key
1316  TRACE_DEBUG("EC private key:\r\n");
1317  TRACE_DEBUG_EC_SCALAR(" ", privateKey->d, (curve->orderSize + 31) / 32);
1318 
1319  //Valid public key?
1320  if(privateKey->q.curve != NULL)
1321  {
1322  //Dump EC public key
1323  TRACE_DEBUG("EC public key X:\r\n");
1324  TRACE_DEBUG_EC_SCALAR(" ", privateKey->q.q.x, (curve->fieldSize + 31) / 32);
1325  TRACE_DEBUG("EC public key Y:\r\n");
1326  TRACE_DEBUG_EC_SCALAR(" ", privateKey->q.q.y, (curve->fieldSize + 31) / 32);
1327  }
1328  }
1329  }
1330  else
1331  {
1332  //The private key is not valid
1333  error = ERROR_INVALID_KEY;
1334  }
1335  }
1336  else
1337 #endif
1338  //Invalid algorithm identifier?
1339  {
1340  //Report an error
1341  error = ERROR_WRONG_IDENTIFIER;
1342  }
1343 
1344  //Return status code
1345  return error;
1346 }
1347 
1348 
1349 /**
1350  * @brief Import an EdDSA private key
1351  * @param[out] privateKey EdDSA private key
1352  * @param[in] privateKeyInfo Private key information
1353  * @return Error code
1354  **/
1355 
1357  const Pkcs8PrivateKeyInfo *privateKeyInfo)
1358 {
1359 #if (ED25519_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
1360  error_t error;
1361  const EcCurve *curve;
1362 
1363  //Get the elliptic curve that matches the OID
1364  curve = ecGetCurve(privateKeyInfo->oid.value, privateKeyInfo->oid.length);
1365 
1366  //Edwards elliptic curve?
1367  if(curve != NULL && curve->type == EC_CURVE_TYPE_EDWARDS)
1368  {
1369  //Read the EdDSA private key
1370  error = eddsaImportPrivateKey(privateKey, curve,
1371  privateKeyInfo->eddsaPrivateKey.d.value,
1372  privateKeyInfo->eddsaPrivateKey.d.length);
1373 
1374  //Check status code
1375  if(!error)
1376  {
1377  //The public key is optional
1378  if(privateKeyInfo->eddsaPublicKey.q.value != NULL)
1379  {
1380  //Read the EdDSA public key
1381  error = eddsaImportPublicKey(&privateKey->q, curve,
1382  privateKeyInfo->eddsaPublicKey.q.value,
1383  privateKeyInfo->eddsaPublicKey.q.length);
1384  }
1385  else
1386  {
1387  //The EdDSA public key is not present
1388  eddsaInitPublicKey(&privateKey->q);
1389  }
1390  }
1391  }
1392  else
1393  {
1394  //Report an error
1395  error = ERROR_WRONG_IDENTIFIER;
1396  }
1397 
1398  //Check status code
1399  if(!error)
1400  {
1401  //Dump EdDSA private key
1402  TRACE_DEBUG("EdDSA private key:\r\n");
1403  TRACE_DEBUG_ARRAY(" ", privateKey->d, privateKeyInfo->eddsaPrivateKey.d.length);
1404 
1405  //Valid public key?
1406  if(privateKey->q.curve != NULL)
1407  {
1408  //Dump EdDSA public key
1409  TRACE_DEBUG("EdDSA public key:\r\n");
1410  TRACE_DEBUG_ARRAY(" ", privateKey->q.q, privateKeyInfo->eddsaPublicKey.q.length);
1411  }
1412  }
1413 
1414  //Return status code
1415  return error;
1416 #else
1417  //Not implemented
1418  return ERROR_NOT_IMPLEMENTED;
1419 #endif
1420 }
1421 
1422 #endif
X509OctetString dq
error_t pkcs8ParsePrivateKeyInfo(const uint8_t *data, size_t length, Pkcs8PrivateKeyInfo *privateKeyInfo)
Parse PrivateKeyInfo structure.
Pkcs8RsaPrivateKey rsaPrivateKey
@ PKCS8_VERSION_2
Definition: x509_common.h:504
@ EC_CURVE_TYPE_EDWARDS
Definition: ec.h:364
Private key information.
X509OctetString params
Definition: x509_common.h:776
Mpi p
First factor.
Definition: rsa.h:72
uint8_t d[EDDSA_MAX_PRIVATE_KEY_LEN]
Private key.
Definition: eddsa.h:77
const uint8_t X25519_OID[3]
Definition: ec_curves.c:108
EdDSA public key.
X509OctetString g
Definition: x509_common.h:799
X509OctetString p
Definition: x509_common.h:797
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
OID (Object Identifier)
Mpi q
Group order.
Definition: dsa.h:51
uint8_t data[]
Definition: ethernet.h:224
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:44
Encrypted private key information.
error_t ecImportPublicKey(EcPublicKey *key, const EcCurve *curve, const uint8_t *input, size_t length, EcPublicKeyFormat format)
Import an EC public key.
Definition: ec.c:263
Mpi n
Modulus.
Definition: rsa.h:69
RSA private key.
X509DsaPublicKey dsaPublicKey
X509OctetString d
#define TRACE_DEBUG_EC_SCALAR(p, a, n)
Definition: debug.h:123
@ EC_PUBLIC_KEY_FORMAT_X963
Definition: ec.h:386
uint16_t totalLength
Definition: ipv4.h:323
Mpi p
Prime modulus.
Definition: dsa.h:50
error_t pkcs8ImportDsaPrivateKey(DsaPrivateKey *privateKey, const Pkcs8PrivateKeyInfo *privateKeyInfo)
Import a DSA private key.
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:85
uint8_t version
Definition: coap_common.h:177
error_t asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:52
uint32_t y[EC_MAX_MODULUS_SIZE]
y-coordinate
Definition: ec.h:400
error_t x509ParseDsaParameters(const uint8_t *data, size_t length, X509DsaParameters *dsaParams)
Parse DSA domain parameters.
error_t pkcs8ParseEddsaPublicKey(const uint8_t *data, size_t length, Pkcs8EddsaPublicKey *eddsaPublicKey)
Parse publicKey structure.
@ ERROR_INVALID_VERSION
Definition: error.h:118
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:48
uint8_t oid[]
Definition: lldp_tlv.h:300
Mpi d
Private exponent.
Definition: rsa.h:71
EdDSA private key.
X509OctetString q
Definition: x509_common.h:798
error_t asn1ReadOid(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an object identifier from the input stream.
Definition: asn1.c:218
EC public key.
Definition: x509_common.h:828
const uint8_t DSA_OID[7]
Definition: dsa.c:51
X509OctetString n
size_t totalLength
Definition: asn1.h:111
size_t length
Definition: asn1.h:109
X509OctetString y
Definition: x509_common.h:809
Pkcs8EcPrivateKey ecPrivateKey
#define FALSE
Definition: os_port.h:46
error_t asn1ReadOctetString(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an octet string from the input stream.
Definition: asn1.c:190
error_t pkcs8ParsePrivateKeyAlgo(const uint8_t *data, size_t length, size_t *totalLength, Pkcs8PrivateKeyInfo *privateKeyInfo)
Parse PrivateKeyAlgorithm structure.
error_t pkcs8ParseEddsaPrivateKey(const uint8_t *data, size_t length, Pkcs8EddsaPrivateKey *eddsaPrivateKey)
Parse CurvePrivateKey structure.
uint8_t q[EDDSA_MAX_PUBLIC_KEY_LEN]
Public key.
Definition: eddsa.h:66
const EcCurve * curve
Elliptic curve parameters.
Definition: eddsa.h:65
error_t
Error codes.
Definition: error.h:43
Mpi g
Group generator.
Definition: dsa.h:52
EC parameters.
Definition: x509_common.h:818
X509OctetString dp
void ecInitPublicKey(EcPublicKey *key)
Initialize an EC public key.
Definition: ec.c:52
X509OctetString e
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
error_t pkcs8ImportRsaPrivateKey(RsaPrivateKey *privateKey, const Pkcs8PrivateKeyInfo *privateKeyInfo)
Import an RSA private key.
ASN.1 tag.
Definition: asn1.h:105
Mpi q
Second factor.
Definition: rsa.h:73
Helper routines for ECC.
X509OctetString p
error_t mpiImport(Mpi *r, const uint8_t *input, size_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:712
error_t asn1ReadInt32(const uint8_t *data, size_t length, Asn1Tag *tag, int32_t *value)
Read a 32-bit integer from the input stream.
Definition: asn1.c:285
X509EcPublicKey ecPublicKey
X509DsaParameters dsaParams
X509OctetString oid
Definition: x509_common.h:775
error_t ecImportPrivateKey(EcPrivateKey *key, const EcCurve *curve, const uint8_t *input, size_t length)
Import an EC private key.
Definition: ec.c:514
Pkcs8EddsaPublicKey eddsaPublicKey
General definitions for cryptographic algorithms.
Mpi y
Public key value.
Definition: dsa.h:75
EcPublicKey q
Public key.
Definition: ec.h:436
X509OctetString q
EC private key.
Definition: ec.h:432
Pkcs8EddsaPrivateKey eddsaPrivateKey
DSA private key.
Definition: dsa.h:72
uint_t objClass
Definition: asn1.h:107
uint8_t length
Definition: tcp.h:375
error_t pkcs8ParseRsaPrivateKey(const uint8_t *data, size_t length, Pkcs8RsaPrivateKey *rsaPrivateKey)
Parse RSAPrivateKey structure.
@ PKCS8_VERSION_1
Definition: x509_common.h:503
Mpi e
Public exponent.
Definition: rsa.h:70
error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
Check ASN.1 tag against a specified OID.
Definition: asn1.c:972
error_t pkcs8ParseDsaPrivateKey(const uint8_t *data, size_t length, X509DsaParameters *dsaParams, Pkcs8DsaPrivateKey *dsaPrivateKey, X509DsaPublicKey *dsaPublicKey)
Parse DSAPrivateKey structure.
error_t pkcs8ParseEncryptionAlgoId(const uint8_t *data, size_t length, size_t *totalLength, X509AlgoId *encryptionAlgoId)
Parse EncryptionAlgorithmIdentifier structure.
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
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_INTEGER
Definition: asn1.h:73
#define TRACE_DEBUG(...)
Definition: debug.h:119
error_t pkcs8ImportEddsaPrivateKey(EddsaPrivateKey *privateKey, const Pkcs8PrivateKeyInfo *privateKeyInfo)
Import an EdDSA private key.
error_t pkcs8ImportEcPrivateKey(EcPrivateKey *privateKey, const Pkcs8PrivateKeyInfo *privateKeyInfo)
Import an EC private key.
X509OctetString d
#define TRACE_DEBUG_ARRAY(p, a, n)
Definition: debug.h:120
X509OctetString d
X509OctetString q
Definition: x509_common.h:829
uint32_t d[EC_MAX_ORDER_SIZE]
Private key.
Definition: ec.h:434
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
uint8_t n
RSA private key.
Definition: rsa.h:68
error_t pkcs8ParseEncryptedPrivateKeyInfo(const uint8_t *data, size_t length, Pkcs8EncryptedPrivateKeyInfo *encryptedPrivateKeyInfo)
Parse EncryptedPrivateKeyInfo structure.
DSA domain parameters.
Definition: x509_common.h:796
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:54
X509OctetString qinv
PKCS #8 key parsing.
Mpi x
Secret exponent.
Definition: dsa.h:74
EcPoint q
Public key.
Definition: ec.h:423
uint8_t oidLen
Definition: lldp_tlv.h:299
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ ERROR_INVALID_SYNTAX
Definition: error.h:68
EddsaPublicKey q
Public key.
Definition: eddsa.h:79
error_t x509ParseEcParameters(const uint8_t *data, size_t length, X509EcParameters *ecParams)
Parse ECParameters structure.
const EcCurve * ecGetCurve(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:5888
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:73
const uint8_t * value
Definition: x509_common.h:702
error_t eddsaImportPublicKey(EddsaPublicKey *key, const EcCurve *curve, const uint8_t *input, size_t length)
Import an EdDSA public key.
Definition: eddsa.c:275
X509OctetString q
error_t eddsaImportPrivateKey(EddsaPrivateKey *key, const EcCurve *curve, const uint8_t *data, size_t length)
Import an EdDSA private key.
Definition: eddsa.c:383
#define EcCurve
Definition: ec.h:346
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:74
Parsing of ASN.1 encoded keys.
Pkcs8DsaPrivateKey dsaPrivateKey
@ ASN1_TYPE_BIT_STRING
Definition: asn1.h:74
@ ERROR_INVALID_CLASS
Definition: error.h:117
uint32_t x[EC_MAX_MODULUS_SIZE]
x-coordinate
Definition: ec.h:399
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:122
#define osMemset(p, value, length)
Definition: os_port.h:138
EC private key.
error_t asn1ReadSequence(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 sequence from the input stream.
Definition: asn1.c:163
DSA private key.
DSA public key.
Definition: x509_common.h:808
X509EcParameters ecParams
X509OctetString oid
void eddsaInitPublicKey(EddsaPublicKey *key)
Initialize an EdDSA public key.
Definition: eddsa.c:48
error_t pkcs8ParseEcPrivateKey(const uint8_t *data, size_t length, X509EcParameters *ecParams, Pkcs8EcPrivateKey *ecPrivateKey, X509EcPublicKey *ecPublicKey)
Parse ECPrivateKey structure.
const EcCurve * curve
Elliptic curve parameters.
Definition: ec.h:422
X509OctetString x
const uint8_t * value
Definition: asn1.h:110
error_t pkcs8ParseEcPublicKey(const uint8_t *data, size_t length, X509EcPublicKey *ecPublicKey)
Parse publicKey structure.
error_t asn1CheckTag(const Asn1Tag *tag, bool_t constructed, uint_t objClass, uint_t objType)
Enforce the type of a specified tag.
Definition: asn1.c:944
@ ERROR_INVALID_KEY
Definition: error.h:106
Algorithm identifier.
Definition: x509_common.h:774
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
uint_t objType
Definition: asn1.h:108
ASN.1 (Abstract Syntax Notation One)
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64