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-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/pkcs8_key_parse.h"
37 #include "pkix/x509_key_parse.h"
38 #include "encoding/asn1.h"
39 #include "encoding/oid.h"
40 #include "debug.h"
41 
42 //Check crypto library configuration
43 #if (PEM_SUPPORT == ENABLED)
44 
45 
46 /**
47  * @brief Parse PrivateKeyInfo structure
48  * @param[in] data Pointer to the ASN.1 structure to parse
49  * @param[in] length Length of the ASN.1 structure
50  * @param[out] privateKeyInfo Information resulting from the parsing process
51  * @return Error code
52  **/
53 
55  Pkcs8PrivateKeyInfo *privateKeyInfo)
56 {
57  error_t error;
58  size_t n;
59  size_t oidLen;
60  const uint8_t *oid;
61  Asn1Tag tag;
62 
63  //Clear the PrivateKeyInfo structure
64  osMemset(privateKeyInfo, 0, sizeof(Pkcs8PrivateKeyInfo));
65 
66  //The private key information is encapsulated within a sequence
67  error = asn1ReadSequence(data, length, &tag);
68  //Failed to decode ASN.1 tag?
69  if(error)
70  return error;
71 
72  //Point to the first field of the sequence
73  data = tag.value;
74  length = tag.length;
75 
76  //Read Version field
77  error = asn1ReadInt32(data, length, &tag, &privateKeyInfo->version);
78  //Failed to decode ASN.1 tag?
79  if(error)
80  return error;
81 
82  //Point to the next field
83  data += tag.totalLength;
84  length -= tag.totalLength;
85 
86  //Read PrivateKeyAlgorithm field
87  error = pkcs8ParsePrivateKeyAlgo(data, length, &n, privateKeyInfo);
88  //Failed to decode ASN.1 tag?
89  if(error)
90  return error;
91 
92  //Point to the next field
93  data += n;
94  length -= n;
95 
96  //The PrivateKey is encapsulated within an octet string
97  error = asn1ReadOctetString(data, length, &tag);
98  //Failed to decode ASN.1 tag?
99  if(error)
100  return error;
101 
102  //Point to the private key
103  data = tag.value;
104  length = tag.length;
105 
106  //Get the private key algorithm identifier
107  oid = privateKeyInfo->oid.value;
108  oidLen = privateKeyInfo->oid.length;
109 
110 #if (RSA_SUPPORT == ENABLED)
111  //RSA or RSA-PSS algorithm identifier?
114  {
115  //Read RSAPrivateKey structure
117  &privateKeyInfo->rsaPrivateKey);
118  }
119  else
120 #endif
121 #if (DSA_SUPPORT == ENABLED)
122  //DSA algorithm identifier?
123  if(!oidComp(oid, oidLen, DSA_OID, sizeof(DSA_OID)))
124  {
125  //Read DSAPrivateKey structure
126  error = pkcs8ParseDsaPrivateKey(data, length, NULL,
127  &privateKeyInfo->dsaPrivateKey);
128  }
129  else
130 #endif
131 #if (EC_SUPPORT == ENABLED)
132  //EC public key identifier?
134  {
135  //Read ECPrivateKey structure
136  error = pkcs8ParseEcPrivateKey(data, length, &privateKeyInfo->ecParams,
137  &privateKeyInfo->ecPrivateKey);
138  }
139  else
140 #endif
141 #if (ED25519_SUPPORT == ENABLED)
142  //X25519 or Ed25519 algorithm identifier?
143  if(!oidComp(oid, oidLen, X25519_OID, sizeof(X25519_OID)) ||
145  {
146  //Read CurvePrivateKey structure
148  &privateKeyInfo->eddsaPrivateKey);
149  }
150  else
151 #endif
152 #if (ED448_SUPPORT == ENABLED)
153  //X448 or Ed448 algorithm identifier?
154  if(!oidComp(oid, oidLen, X448_OID, sizeof(X448_OID)) ||
155  !oidComp(oid, oidLen, ED448_OID, sizeof(ED448_OID)))
156  {
157  //Read CurvePrivateKey structure
159  &privateKeyInfo->eddsaPrivateKey);
160  }
161  else
162 #endif
163  //Unknown algorithm identifier?
164  {
165  //Report an error
166  error = ERROR_WRONG_IDENTIFIER;
167  }
168 
169  //Return status code
170  return error;
171 }
172 
173 
174 /**
175  * @brief Parse PrivateKeyAlgorithm structure
176  * @param[in] data Pointer to the ASN.1 structure to parse
177  * @param[in] length Length of the ASN.1 structure
178  * @param[out] totalLength Number of bytes that have been parsed
179  * @param[out] privateKeyInfo Information resulting from the parsing process
180  * @return Error code
181  **/
182 
184  size_t *totalLength, Pkcs8PrivateKeyInfo *privateKeyInfo)
185 {
186  error_t error;
187  Asn1Tag tag;
188 
189  //Read the contents of the PrivateKeyAlgorithm structure
190  error = asn1ReadSequence(data, length, &tag);
191  //Failed to decode ASN.1 tag?
192  if(error)
193  return error;
194 
195  //Save the total length of the field
196  *totalLength = tag.totalLength;
197 
198  //Point to the first field of the sequence
199  data = tag.value;
200  length = tag.length;
201 
202  //Read the private key algorithm identifier
203  error = asn1ReadOid(data, length, &tag);
204  //Failed to decode ASN.1 tag?
205  if(error)
206  return error;
207 
208  //Save the private key algorithm identifier
209  privateKeyInfo->oid.value = tag.value;
210  privateKeyInfo->oid.length = tag.length;
211 
212  //Point to the next field (if any)
213  data += tag.totalLength;
214  length -= tag.totalLength;
215 
216 #if (RSA_SUPPORT == ENABLED)
217  //RSA algorithm identifier?
219  {
220  //The parameters field must have ASN.1 type NULL for this algorithm
221  //identifier (refer to RFC 3279, section 2.3.1)
222  error = NO_ERROR;
223  }
224  //RSA-PSS algorithm identifier?
225  else if(!asn1CheckOid(&tag, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
226  {
227  //The parameters may be either absent or present when used as subject
228  //public key information (refer to RFC 4055, section 3.1)
229  error = NO_ERROR;
230  }
231  else
232 #endif
233 #if (DSA_SUPPORT == ENABLED)
234  //DSA algorithm identifier?
235  if(!asn1CheckOid(&tag, DSA_OID, sizeof(DSA_OID)))
236  {
237  //Read DsaParameters structure
239  &privateKeyInfo->dsaParams);
240  }
241  else
242 #endif
243 #if (EC_SUPPORT == ENABLED)
244  //EC public key identifier?
246  {
247  //Read ECParameters structure
249  &privateKeyInfo->ecParams);
250  }
251  else
252 #endif
253 #if (ED25519_SUPPORT == ENABLED)
254  //X25519 or Ed25519 algorithm identifier?
255  if(!asn1CheckOid(&tag, X25519_OID, sizeof(X25519_OID)) ||
256  !asn1CheckOid(&tag, ED25519_OID, sizeof(ED25519_OID)))
257  {
258  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
259  //section 3)
260  error = NO_ERROR;
261  }
262  else
263 #endif
264 #if (ED448_SUPPORT == ENABLED)
265  //X448 or Ed448 algorithm identifier?
266  if(!asn1CheckOid(&tag, X448_OID, sizeof(X448_OID)) ||
267  !asn1CheckOid(&tag, ED448_OID, sizeof(ED448_OID)))
268  {
269  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
270  //section 3)
271  error = NO_ERROR;
272  }
273  else
274 #endif
275  //Unknown algorithm identifier?
276  {
277  //Report an error
278  error = ERROR_WRONG_IDENTIFIER;
279  }
280 
281  //Return status code
282  return error;
283 }
284 
285 
286 /**
287  * @brief Parse RSAPrivateKey structure
288  * @param[in] data Pointer to the ASN.1 structure to parse
289  * @param[in] length Length of the ASN.1 structure
290  * @param[out] rsaPrivateKey Information resulting from the parsing process
291  * @return Error code
292  **/
293 
295  Pkcs8RsaPrivateKey *rsaPrivateKey)
296 {
297  error_t error;
298  Asn1Tag tag;
299 
300  //Read RSAPrivateKey structure
301  error = asn1ReadSequence(data, length, &tag);
302  //Failed to decode ASN.1 tag?
303  if(error)
304  return error;
305 
306  //Point to the first field
307  data = tag.value;
308  length = tag.length;
309 
310  //Read Version field
311  error = asn1ReadInt32(data, length, &tag, &rsaPrivateKey->version);
312  //Failed to decode ASN.1 tag?
313  if(error)
314  return error;
315 
316  //Point to the next field
317  data += tag.totalLength;
318  length -= tag.totalLength;
319 
320  //Read Modulus field
321  error = asn1ReadTag(data, length, &tag);
322  //Failed to decode ASN.1 tag?
323  if(error)
324  return error;
325 
326  //Enforce encoding, class and type
328  //Invalid tag?
329  if(error)
330  return error;
331 
332  //Save the modulus
333  rsaPrivateKey->n.value = tag.value;
334  rsaPrivateKey->n.length = tag.length;
335 
336  //Point to the next field
337  data += tag.totalLength;
338  length -= tag.totalLength;
339 
340  //Read PublicExponent field
341  error = asn1ReadTag(data, length, &tag);
342  //Failed to decode ASN.1 tag?
343  if(error)
344  return error;
345 
346  //Enforce encoding, class and type
348  //Invalid tag?
349  if(error)
350  return error;
351 
352  //Save the public exponent
353  rsaPrivateKey->e.value = tag.value;
354  rsaPrivateKey->e.length = tag.length;
355 
356  //Point to the next field
357  data += tag.totalLength;
358  length -= tag.totalLength;
359 
360  //Read PrivateExponent field
361  error = asn1ReadTag(data, length, &tag);
362  //Failed to decode ASN.1 tag?
363  if(error)
364  return error;
365 
366  //Enforce encoding, class and type
368  //Invalid tag?
369  if(error)
370  return error;
371 
372  //Save the private exponent
373  rsaPrivateKey->d.value = tag.value;
374  rsaPrivateKey->d.length = tag.length;
375 
376  //Point to the next field
377  data += tag.totalLength;
378  length -= tag.totalLength;
379 
380  //Read Prime1 field
381  error = asn1ReadTag(data, length, &tag);
382  //Failed to decode ASN.1 tag?
383  if(error)
384  return error;
385 
386  //Enforce encoding, class and type
388  //Invalid tag?
389  if(error)
390  return error;
391 
392  //Save the first factor
393  rsaPrivateKey->p.value = tag.value;
394  rsaPrivateKey->p.length = tag.length;
395 
396  //Point to the next field
397  data += tag.totalLength;
398  length -= tag.totalLength;
399 
400  //Read Prime2 field
401  error = asn1ReadTag(data, length, &tag);
402  //Failed to decode ASN.1 tag?
403  if(error)
404  return error;
405 
406  //Enforce encoding, class and type
408  //Invalid tag?
409  if(error)
410  return error;
411 
412  //Save the second factor
413  rsaPrivateKey->q.value = tag.value;
414  rsaPrivateKey->q.length = tag.length;
415 
416  //Point to the next field
417  data += tag.totalLength;
418  length -= tag.totalLength;
419 
420  //Read Exponent1 field
421  error = asn1ReadTag(data, length, &tag);
422  //Failed to decode ASN.1 tag?
423  if(error)
424  return error;
425 
426  //Enforce encoding, class and type
428  //Invalid tag?
429  if(error)
430  return error;
431 
432  //Save the first exponent
433  rsaPrivateKey->dp.value = tag.value;
434  rsaPrivateKey->dp.length = tag.length;
435 
436  //Point to the next field
437  data += tag.totalLength;
438  length -= tag.totalLength;
439 
440  //Read Exponent2 field
441  error = asn1ReadTag(data, length, &tag);
442  //Failed to decode ASN.1 tag?
443  if(error)
444  return error;
445 
446  //Enforce encoding, class and type
448  //Invalid tag?
449  if(error)
450  return error;
451 
452  //Save the second exponent
453  rsaPrivateKey->dq.value = tag.value;
454  rsaPrivateKey->dq.length = tag.length;
455 
456  //Point to the next field
457  data += tag.totalLength;
458  length -= tag.totalLength;
459 
460  //Read Coefficient field
461  error = asn1ReadTag(data, length, &tag);
462  //Failed to decode ASN.1 tag?
463  if(error)
464  return error;
465 
466  //Enforce encoding, class and type
468  //Invalid tag?
469  if(error)
470  return error;
471 
472  //Save the coefficient
473  rsaPrivateKey->qinv.value = tag.value;
474  rsaPrivateKey->qinv.length = tag.length;
475 
476  //Successful processing
477  return NO_ERROR;
478 }
479 
480 
481 /**
482  * @brief Parse DSAPrivateKey structure
483  * @param[in] data Pointer to the ASN.1 structure to parse
484  * @param[in] length Length of the ASN.1 structure
485  * @param[out] dsaParams DSA domain parameters
486  * @param[out] dsaPrivateKey DSA private key
487  * @return Error code
488  **/
489 
491  X509DsaParameters *dsaParams, Pkcs8DsaPrivateKey *dsaPrivateKey)
492 {
493  error_t error;
494  int32_t version;
495  Asn1Tag tag;
496 
497  //The DSA domain parameters can be optionally parsed
498  if(dsaParams != NULL)
499  {
500  //Read DSAPrivateKey structure
501  error = asn1ReadSequence(data, length, &tag);
502  //Failed to decode ASN.1 tag?
503  if(error)
504  return error;
505 
506  //Point to the first field of the sequence
507  data = tag.value;
508  length = tag.length;
509 
510  //Read version
511  error = asn1ReadInt32(data, length, &tag, &version);
512  //Failed to decode ASN.1 tag?
513  if(error)
514  return error;
515 
516  //Point to the next field
517  data += tag.totalLength;
518  length -= tag.totalLength;
519 
520  //Read the parameter p
521  error = asn1ReadTag(data, length, &tag);
522  //Failed to decode ASN.1 tag?
523  if(error)
524  return error;
525 
526  //Enforce encoding, class and type
527  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
529  //Invalid tag?
530  if(error)
531  return error;
532 
533  //Save the parameter p
534  dsaParams->p.value = tag.value;
535  dsaParams->p.length = tag.length;
536 
537  //Point to the next field
538  data += tag.totalLength;
539  length -= tag.totalLength;
540 
541  //Read the parameter q
542  error = asn1ReadTag(data, length, &tag);
543  //Failed to decode ASN.1 tag?
544  if(error)
545  return error;
546 
547  //Enforce encoding, class and type
548  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
550  //Invalid tag?
551  if(error)
552  return error;
553 
554  //Save the parameter q
555  dsaParams->q.value = tag.value;
556  dsaParams->q.length = tag.length;
557 
558  //Point to the next field
559  data += tag.totalLength;
560  length -= tag.totalLength;
561 
562  //Read the parameter g
563  error = asn1ReadTag(data, length, &tag);
564  //Failed to decode ASN.1 tag?
565  if(error)
566  return error;
567 
568  //Enforce encoding, class and type
569  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
571  //Invalid tag?
572  if(error)
573  return error;
574 
575  //Save the parameter g
576  dsaParams->g.value = tag.value;
577  dsaParams->g.length = tag.length;
578 
579  //Point to the next field
580  data += tag.totalLength;
581  length -= tag.totalLength;
582 
583  //Read the public value y
584  error = asn1ReadTag(data, length, &tag);
585  //Failed to decode ASN.1 tag?
586  if(error)
587  return error;
588 
589  //Enforce encoding, class and type
590  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
592  //Invalid tag?
593  if(error)
594  return error;
595 
596  //Point to the next field
597  data += tag.totalLength;
598  length -= tag.totalLength;
599  }
600 
601  //Read the private value x
602  error = asn1ReadTag(data, length, &tag);
603  //Failed to decode ASN.1 tag?
604  if(error)
605  return error;
606 
607  //Enforce encoding, class and type
609  //Invalid tag?
610  if(error)
611  return error;
612 
613  //Save the private value x
614  dsaPrivateKey->x.value = tag.value;
615  dsaPrivateKey->x.length = tag.length;
616 
617  //Successful processing
618  return NO_ERROR;
619 }
620 
621 
622 /**
623  * @brief Parse ECPrivateKey structure
624  * @param[in] data Pointer to the ASN.1 structure to parse
625  * @param[in] length Length of the ASN.1 structure
626  * @param[out] ecParams EC domain parameters
627  * @param[out] ecPrivateKey EC private key
628  * @return Error code
629  **/
630 
631 error_t pkcs8ParseEcPrivateKey(const uint8_t *data, size_t length,
632  X509EcParameters *ecParams, Pkcs8EcPrivateKey *ecPrivateKey)
633 {
634  error_t error;
635  Asn1Tag tag;
636 
637  //Read ECPrivateKey structure
638  error = asn1ReadSequence(data, length, &tag);
639  //Failed to decode ASN.1 tag?
640  if(error)
641  return error;
642 
643  //Point to the first field
644  data = tag.value;
645  length = tag.length;
646 
647  //Read Version field
648  error = asn1ReadInt32(data, length, &tag, &ecPrivateKey->version);
649  //Failed to decode ASN.1 tag?
650  if(error)
651  return error;
652 
653  //Point to the next field
654  data += tag.totalLength;
655  length -= tag.totalLength;
656 
657  //Read PrivateKey field
658  error = asn1ReadOctetString(data, length, &tag);
659  //Failed to decode ASN.1 tag?
660  if(error)
661  return error;
662 
663  //Save the EC private key
664  ecPrivateKey->d.value = tag.value;
665  ecPrivateKey->d.length = tag.length;
666 
667  //Point to the next field
668  data += tag.totalLength;
669  length -= tag.totalLength;
670 
671  //Loop through optional attributes
672  while(length > 0)
673  {
674  //Read current attribute
675  error = asn1ReadTag(data, length, &tag);
676  //Failed to decode ASN.1 tag?
677  if(error)
678  return error;
679 
680  //Explicit tagging shall be used to encode each optional attribute
682  return ERROR_INVALID_CLASS;
683 
684  //Parameters attribute?
685  if(tag.objType == 0)
686  {
687  //Parse ECParameters structure
688  error = x509ParseEcParameters(tag.value, tag.length, ecParams);
689  //Any error to report?
690  if(error)
691  return error;
692  }
693 
694  //Next attribute
695  data += tag.totalLength;
696  length -= tag.totalLength;
697  }
698 
699  //Successful processing
700  return NO_ERROR;
701 }
702 
703 
704 /**
705  * @brief Parse CurvePrivateKey structure
706  * @param[in] data Pointer to the ASN.1 structure to parse
707  * @param[in] length Length of the ASN.1 structure
708  * @param[out] eddsaPrivateKey Information resulting from the parsing process
709  * @return Error code
710  **/
711 
713  Pkcs8EddsaPrivateKey *eddsaPrivateKey)
714 {
715  error_t error;
716  Asn1Tag tag;
717 
718  //The CurvePrivateKey structure is encapsulated within an octet string
719  error = asn1ReadOctetString(data, length, &tag);
720  //Failed to decode ASN.1 tag?
721  if(error)
722  return error;
723 
724  //Save the EdDSA private key
725  eddsaPrivateKey->d.value = tag.value;
726  eddsaPrivateKey->d.length = tag.length;
727 
728  //Successful processing
729  return NO_ERROR;
730 }
731 
732 
733 /**
734  * @brief Parse EncryptedPrivateKeyInfo structure
735  * @param[in] data Pointer to the ASN.1 structure to parse
736  * @param[in] length Length of the ASN.1 structure
737  * @param[out] encryptedPrivateKeyInfo Information resulting from the parsing process
738  * @return Error code
739  **/
740 
742  Pkcs8EncryptedPrivateKeyInfo *encryptedPrivateKeyInfo)
743 {
744  error_t error;
745  size_t n;
746  Asn1Tag tag;
747 
748  //Read EncryptedPrivateKeyInfo structure
749  error = asn1ReadSequence(data, length, &tag);
750  //Failed to decode ASN.1 tag?
751  if(error)
752  return error;
753 
754  //Point to the first field
755  data = tag.value;
756  length = tag.length;
757 
758  //Parse EncryptionAlgorithmIdentifier structure
760  &encryptedPrivateKeyInfo->encryptionAlgo);
761  //Any error to report?
762  if(error)
763  return error;
764 
765  //Point to the next field
766  data += n;
767  length -= n;
768 
769  //The EncryptedData is encapsulated within an octet string
770  error = asn1ReadOctetString(data, length, &tag);
771  //Failed to decode ASN.1 tag?
772  if(error)
773  return error;
774 
775  //The EncryptedData is the result of encrypting the private-key information
776  encryptedPrivateKeyInfo->encryptedData.value = tag.value;
777  encryptedPrivateKeyInfo->encryptedData.length = tag.length;
778 
779  //Successful processing
780  return NO_ERROR;
781 }
782 
783 
784 /**
785  * @brief Parse EncryptionAlgorithmIdentifier structure
786  * @param[in] data Pointer to the ASN.1 structure to parse
787  * @param[in] length Length of the ASN.1 structure
788  * @param[out] totalLength Number of bytes that have been parsed
789  * @param[out] encryptionAlgoId Information resulting from the parsing process
790  * @return Error code
791  **/
792 
794  size_t *totalLength, X509AlgoId *encryptionAlgoId)
795 {
796  error_t error;
797  Asn1Tag tag;
798 
799  //Read the contents of the EncryptionAlgorithmIdentifier structure
800  error = asn1ReadSequence(data, length, &tag);
801  //Failed to decode ASN.1 tag?
802  if(error)
803  return error;
804 
805  //Save the total length of the field
806  *totalLength = tag.totalLength;
807 
808  //Point to the first field of the sequence
809  data = tag.value;
810  length = tag.length;
811 
812  //Read the encryption algorithm identifier
813  error = asn1ReadOid(data, length, &tag);
814  //Failed to decode ASN.1 tag?
815  if(error)
816  return error;
817 
818  //Save the encryption algorithm identifier
819  encryptionAlgoId->oid.value = tag.value;
820  encryptionAlgoId->oid.length = tag.length;
821 
822  //Point to the next field (if any)
823  data += tag.totalLength;
824  length -= tag.totalLength;
825 
826  //The contents of the optional parameters field will vary according to the
827  //algorithm identified
828  encryptionAlgoId->params.value = data;
829  encryptionAlgoId->params.length = length;
830 
831  //Return status code
832  return error;
833 }
834 
835 
836 /**
837  * @brief Import an RSA private key
838  * @param[in] privateKeyInfo Private key information
839  * @param[out] privateKey RSA private key
840  * @return Error code
841  **/
842 
844  RsaPrivateKey *privateKey)
845 {
846  error_t error;
847 
848 #if (RSA_SUPPORT == ENABLED)
849  const uint8_t *oid;
850  size_t oidLen;
851 
852  //Get the private key algorithm identifier
853  oid = privateKeyInfo->oid.value;
854  oidLen = privateKeyInfo->oid.length;
855 
856  //RSA or RSA-PSS algorithm identifier?
859  {
860  //Sanity check
861  if(privateKeyInfo->rsaPrivateKey.n.value != NULL &&
862  privateKeyInfo->rsaPrivateKey.e.value != NULL &&
863  privateKeyInfo->rsaPrivateKey.d.value != NULL &&
864  privateKeyInfo->rsaPrivateKey.p.value != NULL &&
865  privateKeyInfo->rsaPrivateKey.q.value != NULL &&
866  privateKeyInfo->rsaPrivateKey.dp.value != NULL &&
867  privateKeyInfo->rsaPrivateKey.dq.value != NULL &&
868  privateKeyInfo->rsaPrivateKey.qinv.value != NULL)
869  {
870  //Read modulus
871  error = mpiImport(&privateKey->n, privateKeyInfo->rsaPrivateKey.n.value,
872  privateKeyInfo->rsaPrivateKey.n.length, MPI_FORMAT_BIG_ENDIAN);
873 
874  //Check status code
875  if(!error)
876  {
877  //Read public exponent
878  error = mpiImport(&privateKey->e, privateKeyInfo->rsaPrivateKey.e.value,
879  privateKeyInfo->rsaPrivateKey.e.length, MPI_FORMAT_BIG_ENDIAN);
880  }
881 
882  //Check status code
883  if(!error)
884  {
885  //Read private exponent
886  error = mpiImport(&privateKey->d, privateKeyInfo->rsaPrivateKey.d.value,
887  privateKeyInfo->rsaPrivateKey.d.length, MPI_FORMAT_BIG_ENDIAN);
888  }
889 
890  //Check status code
891  if(!error)
892  {
893  //Read first factor
894  error = mpiImport(&privateKey->p, privateKeyInfo->rsaPrivateKey.p.value,
895  privateKeyInfo->rsaPrivateKey.p.length, MPI_FORMAT_BIG_ENDIAN);
896  }
897 
898  //Check status code
899  if(!error)
900  {
901  //Read second factor
902  error = mpiImport(&privateKey->q, privateKeyInfo->rsaPrivateKey.q.value,
903  privateKeyInfo->rsaPrivateKey.q.length, MPI_FORMAT_BIG_ENDIAN);
904  }
905 
906  //Check status code
907  if(!error)
908  {
909  //Read first exponent
910  error = mpiImport(&privateKey->dp, privateKeyInfo->rsaPrivateKey.dp.value,
911  privateKeyInfo->rsaPrivateKey.dp.length, MPI_FORMAT_BIG_ENDIAN);
912  }
913 
914  //Check status code
915  if(!error)
916  {
917  //Read second exponent
918  error = mpiImport(&privateKey->dq, privateKeyInfo->rsaPrivateKey.dq.value,
919  privateKeyInfo->rsaPrivateKey.dq.length, MPI_FORMAT_BIG_ENDIAN);
920  }
921 
922  //Check status code
923  if(!error)
924  {
925  //Read coefficient
926  error = mpiImport(&privateKey->qinv, privateKeyInfo->rsaPrivateKey.qinv.value,
928  }
929 
930  //Check status code
931  if(!error)
932  {
933  //Debug message
934  TRACE_DEBUG("RSA private key:\r\n");
935  TRACE_DEBUG(" Modulus:\r\n");
936  TRACE_DEBUG_MPI(" ", &privateKey->n);
937  TRACE_DEBUG(" Public exponent:\r\n");
938  TRACE_DEBUG_MPI(" ", &privateKey->e);
939  TRACE_DEBUG(" Private exponent:\r\n");
940  TRACE_DEBUG_MPI(" ", &privateKey->d);
941  TRACE_DEBUG(" Prime 1:\r\n");
942  TRACE_DEBUG_MPI(" ", &privateKey->p);
943  TRACE_DEBUG(" Prime 2:\r\n");
944  TRACE_DEBUG_MPI(" ", &privateKey->q);
945  TRACE_DEBUG(" Prime exponent 1:\r\n");
946  TRACE_DEBUG_MPI(" ", &privateKey->dp);
947  TRACE_DEBUG(" Prime exponent 2:\r\n");
948  TRACE_DEBUG_MPI(" ", &privateKey->dq);
949  TRACE_DEBUG(" Coefficient:\r\n");
950  TRACE_DEBUG_MPI(" ", &privateKey->qinv);
951  }
952  }
953  else
954  {
955  //The private key is not valid
956  error = ERROR_INVALID_KEY;
957  }
958  }
959  else
960 #endif
961  //Invalid algorithm identifier?
962  {
963  //Report an error
964  error = ERROR_WRONG_IDENTIFIER;
965  }
966 
967  //Return status code
968  return error;
969 }
970 
971 
972 /**
973  * @brief Import a DSA private key
974  * @param[in] privateKeyInfo Private key information
975  * @param[out] privateKey DSA private key
976  * @return Error code
977  **/
978 
980  DsaPrivateKey *privateKey)
981 {
982  error_t error;
983 
984 #if (DSA_SUPPORT == ENABLED)
985  //DSA algorithm identifier?
986  if(!oidComp(privateKeyInfo->oid.value, privateKeyInfo->oid.length,
987  DSA_OID, sizeof(DSA_OID)))
988  {
989  //Sanity check
990  if(privateKeyInfo->dsaParams.p.value != NULL &&
991  privateKeyInfo->dsaParams.q.value != NULL &&
992  privateKeyInfo->dsaParams.g.value != NULL &&
993  privateKeyInfo->dsaPrivateKey.x.value != NULL)
994  {
995  //Read parameter p
996  error = mpiImport(&privateKey->params.p, privateKeyInfo->dsaParams.p.value,
997  privateKeyInfo->dsaParams.p.length, MPI_FORMAT_BIG_ENDIAN);
998 
999  //Check status code
1000  if(!error)
1001  {
1002  //Read parameter q
1003  error = mpiImport(&privateKey->params.q, privateKeyInfo->dsaParams.q.value,
1004  privateKeyInfo->dsaParams.q.length, MPI_FORMAT_BIG_ENDIAN);
1005  }
1006 
1007  //Check status code
1008  if(!error)
1009  {
1010  //Read parameter g
1011  error = mpiImport(&privateKey->params.g, privateKeyInfo->dsaParams.g.value,
1012  privateKeyInfo->dsaParams.g.length, MPI_FORMAT_BIG_ENDIAN);
1013  }
1014 
1015  //Check status code
1016  if(!error)
1017  {
1018  //Read private value
1019  error = mpiImport(&privateKey->x, privateKeyInfo->dsaPrivateKey.x.value,
1020  privateKeyInfo->dsaPrivateKey.x.length, MPI_FORMAT_BIG_ENDIAN);
1021  }
1022 
1023  //Check status code
1024  if(!error)
1025  {
1026  //Debug message
1027  TRACE_DEBUG("DSA private key:\r\n");
1028  TRACE_DEBUG(" Parameter p:\r\n");
1029  TRACE_DEBUG_MPI(" ", &privateKey->params.p);
1030  TRACE_DEBUG(" Parameter q:\r\n");
1031  TRACE_DEBUG_MPI(" ", &privateKey->params.q);
1032  TRACE_DEBUG(" Parameter g:\r\n");
1033  TRACE_DEBUG_MPI(" ", &privateKey->params.g);
1034  TRACE_DEBUG(" Private value x:\r\n");
1035  TRACE_DEBUG_MPI(" ", &privateKey->x);
1036  }
1037  }
1038  else
1039  {
1040  //The private key is not valid
1041  error = ERROR_INVALID_KEY;
1042  }
1043  }
1044  else
1045 #endif
1046  //Invalid algorithm identifier?
1047  {
1048  //Report an error
1049  error = ERROR_WRONG_IDENTIFIER;
1050  }
1051 
1052  //Return status code
1053  return error;
1054 }
1055 
1056 
1057 /**
1058  * @brief Import an EC private key
1059  * @param[in] privateKeyInfo Private key information
1060  * @param[out] privateKey EC private key
1061  * @return Error code
1062  **/
1063 
1065  EcPrivateKey *privateKey)
1066 {
1067  error_t error;
1068 
1069 #if (EC_SUPPORT == ENABLED)
1070  //EC public key algorithm identifier?
1071  if(!oidComp(privateKeyInfo->oid.value, privateKeyInfo->oid.length,
1073  {
1074  //Sanity check
1075  if(privateKeyInfo->ecPrivateKey.d.value != NULL)
1076  {
1077  //Read the EC private key
1078  error = mpiImport(&privateKey->d, privateKeyInfo->ecPrivateKey.d.value,
1079  privateKeyInfo->ecPrivateKey.d.length, MPI_FORMAT_BIG_ENDIAN);
1080 
1081  //Check status code
1082  if(!error)
1083  {
1084  //Debug message
1085  TRACE_DEBUG("EC private key:\r\n");
1086  TRACE_DEBUG_MPI(" ", &privateKey->d);
1087  }
1088  }
1089  else
1090  {
1091  //The private key is not valid
1092  error = ERROR_INVALID_KEY;
1093  }
1094  }
1095  else
1096 #endif
1097  //Invalid algorithm identifier?
1098  {
1099  //Report an error
1100  error = ERROR_WRONG_IDENTIFIER;
1101  }
1102 
1103  //Return status code
1104  return error;
1105 }
1106 
1107 
1108 /**
1109  * @brief Import an EdDSA private key
1110  * @param[in] privateKeyInfo Private key information
1111  * @param[out] privateKey EdDSA private key
1112  * @return Error code
1113  **/
1114 
1116  EddsaPrivateKey *privateKey)
1117 {
1118  error_t error;
1119 
1120 #if (ED25519_SUPPORT == ENABLED)
1121  //Ed25519 algorithm identifier?
1122  if(!oidComp(privateKeyInfo->oid.value, privateKeyInfo->oid.length,
1123  ED25519_OID, sizeof(ED25519_OID)))
1124  {
1125  //Check the length of the Ed25519 private key
1126  if(privateKeyInfo->eddsaPrivateKey.d.value != NULL &&
1127  privateKeyInfo->eddsaPrivateKey.d.length == ED25519_PRIVATE_KEY_LEN)
1128  {
1129  //Read the Ed25519 private key
1130  error = mpiImport(&privateKey->d, privateKeyInfo->eddsaPrivateKey.d.value,
1132  }
1133  else
1134  {
1135  //The private key is not valid
1136  error = ERROR_INVALID_KEY;
1137  }
1138  }
1139  else
1140 #endif
1141 #if (ED448_SUPPORT == ENABLED)
1142  //Ed448 algorithm identifier?
1143  if(!oidComp(privateKeyInfo->oid.value, privateKeyInfo->oid.length,
1144  ED448_OID, sizeof(ED448_OID)))
1145  {
1146  //Check the length of the Ed448 private key
1147  if(privateKeyInfo->eddsaPrivateKey.d.value != NULL &&
1148  privateKeyInfo->eddsaPrivateKey.d.length == ED448_PRIVATE_KEY_LEN)
1149  {
1150  //Read the Ed448 private key
1151  error = mpiImport(&privateKey->d, privateKeyInfo->eddsaPrivateKey.d.value,
1153  }
1154  else
1155  {
1156  //The private key is not valid
1157  error = ERROR_INVALID_KEY;
1158  }
1159  }
1160  else
1161 #endif
1162  //Invalid algorithm identifier?
1163  {
1164  //Report an error
1165  error = ERROR_WRONG_IDENTIFIER;
1166  }
1167 
1168  //Check status code
1169  if(!error)
1170  {
1171  //Debug message
1172  TRACE_DEBUG("EdDSA private key:\r\n");
1173  TRACE_DEBUG_MPI(" ", &privateKey->d);
1174  }
1175 
1176  //Return status code
1177  return error;
1178 }
1179 
1180 #endif
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 asn1ReadTag(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an ASN.1 tag from the input stream.
Definition: asn1.c:52
error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
Check ASN.1 tag against a specified OID.
Definition: asn1.c:679
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
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:653
error_t asn1ReadOid(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an object identifier from the input stream.
Definition: asn1.c:218
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
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_INTEGER
Definition: asn1.h:70
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:54
uint8_t version
Definition: coap_common.h:177
General definitions for cryptographic algorithms.
Debugging facilities.
#define TRACE_DEBUG(...)
Definition: debug.h:107
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:110
uint8_t n
const uint8_t DSA_OID[7]
Definition: dsa.c:51
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:43
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_PRIVATE_KEY_LEN
Definition: ed25519.h:40
#define ED448_PRIVATE_KEY_LEN
Definition: ed448.h:40
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ ERROR_INVALID_KEY
Definition: error.h:106
@ ERROR_INVALID_CLASS
Definition: error.h:117
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t data[]
Definition: ethernet.h:222
uint16_t totalLength
Definition: ipv4.h:292
uint8_t oid[]
Definition: lldp_tlv.h:300
uint8_t oidLen
Definition: lldp_tlv.h:299
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:624
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:71
@ MPI_FORMAT_LITTLE_ENDIAN
Definition: mpi.h:70
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 osMemset(p, value, length)
Definition: os_port.h:135
#define FALSE
Definition: os_port.h:46
error_t pkcs8ImportEcPrivateKey(const Pkcs8PrivateKeyInfo *privateKeyInfo, EcPrivateKey *privateKey)
Import an EC private key.
error_t pkcs8ParseEddsaPrivateKey(const uint8_t *data, size_t length, Pkcs8EddsaPrivateKey *eddsaPrivateKey)
Parse CurvePrivateKey structure.
error_t pkcs8ImportRsaPrivateKey(const Pkcs8PrivateKeyInfo *privateKeyInfo, RsaPrivateKey *privateKey)
Import an RSA private key.
error_t pkcs8ParsePrivateKeyAlgo(const uint8_t *data, size_t length, size_t *totalLength, Pkcs8PrivateKeyInfo *privateKeyInfo)
Parse PrivateKeyAlgorithm structure.
error_t pkcs8ParseRsaPrivateKey(const uint8_t *data, size_t length, Pkcs8RsaPrivateKey *rsaPrivateKey)
Parse RSAPrivateKey structure.
error_t pkcs8ParseEncryptionAlgoId(const uint8_t *data, size_t length, size_t *totalLength, X509AlgoId *encryptionAlgoId)
Parse EncryptionAlgorithmIdentifier structure.
error_t pkcs8ParseDsaPrivateKey(const uint8_t *data, size_t length, X509DsaParameters *dsaParams, Pkcs8DsaPrivateKey *dsaPrivateKey)
Parse DSAPrivateKey structure.
error_t pkcs8ParseEcPrivateKey(const uint8_t *data, size_t length, X509EcParameters *ecParams, Pkcs8EcPrivateKey *ecPrivateKey)
Parse ECPrivateKey structure.
error_t pkcs8ParseEncryptedPrivateKeyInfo(const uint8_t *data, size_t length, Pkcs8EncryptedPrivateKeyInfo *encryptedPrivateKeyInfo)
Parse EncryptedPrivateKeyInfo structure.
error_t pkcs8ImportEddsaPrivateKey(const Pkcs8PrivateKeyInfo *privateKeyInfo, EddsaPrivateKey *privateKey)
Import an EdDSA private key.
error_t pkcs8ParsePrivateKeyInfo(const uint8_t *data, size_t length, Pkcs8PrivateKeyInfo *privateKeyInfo)
Parse PrivateKeyInfo structure.
error_t pkcs8ImportDsaPrivateKey(const Pkcs8PrivateKeyInfo *privateKeyInfo, DsaPrivateKey *privateKey)
Import a DSA private key.
PKCS #8 key parsing.
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:57
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:88
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
size_t length
Definition: asn1.h:106
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
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:73
Mpi x
Secret exponent.
Definition: dsa.h:74
EC private key.
Definition: ec.h:104
Mpi d
Private key.
Definition: ec.h:105
EdDSA private key.
Definition: eddsa.h:59
Mpi d
Private key.
Definition: eddsa.h:60
DSA private key.
X509OctetString x
EC private key.
X509OctetString d
EdDSA private key.
X509OctetString d
Encrypted private key information.
Private key information.
Pkcs8DsaPrivateKey dsaPrivateKey
Pkcs8RsaPrivateKey rsaPrivateKey
X509OctetString oid
X509DsaParameters dsaParams
Pkcs8EddsaPrivateKey eddsaPrivateKey
X509EcParameters ecParams
Pkcs8EcPrivateKey ecPrivateKey
RSA private key.
X509OctetString n
X509OctetString p
X509OctetString dp
X509OctetString e
X509OctetString q
X509OctetString d
X509OctetString dq
X509OctetString qinv
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
Algorithm identifier.
Definition: x509_common.h:719
X509OctetString oid
Definition: x509_common.h:720
X509OctetString params
Definition: x509_common.h:721
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
EC parameters.
Definition: x509_common.h:763
const uint8_t * value
Definition: x509_common.h:647
uint8_t length
Definition: tcp.h:368
error_t x509ParseEcParameters(const uint8_t *data, size_t length, X509EcParameters *ecParams)
Parse ECParameters structure.
error_t x509ParseDsaParameters(const uint8_t *data, size_t length, X509DsaParameters *dsaParams)
Parse DSA domain parameters.
Parsing of ASN.1 encoded keys.