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-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/x509_key_parse.h"
37 #include "encoding/asn1.h"
38 #include "encoding/oid.h"
39 #include "ecc/eddsa.h"
40 #include "hash/sha1.h"
41 #include "debug.h"
42 
43 //Check crypto library configuration
44 #if (X509_SUPPORT == ENABLED || PEM_SUPPORT == ENABLED)
45 
46 
47 /**
48  * @brief Parse SubjectPublicKeyInfo structure
49  * @param[in] data Pointer to the ASN.1 structure to parse
50  * @param[in] length Length of the ASN.1 structure
51  * @param[out] totalLength Number of bytes that have been parsed
52  * @param[out] publicKeyInfo Information resulting from the parsing process
53  * @return Error code
54  **/
55 
57  size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
58 {
59  error_t error;
60  size_t n;
61  size_t oidLen;
62  const uint8_t *oid;
63  Asn1Tag tag;
64 
65  //Debug message
66  TRACE_DEBUG(" Parsing SubjectPublicKeyInfo...\r\n");
67 
68  //Clear the SubjectPublicKeyInfo structure
69  osMemset(publicKeyInfo, 0, sizeof(X509SubjectPublicKeyInfo));
70 
71  //The public key information is encapsulated within a sequence
72  error = asn1ReadSequence(data, length, &tag);
73  //Failed to decode ASN.1 tag?
74  if(error)
75  return error;
76 
77  //Save the total length of the field
78  *totalLength = tag.totalLength;
79 
80  //Raw contents of the ASN.1 sequence
81  publicKeyInfo->raw.value = data;
82  publicKeyInfo->raw.length = tag.totalLength;
83 
84  //Point to the first field of the sequence
85  data = tag.value;
86  length = tag.length;
87 
88  //Read AlgorithmIdentifier field
89  error = x509ParseAlgoId(data, length, &n, publicKeyInfo);
90  //Any error to report?
91  if(error)
92  return error;
93 
94  //Point to the next field
95  data += n;
96  length -= n;
97 
98  //The SubjectPublicKey is encapsulated within a bit string
99  error = asn1ReadTag(data, length, &tag);
100  //Failed to decode ASN.1 tag?
101  if(error)
102  return error;
103 
104  //Enforce encoding, class and type
105  error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL,
107  //Invalid tag?
108  if(error)
109  return error;
110 
111  //The bit string shall contain an initial octet which encodes the number
112  //of unused bits in the final subsequent octet
113  if(tag.length < 1 || tag.value[0] != 0x00)
114  return ERROR_FAILURE;
115 
116  //Point to the public key
117  data = tag.value + 1;
118  length = tag.length - 1;
119 
120  //Raw contents of the SubjectPublicKey (excluding the tag, length, and
121  //number of unused bits)
122  publicKeyInfo->rawSubjectPublicKey.value = data;
123  publicKeyInfo->rawSubjectPublicKey.length = length;
124 
125  //Get the public key algorithm identifier
126  oid = publicKeyInfo->oid.value;
127  oidLen = publicKeyInfo->oid.length;
128 
129 #if (RSA_SUPPORT == ENABLED)
130  //RSA or RSA-PSS algorithm identifier?
133  {
134  //Read RSAPublicKey structure
135  error = x509ParseRsaPublicKey(data, length, &publicKeyInfo->rsaPublicKey);
136  }
137  else
138 #endif
139 #if (DSA_SUPPORT == ENABLED)
140  //DSA algorithm identifier?
141  if(!oidComp(oid, oidLen, DSA_OID, sizeof(DSA_OID)))
142  {
143  //Read DSAPublicKey structure
144  error = x509ParseDsaPublicKey(data, length, &publicKeyInfo->dsaPublicKey);
145  }
146  else
147 #endif
148 #if (EC_SUPPORT == ENABLED)
149  //EC public key identifier?
151  {
152  //Read ECPublicKey structure
153  error = x509ParseEcPublicKey(data, length, &publicKeyInfo->ecPublicKey);
154  }
155  else
156 #endif
157 #if (ED25519_SUPPORT == ENABLED)
158  //X25519 or Ed25519 algorithm identifier?
159  if(!oidComp(oid, oidLen, X25519_OID, sizeof(X25519_OID)) ||
161  {
162  //Read ECPublicKey structure
163  error = x509ParseEcPublicKey(data, length, &publicKeyInfo->ecPublicKey);
164  }
165  else
166 #endif
167 #if (ED448_SUPPORT == ENABLED)
168  //X448 or Ed448 algorithm identifier?
169  if(!oidComp(oid, oidLen, X448_OID, sizeof(X448_OID)) ||
170  !oidComp(oid, oidLen, ED448_OID, sizeof(ED448_OID)))
171  {
172  //Read ECPublicKey structure
173  error = x509ParseEcPublicKey(data, length, &publicKeyInfo->ecPublicKey);
174  }
175  else
176 #endif
177  //Unknown algorithm identifier?
178  {
179  //Report an error
180  error = ERROR_WRONG_IDENTIFIER;
181  }
182 
183  //Return status code
184  return error;
185 }
186 
187 
188 /**
189  * @brief Parse AlgorithmIdentifier structure
190  * @param[in] data Pointer to the ASN.1 structure to parse
191  * @param[in] length Length of the ASN.1 structure
192  * @param[out] totalLength Number of bytes that have been parsed
193  * @param[out] publicKeyInfo Information resulting from the parsing process
194  * @return Error code
195  **/
196 
197 error_t x509ParseAlgoId(const uint8_t *data, size_t length,
198  size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
199 {
200  error_t error;
201  Asn1Tag tag;
202 
203  //Debug message
204  TRACE_DEBUG(" Parsing AlgorithmIdentifier...\r\n");
205 
206  //Read AlgorithmIdentifier field
207  error = asn1ReadSequence(data, length, &tag);
208  //Failed to decode ASN.1 tag?
209  if(error)
210  return error;
211 
212  //Save the total length of the field
213  *totalLength = tag.totalLength;
214 
215  //Point to the first field
216  data = tag.value;
217  length = tag.length;
218 
219  //Read algorithm identifier (OID)
220  error = asn1ReadOid(data, length, &tag);
221  //Failed to decode ASN.1 tag?
222  if(error)
223  return error;
224 
225  //Save the algorithm identifier
226  publicKeyInfo->oid.value = tag.value;
227  publicKeyInfo->oid.length = tag.length;
228 
229  //Point to the next field (if any)
230  data += tag.totalLength;
231  length -= tag.totalLength;
232 
233 #if (RSA_SUPPORT == ENABLED)
234  //RSA algorithm identifier?
236  {
237  //The parameters field must have ASN.1 type NULL for this algorithm
238  //identifier (refer to RFC 3279, section 2.3.1)
239  error = NO_ERROR;
240  }
241  //RSA-PSS algorithm identifier?
242  else if(!asn1CheckOid(&tag, RSASSA_PSS_OID, sizeof(RSASSA_PSS_OID)))
243  {
244  //The parameters may be either absent or present when used as subject
245  //public key information (refer to RFC 4055, section 3.1)
246  error = NO_ERROR;
247  }
248  else
249 #endif
250 #if (DSA_SUPPORT == ENABLED)
251  //DSA algorithm identifier?
252  if(!asn1CheckOid(&tag, DSA_OID, sizeof(DSA_OID)))
253  {
254  //Read DsaParameters structure
255  error = x509ParseDsaParameters(data, length, &publicKeyInfo->dsaParams);
256  }
257  else
258 #endif
259 #if (EC_SUPPORT == ENABLED)
260  //EC public key identifier?
262  {
263  //Read ECParameters structure
264  error = x509ParseEcParameters(data, length, &publicKeyInfo->ecParams);
265  }
266  else
267 #endif
268 #if (ED25519_SUPPORT == ENABLED)
269  //X25519 or Ed25519 algorithm identifier?
270  if(!asn1CheckOid(&tag, X25519_OID, sizeof(X25519_OID)) ||
271  !asn1CheckOid(&tag, ED25519_OID, sizeof(ED25519_OID)))
272  {
273  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
274  //section 3)
275  error = NO_ERROR;
276  }
277  else
278 #endif
279 #if (ED448_SUPPORT == ENABLED)
280  //X448 or Ed448 algorithm identifier?
281  if(!asn1CheckOid(&tag, X448_OID, sizeof(X448_OID)) ||
282  !asn1CheckOid(&tag, ED448_OID, sizeof(ED448_OID)))
283  {
284  //For all of the OIDs, the parameters must be absent (refer to RFC 8410,
285  //section 3)
286  error = NO_ERROR;
287  }
288  else
289 #endif
290  //Unknown algorithm identifier?
291  {
292  //Report an error
293  error = ERROR_WRONG_IDENTIFIER;
294  }
295 
296  //Return status code
297  return error;
298 }
299 
300 
301 /**
302  * @brief Parse RSAPublicKey structure
303  * @param[in] data Pointer to the ASN.1 structure to parse
304  * @param[in] length Length of the ASN.1 structure
305  * @param[out] rsaPublicKey Information resulting from the parsing process
306  * @return Error code
307  **/
308 
309 error_t x509ParseRsaPublicKey(const uint8_t *data, size_t length,
310  X509RsaPublicKey *rsaPublicKey)
311 {
312  error_t error;
313  Asn1Tag tag;
314 
315  //Debug message
316  TRACE_DEBUG(" Parsing RSAPublicKey...\r\n");
317 
318  //Read RSAPublicKey structure
319  error = asn1ReadSequence(data, length, &tag);
320  //Failed to decode ASN.1 tag?
321  if(error)
322  return error;
323 
324  //Point to the first field
325  data = tag.value;
326  length = tag.length;
327 
328  //Read Modulus field
329  error = asn1ReadTag(data, length, &tag);
330  //Failed to decode ASN.1 tag?
331  if(error)
332  return error;
333 
334  //Enforce encoding, class and type
336  //Invalid tag?
337  if(error)
338  return error;
339 
340  //Save the modulus
341  rsaPublicKey->n.value = tag.value;
342  rsaPublicKey->n.length = tag.length;
343 
344  //Point to the next field
345  data += tag.totalLength;
346  length -= tag.totalLength;
347 
348  //Read PublicExponent field
349  error = asn1ReadTag(data, length, &tag);
350  //Failed to decode ASN.1 tag?
351  if(error)
352  return error;
353 
354  //Enforce encoding, class and type
356  //Invalid tag?
357  if(error)
358  return error;
359 
360  //Save the public exponent
361  rsaPublicKey->e.value = tag.value;
362  rsaPublicKey->e.length = tag.length;
363 
364  //Successful processing
365  return NO_ERROR;
366 }
367 
368 
369 /**
370  * @brief Parse DSAPublicKey structure
371  * @param[in] data Pointer to the ASN.1 structure to parse
372  * @param[in] length Length of the ASN.1 structure
373  * @param[out] dsaPublicKey Information resulting from the parsing process
374  * @return Error code
375  **/
376 
377 error_t x509ParseDsaPublicKey(const uint8_t *data, size_t length,
378  X509DsaPublicKey *dsaPublicKey)
379 {
380  error_t error;
381  Asn1Tag tag;
382 
383  //Debug message
384  TRACE_DEBUG(" Parsing DSAPublicKey...\r\n");
385 
386  //Read DSAPublicKey structure
387  error = asn1ReadTag(data, length, &tag);
388  //Failed to decode ASN.1 tag?
389  if(error)
390  return error;
391 
392  //Enforce encoding, class and type
394  //Invalid tag?
395  if(error)
396  return error;
397 
398  //Save the DSA public value
399  dsaPublicKey->y.value = tag.value;
400  dsaPublicKey->y.length = tag.length;
401 
402  //Successful processing
403  return NO_ERROR;
404 }
405 
406 
407 /**
408  * @brief Parse DSA domain parameters
409  * @param[in] data Pointer to the ASN.1 structure to parse
410  * @param[in] length Length of the ASN.1 structure
411  * @param[out] dsaParams Information resulting from the parsing process
412  * @return Error code
413  **/
414 
415 error_t x509ParseDsaParameters(const uint8_t *data, size_t length,
416  X509DsaParameters *dsaParams)
417 {
418  error_t error;
419  Asn1Tag tag;
420 
421  //Debug message
422  TRACE_DEBUG(" Parsing DSAParameters...\r\n");
423 
424  //Read DSAParameters structure
425  error = asn1ReadSequence(data, length, &tag);
426  //Failed to decode ASN.1 tag?
427  if(error)
428  return error;
429 
430  //Point to the first field
431  data = tag.value;
432  length = tag.length;
433 
434  //Read the parameter p
435  error = asn1ReadTag(data, length, &tag);
436  //Failed to decode ASN.1 tag?
437  if(error)
438  return error;
439 
440  //Enforce encoding, class and type
442  //Invalid tag?
443  if(error)
444  return error;
445 
446  //Save the parameter p
447  dsaParams->p.value = tag.value;
448  dsaParams->p.length = tag.length;
449 
450  //Point to the next field
451  data += tag.totalLength;
452  length -= tag.totalLength;
453 
454  //Read the parameter q
455  error = asn1ReadTag(data, length, &tag);
456  //Failed to decode ASN.1 tag?
457  if(error)
458  return error;
459 
460  //Enforce encoding, class and type
462  //Invalid tag?
463  if(error)
464  return error;
465 
466  //Save the parameter q
467  dsaParams->q.value = tag.value;
468  dsaParams->q.length = tag.length;
469 
470  //Point to the next field
471  data += tag.totalLength;
472  length -= tag.totalLength;
473 
474  //Read the parameter g
475  error = asn1ReadTag(data, length, &tag);
476  //Failed to decode ASN.1 tag?
477  if(error)
478  return error;
479 
480  //Enforce encoding, class and type
482  //Invalid tag?
483  if(error)
484  return error;
485 
486  //Save the parameter g
487  dsaParams->g.value = tag.value;
488  dsaParams->g.length = tag.length;
489 
490  //Successful processing
491  return NO_ERROR;
492 }
493 
494 
495 /**
496  * @brief Parse ECPublicKey structure
497  * @param[in] data Pointer to the ASN.1 structure to parse
498  * @param[in] length Length of the ASN.1 structure
499  * @param[out] ecPublicKey Information resulting from the parsing process
500  * @return Error code
501  **/
502 
503 error_t x509ParseEcPublicKey(const uint8_t *data, size_t length,
504  X509EcPublicKey *ecPublicKey)
505 {
506  //Debug message
507  TRACE_DEBUG(" Parsing ECPublicKey...\r\n");
508 
509  //Make sure the EC public key is valid
510  if(length == 0)
511  return ERROR_BAD_CERTIFICATE;
512 
513  //Save the EC public key
514  ecPublicKey->q.value = data;
515  ecPublicKey->q.length = length;
516 
517  //Successful processing
518  return NO_ERROR;
519 }
520 
521 
522 /**
523  * @brief Parse ECParameters structure
524  * @param[in] data Pointer to the ASN.1 structure to parse
525  * @param[in] length Length of the ASN.1 structure
526  * @param[out] ecParams Information resulting from the parsing process
527  * @return Error code
528  **/
529 
530 error_t x509ParseEcParameters(const uint8_t *data, size_t length,
531  X509EcParameters *ecParams)
532 {
533  error_t error;
534  Asn1Tag tag;
535 
536  //Debug message
537  TRACE_DEBUG(" Parsing ECParameters...\r\n");
538 
539  //Read namedCurve field
540  error = asn1ReadOid(data, length, &tag);
541  //Failed to decode ASN.1 tag?
542  if(error)
543  return error;
544 
545  //The namedCurve field identifies all the required values for a particular
546  //set of elliptic curve domain parameters to be represented by an object
547  //identifier
548  ecParams->namedCurve.value = tag.value;
549  ecParams->namedCurve.length = tag.length;
550 
551  //Successful processing
552  return NO_ERROR;
553 }
554 
555 
556 /**
557  * @brief Import an RSA public key
558  * @param[in] publicKeyInfo Public key information
559  * @param[out] publicKey RSA public key
560  * @return Error code
561  **/
562 
564  RsaPublicKey *publicKey)
565 {
566  error_t error;
567 
568 #if (RSA_SUPPORT == ENABLED)
569  const uint8_t *oid;
570  size_t oidLen;
571 
572  //Get the public key algorithm identifier
573  oid = publicKeyInfo->oid.value;
574  oidLen = publicKeyInfo->oid.length;
575 
576  //RSA algorithm identifier?
579  {
580  //Sanity check
581  if(publicKeyInfo->rsaPublicKey.n.value != NULL &&
582  publicKeyInfo->rsaPublicKey.e.value != NULL)
583  {
584  //Read modulus
585  error = mpiImport(&publicKey->n, publicKeyInfo->rsaPublicKey.n.value,
586  publicKeyInfo->rsaPublicKey.n.length, MPI_FORMAT_BIG_ENDIAN);
587 
588  //Check status code
589  if(!error)
590  {
591  //Read public exponent
592  error = mpiImport(&publicKey->e, publicKeyInfo->rsaPublicKey.e.value,
593  publicKeyInfo->rsaPublicKey.e.length, MPI_FORMAT_BIG_ENDIAN);
594  }
595 
596  //Check status code
597  if(!error)
598  {
599  //Debug message
600  TRACE_DEBUG("RSA public key:\r\n");
601  TRACE_DEBUG(" Modulus:\r\n");
602  TRACE_DEBUG_MPI(" ", &publicKey->n);
603  TRACE_DEBUG(" Public exponent:\r\n");
604  TRACE_DEBUG_MPI(" ", &publicKey->e);
605  }
606  }
607  else
608  {
609  //The public key is not valid
610  error = ERROR_INVALID_KEY;
611  }
612  }
613  else
614 #endif
615  //Invalid algorithm identifier?
616  {
617  //Report an error
618  error = ERROR_WRONG_IDENTIFIER;
619  }
620 
621  //Return status code
622  return error;
623 }
624 
625 
626 /**
627  * @brief Import a DSA public key
628  * @param[in] publicKeyInfo Public key information
629  * @param[out] publicKey DSA public key
630  * @return Error code
631  **/
632 
634  DsaPublicKey *publicKey)
635 {
636  error_t error;
637 
638 #if (DSA_SUPPORT == ENABLED)
639  //DSA algorithm identifier?
640  if(!oidComp(publicKeyInfo->oid.value, publicKeyInfo->oid.length,
641  DSA_OID, sizeof(DSA_OID)))
642  {
643  //Sanity check
644  if(publicKeyInfo->dsaParams.p.value != NULL &&
645  publicKeyInfo->dsaParams.q.value != NULL &&
646  publicKeyInfo->dsaParams.g.value != NULL &&
647  publicKeyInfo->dsaPublicKey.y.value != NULL)
648  {
649  //Read parameter p
650  error = mpiImport(&publicKey->params.p, publicKeyInfo->dsaParams.p.value,
651  publicKeyInfo->dsaParams.p.length, MPI_FORMAT_BIG_ENDIAN);
652 
653  //Check status code
654  if(!error)
655  {
656  //Read parameter q
657  error = mpiImport(&publicKey->params.q, publicKeyInfo->dsaParams.q.value,
658  publicKeyInfo->dsaParams.q.length, MPI_FORMAT_BIG_ENDIAN);
659  }
660 
661  //Check status code
662  if(!error)
663  {
664  //Read parameter g
665  error = mpiImport(&publicKey->params.g, publicKeyInfo->dsaParams.g.value,
666  publicKeyInfo->dsaParams.g.length, MPI_FORMAT_BIG_ENDIAN);
667  }
668 
669  //Check status code
670  if(!error)
671  {
672  //Read public value
673  error = mpiImport(&publicKey->y, publicKeyInfo->dsaPublicKey.y.value,
674  publicKeyInfo->dsaPublicKey.y.length, MPI_FORMAT_BIG_ENDIAN);
675  }
676 
677  //Check status code
678  if(!error)
679  {
680  //Debug message
681  TRACE_DEBUG("DSA public key:\r\n");
682  TRACE_DEBUG(" Parameter p:\r\n");
683  TRACE_DEBUG_MPI(" ", &publicKey->params.p);
684  TRACE_DEBUG(" Parameter q:\r\n");
685  TRACE_DEBUG_MPI(" ", &publicKey->params.q);
686  TRACE_DEBUG(" Parameter g:\r\n");
687  TRACE_DEBUG_MPI(" ", &publicKey->params.g);
688  TRACE_DEBUG(" Public value y:\r\n");
689  TRACE_DEBUG_MPI(" ", &publicKey->y);
690  }
691  }
692  else
693  {
694  //The public key is not valid
695  error = ERROR_INVALID_KEY;
696  }
697  }
698  else
699 #endif
700  //Invalid algorithm identifier?
701  {
702  //Report an error
703  error = ERROR_WRONG_IDENTIFIER;
704  }
705 
706  //Return status code
707  return error;
708 }
709 
710 
711 /**
712  * @brief Import an EC public key
713  * @param[in] publicKeyInfo Public key information
714  * @param[out] publicKey EC public key
715  * @return Error code
716  **/
717 
719  EcPublicKey *publicKey)
720 {
721  error_t error;
722 
723 #if (EC_SUPPORT == ENABLED)
724  const EcCurveInfo *curveInfo;
725  EcDomainParameters params;
726 
727  //EC public key identifier?
728  if(!oidComp(publicKeyInfo->oid.value, publicKeyInfo->oid.length,
730  {
731  //Sanity check
732  if(publicKeyInfo->ecParams.namedCurve.value != NULL &&
733  publicKeyInfo->ecPublicKey.q.value != NULL)
734  {
735  //Initialize EC domain parameters
736  ecInitDomainParameters(&params);
737 
738  //Retrieve EC domain parameters
739  curveInfo = x509GetCurveInfo(publicKeyInfo->ecParams.namedCurve.value,
740  publicKeyInfo->ecParams.namedCurve.length);
741 
742  //Make sure the specified elliptic curve is supported
743  if(curveInfo != NULL)
744  {
745  //Load EC domain parameters
746  error = ecLoadDomainParameters(&params, curveInfo);
747  }
748  else
749  {
750  //Invalid EC domain parameters
751  error = ERROR_WRONG_IDENTIFIER;
752  }
753 
754  //Check status code
755  if(!error)
756  {
757  //Read the EC public key
758  error = ecImport(&params, &publicKey->q,
759  publicKeyInfo->ecPublicKey.q.value,
760  publicKeyInfo->ecPublicKey.q.length);
761  }
762 
763  //Check status code
764  if(!error)
765  {
766  //Debug message
767  TRACE_DEBUG(" Public key X:\r\n");
768  TRACE_DEBUG_MPI(" ", &publicKey->q.x);
769  TRACE_DEBUG(" Public key Y:\r\n");
770  TRACE_DEBUG_MPI(" ", &publicKey->q.y);
771  }
772 
773  //Release EC domain parameters
774  ecFreeDomainParameters(&params);
775  }
776  else
777  {
778  //The public key is not valid
779  error = ERROR_INVALID_KEY;
780  }
781  }
782  else
783 #endif
784  //Invalid algorithm identifier?
785  {
786  //Report an error
787  error = ERROR_WRONG_IDENTIFIER;
788  }
789 
790  //Return status code
791  return error;
792 }
793 
794 
795 /**
796  * @brief Import EC domain parameters
797  * @param[in] ecParams Pointer to the ECParameters structure
798  * @param[out] params EC domain parameters
799  * @return Error code
800  **/
801 
803  EcDomainParameters *params)
804 {
805  error_t error;
806 
807 #if (EC_SUPPORT == ENABLED)
808  const EcCurveInfo *curveInfo;
809 
810  //Retrieve EC domain parameters
811  curveInfo = ecGetCurveInfo(ecParams->namedCurve.value,
812  ecParams->namedCurve.length);
813 
814  //Make sure the specified elliptic curve is supported
815  if(curveInfo != NULL)
816  {
817  //Load EC domain parameters
818  error = ecLoadDomainParameters(params, curveInfo);
819  }
820  else
821 #endif
822  {
823  //Invalid EC domain parameters
824  error = ERROR_WRONG_IDENTIFIER;
825  }
826 
827  //Return status code
828  return error;
829 }
830 
831 
832 /**
833  * @brief Import an EdDSA public key
834  * @param[in] publicKeyInfo Public key information
835  * @param[out] publicKey EdDSA public key
836  * @return Error code
837  **/
838 
840  EddsaPublicKey *publicKey)
841 {
842  error_t error;
843 
844 #if (ED25519_SUPPORT == ENABLED)
845  //Ed25519 algorithm identifier?
846  if(!oidComp(publicKeyInfo->oid.value, publicKeyInfo->oid.length,
847  ED25519_OID, sizeof(ED25519_OID)))
848  {
849  //Check the length of the Ed25519 public key
850  if(publicKeyInfo->ecPublicKey.q.value != NULL &&
851  publicKeyInfo->ecPublicKey.q.length == ED25519_PUBLIC_KEY_LEN)
852  {
853  //Read the Ed25519 public key
854  error = mpiImport(&publicKey->q, publicKeyInfo->ecPublicKey.q.value,
855  publicKeyInfo->ecPublicKey.q.length, MPI_FORMAT_LITTLE_ENDIAN);
856  }
857  else
858  {
859  //The public key is not valid
860  error = ERROR_INVALID_KEY;
861  }
862  }
863  else
864 #endif
865 #if (ED448_SUPPORT == ENABLED)
866  //Ed448 algorithm identifier?
867  if(!oidComp(publicKeyInfo->oid.value, publicKeyInfo->oid.length,
868  ED448_OID, sizeof(ED448_OID)))
869  {
870  //Check the length of the Ed448 public key
871  if(publicKeyInfo->ecPublicKey.q.value != NULL &&
872  publicKeyInfo->ecPublicKey.q.length == ED448_PUBLIC_KEY_LEN)
873  {
874  //Read the Ed448 public key
875  error = mpiImport(&publicKey->q, publicKeyInfo->ecPublicKey.q.value,
876  publicKeyInfo->ecPublicKey.q.length, MPI_FORMAT_LITTLE_ENDIAN);
877  }
878  else
879  {
880  //The public key is not valid
881  error = ERROR_INVALID_KEY;
882  }
883  }
884  else
885 #endif
886  //Invalid algorithm identifier?
887  {
888  //Report an error
889  error = ERROR_WRONG_IDENTIFIER;
890  }
891 
892  //Check status code
893  if(!error)
894  {
895  //Debug message
896  TRACE_DEBUG("EdDSA public key:\r\n");
897  TRACE_DEBUG_MPI(" ", &publicKey->q);
898  }
899 
900  //Return status code
901  return error;
902 }
903 
904 #endif
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
ASN.1 (Abstract Syntax Notation One)
@ ASN1_TYPE_BIT_STRING
Definition: asn1.h:71
@ ASN1_TYPE_INTEGER
Definition: asn1.h:70
#define ASN1_CLASS_UNIVERSAL
Definition: asn1.h:52
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
void ecFreeDomainParameters(EcDomainParameters *params)
Release EC domain parameters.
Definition: ec.c:72
void ecInitDomainParameters(EcDomainParameters *params)
Initialize EC domain parameters.
Definition: ec.c:51
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:43
error_t ecLoadDomainParameters(EcDomainParameters *params, const EcCurveInfo *curveInfo)
Load EC domain parameters.
Definition: ec.c:90
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:365
const uint8_t ED25519_OID[3]
Definition: ec_curves.c:98
const EcCurveInfo * ecGetCurveInfo(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:2374
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_PUBLIC_KEY_LEN
Definition: ed25519.h:42
#define ED448_PUBLIC_KEY_LEN
Definition: ed448.h:42
EdDSA (Edwards-Curve Digital Signature Algorithm)
error_t
Error codes.
Definition: error.h:43
@ ERROR_WRONG_IDENTIFIER
Definition: error.h:89
@ ERROR_INVALID_KEY
Definition: error.h:106
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_BAD_CERTIFICATE
Definition: error.h:234
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
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
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:57
const uint8_t RSASSA_PSS_OID[9]
Definition: rsa.c:88
SHA-1 (Secure Hash Algorithm 1)
ASN.1 tag.
Definition: asn1.h:102
size_t totalLength
Definition: asn1.h:108
const uint8_t * value
Definition: asn1.h:107
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 public key.
Definition: dsa.h:61
Mpi y
Public key value.
Definition: dsa.h:63
DsaDomainParameters params
DSA domain parameters.
Definition: dsa.h:62
Elliptic curve parameters.
Definition: ec_curves.h:295
EC domain parameters.
Definition: ec.h:76
Mpi y
y-coordinate
Definition: ec.h:66
Mpi x
x-coordinate
Definition: ec.h:65
EC public key.
Definition: ec.h:94
EcPoint q
Public key.
Definition: ec.h:95
EdDSA public key.
Definition: eddsa.h:49
Mpi q
Public key.
Definition: eddsa.h:50
RSA public key.
Definition: rsa.h:57
Mpi e
Public exponent.
Definition: rsa.h:59
Mpi n
Modulus.
Definition: rsa.h:58
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
DSA public key.
Definition: x509_common.h:753
X509OctetString y
Definition: x509_common.h:754
EC parameters.
Definition: x509_common.h:763
X509OctetString namedCurve
Definition: x509_common.h:764
EC public key.
Definition: x509_common.h:773
X509OctetString q
Definition: x509_common.h:774
const uint8_t * value
Definition: x509_common.h:647
RSA public key.
Definition: x509_common.h:730
X509OctetString n
Definition: x509_common.h:731
X509OctetString e
Definition: x509_common.h:732
Subject Public Key Information extension.
Definition: x509_common.h:783
X509RsaPublicKey rsaPublicKey
Definition: x509_common.h:788
X509OctetString rawSubjectPublicKey
Definition: x509_common.h:786
X509DsaPublicKey dsaPublicKey
Definition: x509_common.h:792
X509OctetString raw
Definition: x509_common.h:784
X509EcPublicKey ecPublicKey
Definition: x509_common.h:796
X509OctetString oid
Definition: x509_common.h:785
X509DsaParameters dsaParams
Definition: x509_common.h:791
X509EcParameters ecParams
Definition: x509_common.h:795
uint8_t length
Definition: tcp.h:368
const EcCurveInfo * x509GetCurveInfo(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: x509_common.c:910
error_t x509ImportEcPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, EcPublicKey *publicKey)
Import an EC public key.
error_t x509ParseEcParameters(const uint8_t *data, size_t length, X509EcParameters *ecParams)
Parse ECParameters structure.
error_t x509ParseAlgoId(const uint8_t *data, size_t length, size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
Parse AlgorithmIdentifier structure.
error_t x509ImportEcParameters(const X509EcParameters *ecParams, EcDomainParameters *params)
Import EC domain parameters.
error_t x509ParseDsaPublicKey(const uint8_t *data, size_t length, X509DsaPublicKey *dsaPublicKey)
Parse DSAPublicKey structure.
error_t x509ImportRsaPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, RsaPublicKey *publicKey)
Import an RSA public key.
error_t x509ImportEddsaPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, EddsaPublicKey *publicKey)
Import an EdDSA public key.
error_t x509ParseRsaPublicKey(const uint8_t *data, size_t length, X509RsaPublicKey *rsaPublicKey)
Parse RSAPublicKey structure.
error_t x509ImportDsaPublicKey(const X509SubjectPublicKeyInfo *publicKeyInfo, DsaPublicKey *publicKey)
Import a DSA public key.
error_t x509ParseSubjectPublicKeyInfo(const uint8_t *data, size_t length, size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
Parse SubjectPublicKeyInfo structure.
error_t x509ParseEcPublicKey(const uint8_t *data, size_t length, X509EcPublicKey *ecPublicKey)
Parse ECPublicKey structure.
error_t x509ParseDsaParameters(const uint8_t *data, size_t length, X509DsaParameters *dsaParams)
Parse DSA domain parameters.
Parsing of ASN.1 encoded keys.