x509_key_parse.c
Go to the documentation of this file.
1 /**
2  * @file x509_key_parse.c
3  * @brief Parsing of ASN.1 encoded keys
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/x509_key_parse.h"
37 #include "encoding/asn1.h"
38 #include "encoding/oid.h"
39 #include "hash/sha1.h"
40 #include "ecc/ed25519.h"
41 #include "ecc/ed448.h"
42 #include "debug.h"
43 
44 //Check crypto library configuration
45 #if (X509_SUPPORT == ENABLED || PEM_SUPPORT == ENABLED)
46 
47 
48 /**
49  * @brief Parse SubjectPublicKeyInfo 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] totalLength Number of bytes that have been parsed
53  * @param[out] publicKeyInfo Information resulting from the parsing process
54  * @return Error code
55  **/
56 
58  size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
59 {
60  error_t error;
61  size_t n;
62  size_t oidLen;
63  const uint8_t *oid;
64  Asn1Tag tag;
65 
66  //Debug message
67  TRACE_DEBUG(" Parsing SubjectPublicKeyInfo...\r\n");
68 
69  //Clear the SubjectPublicKeyInfo structure
70  cryptoMemset(publicKeyInfo, 0, sizeof(X509SubjectPublicKeyInfo));
71 
72  //The public key information is encapsulated within a sequence
73  error = asn1ReadSequence(data, length, &tag);
74  //Failed to decode ASN.1 tag?
75  if(error)
76  return error;
77 
78  //Save the total length of the field
79  *totalLength = tag.totalLength;
80 
81  //Raw contents of the ASN.1 sequence
82  publicKeyInfo->rawData = data;
83  publicKeyInfo->rawDataLen = tag.totalLength;
84 
85  //Point to the first field of the sequence
86  data = tag.value;
87  length = tag.length;
88 
89  //Read AlgorithmIdentifier field
90  error = x509ParseAlgorithmIdentifier(data, length, &n, publicKeyInfo);
91  //Any error to report?
92  if(error)
93  return error;
94 
95  //Point to the next field
96  data += n;
97  length -= n;
98 
99  //The SubjectPublicKey is encapsulated within a bit string
100  error = asn1ReadTag(data, length, &tag);
101  //Failed to decode ASN.1 tag?
102  if(error)
103  return error;
104 
105  //Enforce encoding, class and type
106  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
108  //Invalid tag?
109  if(error)
110  return error;
111 
112  //The bit string shall contain an initial octet which encodes the number
113  //of unused bits in the final subsequent octet
114  if(tag.length < 1 || tag.value[0] != 0x00)
115  return ERROR_FAILURE;
116 
117  //Point to the public key
118  data = tag.value + 1;
119  length = tag.length - 1;
120 
121  //Get the public key algorithm identifier
122  oid = publicKeyInfo->oid;
123  oidLen = publicKeyInfo->oidLen;
124 
125 #if (RSA_SUPPORT == ENABLED)
126  //RSA or RSA-PSS algorithm identifier?
127  if(!oidComp(oid, oidLen, RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID)) ||
128  !oidComp(oid, oidLen, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
129  {
130  //Read RSAPublicKey structure
131  error = x509ParseRsaPublicKey(data, length, &publicKeyInfo->rsaPublicKey);
132  }
133  else
134 #endif
135 #if (DSA_SUPPORT == ENABLED)
136  //DSA algorithm identifier?
137  if(!oidComp(oid, oidLen, DSA_OID, sizeof(DSA_OID)))
138  {
139  //Read DSAPublicKey structure
140  error = x509ParseDsaPublicKey(data, length, &publicKeyInfo->dsaPublicKey);
141  }
142  else
143 #endif
144 #if (ECDSA_SUPPORT == ENABLED)
145  //EC public key identifier?
146  if(!oidComp(oid, oidLen, EC_PUBLIC_KEY_OID, sizeof(EC_PUBLIC_KEY_OID)))
147  {
148  //Read ECPublicKey structure
149  error = x509ParseEcPublicKey(data, length, &publicKeyInfo->ecPublicKey);
150  }
151  else
152 #endif
153 #if (ED25519_SUPPORT == ENABLED)
154  //X25519 or Ed25519 algorithm identifier?
155  if(!oidComp(oid, oidLen, X25519_OID, sizeof(X25519_OID)) ||
156  !oidComp(oid, oidLen, ED25519_OID, sizeof(ED25519_OID)))
157  {
158  //Read ECPublicKey structure
159  error = x509ParseEcPublicKey(data, length, &publicKeyInfo->ecPublicKey);
160  }
161  else
162 #endif
163 #if (ED448_SUPPORT == ENABLED)
164  //X448 or Ed448 algorithm identifier?
165  if(!oidComp(oid, oidLen, X448_OID, sizeof(X448_OID)) ||
166  !oidComp(oid, oidLen, ED448_OID, sizeof(ED448_OID)))
167  {
168  //Read ECPublicKey structure
169  error = x509ParseEcPublicKey(data, length, &publicKeyInfo->ecPublicKey);
170  }
171  else
172 #endif
173  //Unknown algorithm identifier?
174  {
175  //Report an error
176  error = ERROR_WRONG_IDENTIFIER;
177  }
178 
179  //Return status code
180  return error;
181 }
182 
183 
184 /**
185  * @brief Parse AlgorithmIdentifier structure
186  * @param[in] data Pointer to the ASN.1 structure to parse
187  * @param[in] length Length of the ASN.1 structure
188  * @param[out] totalLength Number of bytes that have been parsed
189  * @param[out] publicKeyInfo Information resulting from the parsing process
190  * @return Error code
191  **/
192 
194  size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
195 {
196  error_t error;
197  Asn1Tag tag;
198 
199  //Debug message
200  TRACE_DEBUG(" Parsing AlgorithmIdentifier...\r\n");
201 
202  //Read AlgorithmIdentifier field
203  error = asn1ReadSequence(data, length, &tag);
204  //Failed to decode ASN.1 tag?
205  if(error)
206  return error;
207 
208  //Save the total length of the field
209  *totalLength = tag.totalLength;
210 
211  //Point to the first field
212  data = tag.value;
213  length = tag.length;
214 
215  //Read algorithm identifier (OID)
216  error = asn1ReadOid(data, length, &tag);
217  //Failed to decode ASN.1 tag?
218  if(error)
219  return error;
220 
221  //Save the algorithm identifier
222  publicKeyInfo->oid = tag.value;
223  publicKeyInfo->oidLen = tag.length;
224 
225  //Point to the next field (if any)
226  data += tag.totalLength;
227  length -= tag.totalLength;
228 
229 #if (RSA_SUPPORT == ENABLED)
230  //RSA algorithm identifier?
232  {
233  //The parameters field must have ASN.1 type NULL for this algorithm
234  //identifier (refer to RFC 3279, section 2.3.1)
235  error = NO_ERROR;
236  }
237  //RSA-PSS algorithm identifier?
238  else if(!asn1CheckOid(&tag, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
239  {
240  //The parameters may be either absent or present when used as subject
241  //public key information (refer to RFC 4055, section 3.1)
242  error = NO_ERROR;
243  }
244  else
245 #endif
246 #if (DSA_SUPPORT == ENABLED)
247  //DSA algorithm identifier?
248  if(!asn1CheckOid(&tag, DSA_OID, sizeof(DSA_OID)))
249  {
250  //Read DsaParameters structure
252  &publicKeyInfo->dsaParams);
253  }
254  else
255 #endif
256 #if (ECDSA_SUPPORT == ENABLED)
257  //EC public key identifier?
259  {
260  //Read ECParameters structure
262  &publicKeyInfo->ecParams);
263  }
264  else
265 #endif
266 #if (ED25519_SUPPORT == ENABLED)
267  //X25519 or Ed25519 algorithm identifier?
268  if(!asn1CheckOid(&tag, X25519_OID, sizeof(X25519_OID)) ||
269  !asn1CheckOid(&tag, ED25519_OID, sizeof(ED25519_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 #if (ED448_SUPPORT == ENABLED)
278  //X448 or Ed448 algorithm identifier?
279  if(!asn1CheckOid(&tag, X448_OID, sizeof(X448_OID)) ||
280  !asn1CheckOid(&tag, ED448_OID, sizeof(ED448_OID)))
281  {
282  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
283  //section 3)
284  error = NO_ERROR;
285  }
286  else
287 #endif
288  //Unknown algorithm identifier?
289  {
290  //Report an error
291  error = ERROR_WRONG_IDENTIFIER;
292  }
293 
294  //Return status code
295  return error;
296 }
297 
298 
299 /**
300  * @brief Parse RSAPublicKey structure
301  * @param[in] data Pointer to the ASN.1 structure to parse
302  * @param[in] length Length of the ASN.1 structure
303  * @param[out] rsaPublicKey Information resulting from the parsing process
304  * @return Error code
305  **/
306 
307 error_t x509ParseRsaPublicKey(const uint8_t *data, size_t length,
308  X509RsaPublicKey *rsaPublicKey)
309 {
310  error_t error;
311  Asn1Tag tag;
312 
313  //Debug message
314  TRACE_DEBUG(" Parsing RSAPublicKey...\r\n");
315 
316  //Read RSAPublicKey structure
317  error = asn1ReadSequence(data, length, &tag);
318  //Failed to decode ASN.1 tag?
319  if(error)
320  return error;
321 
322  //Point to the first field
323  data = tag.value;
324  length = tag.length;
325 
326  //Read Modulus field
327  error = asn1ReadTag(data, length, &tag);
328  //Failed to decode ASN.1 tag?
329  if(error)
330  return error;
331 
332  //Enforce encoding, class and type
334  //Invalid tag?
335  if(error)
336  return error;
337 
338  //Save the modulus
339  rsaPublicKey->n = tag.value;
340  rsaPublicKey->nLen = tag.length;
341 
342  //Point to the next field
343  data += tag.totalLength;
344  length -= tag.totalLength;
345 
346  //Read PublicExponent field
347  error = asn1ReadTag(data, length, &tag);
348  //Failed to decode ASN.1 tag?
349  if(error)
350  return error;
351 
352  //Enforce encoding, class and type
354  //Invalid tag?
355  if(error)
356  return error;
357 
358  //Save the public exponent
359  rsaPublicKey->e = tag.value;
360  rsaPublicKey->eLen = tag.length;
361 
362  //Successful processing
363  return NO_ERROR;
364 }
365 
366 
367 /**
368  * @brief Parse RSASSA-PSS parameters
369  * @param[in] data Pointer to the ASN.1 structure to parse
370  * @param[in] length Length of the ASN.1 structure
371  * @param[out] rsaPssParams Information resulting from the parsing process
372  * @return Error code
373  **/
374 
376  X509RsaPssParameters *rsaPssParams)
377 {
378  error_t error;
379  Asn1Tag tag;
380 
381  //Clear RSASSA-PSS parameters
382  cryptoMemset(rsaPssParams, 0, sizeof(X509RsaPssParameters));
383 
384 #if (SHA1_SUPPORT == ENABLED)
385  //The default hash algorithm is SHA-1 (refer to RFC 4055, section 3.1)
386  rsaPssParams->hashAlgo = SHA1_OID;
387  rsaPssParams->hashAlgoLen = sizeof(SHA1_OID);
388 #endif
389 
390 #if (RSA_SUPPORT == ENABLED)
391  //The default mask generation function is MGF1 with SHA-1
392  rsaPssParams->maskGenAlgo = MGF1_OID;
393  rsaPssParams->maskGenAlgoLen = sizeof(MGF1_OID);
394 #endif
395 
396 #if (SHA1_SUPPORT == ENABLED)
397  //MGF1 requires a one-way hash function that is identified in the
398  //parameters field of the MGF1 algorithm identifier
399  rsaPssParams->maskGenHashAlgo = SHA1_OID;
400  rsaPssParams->maskGenHashAlgoLen = sizeof(SHA1_OID);
401 #endif
402 
403  //The default length of the salt is 20
404  rsaPssParams->saltLen = 20;
405 
406  //Read the contents of the structure
407  error = asn1ReadSequence(data, length, &tag);
408  //Failed to decode ASN.1 tag?
409  if(error)
410  return error;
411 
412  //Point to the first field of the sequence
413  data = tag.value;
414  length = tag.length;
415 
416  //Parse RSASSA-PSS parameters
417  while(length > 0)
418  {
419  //Read current parameter
420  error = asn1ReadTag(data, length, &tag);
421  //Failed to decode ASN.1 tag?
422  if(error)
423  return error;
424 
425  //The tags in this sequence are explicit
427  {
428  //Parse hashAlgorithm parameter
429  error = x509ParseRsaPssHashAlgo(tag.value, tag.length,
430  rsaPssParams);
431  }
432  else if(!asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 1))
433  {
434  //Parse maskGenAlgorithm parameter
435  error = x509ParseRsaPssMaskGenAlgo(tag.value, tag.length,
436  rsaPssParams);
437  }
438  else if(!asn1CheckTag(&tag, TRUE, ASN1_CLASS_CONTEXT_SPECIFIC, 2))
439  {
440  //Parse saltLength parameter
441  error = x509ParseRsaPssSaltLength(tag.value, tag.length,
442  rsaPssParams);
443  }
444  else
445  {
446  //Discard current parameter
447  error = NO_ERROR;
448  }
449 
450  //Any parsing error?
451  if(error)
452  return error;
453 
454  //Next parameter
455  data += tag.totalLength;
456  length -= tag.totalLength;
457  }
458 
459  //Successful processing
460  return NO_ERROR;
461 }
462 
463 
464 /**
465  * @brief Parse RSASSA-PSS hash algorithm
466  * @param[in] data Pointer to the ASN.1 structure to parse
467  * @param[in] length Length of the ASN.1 structure
468  * @param[out] rsaPssParams Information resulting from the parsing process
469  * @return Error code
470  **/
471 
473  X509RsaPssParameters *rsaPssParams)
474 {
475  error_t error;
476  Asn1Tag tag;
477 
478  //Read the contents of the structure
479  error = asn1ReadSequence(data, length, &tag);
480  //Failed to decode ASN.1 tag?
481  if(error)
482  return error;
483 
484  //Point to the first field of the sequence
485  data = tag.value;
486  length = tag.length;
487 
488  //Read hash algorithm identifier
489  error = asn1ReadOid(data, length, &tag);
490  //Failed to decode ASN.1 tag?
491  if(error)
492  return error;
493 
494  //Save the hash algorithm identifier
495  rsaPssParams->hashAlgo = tag.value;
496  rsaPssParams->hashAlgoLen = tag.length;
497 
498  //No error to report
499  return NO_ERROR;
500 }
501 
502 
503 /**
504  * @brief Parse RSASSA-PSS mask generation algorithm
505  * @param[in] data Pointer to the ASN.1 structure to parse
506  * @param[in] length Length of the ASN.1 structure
507  * @param[out] rsaPssParams Information resulting from the parsing process
508  * @return Error code
509  **/
510 
512  X509RsaPssParameters *rsaPssParams)
513 {
514  error_t error;
515  Asn1Tag tag;
516 
517  //Read the contents of the structure
518  error = asn1ReadSequence(data, length, &tag);
519  //Failed to decode ASN.1 tag?
520  if(error)
521  return error;
522 
523  //Point to the first field of the sequence
524  data = tag.value;
525  length = tag.length;
526 
527  //Read mask generation algorithm identifier
528  error = asn1ReadOid(data, length, &tag);
529  //Failed to decode ASN.1 tag?
530  if(error)
531  return error;
532 
533  //Save the mask generation algorithm identifier
534  rsaPssParams->maskGenAlgo = tag.value;
535  rsaPssParams->maskGenAlgoLen = tag.length;
536 
537  //Point to the next field
538  data += tag.totalLength;
539  length -= tag.totalLength;
540 
541  //Read the algorithm identifier of the one-way hash function employed
542  //with the mask generation function
543  error = x509ParseRsaPssMaskGenHashAlgo(data, length, rsaPssParams);
544  //Any error to report?
545  if(error)
546  return error;
547 
548  //No error to report
549  return NO_ERROR;
550 }
551 
552 
553 /**
554  * @brief Parse RSASSA-PSS mask generation hash algorithm
555  * @param[in] data Pointer to the ASN.1 structure to parse
556  * @param[in] length Length of the ASN.1 structure
557  * @param[out] rsaPssParams Information resulting from the parsing process
558  * @return Error code
559  **/
560 
562  X509RsaPssParameters *rsaPssParams)
563 {
564  error_t error;
565  Asn1Tag tag;
566 
567  //Read the contents of the structure
568  error = asn1ReadSequence(data, length, &tag);
569  //Failed to decode ASN.1 tag?
570  if(error)
571  return error;
572 
573  //Point to the first field of the sequence
574  data = tag.value;
575  length = tag.length;
576 
577  //Read the algorithm identifier of the one-way hash function employed
578  //with the mask generation function
579  error = asn1ReadOid(data, length, &tag);
580  //Failed to decode ASN.1 tag?
581  if(error)
582  return error;
583 
584  //Save the hash algorithm identifier
585  rsaPssParams->maskGenHashAlgo = tag.value;
586  rsaPssParams->maskGenHashAlgoLen = tag.length;
587 
588  //No error to report
589  return NO_ERROR;
590 }
591 
592 
593 /**
594  * @brief Parse RSASSA-PSS salt length
595  * @param[in] data Pointer to the ASN.1 structure to parse
596  * @param[in] length Length of the ASN.1 structure
597  * @param[out] rsaPssParams Information resulting from the parsing process
598  * @return Error code
599  **/
600 
602  X509RsaPssParameters *rsaPssParams)
603 {
604  error_t error;
605  int32_t saltLen;
606  Asn1Tag tag;
607 
608  //Read the saltLength field
609  error = asn1ReadInt32(data, length, &tag, &saltLen);
610  //Failed to decode ASN.1 tag?
611  if(error)
612  return error;
613 
614  //Sanity check
615  if(saltLen < 0)
616  return ERROR_INVALID_SYNTAX;
617 
618  //Save the length of the salt
619  rsaPssParams->saltLen = (size_t) saltLen;
620 
621  //No error to report
622  return NO_ERROR;
623 }
624 
625 
626 /**
627  * @brief Parse DSAPublicKey structure
628  * @param[in] data Pointer to the ASN.1 structure to parse
629  * @param[in] length Length of the ASN.1 structure
630  * @param[out] dsaPublicKey Information resulting from the parsing process
631  * @return Error code
632  **/
633 
634 error_t x509ParseDsaPublicKey(const uint8_t *data, size_t length,
635  X509DsaPublicKey *dsaPublicKey)
636 {
637  error_t error;
638  Asn1Tag tag;
639 
640  //Debug message
641  TRACE_DEBUG(" Parsing DSAPublicKey...\r\n");
642 
643  //Read DSAPublicKey structure
644  error = asn1ReadTag(data, length, &tag);
645  //Failed to decode ASN.1 tag?
646  if(error)
647  return error;
648 
649  //Enforce encoding, class and type
651  //Invalid tag?
652  if(error)
653  return error;
654 
655  //Save the DSA public value
656  dsaPublicKey->y = tag.value;
657  dsaPublicKey->yLen = tag.length;
658 
659  //Successful processing
660  return NO_ERROR;
661 }
662 
663 
664 /**
665  * @brief Parse DSA domain parameters
666  * @param[in] data Pointer to the ASN.1 structure to parse
667  * @param[in] length Length of the ASN.1 structure
668  * @param[out] dsaParams Information resulting from the parsing process
669  * @return Error code
670  **/
671 
672 error_t x509ParseDsaParameters(const uint8_t *data, size_t length,
673  X509DsaParameters *dsaParams)
674 {
675  error_t error;
676  Asn1Tag tag;
677 
678  //Debug message
679  TRACE_DEBUG(" Parsing DSAParameters...\r\n");
680 
681  //Read DSAParameters structure
682  error = asn1ReadSequence(data, length, &tag);
683  //Failed to decode ASN.1 tag?
684  if(error)
685  return error;
686 
687  //Point to the first field
688  data = tag.value;
689  length = tag.length;
690 
691  //Read the parameter p
692  error = asn1ReadTag(data, length, &tag);
693  //Failed to decode ASN.1 tag?
694  if(error)
695  return error;
696 
697  //Enforce encoding, class and type
699  //Invalid tag?
700  if(error)
701  return error;
702 
703  //Save the parameter p
704  dsaParams->p = tag.value;
705  dsaParams->pLen = tag.length;
706 
707  //Point to the next field
708  data += tag.totalLength;
709  length -= tag.totalLength;
710 
711  //Read the parameter q
712  error = asn1ReadTag(data, length, &tag);
713  //Failed to decode ASN.1 tag?
714  if(error)
715  return error;
716 
717  //Enforce encoding, class and type
719  //Invalid tag?
720  if(error)
721  return error;
722 
723  //Save the parameter q
724  dsaParams->q = tag.value;
725  dsaParams->qLen = tag.length;
726 
727  //Point to the next field
728  data += tag.totalLength;
729  length -= tag.totalLength;
730 
731  //Read the parameter g
732  error = asn1ReadTag(data, length, &tag);
733  //Failed to decode ASN.1 tag?
734  if(error)
735  return error;
736 
737  //Enforce encoding, class and type
739  //Invalid tag?
740  if(error)
741  return error;
742 
743  //Save the parameter g
744  dsaParams->g = tag.value;
745  dsaParams->gLen = tag.length;
746 
747  //Successful processing
748  return NO_ERROR;
749 }
750 
751 
752 /**
753  * @brief Parse ECPublicKey structure
754  * @param[in] data Pointer to the ASN.1 structure to parse
755  * @param[in] length Length of the ASN.1 structure
756  * @param[out] ecPublicKey Information resulting from the parsing process
757  * @return Error code
758  **/
759 
760 error_t x509ParseEcPublicKey(const uint8_t *data, size_t length,
761  X509EcPublicKey *ecPublicKey)
762 {
763  //Debug message
764  TRACE_DEBUG(" Parsing ECPublicKey...\r\n");
765 
766  //Make sure the EC public key is valid
767  if(length == 0)
768  return ERROR_BAD_CERTIFICATE;
769 
770  //Save the EC public key
771  ecPublicKey->q = data;
772  ecPublicKey->qLen = length;
773 
774  //Successful processing
775  return NO_ERROR;
776 }
777 
778 
779 /**
780  * @brief Parse ECParameters structure
781  * @param[in] data Pointer to the ASN.1 structure to parse
782  * @param[in] length Length of the ASN.1 structure
783  * @param[out] ecParams Information resulting from the parsing process
784  * @return Error code
785  **/
786 
787 error_t x509ParseEcParameters(const uint8_t *data, size_t length,
788  X509EcParameters *ecParams)
789 {
790  error_t error;
791  Asn1Tag tag;
792 
793  //Debug message
794  TRACE_DEBUG(" Parsing ECParameters...\r\n");
795 
796  //Read namedCurve field
797  error = asn1ReadOid(data, length, &tag);
798  //Failed to decode ASN.1 tag?
799  if(error)
800  return error;
801 
802  //The namedCurve field identifies all the required values for a particular
803  //set of elliptic curve domain parameters to be represented by an object
804  //identifier
805  ecParams->namedCurve = tag.value;
806  ecParams->namedCurveLen = tag.length;
807 
808  //Successful processing
809  return NO_ERROR;
810 }
811 
812 
813 /**
814  * @brief Import an RSA public key
815  * @param[in] publicKeyInfo Public key information
816  * @param[out] publicKey RSA public key
817  * @return Error code
818  **/
819 
821  RsaPublicKey *publicKey)
822 {
823  error_t error;
824 
825 #if (RSA_SUPPORT == ENABLED)
826  const uint8_t *oid;
827  size_t oidLen;
828 
829  //Get the public key algorithm identifier
830  oid = publicKeyInfo->oid;
831  oidLen = publicKeyInfo->oidLen;
832 
833  //RSA algorithm identifier?
834  if(!oidComp(oid, oidLen, RSA_ENCRYPTION_OID, sizeof(RSA_ENCRYPTION_OID)) ||
835  !oidComp(oid, oidLen, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
836  {
837  //Sanity check
838  if(publicKeyInfo->rsaPublicKey.n != NULL &&
839  publicKeyInfo->rsaPublicKey.e != NULL)
840  {
841  //Read modulus
842  error = mpiImport(&publicKey->n, publicKeyInfo->rsaPublicKey.n,
843  publicKeyInfo->rsaPublicKey.nLen, MPI_FORMAT_BIG_ENDIAN);
844 
845  //Check status code
846  if(!error)
847  {
848  //Read public exponent
849  error = mpiImport(&publicKey->e, publicKeyInfo->rsaPublicKey.e,
850  publicKeyInfo->rsaPublicKey.eLen, MPI_FORMAT_BIG_ENDIAN);
851  }
852 
853  //Check status code
854  if(!error)
855  {
856  //Debug message
857  TRACE_DEBUG("RSA public key:\r\n");
858  TRACE_DEBUG(" Modulus:\r\n");
859  TRACE_DEBUG_MPI(" ", &publicKey->n);
860  TRACE_DEBUG(" Public exponent:\r\n");
861  TRACE_DEBUG_MPI(" ", &publicKey->e);
862  }
863  }
864  else
865  {
866  //The public key is not valid
867  error = ERROR_INVALID_KEY;
868  }
869  }
870  else
871 #endif
872  //Invalid algorithm identifier?
873  {
874  //Report an error
875  error = ERROR_WRONG_IDENTIFIER;
876  }
877 
878  //Return status code
879  return error;
880 }
881 
882 
883 /**
884  * @brief Import a DSA public key
885  * @param[in] publicKeyInfo Public key information
886  * @param[out] publicKey DSA public key
887  * @return Error code
888  **/
889 
891  DsaPublicKey *publicKey)
892 {
893  error_t error;
894 
895 #if (DSA_SUPPORT == ENABLED)
896  //DSA algorithm identifier?
897  if(!oidComp(publicKeyInfo->oid, publicKeyInfo->oidLen, DSA_OID,
898  sizeof(DSA_OID)))
899  {
900  //Sanity check
901  if(publicKeyInfo->dsaParams.p != NULL &&
902  publicKeyInfo->dsaParams.q != NULL &&
903  publicKeyInfo->dsaParams.g != NULL &&
904  publicKeyInfo->dsaPublicKey.y != NULL)
905  {
906  //Read parameter p
907  error = mpiImport(&publicKey->p, publicKeyInfo->dsaParams.p,
908  publicKeyInfo->dsaParams.pLen, MPI_FORMAT_BIG_ENDIAN);
909 
910  //Check status code
911  if(!error)
912  {
913  //Read parameter q
914  error = mpiImport(&publicKey->q, publicKeyInfo->dsaParams.q,
915  publicKeyInfo->dsaParams.qLen, MPI_FORMAT_BIG_ENDIAN);
916  }
917 
918  //Check status code
919  if(!error)
920  {
921  //Read parameter g
922  error = mpiImport(&publicKey->g, publicKeyInfo->dsaParams.g,
923  publicKeyInfo->dsaParams.gLen, MPI_FORMAT_BIG_ENDIAN);
924  }
925 
926  //Check status code
927  if(!error)
928  {
929  //Read public value
930  error = mpiImport(&publicKey->y, publicKeyInfo->dsaPublicKey.y,
931  publicKeyInfo->dsaPublicKey.yLen, MPI_FORMAT_BIG_ENDIAN);
932  }
933 
934  //Check status code
935  if(!error)
936  {
937  //Debug message
938  TRACE_DEBUG("DSA public key:\r\n");
939  TRACE_DEBUG(" Parameter p:\r\n");
940  TRACE_DEBUG_MPI(" ", &publicKey->p);
941  TRACE_DEBUG(" Parameter q:\r\n");
942  TRACE_DEBUG_MPI(" ", &publicKey->q);
943  TRACE_DEBUG(" Parameter g:\r\n");
944  TRACE_DEBUG_MPI(" ", &publicKey->g);
945  TRACE_DEBUG(" Public value y:\r\n");
946  TRACE_DEBUG_MPI(" ", &publicKey->y);
947  }
948  }
949  else
950  {
951  //The public key is not valid
952  error = ERROR_INVALID_KEY;
953  }
954  }
955  else
956 #endif
957  //Invalid algorithm identifier?
958  {
959  //Report an error
960  error = ERROR_WRONG_IDENTIFIER;
961  }
962 
963  //Return status code
964  return error;
965 }
966 
967 
968 /**
969  * @brief Import an EC public key
970  * @param[in] publicKeyInfo Public key information
971  * @param[out] publicKey EC public key
972  * @return Error code
973  **/
974 
976  EcPoint *publicKey)
977 {
978  error_t error;
979 
980 #if (EC_SUPPORT == ENABLED)
981  const EcCurveInfo *curveInfo;
982  EcDomainParameters params;
983 
984  //EC public key identifier?
985  if(!oidComp(publicKeyInfo->oid, publicKeyInfo->oidLen, EC_PUBLIC_KEY_OID,
986  sizeof(EC_PUBLIC_KEY_OID)))
987  {
988  //Sanity check
989  if(publicKeyInfo->ecParams.namedCurve != NULL &&
990  publicKeyInfo->ecPublicKey.q != NULL)
991  {
992  //Initialize EC domain parameters
993  ecInitDomainParameters(&params);
994 
995  //Retrieve EC domain parameters
996  curveInfo = x509GetCurveInfo(publicKeyInfo->ecParams.namedCurve,
997  publicKeyInfo->ecParams.namedCurveLen);
998 
999  //Make sure the specified elliptic curve is supported
1000  if(curveInfo != NULL)
1001  {
1002  //Load EC domain parameters
1003  error = ecLoadDomainParameters(&params, curveInfo);
1004  }
1005  else
1006  {
1007  //Invalid EC domain parameters
1008  error = ERROR_WRONG_IDENTIFIER;
1009  }
1010 
1011  //Check status code
1012  if(!error)
1013  {
1014  //Read the EC public key
1015  error = ecImport(&params, publicKey, publicKeyInfo->ecPublicKey.q,
1016  publicKeyInfo->ecPublicKey.qLen);
1017  }
1018 
1019  //Check status code
1020  if(!error)
1021  {
1022  //Debug message
1023  TRACE_DEBUG(" Public key X:\r\n");
1024  TRACE_DEBUG_MPI(" ", &publicKey->x);
1025  TRACE_DEBUG(" Public key Y:\r\n");
1026  TRACE_DEBUG_MPI(" ", &publicKey->y);
1027  }
1028 
1029  //Release EC domain parameters
1030  ecFreeDomainParameters(&params);
1031  }
1032  else
1033  {
1034  //The public key is not valid
1035  error = ERROR_INVALID_KEY;
1036  }
1037  }
1038  else
1039 #endif
1040  //Invalid algorithm identifier?
1041  {
1042  //Report an error
1043  error = ERROR_WRONG_IDENTIFIER;
1044  }
1045 
1046  //Return status code
1047  return error;
1048 }
1049 
1050 
1051 /**
1052  * @brief Import EC domain parameters
1053  * @param[in] ecParams Pointer to the ECParameters structure
1054  * @param[out] params EC domain parameters
1055  * @return Error code
1056  **/
1057 
1059  EcDomainParameters *params)
1060 {
1061  error_t error;
1062 
1063 #if (EC_SUPPORT == ENABLED)
1064  const EcCurveInfo *curveInfo;
1065 
1066  //Retrieve EC domain parameters
1067  curveInfo = ecGetCurveInfo(ecParams->namedCurve, ecParams->namedCurveLen);
1068 
1069  //Make sure the specified elliptic curve is supported
1070  if(curveInfo != NULL)
1071  {
1072  //Load EC domain parameters
1073  error = ecLoadDomainParameters(params, curveInfo);
1074  }
1075  else
1076 #endif
1077  {
1078  //Invalid EC domain parameters
1079  error = ERROR_WRONG_IDENTIFIER;
1080  }
1081 
1082  //Return status code
1083  return error;
1084 }
1085 
1086 
1087 /**
1088  * @brief Import an EdDSA public key
1089  * @param[in] publicKeyInfo Public key information
1090  * @param[out] publicKey EdDSA public key
1091  * @return Error code
1092  **/
1093 
1095  EddsaPublicKey *publicKey)
1096 {
1097  error_t error;
1098 
1099 #if (ED25519_SUPPORT == ENABLED)
1100  //Ed25519 algorithm identifier?
1101  if(!oidComp(publicKeyInfo->oid, publicKeyInfo->oidLen, ED25519_OID,
1102  sizeof(ED25519_OID)))
1103  {
1104  //Check the length of the Ed25519 public key
1105  if(publicKeyInfo->ecPublicKey.q != NULL &&
1106  publicKeyInfo->ecPublicKey.qLen == ED25519_PUBLIC_KEY_LEN)
1107  {
1108  //Read the Ed25519 public key
1109  error = mpiImport(&publicKey->q, publicKeyInfo->ecPublicKey.q,
1110  publicKeyInfo->ecPublicKey.qLen, MPI_FORMAT_LITTLE_ENDIAN);
1111  }
1112  else
1113  {
1114  //The public key is not valid
1115  error = ERROR_INVALID_KEY;
1116  }
1117  }
1118  else
1119 #endif
1120 #if (ED448_SUPPORT == ENABLED)
1121  //Ed448 algorithm identifier?
1122  if(!oidComp(publicKeyInfo->oid, publicKeyInfo->oidLen, ED448_OID,
1123  sizeof(ED448_OID)))
1124  {
1125  //Check the length of the Ed448 public key
1126  if(publicKeyInfo->ecPublicKey.q != NULL &&
1127  publicKeyInfo->ecPublicKey.qLen == ED448_PUBLIC_KEY_LEN)
1128  {
1129  //Read the Ed448 public key
1130  error = mpiImport(&publicKey->q, publicKeyInfo->ecPublicKey.q,
1131  publicKeyInfo->ecPublicKey.qLen, MPI_FORMAT_LITTLE_ENDIAN);
1132  }
1133  else
1134  {
1135  //The public key is not valid
1136  error = ERROR_INVALID_KEY;
1137  }
1138  }
1139  else
1140 #endif
1141  //Invalid algorithm identifier?
1142  {
1143  //Report an error
1144  error = ERROR_WRONG_IDENTIFIER;
1145  }
1146 
1147  //Check status code
1148  if(!error)
1149  {
1150  //Debug message
1151  TRACE_DEBUG("EdDSA public key:\r\n");
1152  TRACE_DEBUG_MPI(" ", &publicKey->q);
1153  }
1154 
1155  //Return status code
1156  return error;
1157 }
1158 
1159 #endif
uint8_t length
Definition: dtls_misc.h:149
Ed25519 elliptic curve (constant-time implementation)
const uint8_t * maskGenHashAlgo
Definition: x509_common.h:866
const uint8_t * oid
Definition: x509_common.h:698
error_t x509ImportEddsaPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, EddsaPublicKey *publicKey)
Import an EdDSA public key.
const uint8_t * q
Definition: x509_common.h:650
const EcCurveInfo * ecGetCurveInfo(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:2172
const EcCurveInfo * x509GetCurveInfo(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: x509_common.c:860
const uint8_t X25519_OID[3]
Definition: ec_curves.c:92
const uint8_t * maskGenAlgo
Definition: x509_common.h:864
error_t x509ImportRsaPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, RsaPublicKey *publicKey)
Import an RSA public key.
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:55
error_t ecImport(const EcDomainParameters *params, EcPoint *r, const uint8_t *data, size_t length)
Convert an octet string to an EC point.
Definition: ec.c:214
error_t x509ImportEcParameters(const X509EcParameters *ecParams, EcDomainParameters *params)
Import EC domain parameters.
X509DsaPublicKey dsaPublicKey
Definition: x509_common.h:705
#define ED25519_PUBLIC_KEY_LEN
Definition: ed25519.h:41
error_t x509ParseSubjectPublicKeyInfo(const uint8_t *data, size_t length, size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
Parse SubjectPublicKeyInfo structure.
OID (Object Identifier)
SHA-1 (Secure Hash Algorithm 1)
#define TRUE
Definition: os_port.h:50
#define ED448_PUBLIC_KEY_LEN
Definition: ed448.h:41
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:47
X509EcParameters ecParams
Definition: x509_common.h:708
error_t x509ParseRsaPublicKey(const uint8_t *data, size_t length, X509RsaPublicKey *rsaPublicKey)
Parse RSAPublicKey structure.
const uint8_t * q
Definition: x509_common.h:685
Mpi e
Public exponent.
Definition: rsa.h:51
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
Mpi y
y-coordinate
Definition: ec.h:54
error_t x509ParseRsaPssParameters(const uint8_t *data, size_t length, X509RsaPssParameters *rsaPssParams)
Parse RSASSA-PSS parameters.
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
EC domain parameters.
Definition: ec.h:63
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:75
int_t oidComp(const uint8_t *oid1, size_t oidLen1, const uint8_t *oid2, size_t oidLen2)
Compare object identifiers.
Definition: oid.c:101
const uint8_t MGF1_OID[9]
Definition: rsa.c:91
Mpi n
Modulus.
Definition: rsa.h:50
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:683
const uint8_t DSA_OID[7]
Definition: dsa.c:51
error_t x509ParseRsaPssSaltLength(const uint8_t *data, size_t length, X509RsaPssParameters *rsaPssParams)
Parse RSASSA-PSS salt length.
size_t totalLength
Definition: asn1.h:104
size_t length
Definition: asn1.h:102
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:93
#define FALSE
Definition: os_port.h:46
Elliptic curve parameters.
Definition: ec_curves.h:292
DSA public key.
Definition: dsa.h:60
error_t x509ImportDsaPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, DsaPublicKey *publicKey)
Import a DSA public key.
error_t
Error codes.
Definition: error.h:42
const uint8_t * n
Definition: x509_common.h:635
EC parameters.
Definition: x509_common.h:672
Mpi q
Public key.
Definition: eddsa.h:50
EdDSA public key.
Definition: eddsa.h:48
const uint8_t * g
Definition: x509_common.h:652
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:48
RSA public key.
Definition: x509_common.h:633
const uint8_t * rawData
Definition: x509_common.h:696
error_t x509ParseRsaPssMaskGenAlgo(const uint8_t *data, size_t length, X509RsaPssParameters *rsaPssParams)
Parse RSASSA-PSS mask generation algorithm.
Generic error code.
Definition: error.h:45
ASN.1 tag.
Definition: asn1.h:97
RSA public key.
Definition: rsa.h:48
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
X509RsaPublicKey rsaPublicKey
Definition: x509_common.h:701
const uint8_t * e
Definition: x509_common.h:637
General definitions for cryptographic algorithms.
uint8_t oid[1]
Definition: mib_common.h:186
Mpi x
x-coordinate
Definition: ec.h:53
X509DsaParameters dsaParams
Definition: x509_common.h:704
Elliptic curve point.
Definition: ec.h:51
size_t namedCurveLen
Definition: x509_common.h:675
error_t x509ImportEcPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, EcPoint *publicKey)
Import an EC public key.
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
const uint8_t ED448_OID[3]
Definition: ec_curves.c:98
error_t x509ParseRsaPssHashAlgo(const uint8_t *data, size_t length, X509RsaPssParameters *rsaPssParams)
Parse RSASSA-PSS hash algorithm.
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 cryptoMemset(p, value, length)
Definition: crypto.h:636
#define TRACE_DEBUG(...)
Definition: debug.h:106
Mpi q
Group order.
Definition: dsa.h:63
Mpi p
Prime modulus.
Definition: dsa.h:62
uint8_t n
Subject public key information.
Definition: x509_common.h:694
DSA domain parameters.
Definition: x509_common.h:646
#define ASN1_CLASS_CONTEXT_SPECIFIC
Definition: asn1.h:50
#define SHA1_OID
Definition: sha1.h:44
Mpi y
Public key value.
Definition: dsa.h:65
RSASSA-PSS parameters.
Definition: x509_common.h:860
error_t x509ParseEcParameters(const uint8_t *data, size_t length, X509EcParameters *ecParams)
Parse ECParameters structure.
const uint8_t * p
Definition: x509_common.h:648
const uint8_t * y
Definition: x509_common.h:663
Parsing of ASN.1 encoded keys.
error_t x509ParseDsaPublicKey(const uint8_t *data, size_t length, X509DsaPublicKey *dsaPublicKey)
Parse DSAPublicKey structure.
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:109
uint8_t data[]
Definition: dtls_misc.h:176
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
X509EcPublicKey ecPublicKey
Definition: x509_common.h:709
DSA public key.
Definition: x509_common.h:661
Ed448 elliptic curve (constant-time implementation)
const uint8_t * namedCurve
Definition: x509_common.h:674
Mpi g
Group generator.
Definition: dsa.h:64
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
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)
const uint8_t * hashAlgo
Definition: x509_common.h:862
error_t x509ParseAlgorithmIdentifier(const uint8_t *data, size_t length, size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
Parse AlgorithmIdentifier structure.
error_t x509ParseRsaPssMaskGenHashAlgo(const uint8_t *data, size_t length, X509RsaPssParameters *rsaPssParams)
Parse RSASSA-PSS mask generation hash algorithm.
error_t x509ParseEcPublicKey(const uint8_t *data, size_t length, X509EcPublicKey *ecPublicKey)
Parse ECPublicKey structure.