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-2019 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCrypto Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 1.9.6
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "pkix/pkcs8_key_parse.h"
37 #include "pkix/x509_key_parse.h"
38 #include "encoding/asn1.h"
39 #include "encoding/oid.h"
40 #include "ecc/ed25519.h"
41 #include "ecc/ed448.h"
42 #include "debug.h"
43 
44 //Check crypto library configuration
45 #if (PEM_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief Parse PrivateKeyInfo structure
50  * @param[in] data Pointer to the ASN.1 structure to parse
51  * @param[in] length Length of the ASN.1 structure
52  * @param[out] privateKeyInfo Information resulting from the parsing process
53  * @return Error code
54  **/
55 
57  Pkcs8PrivateKeyInfo *privateKeyInfo)
58 {
59  error_t error;
60  size_t n;
61  size_t oidLen;
62  const uint8_t *oid;
63  Asn1Tag tag;
64 
65  //Clear the PrivateKeyInfo structure
66  cryptoMemset(privateKeyInfo, 0, sizeof(Pkcs8PrivateKeyInfo));
67 
68  //The private key information is encapsulated within a sequence
69  error = asn1ReadSequence(data, length, &tag);
70  //Failed to decode ASN.1 tag?
71  if(error)
72  return error;
73 
74  //Point to the first field of the sequence
75  data = tag.value;
76  length = tag.length;
77 
78  //Read Version field
79  error = asn1ReadInt32(data, length, &tag, &privateKeyInfo->version);
80  //Failed to decode ASN.1 tag?
81  if(error)
82  return error;
83 
84  //Point to the next field
85  data += tag.totalLength;
86  length -= tag.totalLength;
87 
88  //Read PrivateKeyAlgorithm field
89  error = pkcs8ParsePrivateKeyAlgo(data, length, &n, privateKeyInfo);
90  //Failed to decode ASN.1 tag?
91  if(error)
92  return error;
93 
94  //Point to the next field
95  data += n;
96  length -= n;
97 
98  //The PrivateKey is encapsulated within an octet string
99  error = asn1ReadOctetString(data, length, &tag);
100  //Failed to decode ASN.1 tag?
101  if(error)
102  return error;
103 
104  //Point to the private key
105  data = tag.value;
106  length = tag.length;
107 
108  //Get the private key algorithm identifier
109  oid = privateKeyInfo->oid;
110  oidLen = privateKeyInfo->oidLen;
111 
112 #if (RSA_SUPPORT == ENABLED)
113  //RSA or RSA-PSS algorithm identifier?
114  if(!oidComp(oid, oidLen, RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID)) ||
115  !oidComp(oid, oidLen, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
116  {
117  //Read RSAPrivateKey structure
119  &privateKeyInfo->rsaPrivateKey);
120  }
121  else
122 #endif
123 #if (DSA_SUPPORT == ENABLED)
124  //DSA algorithm identifier?
125  if(!oidComp(oid, oidLen, DSA_OID, sizeof(DSA_OID)))
126  {
127  //Read DSAPrivateKey structure
128  error = pkcs8ParseDsaPrivateKey(data, length, NULL,
129  &privateKeyInfo->dsaPrivateKey);
130  }
131  else
132 #endif
133 #if (EC_SUPPORT == ENABLED)
134  //EC public key identifier?
135  if(!oidComp(oid, oidLen, EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID)))
136  {
137  //Read ECPrivateKey structure
138  error = pkcs8ParseEcPrivateKey(data, length, &privateKeyInfo->ecParams,
139  &privateKeyInfo->ecPrivateKey);
140  }
141  else
142 #endif
143 #if (ED25519_SUPPORT == ENABLED)
144  //X25519 or Ed25519 algorithm identifier?
145  if(!oidComp(oid, oidLen, X25519_OID, sizeof(X25519_OID)) ||
146  !oidComp(oid, oidLen, ED25519_OID, sizeof(ED25519_OID)))
147  {
148  //Read CurvePrivateKey structure
150  &privateKeyInfo->eddsaPrivateKey);
151  }
152  else
153 #endif
154 #if (ED448_SUPPORT == ENABLED)
155  //X448 or Ed448 algorithm identifier?
156  if(!oidComp(oid, oidLen, X448_OID, sizeof(X448_OID)) ||
157  !oidComp(oid, oidLen, ED448_OID, sizeof(ED448_OID)))
158  {
159  //Read CurvePrivateKey structure
161  &privateKeyInfo->eddsaPrivateKey);
162  }
163  else
164 #endif
165  //Unknown algorithm identifier?
166  {
167  //Report an error
168  error = ERROR_WRONG_IDENTIFIER;
169  }
170 
171  //Return status code
172  return error;
173 }
174 
175 
176 /**
177  * @brief Parse PrivateKeyAlgorithm structure
178  * @param[in] data Pointer to the ASN.1 structure to parse
179  * @param[in] length Length of the ASN.1 structure
180  * @param[out] totalLength Number of bytes that have been parsed
181  * @param[out] privateKeyInfo Information resulting from the parsing process
182  * @return Error code
183  **/
184 
186  size_t *totalLength, Pkcs8PrivateKeyInfo *privateKeyInfo)
187 {
188  error_t error;
189  Asn1Tag tag;
190 
191  //Read the contents of the PrivateKeyAlgorithm structure
192  error = asn1ReadSequence(data, length, &tag);
193  //Failed to decode ASN.1 tag?
194  if(error)
195  return error;
196 
197  //Save the total length of the field
198  *totalLength = tag.totalLength;
199 
200  //Point to the first field of the sequence
201  data = tag.value;
202  length = tag.length;
203 
204  //Read the private key algorithm identifier
205  error = asn1ReadOid(data, length, &tag);
206  //Failed to decode ASN.1 tag?
207  if(error)
208  return error;
209 
210  //Save the private key algorithm identifier
211  privateKeyInfo->oid = tag.value;
212  privateKeyInfo->oidLen = tag.length;
213 
214  //Point to the next field (if any)
215  data += tag.totalLength;
216  length -= tag.totalLength;
217 
218 #if (RSA_SUPPORT == ENABLED)
219  //RSA algorithm identifier?
221  {
222  //The parameters field must have ASN.1 type NULL for this algorithm
223  //identifier (refer to RFC 3279, section 2.3.1)
224  error = NO_ERROR;
225  }
226  //RSA-PSS algorithm identifier?
227  else if(!asn1CheckOid(&tag, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
228  {
229  //The parameters may be either absent or present when used as subject
230  //public key information (refer to RFC 4055, section 3.1)
231  error = NO_ERROR;
232  }
233  else
234 #endif
235 #if (DSA_SUPPORT == ENABLED)
236  //DSA algorithm identifier?
237  if(!asn1CheckOid(&tag, DSA_OID, sizeof(DSA_OID)))
238  {
239  //Read DsaParameters structure
241  &privateKeyInfo->dsaParams);
242  }
243  else
244 #endif
245 #if (EC_SUPPORT == ENABLED)
246  //EC public key identifier?
248  {
249  //Read ECParameters structure
251  &privateKeyInfo->ecParams);
252  }
253  else
254 #endif
255 #if (ED25519_SUPPORT == ENABLED)
256  //X25519 or Ed25519 algorithm identifier?
257  if(!asn1CheckOid(&tag, X25519_OID, sizeof(X25519_OID)) ||
258  !asn1CheckOid(&tag, ED25519_OID, sizeof(ED25519_OID)))
259  {
260  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
261  //section 3)
262  error = NO_ERROR;
263  }
264  else
265 #endif
266 #if (ED448_SUPPORT == ENABLED)
267  //X448 or Ed448 algorithm identifier?
268  if(!asn1CheckOid(&tag, X448_OID, sizeof(X448_OID)) ||
269  !asn1CheckOid(&tag, ED448_OID, sizeof(ED448_OID)))
270  {
271  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
272  //section 3)
273  error = NO_ERROR;
274  }
275  else
276 #endif
277  //Unknown algorithm identifier?
278  {
279  //Report an error
280  error = ERROR_WRONG_IDENTIFIER;
281  }
282 
283  //Return status code
284  return error;
285 }
286 
287 
288 /**
289  * @brief Parse RSAPrivateKey structure
290  * @param[in] data Pointer to the ASN.1 structure to parse
291  * @param[in] length Length of the ASN.1 structure
292  * @param[out] rsaPrivateKey Information resulting from the parsing process
293  * @return Error code
294  **/
295 
297  Pkcs8RsaPrivateKey *rsaPrivateKey)
298 {
299  error_t error;
300  Asn1Tag tag;
301 
302  //Read RSAPrivateKey structure
303  error = asn1ReadSequence(data, length, &tag);
304  //Failed to decode ASN.1 tag?
305  if(error)
306  return error;
307 
308  //Point to the first field
309  data = tag.value;
310  length = tag.length;
311 
312  //Read Version field
313  error = asn1ReadInt32(data, length, &tag, &rsaPrivateKey->version);
314  //Failed to decode ASN.1 tag?
315  if(error)
316  return error;
317 
318  //Point to the next field
319  data += tag.totalLength;
320  length -= tag.totalLength;
321 
322  //Read Modulus field
323  error = asn1ReadTag(data, length, &tag);
324  //Failed to decode ASN.1 tag?
325  if(error)
326  return error;
327 
328  //Enforce encoding, class and type
330  //Invalid tag?
331  if(error)
332  return error;
333 
334  //Save the modulus
335  rsaPrivateKey->n = tag.value;
336  rsaPrivateKey->nLen = tag.length;
337 
338  //Point to the next field
339  data += tag.totalLength;
340  length -= tag.totalLength;
341 
342  //Read PublicExponent field
343  error = asn1ReadTag(data, length, &tag);
344  //Failed to decode ASN.1 tag?
345  if(error)
346  return error;
347 
348  //Enforce encoding, class and type
350  //Invalid tag?
351  if(error)
352  return error;
353 
354  //Save the public exponent
355  rsaPrivateKey->e = tag.value;
356  rsaPrivateKey->eLen = tag.length;
357 
358  //Point to the next field
359  data += tag.totalLength;
360  length -= tag.totalLength;
361 
362  //Read PrivateExponent field
363  error = asn1ReadTag(data, length, &tag);
364  //Failed to decode ASN.1 tag?
365  if(error)
366  return error;
367 
368  //Enforce encoding, class and type
370  //Invalid tag?
371  if(error)
372  return error;
373 
374  //Save the private exponent
375  rsaPrivateKey->d = tag.value;
376  rsaPrivateKey->dLen = tag.length;
377 
378  //Point to the next field
379  data += tag.totalLength;
380  length -= tag.totalLength;
381 
382  //Read Prime1 field
383  error = asn1ReadTag(data, length, &tag);
384  //Failed to decode ASN.1 tag?
385  if(error)
386  return error;
387 
388  //Enforce encoding, class and type
390  //Invalid tag?
391  if(error)
392  return error;
393 
394  //Save the first factor
395  rsaPrivateKey->p = tag.value;
396  rsaPrivateKey->pLen = tag.length;
397 
398  //Point to the next field
399  data += tag.totalLength;
400  length -= tag.totalLength;
401 
402  //Read Prime2 field
403  error = asn1ReadTag(data, length, &tag);
404  //Failed to decode ASN.1 tag?
405  if(error)
406  return error;
407 
408  //Enforce encoding, class and type
410  //Invalid tag?
411  if(error)
412  return error;
413 
414  //Save the second factor
415  rsaPrivateKey->q = tag.value;
416  rsaPrivateKey->qLen = tag.length;
417 
418  //Point to the next field
419  data += tag.totalLength;
420  length -= tag.totalLength;
421 
422  //Read Exponent1 field
423  error = asn1ReadTag(data, length, &tag);
424  //Failed to decode ASN.1 tag?
425  if(error)
426  return error;
427 
428  //Enforce encoding, class and type
430  //Invalid tag?
431  if(error)
432  return error;
433 
434  //Save the first exponent
435  rsaPrivateKey->dp = tag.value;
436  rsaPrivateKey->dpLen = tag.length;
437 
438  //Point to the next field
439  data += tag.totalLength;
440  length -= tag.totalLength;
441 
442  //Read Exponent2 field
443  error = asn1ReadTag(data, length, &tag);
444  //Failed to decode ASN.1 tag?
445  if(error)
446  return error;
447 
448  //Enforce encoding, class and type
450  //Invalid tag?
451  if(error)
452  return error;
453 
454  //Save the second exponent
455  rsaPrivateKey->dq = tag.value;
456  rsaPrivateKey->dqLen = tag.length;
457 
458  //Point to the next field
459  data += tag.totalLength;
460  length -= tag.totalLength;
461 
462  //Read Coefficient field
463  error = asn1ReadTag(data, length, &tag);
464  //Failed to decode ASN.1 tag?
465  if(error)
466  return error;
467 
468  //Enforce encoding, class and type
470  //Invalid tag?
471  if(error)
472  return error;
473 
474  //Save the coefficient
475  rsaPrivateKey->qinv = tag.value;
476  rsaPrivateKey->qinvLen = tag.length;
477 
478  //Successful processing
479  return NO_ERROR;
480 }
481 
482 
483 /**
484  * @brief Parse DSAPrivateKey structure
485  * @param[in] data Pointer to the ASN.1 structure to parse
486  * @param[in] length Length of the ASN.1 structure
487  * @param[out] dsaParams DSA domain parameters
488  * @param[out] dsaPrivateKey DSA private key
489  * @return Error code
490  **/
491 
493  X509DsaParameters *dsaParams, Pkcs8DsaPrivateKey *dsaPrivateKey)
494 {
495  error_t error;
496  int32_t version;
497  Asn1Tag tag;
498 
499  //The DSA domain parameters can be optionally parsed
500  if(dsaParams != NULL)
501  {
502  //Read DSAPrivateKey structure
503  error = asn1ReadSequence(data, length, &tag);
504  //Failed to decode ASN.1 tag?
505  if(error)
506  return error;
507 
508  //Point to the first field of the sequence
509  data = tag.value;
510  length = tag.length;
511 
512  //Read version
513  error = asn1ReadInt32(data, length, &tag, &version);
514  //Failed to decode ASN.1 tag?
515  if(error)
516  return error;
517 
518  //Point to the next field
519  data += tag.totalLength;
520  length -= tag.totalLength;
521 
522  //Read the parameter p
523  error = asn1ReadTag(data, length, &tag);
524  //Failed to decode ASN.1 tag?
525  if(error)
526  return error;
527 
528  //Enforce encoding, class and type
529  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
531  //Invalid tag?
532  if(error)
533  return error;
534 
535  //Save the parameter p
536  dsaParams->p = tag.value;
537  dsaParams->pLen = tag.length;
538 
539  //Point to the next field
540  data += tag.totalLength;
541  length -= tag.totalLength;
542 
543  //Read the parameter q
544  error = asn1ReadTag(data, length, &tag);
545  //Failed to decode ASN.1 tag?
546  if(error)
547  return error;
548 
549  //Enforce encoding, class and type
550  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
552  //Invalid tag?
553  if(error)
554  return error;
555 
556  //Save the parameter q
557  dsaParams->q = tag.value;
558  dsaParams->qLen = tag.length;
559 
560  //Point to the next field
561  data += tag.totalLength;
562  length -= tag.totalLength;
563 
564  //Read the parameter g
565  error = asn1ReadTag(data, length, &tag);
566  //Failed to decode ASN.1 tag?
567  if(error)
568  return error;
569 
570  //Enforce encoding, class and type
571  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
573  //Invalid tag?
574  if(error)
575  return error;
576 
577  //Save the parameter g
578  dsaParams->g = tag.value;
579  dsaParams->gLen = tag.length;
580 
581  //Point to the next field
582  data += tag.totalLength;
583  length -= tag.totalLength;
584 
585  //Read the public value y
586  error = asn1ReadTag(data, length, &tag);
587  //Failed to decode ASN.1 tag?
588  if(error)
589  return error;
590 
591  //Enforce encoding, class and type
592  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
594  //Invalid tag?
595  if(error)
596  return error;
597 
598  //Point to the next field
599  data += tag.totalLength;
600  length -= tag.totalLength;
601  }
602 
603  //Read the private value x
604  error = asn1ReadTag(data, length, &tag);
605  //Failed to decode ASN.1 tag?
606  if(error)
607  return error;
608 
609  //Enforce encoding, class and type
611  //Invalid tag?
612  if(error)
613  return error;
614 
615  //Save the private value x
616  dsaPrivateKey->x = tag.value;
617  dsaPrivateKey->xLen = tag.length;
618 
619  //Successful processing
620  return NO_ERROR;
621 }
622 
623 
624 /**
625  * @brief Parse ECPrivateKey structure
626  * @param[in] data Pointer to the ASN.1 structure to parse
627  * @param[in] length Length of the ASN.1 structure
628  * @param[out] ecParams EC domain parameters
629  * @param[out] ecPrivateKey EC private key
630  * @return Error code
631  **/
632 
633 error_t pkcs8ParseEcPrivateKey(const uint8_t *data, size_t length,
634  X509EcParameters *ecParams, Pkcs8EcPrivateKey *ecPrivateKey)
635 {
636  error_t error;
637  Asn1Tag tag;
638 
639  //Read ECPrivateKey structure
640  error = asn1ReadSequence(data, length, &tag);
641  //Failed to decode ASN.1 tag?
642  if(error)
643  return error;
644 
645  //Point to the first field
646  data = tag.value;
647  length = tag.length;
648 
649  //Read Version field
650  error = asn1ReadInt32(data, length, &tag, &ecPrivateKey->version);
651  //Failed to decode ASN.1 tag?
652  if(error)
653  return error;
654 
655  //Point to the next field
656  data += tag.totalLength;
657  length -= tag.totalLength;
658 
659  //Read PrivateKey field
660  error = asn1ReadOctetString(data, length, &tag);
661  //Failed to decode ASN.1 tag?
662  if(error)
663  return error;
664 
665  //Save the EC private key
666  ecPrivateKey->d = tag.value;
667  ecPrivateKey->dLen = tag.length;
668 
669  //Point to the next field
670  data += tag.totalLength;
671  length -= tag.totalLength;
672 
673  //Loop through optional attributes
674  while(length > 0)
675  {
676  //Read current attribute
677  error = asn1ReadTag(data, length, &tag);
678  //Failed to decode ASN.1 tag?
679  if(error)
680  return error;
681 
682  //Explicit tagging shall be used to encode each optional attribute
684  return ERROR_INVALID_CLASS;
685 
686  //Parameters attribute?
687  if(tag.objType == 0)
688  {
689  //Parse ECParameters structure
690  error = x509ParseEcParameters(tag.value, tag.length, ecParams);
691  //Any error to report?
692  if(error)
693  return error;
694  }
695 
696  //Next attribute
697  data += tag.totalLength;
698  length -= tag.totalLength;
699  }
700 
701  //Successful processing
702  return NO_ERROR;
703 }
704 
705 
706 /**
707  * @brief Parse CurvePrivateKey structure
708  * @param[in] data Pointer to the ASN.1 structure to parse
709  * @param[in] length Length of the ASN.1 structure
710  * @param[out] eddsaPrivateKey Information resulting from the parsing process
711  * @return Error code
712  **/
713 
715  Pkcs8EddsaPrivateKey *eddsaPrivateKey)
716 {
717  error_t error;
718  Asn1Tag tag;
719 
720  //The CurvePrivateKey structure is encapsulated within an octet string
721  error = asn1ReadOctetString(data, length, &tag);
722  //Failed to decode ASN.1 tag?
723  if(error)
724  return error;
725 
726  //Save the EdDSA private key
727  eddsaPrivateKey->d = tag.value;
728  eddsaPrivateKey->dLen = tag.length;
729 
730  //Successful processing
731  return NO_ERROR;
732 }
733 
734 
735 /**
736  * @brief Import an RSA private key
737  * @param[in] privateKeyInfo Private key information
738  * @param[out] privateKey RSA private key
739  * @return Error code
740  **/
741 
743  RsaPrivateKey *privateKey)
744 {
745  error_t error;
746 
747 #if (RSA_SUPPORT == ENABLED)
748  const uint8_t *oid;
749  size_t oidLen;
750 
751  //Get the private key algorithm identifier
752  oid = privateKeyInfo->oid;
753  oidLen = privateKeyInfo->oidLen;
754 
755  //RSA or RSA-PSS algorithm identifier?
756  if(!oidComp(oid, oidLen, RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID)) ||
757  !oidComp(oid, oidLen, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
758  {
759  //Sanity check
760  if(privateKeyInfo->rsaPrivateKey.n != NULL &&
761  privateKeyInfo->rsaPrivateKey.e != NULL &&
762  privateKeyInfo->rsaPrivateKey.d != NULL &&
763  privateKeyInfo->rsaPrivateKey.p != NULL &&
764  privateKeyInfo->rsaPrivateKey.q != NULL &&
765  privateKeyInfo->rsaPrivateKey.dp != NULL &&
766  privateKeyInfo->rsaPrivateKey.dq != NULL &&
767  privateKeyInfo->rsaPrivateKey.qinv != NULL)
768  {
769  //Read modulus
770  error = mpiImport(&privateKey->n, privateKeyInfo->rsaPrivateKey.n,
771  privateKeyInfo->rsaPrivateKey.nLen, MPI_FORMAT_BIG_ENDIAN);
772 
773  //Check status code
774  if(!error)
775  {
776  //Read public exponent
777  error = mpiImport(&privateKey->e, privateKeyInfo->rsaPrivateKey.e,
778  privateKeyInfo->rsaPrivateKey.eLen, MPI_FORMAT_BIG_ENDIAN);
779  }
780 
781  //Check status code
782  if(!error)
783  {
784  //Read private exponent
785  error = mpiImport(&privateKey->d, privateKeyInfo->rsaPrivateKey.d,
786  privateKeyInfo->rsaPrivateKey.dLen, MPI_FORMAT_BIG_ENDIAN);
787  }
788 
789  //Check status code
790  if(!error)
791  {
792  //Read first factor
793  error = mpiImport(&privateKey->p, privateKeyInfo->rsaPrivateKey.p,
794  privateKeyInfo->rsaPrivateKey.pLen, MPI_FORMAT_BIG_ENDIAN);
795  }
796 
797  //Check status code
798  if(!error)
799  {
800  //Read second factor
801  error = mpiImport(&privateKey->q, privateKeyInfo->rsaPrivateKey.q,
802  privateKeyInfo->rsaPrivateKey.qLen, MPI_FORMAT_BIG_ENDIAN);
803  }
804 
805  //Check status code
806  if(!error)
807  {
808  //Read first exponent
809  error = mpiImport(&privateKey->dp, privateKeyInfo->rsaPrivateKey.dp,
810  privateKeyInfo->rsaPrivateKey.dpLen, MPI_FORMAT_BIG_ENDIAN);
811  }
812 
813  //Check status code
814  if(!error)
815  {
816  //Read second exponent
817  error = mpiImport(&privateKey->dq, privateKeyInfo->rsaPrivateKey.dq,
818  privateKeyInfo->rsaPrivateKey.dqLen, MPI_FORMAT_BIG_ENDIAN);
819  }
820 
821  //Check status code
822  if(!error)
823  {
824  //Read coefficient
825  error = mpiImport(&privateKey->qinv, privateKeyInfo->rsaPrivateKey.qinv,
826  privateKeyInfo->rsaPrivateKey.qinvLen, MPI_FORMAT_BIG_ENDIAN);
827  }
828 
829  //Check status code
830  if(!error)
831  {
832  //Debug message
833  TRACE_DEBUG("RSA private key:\r\n");
834  TRACE_DEBUG(" Modulus:\r\n");
835  TRACE_DEBUG_MPI(" ", &privateKey->n);
836  TRACE_DEBUG(" Public exponent:\r\n");
837  TRACE_DEBUG_MPI(" ", &privateKey->e);
838  TRACE_DEBUG(" Private exponent:\r\n");
839  TRACE_DEBUG_MPI(" ", &privateKey->d);
840  TRACE_DEBUG(" Prime 1:\r\n");
841  TRACE_DEBUG_MPI(" ", &privateKey->p);
842  TRACE_DEBUG(" Prime 2:\r\n");
843  TRACE_DEBUG_MPI(" ", &privateKey->q);
844  TRACE_DEBUG(" Prime exponent 1:\r\n");
845  TRACE_DEBUG_MPI(" ", &privateKey->dp);
846  TRACE_DEBUG(" Prime exponent 2:\r\n");
847  TRACE_DEBUG_MPI(" ", &privateKey->dq);
848  TRACE_DEBUG(" Coefficient:\r\n");
849  TRACE_DEBUG_MPI(" ", &privateKey->qinv);
850  }
851  }
852  else
853  {
854  //The private key is not valid
855  error = ERROR_INVALID_KEY;
856  }
857  }
858  else
859 #endif
860  //Invalid algorithm identifier?
861  {
862  //Report an error
863  error = ERROR_WRONG_IDENTIFIER;
864  }
865 
866  //Return status code
867  return error;
868 }
869 
870 
871 /**
872  * @brief Import an DSA private key
873  * @param[in] privateKeyInfo Private key information
874  * @param[out] privateKey DSA private key
875  * @return Error code
876  **/
877 
879  DsaPrivateKey *privateKey)
880 {
881  error_t error;
882 
883 #if (DSA_SUPPORT == ENABLED)
884  //DSA algorithm identifier?
885  if(!oidComp(privateKeyInfo->oid, privateKeyInfo->oidLen, DSA_OID,
886  sizeof(DSA_OID)))
887  {
888  //Sanity check
889  if(privateKeyInfo->dsaParams.p != NULL &&
890  privateKeyInfo->dsaParams.q != NULL &&
891  privateKeyInfo->dsaParams.g != NULL &&
892  privateKeyInfo->dsaPrivateKey.x != NULL)
893  {
894  //Read parameter p
895  error = mpiImport(&privateKey->p, privateKeyInfo->dsaParams.p,
896  privateKeyInfo->dsaParams.pLen, MPI_FORMAT_BIG_ENDIAN);
897 
898  //Check status code
899  if(!error)
900  {
901  //Read parameter q
902  error = mpiImport(&privateKey->q, privateKeyInfo->dsaParams.q,
903  privateKeyInfo->dsaParams.qLen, MPI_FORMAT_BIG_ENDIAN);
904  }
905 
906  //Check status code
907  if(!error)
908  {
909  //Read parameter g
910  error = mpiImport(&privateKey->g, privateKeyInfo->dsaParams.g,
911  privateKeyInfo->dsaParams.gLen, MPI_FORMAT_BIG_ENDIAN);
912  }
913 
914  //Check status code
915  if(!error)
916  {
917  //Read private value
918  error = mpiImport(&privateKey->x, privateKeyInfo->dsaPrivateKey.x,
919  privateKeyInfo->dsaPrivateKey.xLen, MPI_FORMAT_BIG_ENDIAN);
920  }
921 
922  //Check status code
923  if(!error)
924  {
925  //Debug message
926  TRACE_DEBUG("DSA private key:\r\n");
927  TRACE_DEBUG(" Parameter p:\r\n");
928  TRACE_DEBUG_MPI(" ", &privateKey->p);
929  TRACE_DEBUG(" Parameter q:\r\n");
930  TRACE_DEBUG_MPI(" ", &privateKey->q);
931  TRACE_DEBUG(" Parameter g:\r\n");
932  TRACE_DEBUG_MPI(" ", &privateKey->g);
933  TRACE_DEBUG(" Private value x:\r\n");
934  TRACE_DEBUG_MPI(" ", &privateKey->x);
935  }
936  }
937  else
938  {
939  //The private key is not valid
940  error = ERROR_INVALID_KEY;
941  }
942  }
943  else
944 #endif
945  //Invalid algorithm identifier?
946  {
947  //Report an error
948  error = ERROR_WRONG_IDENTIFIER;
949  }
950 
951  //Return status code
952  return error;
953 }
954 
955 
956 /**
957  * @brief Import an EC private key
958  * @param[in] privateKeyInfo Private key information
959  * @param[out] privateKey EC private key
960  * @return Error code
961  **/
962 
964  Mpi *privateKey)
965 {
966  error_t error;
967 
968 #if (EC_SUPPORT == ENABLED)
969  //EC public key algorithm identifier?
970  if(!oidComp(privateKeyInfo->oid, privateKeyInfo->oidLen, EC_PUBLIC_KEY_OID,
971  sizeof(EC_PUBLIC_KEY_OID)))
972  {
973  //Sanity check
974  if(privateKeyInfo->ecPrivateKey.d != NULL)
975  {
976  //Read the EC private key
977  error = mpiImport(privateKey, privateKeyInfo->ecPrivateKey.d,
978  privateKeyInfo->ecPrivateKey.dLen, MPI_FORMAT_BIG_ENDIAN);
979 
980  //Check status code
981  if(!error)
982  {
983  //Debug message
984  TRACE_DEBUG("EC private key:\r\n");
985  TRACE_DEBUG_MPI(" ", privateKey);
986  }
987  }
988  else
989  {
990  //The private key is not valid
991  error = ERROR_INVALID_KEY;
992  }
993  }
994  else
995 #endif
996  //Invalid algorithm identifier?
997  {
998  //Report an error
999  error = ERROR_WRONG_IDENTIFIER;
1000  }
1001 
1002  //Return status code
1003  return error;
1004 }
1005 
1006 
1007 /**
1008  * @brief Import an EdDSA private key
1009  * @param[in] privateKeyInfo Private key information
1010  * @param[out] privateKey EdDSA private key
1011  * @return Error code
1012  **/
1013 
1015  EddsaPrivateKey *privateKey)
1016 {
1017  error_t error;
1018 
1019 #if (ED25519_SUPPORT == ENABLED)
1020  //Ed25519 algorithm identifier?
1021  if(!oidComp(privateKeyInfo->oid, privateKeyInfo->oidLen, ED25519_OID,
1022  sizeof(ED25519_OID)))
1023  {
1024  //Check the length of the Ed25519 private key
1025  if(privateKeyInfo->eddsaPrivateKey.d != NULL &&
1026  privateKeyInfo->eddsaPrivateKey.dLen == ED25519_PRIVATE_KEY_LEN)
1027  {
1028  //Read the Ed25519 private key
1029  error = mpiImport(&privateKey->d, privateKeyInfo->eddsaPrivateKey.d,
1030  privateKeyInfo->eddsaPrivateKey.dLen, MPI_FORMAT_LITTLE_ENDIAN);
1031  }
1032  else
1033  {
1034  //The private key is not valid
1035  error = ERROR_INVALID_KEY;
1036  }
1037  }
1038  else
1039 #endif
1040 #if (ED448_SUPPORT == ENABLED)
1041  //Ed448 algorithm identifier?
1042  if(!oidComp(privateKeyInfo->oid, privateKeyInfo->oidLen, ED448_OID,
1043  sizeof(ED448_OID)))
1044  {
1045  //Check the length of the Ed448 private key
1046  if(privateKeyInfo->eddsaPrivateKey.d != NULL &&
1047  privateKeyInfo->eddsaPrivateKey.dLen == ED448_PRIVATE_KEY_LEN)
1048  {
1049  //Read the Ed448 private key
1050  error = mpiImport(&privateKey->d, privateKeyInfo->eddsaPrivateKey.d,
1051  privateKeyInfo->eddsaPrivateKey.dLen, MPI_FORMAT_LITTLE_ENDIAN);
1052  }
1053  else
1054  {
1055  //The private key is not valid
1056  error = ERROR_INVALID_KEY;
1057  }
1058  }
1059  else
1060 #endif
1061  //Invalid algorithm identifier?
1062  {
1063  //Report an error
1064  error = ERROR_WRONG_IDENTIFIER;
1065  }
1066 
1067  //Check status code
1068  if(!error)
1069  {
1070  //Debug message
1071  TRACE_DEBUG("EdDSA private key:\r\n");
1072  TRACE_DEBUG_MPI(" ", &privateKey->d);
1073  }
1074 
1075  //Return status code
1076  return error;
1077 }
1078 
1079 #endif
error_t pkcs8ParsePrivateKeyInfo(const uint8_t *data, size_t length, Pkcs8PrivateKeyInfo *privateKeyInfo)
Parse PrivateKeyInfo structure.
Pkcs8RsaPrivateKey rsaPrivateKey
uint8_t length
Definition: dtls_misc.h:149
Ed25519 elliptic curve (constant-time implementation)
Private key information.
const uint8_t * q
Definition: x509_common.h:650
const uint8_t * oid
Mpi p
First factor.
Definition: rsa.h:64
Arbitrary precision integer.
Definition: mpi.h:69
const uint8_t X25519_OID[3]
Definition: ec_curves.c:92
OID (Object Identifier)
const uint8_t * d
const uint8_t * q
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:47
uint16_t version
Definition: dtls_misc.h:172
Mpi n
Modulus.
Definition: rsa.h:61
RSA private key.
const uint8_t * d
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:88
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 x509ParseDsaParameters(const uint8_t *data, size_t length, X509DsaParameters *dsaParams)
Parse DSA domain parameters.
error_t mpiImport(Mpi *r, const uint8_t *data, uint_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:533
#define ED25519_PRIVATE_KEY_LEN
Definition: ed25519.h:39
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:101
Mpi d
Private exponent.
Definition: rsa.h:63
EdDSA private key.
error_t asn1ReadOid(const uint8_t *data, size_t length, Asn1Tag *tag)
Read an object identifier from the input stream.
Definition: asn1.c:218
const uint8_t DSA_OID[7]
Definition: dsa.c:51
size_t totalLength
Definition: asn1.h:104
size_t length
Definition: asn1.h:102
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.
const uint8_t * n
error_t
Error codes.
Definition: error.h:42
EC parameters.
Definition: x509_common.h:672
const uint8_t * g
Definition: x509_common.h:652
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:48
ASN.1 tag.
Definition: asn1.h:97
Mpi q
Second factor.
Definition: rsa.h:65
const uint8_t * e
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
X509DsaParameters dsaParams
General definitions for cryptographic algorithms.
uint8_t oid[1]
Definition: mib_common.h:186
Pkcs8EddsaPrivateKey eddsaPrivateKey
DSA private key.
Definition: dsa.h:73
const uint8_t * qinv
uint_t objClass
Definition: asn1.h:100
error_t pkcs8ParseRsaPrivateKey(const uint8_t *data, size_t length, Pkcs8RsaPrivateKey *rsaPrivateKey)
Parse RSAPrivateKey structure.
error_t pkcs8ImportEddsaPrivateKey(const Pkcs8PrivateKeyInfo *privateKeyInfo, EddsaPrivateKey *privateKey)
Import an EdDSA private key.
Mpi e
Public exponent.
Definition: rsa.h:62
error_t asn1CheckOid(const Asn1Tag *tag, const uint8_t *oid, size_t length)
Check ASN.1 tag against a specified OID.
Definition: asn1.c:663
Mpi p
Prime modulus.
Definition: dsa.h:75
Mpi g
Group generator.
Definition: dsa.h:77
const uint8_t ED448_OID[3]
Definition: ec_curves.c:98
Mpi qinv
CRT coefficient.
Definition: rsa.h:68
EdDSA private key.
Definition: eddsa.h:58
Mpi dq
second factor's CRT exponent
Definition: rsa.h:67
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:96
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:57
const uint8_t X448_OID[3]
Definition: ec_curves.c:94
#define ED448_PRIVATE_KEY_LEN
Definition: ed448.h:39
#define cryptoMemset(p, value, length)
Definition: crypto.h:636
#define TRACE_DEBUG(...)
Definition: debug.h:106
Mpi d
Private key.
Definition: eddsa.h:60
const uint8_t * x
const uint8_t * dp
uint8_t n
RSA private key.
Definition: rsa.h:59
const uint8_t * d
DSA domain parameters.
Definition: x509_common.h:646
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:50
PKCS #8 key parsing.
Mpi x
Secret exponent.
Definition: dsa.h:78
error_t pkcs8ImportEcPrivateKey(const Pkcs8PrivateKeyInfo *privateKeyInfo, Mpi *privateKey)
Import an EC private key.
error_t x509ParseEcParameters(const uint8_t *data, size_t length, X509EcParameters *ecParams)
Parse ECParameters structure.
error_t pkcs8ImportDsaPrivateKey(const Pkcs8PrivateKeyInfo *privateKeyInfo, DsaPrivateKey *privateKey)
Import an DSA private key.
error_t pkcs8ParseEcPrivateKey(const uint8_t *data, size_t length, X509EcParameters *ecParams, Pkcs8EcPrivateKey *ecPrivateKey)
Parse ECPrivateKey structure.
Mpi q
Group order.
Definition: dsa.h:76
const uint8_t * p
Definition: x509_common.h:648
Mpi dp
First factor's CRT exponent.
Definition: rsa.h:66
const uint8_t * dq
Parsing of ASN.1 encoded keys.
Pkcs8DsaPrivateKey dsaPrivateKey
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:109
uint8_t data[]
Definition: dtls_misc.h:176
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.
X509EcParameters ecParams
const uint8_t * p
Ed448 elliptic curve (constant-time implementation)
const uint8_t * value
Definition: asn1.h:103
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:637
Success.
Definition: error.h:44
error_t pkcs8ImportRsaPrivateKey(const Pkcs8PrivateKeyInfo *privateKeyInfo, RsaPrivateKey *privateKey)
Import an RSA private key.
error_t pkcs8ParseDsaPrivateKey(const uint8_t *data, size_t length, X509DsaParameters *dsaParams, Pkcs8DsaPrivateKey *dsaPrivateKey)
Parse DSAPrivateKey structure.
Debugging facilities.
uint_t objType
Definition: asn1.h:101
ASN.1 (Abstract Syntax Notation One)