pem_import.c
Go to the documentation of this file.
1 /**
2  * @file pem_import.c
3  * @brief PEM file import functions
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.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/pem_import.h"
37 #include "pkix/pem_decrypt.h"
38 #include "pkix/pkcs5_decrypt.h"
39 #include "pkix/pkcs8_key_parse.h"
40 #include "pkix/x509_key_parse.h"
41 #include "encoding/asn1.h"
42 #include "encoding/oid.h"
43 #include "mpi/mpi.h"
44 #include "debug.h"
45 
46 //Check crypto library configuration
47 #if (PEM_SUPPORT == ENABLED)
48 
49 
50 /**
51  * @brief Decode a PEM file containing a certificate
52  * @param[in] input Pointer to the PEM encoding
53  * @param[in] inputLen Length of the PEM structure
54  * @param[out] output Pointer to the DER-encoded certificate
55  * @param[out] outputLen Length of the DER-encoded certificate, in bytes
56  * @param[out] consumed Total number of characters that have been consumed
57  * (optional parameter)
58  * @return Error code
59  **/
60 
61 error_t pemImportCertificate(const char_t *input, size_t inputLen,
62  uint8_t *output, size_t *outputLen, size_t *consumed)
63 {
64  error_t error;
65 
66  //Check parameters
67  if(input == NULL || outputLen == NULL)
69 
70  //X.509 certificates are encoded using the "CERTIFICATE" label
71  error = pemDecodeFile(input, inputLen, "CERTIFICATE", output, outputLen,
72  NULL, consumed);
73 
74  //Return status code
75  return error;
76 }
77 
78 
79 /**
80  * @brief Decode a PEM file containing a certificate revocation list
81  * @param[in] input Pointer to the PEM encoding
82  * @param[in] inputLen Length of the PEM structure
83  * @param[out] output Pointer to the DER-encoded CRL
84  * @param[out] outputLen Length of the DER-encoded CRL, in bytes
85  * @param[out] consumed Total number of characters that have been consumed
86  * (optional parameter)
87  * @return Error code
88  **/
89 
90 error_t pemImportCrl(const char_t *input, size_t inputLen,
91  uint8_t *output, size_t *outputLen, size_t *consumed)
92 {
93  error_t error;
94 
95  //Check parameters
96  if(input == NULL || outputLen == NULL)
98 
99  //CRLs are encoded using the "X509 CRL" label
100  error = pemDecodeFile(input, inputLen, "X509 CRL", output, outputLen,
101  NULL, consumed);
102 
103  //Return status code
104  return error;
105 }
106 
107 
108 /**
109  * @brief Decode a PEM file containing a certification signing request
110  * @param[in] input Pointer to the PEM encoding
111  * @param[in] inputLen Length of the PEM structure
112  * @param[out] output Pointer to the DER-encoded CSR
113  * @param[out] outputLen Length of the DER-encoded CSR, in bytes
114  * @return Error code
115  **/
116 
117 error_t pemImportCsr(const char_t *input, size_t inputLen,
118  uint8_t *output, size_t *outputLen)
119 {
120  error_t error;
121 
122  //Check parameters
123  if(input == NULL || outputLen == NULL)
125 
126  //CSRs are encoded using the "CERTIFICATE REQUEST" label
127  error = pemDecodeFile(input, inputLen, "CERTIFICATE REQUEST", output,
128  outputLen, NULL, NULL);
129 
130  //Return status code
131  return error;
132 }
133 
134 
135 /**
136  * @brief Decode a PEM file containing Diffie-Hellman parameters
137  * @param[out] params Diffie-Hellman parameters resulting from the parsing process
138  * @param[in] input Pointer to the PEM encoding
139  * @param[in] length Length of the PEM encoding
140  * @return Error code
141  **/
142 
144  size_t length)
145 {
146 #if (DH_SUPPORT == ENABLED)
147  error_t error;
148  size_t n;
149  uint8_t *buffer;
150  const uint8_t *p;
151  Asn1Tag tag;
152 
153  //Check parameters
154  if(params == NULL || input == NULL)
156 
157  //Initialize variables
158  p = NULL;
159  n = 0;
160 
161  //Diffie-Hellman parameters are encoded using the "DH PARAMETERS" label
162  error = pemDecodeFile(input, length, "DH PARAMETERS", NULL, &n, NULL, NULL);
163 
164  //Check status code
165  if(!error)
166  {
167  //Allocate a memory buffer to hold the ASN.1 data
168  buffer = cryptoAllocMem(n);
169 
170  //Successful memory allocation?
171  if(buffer != NULL)
172  {
173  //Decode the content of the PEM container
174  error = pemDecodeFile(input, length, "DH PARAMETERS", buffer, &n,
175  NULL, NULL);
176 
177  //Check status code
178  if(!error)
179  {
180  //The Diffie-Hellman parameters are encapsulated within a sequence
181  error = asn1ReadSequence(buffer, n, &tag);
182  }
183 
184  //Check status code
185  if(!error)
186  {
187  //Point to the first field of the sequence
188  p = tag.value;
189  n = tag.length;
190 
191  //Read the prime modulus
192  error = asn1ReadMpi(p, n, &tag, &params->p);
193  }
194 
195  //Check status code
196  if(!error)
197  {
198  //Point to the next field
199  p += tag.totalLength;
200  n -= tag.totalLength;
201 
202  //Read the generator
203  error = asn1ReadMpi(p, n, &tag, &params->g);
204  }
205 
206  //Check status code
207  if(!error)
208  {
209  //Debug message
210  TRACE_DEBUG("Diffie-Hellman parameters:\r\n");
211  TRACE_DEBUG(" Prime modulus:\r\n");
212  TRACE_DEBUG_MPI(" ", &params->p);
213  TRACE_DEBUG(" Generator:\r\n");
214  TRACE_DEBUG_MPI(" ", &params->g);
215  }
216 
217  //Release previously allocated memory
218  cryptoFreeMem(buffer);
219  }
220  else
221  {
222  //Failed to allocate memory
223  error = ERROR_OUT_OF_MEMORY;
224  }
225  }
226 
227  //Any error to report?
228  if(error)
229  {
230  //Clean up side effects
231  mpiFree(&params->p);
232  mpiFree(&params->g);
233  }
234 
235  //Return status code
236  return error;
237 #else
238  //Not implemented
239  return ERROR_NOT_IMPLEMENTED;
240 #endif
241 }
242 
243 
244 /**
245  * @brief Decode a PEM file containing an RSA public key
246  * @param[out] publicKey RSA public key resulting from the parsing process
247  * @param[in] input Pointer to the PEM encoding
248  * @param[in] length Length of the PEM encoding
249  * @return Error code
250  **/
251 
253  size_t length)
254 {
255 #if (RSA_SUPPORT == ENABLED)
256  error_t error;
257  size_t n;
258  uint8_t *buffer;
259  X509SubjectPublicKeyInfo publicKeyInfo;
260 
261  //Check parameters
262  if(publicKey == NULL || input == NULL)
264 
265  //Clear the SubjectPublicKeyInfo structure
266  osMemset(&publicKeyInfo, 0, sizeof(X509SubjectPublicKeyInfo));
267 
268  //The type of data encoded is labeled depending on the type label in
269  //the "-----BEGIN " line (refer to RFC 7468, section 2)
270  if(pemDecodeFile(input, length, "RSA PUBLIC KEY", NULL, &n, NULL,
271  NULL) == NO_ERROR)
272  {
273  //Allocate a memory buffer to hold the ASN.1 data
274  buffer = cryptoAllocMem(n);
275 
276  //Successful memory allocation?
277  if(buffer != NULL)
278  {
279  //Decode the content of the PEM container
280  error = pemDecodeFile(input, length, "RSA PUBLIC KEY", buffer, &n,
281  NULL, NULL);
282 
283  //Check status code
284  if(!error)
285  {
286  //Read RSAPublicKey structure
287  error = x509ParseRsaPublicKey(buffer, n, &publicKeyInfo.rsaPublicKey);
288  }
289 
290  //Check status code
291  if(!error)
292  {
293  //Set public key algorithm identifier
294  publicKeyInfo.oid.value = RSA_ENCRYPTION_OID;
295  publicKeyInfo.oid.length = sizeof(RSA_ENCRYPTION_OID);
296 
297  //Import the RSA public key
298  error = x509ImportRsaPublicKey(publicKey, &publicKeyInfo);
299  }
300 
301  //Release previously allocated memory
302  cryptoFreeMem(buffer);
303  }
304  else
305  {
306  //Failed to allocate memory
307  error = ERROR_OUT_OF_MEMORY;
308  }
309  }
310  else if(pemDecodeFile(input, length, "PUBLIC KEY", NULL, &n, NULL,
311  NULL) == NO_ERROR)
312  {
313  //Allocate a memory buffer to hold the ASN.1 data
314  buffer = cryptoAllocMem(n);
315 
316  //Successful memory allocation?
317  if(buffer != NULL)
318  {
319  //Decode the content of the PEM container
320  error = pemDecodeFile(input, length, "PUBLIC KEY", buffer, &n,
321  NULL, NULL);
322 
323  //Check status code
324  if(!error)
325  {
326  //The ASN.1 encoded data of the public key is the SubjectPublicKeyInfo
327  //structure (refer to RFC 7468, section 13)
328  error = x509ParseSubjectPublicKeyInfo(buffer, n, &n, &publicKeyInfo);
329  }
330 
331  //Check status code
332  if(!error)
333  {
334  //Import the RSA public key
335  error = x509ImportRsaPublicKey(publicKey, &publicKeyInfo);
336  }
337 
338  //Release previously allocated memory
339  cryptoFreeMem(buffer);
340  }
341  else
342  {
343  //Failed to allocate memory
344  error = ERROR_OUT_OF_MEMORY;
345  }
346  }
347  else
348  {
349  //The PEM file does not contain a valid public key
350  error = ERROR_END_OF_FILE;
351  }
352 
353  //Any error to report?
354  if(error)
355  {
356  //Clean up side effects
357  rsaFreePublicKey(publicKey);
358  }
359 
360  //Return status code
361  return error;
362 #else
363  //Not implemented
364  return ERROR_NOT_IMPLEMENTED;
365 #endif
366 }
367 
368 
369 /**
370  * @brief Decode a PEM file containing an RSA private key
371  * @param[out] privateKey RSA private key resulting from the parsing process
372  * @param[in] input Pointer to the PEM encoding
373  * @param[in] length Length of the PEM encoding
374  * @param[in] password NULL-terminated string containing the password. This
375  * parameter is required if the private key is encrypted
376  * @return Error code
377  **/
378 
380  size_t length, const char_t *password)
381 {
382 #if (RSA_SUPPORT == ENABLED)
383  error_t error;
384  size_t n;
385  uint8_t *buffer;
386  PemHeader header;
387  Pkcs8PrivateKeyInfo privateKeyInfo;
388 
389  //Check parameters
390  if(privateKey == NULL || input == NULL)
392 
393  //Clear the PrivateKeyInfo structure
394  osMemset(&privateKeyInfo, 0, sizeof(Pkcs8PrivateKeyInfo));
395 
396  //The type of data encoded is labeled depending on the type label in
397  //the "-----BEGIN " line (refer to RFC 7468, section 2)
398  if(pemDecodeFile(input, length, "RSA PRIVATE KEY", NULL, &n, NULL,
399  NULL) == NO_ERROR)
400  {
401  //Allocate a memory buffer to hold the ASN.1 data
402  buffer = cryptoAllocMem(n);
403 
404  //Successful memory allocation?
405  if(buffer != NULL)
406  {
407  //Decode the content of the PEM container
408  error = pemDecodeFile(input, length, "RSA PRIVATE KEY", buffer, &n,
409  &header, NULL);
410 
411  //Check status code
412  if(!error)
413  {
414  //Check whether the PEM file is encrypted
415  if(pemCompareString(&header.procType.type, "ENCRYPTED"))
416  {
417  //Perform decryption
418  error = pemDecryptMessage(&header, password, buffer, n,
419  buffer, &n);
420  }
421  }
422 
423  //Check status code
424  if(!error)
425  {
426  //Read RSAPrivateKey structure
427  error = pkcs8ParseRsaPrivateKey(buffer, n,
428  &privateKeyInfo.rsaPrivateKey);
429  }
430 
431  //Check status code
432  if(!error)
433  {
434  //Set private key algorithm identifier
435  privateKeyInfo.oid.value = RSA_ENCRYPTION_OID;
436  privateKeyInfo.oid.length = sizeof(RSA_ENCRYPTION_OID);
437 
438  //Import the RSA private key
439  error = pkcs8ImportRsaPrivateKey(privateKey, &privateKeyInfo);
440  }
441 
442  //Release previously allocated memory
443  cryptoFreeMem(buffer);
444  }
445  else
446  {
447  //Failed to allocate memory
448  error = ERROR_OUT_OF_MEMORY;
449  }
450  }
451  else if(pemDecodeFile(input, length, "PRIVATE KEY", NULL, &n, NULL,
452  NULL) == NO_ERROR)
453  {
454  //Allocate a memory buffer to hold the ASN.1 data
455  buffer = cryptoAllocMem(n);
456 
457  //Successful memory allocation?
458  if(buffer != NULL)
459  {
460  //Decode the content of the PEM container
461  error = pemDecodeFile(input, length, "PRIVATE KEY", buffer, &n,
462  NULL, NULL);
463 
464  //Check status code
465  if(!error)
466  {
467  //Read the PrivateKeyInfo structure (refer to RFC 5208, section 5)
468  error = pkcs8ParsePrivateKeyInfo(buffer, n, &privateKeyInfo);
469  }
470 
471  //Check status code
472  if(!error)
473  {
474  //Import the RSA private key
475  error = pkcs8ImportRsaPrivateKey(privateKey, &privateKeyInfo);
476  }
477 
478  //Release previously allocated memory
479  cryptoFreeMem(buffer);
480  }
481  else
482  {
483  //Failed to allocate memory
484  error = ERROR_OUT_OF_MEMORY;
485  }
486  }
487  else if(pemDecodeFile(input, length, "ENCRYPTED PRIVATE KEY", NULL, &n, NULL,
488  NULL) == NO_ERROR)
489  {
490 #if (PEM_ENCRYPTED_KEY_SUPPORT == ENABLED)
491  //Allocate a memory buffer to hold the ASN.1 data
492  buffer = cryptoAllocMem(n);
493 
494  //Successful memory allocation?
495  if(buffer != NULL)
496  {
497  uint8_t *data;
498  Pkcs8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo;
499 
500  //Decode the content of the PEM container
501  error = pemDecodeFile(input, length, "ENCRYPTED PRIVATE KEY", buffer,
502  &n, NULL, NULL);
503 
504  //Check status code
505  if(!error)
506  {
507  //Read the EncryptedPrivateKeyInfo structure (refer to RFC 5208,
508  //section 6)
509  error = pkcs8ParseEncryptedPrivateKeyInfo(buffer, n,
510  &encryptedPrivateKeyInfo);
511  }
512 
513  //Check status code
514  if(!error)
515  {
516  //Point to the encrypted data
517  data = (uint8_t *) encryptedPrivateKeyInfo.encryptedData.value;
518  n = encryptedPrivateKeyInfo.encryptedData.length;
519 
520  //Decrypt the private key information
521  error = pkcs5Decrypt(&encryptedPrivateKeyInfo.encryptionAlgo,
522  password, data, n, data, &n);
523  }
524 
525  //Check status code
526  if(!error)
527  {
528  //Read the PrivateKeyInfo structure (refer to RFC 5208, section 5)
529  error = pkcs8ParsePrivateKeyInfo(data, n, &privateKeyInfo);
530  }
531 
532  //Check status code
533  if(!error)
534  {
535  //Import the RSA private key
536  error = pkcs8ImportRsaPrivateKey(privateKey, &privateKeyInfo);
537  }
538 
539  //Release previously allocated memory
540  cryptoFreeMem(buffer);
541  }
542  else
543  {
544  //Failed to allocate memory
545  error = ERROR_OUT_OF_MEMORY;
546  }
547 #else
548  //The PEM file contains an encrypted private key
549  error = ERROR_DECRYPTION_FAILED;
550 #endif
551  }
552  else
553  {
554  //The PEM file does not contain a valid private key
555  error = ERROR_END_OF_FILE;
556  }
557 
558  //Any error to report?
559  if(error)
560  {
561  //Clean up side effects
562  rsaFreePrivateKey(privateKey);
563  }
564 
565  //Return status code
566  return error;
567 #else
568  //Not implemented
569  return ERROR_NOT_IMPLEMENTED;
570 #endif
571 }
572 
573 
574 /**
575  * @brief Decode a PEM file containing a DSA public key
576  * @param[out] publicKey DSA public key resulting from the parsing process
577  * @param[in] input Pointer to the PEM encoding
578  * @param[in] length Length of the PEM encoding
579  * @return Error code
580  **/
581 
583  size_t length)
584 {
585 #if (DSA_SUPPORT == ENABLED)
586  error_t error;
587  size_t n;
588  uint8_t *buffer;
589  X509SubjectPublicKeyInfo publicKeyInfo;
590 
591  //Check parameters
592  if(publicKey == NULL || input == NULL)
594 
595  //Public keys are encoded using the "PUBLIC KEY" label
596  error = pemDecodeFile(input, length, "PUBLIC KEY", NULL, &n, NULL, NULL);
597 
598  //Check status code
599  if(!error)
600  {
601  //Allocate a memory buffer to hold the ASN.1 data
602  buffer = cryptoAllocMem(n);
603 
604  //Successful memory allocation?
605  if(buffer != NULL)
606  {
607  //Decode the content of the PEM container
608  error = pemDecodeFile(input, length, "PUBLIC KEY", buffer, &n, NULL,
609  NULL);
610 
611  //Check status code
612  if(!error)
613  {
614  //The ASN.1 encoded data of the public key is the SubjectPublicKeyInfo
615  //structure (refer to RFC 7468, section 13)
616  error = x509ParseSubjectPublicKeyInfo(buffer, n, &n, &publicKeyInfo);
617  }
618 
619  //Check status code
620  if(!error)
621  {
622  //Import the DSA public key
623  error = x509ImportDsaPublicKey(publicKey, &publicKeyInfo);
624  }
625 
626  //Release previously allocated memory
627  cryptoFreeMem(buffer);
628  }
629  else
630  {
631  //Failed to allocate memory
632  error = ERROR_OUT_OF_MEMORY;
633  }
634  }
635 
636  //Any error to report?
637  if(error)
638  {
639  //Clean up side effects
640  dsaFreePublicKey(publicKey);
641  }
642 
643  //Return status code
644  return error;
645 #else
646  //Not implemented
647  return ERROR_NOT_IMPLEMENTED;
648 #endif
649 }
650 
651 
652 /**
653  * @brief Decode a PEM file containing a DSA private key
654  * @param[out] privateKey DSA private key resulting from the parsing process
655  * @param[in] input Pointer to the PEM encoding
656  * @param[in] length Length of the PEM encoding
657  * @param[in] password NULL-terminated string containing the password. This
658  * parameter is required if the private key is encrypted
659  * @return Error code
660  **/
661 
663  size_t length, const char_t *password)
664 {
665 #if (DSA_SUPPORT == ENABLED)
666  error_t error;
667  size_t n;
668  uint8_t *buffer;
669  PemHeader header;
670  Pkcs8PrivateKeyInfo privateKeyInfo;
671 
672  //Check parameters
673  if(privateKey == NULL || input == NULL)
675 
676  //Clear the PrivateKeyInfo structure
677  osMemset(&privateKeyInfo, 0, sizeof(Pkcs8PrivateKeyInfo));
678 
679  //The type of data encoded is labeled depending on the type label in
680  //the "-----BEGIN " line (refer to RFC 7468, section 2)
681  if(pemDecodeFile(input, length, "DSA PRIVATE KEY", NULL, &n, NULL,
682  NULL) == NO_ERROR)
683  {
684  //Allocate a memory buffer to hold the ASN.1 data
685  buffer = cryptoAllocMem(n);
686 
687  //Successful memory allocation?
688  if(buffer != NULL)
689  {
690  //Decode the content of the PEM container
691  error = pemDecodeFile(input, length, "DSA PRIVATE KEY", buffer, &n,
692  &header, NULL);
693 
694  //Check status code
695  if(!error)
696  {
697  //Check whether the PEM file is encrypted
698  if(pemCompareString(&header.procType.type, "ENCRYPTED"))
699  {
700  //Perform decryption
701  error = pemDecryptMessage(&header, password, buffer, n,
702  buffer, &n);
703  }
704  }
705 
706  //Check status code
707  if(!error)
708  {
709  //Read DSAPrivateKey structure
710  error = pkcs8ParseDsaPrivateKey(buffer, n, &privateKeyInfo.dsaParams,
711  &privateKeyInfo.dsaPrivateKey, &privateKeyInfo.dsaPublicKey);
712  }
713 
714  //Check status code
715  if(!error)
716  {
717  //Set private key algorithm identifier
718  privateKeyInfo.oid.value = DSA_OID;
719  privateKeyInfo.oid.length = sizeof(DSA_OID);
720 
721  //Import the DSA private key
722  error = pkcs8ImportDsaPrivateKey(privateKey, &privateKeyInfo);
723  }
724 
725  //Release previously allocated memory
726  cryptoFreeMem(buffer);
727  }
728  else
729  {
730  //Failed to allocate memory
731  error = ERROR_OUT_OF_MEMORY;
732  }
733  }
734  else if(pemDecodeFile(input, length, "PRIVATE KEY", NULL, &n, NULL,
735  NULL) == NO_ERROR)
736  {
737  //Allocate a memory buffer to hold the ASN.1 data
738  buffer = cryptoAllocMem(n);
739 
740  //Successful memory allocation?
741  if(buffer != NULL)
742  {
743  //Decode the content of the PEM container
744  error = pemDecodeFile(input, length, "PRIVATE KEY", buffer, &n,
745  NULL, NULL);
746 
747  //Check status code
748  if(!error)
749  {
750  //Read the PrivateKeyInfo structure (refer to RFC 5208, section 5)
751  error = pkcs8ParsePrivateKeyInfo(buffer, n, &privateKeyInfo);
752  }
753 
754  //Check status code
755  if(!error)
756  {
757  //Import the DSA private key
758  error = pkcs8ImportDsaPrivateKey(privateKey, &privateKeyInfo);
759  }
760 
761  //Release previously allocated memory
762  cryptoFreeMem(buffer);
763  }
764  else
765  {
766  //Failed to allocate memory
767  error = ERROR_OUT_OF_MEMORY;
768  }
769  }
770  else if(pemDecodeFile(input, length, "ENCRYPTED PRIVATE KEY", NULL, &n, NULL,
771  NULL) == NO_ERROR)
772  {
773 #if (PEM_ENCRYPTED_KEY_SUPPORT == ENABLED)
774  //Allocate a memory buffer to hold the ASN.1 data
775  buffer = cryptoAllocMem(n);
776 
777  //Successful memory allocation?
778  if(buffer != NULL)
779  {
780  uint8_t *data;
781  Pkcs8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo;
782 
783  //Decode the content of the PEM container
784  error = pemDecodeFile(input, length, "ENCRYPTED PRIVATE KEY", buffer,
785  &n, NULL, NULL);
786 
787  //Check status code
788  if(!error)
789  {
790  //Read the EncryptedPrivateKeyInfo structure (refer to RFC 5208,
791  //section 6)
792  error = pkcs8ParseEncryptedPrivateKeyInfo(buffer, n,
793  &encryptedPrivateKeyInfo);
794  }
795 
796  //Check status code
797  if(!error)
798  {
799  //Point to the encrypted data
800  data = (uint8_t *) encryptedPrivateKeyInfo.encryptedData.value;
801  n = encryptedPrivateKeyInfo.encryptedData.length;
802 
803  //Decrypt the private key information
804  error = pkcs5Decrypt(&encryptedPrivateKeyInfo.encryptionAlgo,
805  password, data, n, data, &n);
806  }
807 
808  //Check status code
809  if(!error)
810  {
811  //Read the PrivateKeyInfo structure (refer to RFC 5208, section 5)
812  error = pkcs8ParsePrivateKeyInfo(data, n, &privateKeyInfo);
813  }
814 
815  //Check status code
816  if(!error)
817  {
818  //Import the DSA private key
819  error = pkcs8ImportDsaPrivateKey(privateKey, &privateKeyInfo);
820  }
821 
822  //Release previously allocated memory
823  cryptoFreeMem(buffer);
824  }
825  else
826  {
827  //Failed to allocate memory
828  error = ERROR_OUT_OF_MEMORY;
829  }
830 #else
831  //The PEM file contains an encrypted private key
832  error = ERROR_DECRYPTION_FAILED;
833 #endif
834  }
835  else
836  {
837  //The PEM file does not contain a valid private key
838  error = ERROR_END_OF_FILE;
839  }
840 
841  //Any error to report?
842  if(error)
843  {
844  //Clean up side effects
845  dsaFreePrivateKey(privateKey);
846  }
847 
848  //Return status code
849  return error;
850 #else
851  //Not implemented
852  return ERROR_NOT_IMPLEMENTED;
853 #endif
854 }
855 
856 
857 /**
858  * @brief Decode a PEM file containing an EC public key
859  * @param[out] publicKey EC public key resulting from the parsing process
860  * @param[in] input Pointer to the PEM encoding
861  * @param[in] length Length of the PEM encoding
862  * @return Error code
863  **/
864 
866  size_t length)
867 {
868 #if (EC_SUPPORT == ENABLED)
869  error_t error;
870  size_t n;
871  uint8_t *buffer;
872  X509SubjectPublicKeyInfo publicKeyInfo;
873 
874  //Check parameters
875  if(publicKey == NULL || input == NULL)
877 
878  //Public keys are encoded using the "PUBLIC KEY" label
879  error = pemDecodeFile(input, length, "PUBLIC KEY", NULL, &n, NULL, NULL);
880 
881  //Check status code
882  if(!error)
883  {
884  //Allocate a memory buffer to hold the ASN.1 data
885  buffer = cryptoAllocMem(n);
886 
887  //Successful memory allocation?
888  if(buffer != NULL)
889  {
890  //Decode the content of the PEM container
891  error = pemDecodeFile(input, length, "PUBLIC KEY", buffer, &n, NULL,
892  NULL);
893 
894  //Check status code
895  if(!error)
896  {
897  //The ASN.1 encoded data of the public key is the SubjectPublicKeyInfo
898  //structure (refer to RFC 7468, section 13)
899  error = x509ParseSubjectPublicKeyInfo(buffer, n, &n, &publicKeyInfo);
900  }
901 
902  //Check status code
903  if(!error)
904  {
905  //Import the EC public key
906  error = x509ImportEcPublicKey(publicKey, &publicKeyInfo);
907  }
908 
909  //Release previously allocated memory
910  cryptoFreeMem(buffer);
911  }
912  else
913  {
914  //Failed to allocate memory
915  error = ERROR_OUT_OF_MEMORY;
916  }
917  }
918 
919  //Any error to report?
920  if(error)
921  {
922  //Clean up side effects
923  ecFreePublicKey(publicKey);
924  }
925 
926  //Return status code
927  return error;
928 #else
929  //Not implemented
930  return ERROR_NOT_IMPLEMENTED;
931 #endif
932 }
933 
934 
935 /**
936  * @brief Decode a PEM file containing an EC private key
937  * @param[out] privateKey EC private key resulting from the parsing process
938  * @param[in] input Pointer to the PEM encoding
939  * @param[in] length Length of the PEM encoding
940  * @param[in] password NULL-terminated string containing the password. This
941  * parameter is required if the private key is encrypted
942  * @return Error code
943  **/
944 
946  size_t length, const char_t *password)
947 {
948 #if (EC_SUPPORT == ENABLED)
949  error_t error;
950  size_t n;
951  uint8_t *buffer;
952  PemHeader header;
953  Pkcs8PrivateKeyInfo privateKeyInfo;
954 
955  //Check parameters
956  if(privateKey == NULL || input == NULL)
958 
959  //Clear the PrivateKeyInfo structure
960  osMemset(&privateKeyInfo, 0, sizeof(Pkcs8PrivateKeyInfo));
961 
962  //The type of data encoded is labeled depending on the type label in
963  //the "-----BEGIN " line (refer to RFC 7468, section 2)
964  if(pemDecodeFile(input, length, "EC PRIVATE KEY", NULL, &n, NULL,
965  NULL) == NO_ERROR)
966  {
967  //Allocate a memory buffer to hold the ASN.1 data
968  buffer = cryptoAllocMem(n);
969 
970  //Successful memory allocation?
971  if(buffer != NULL)
972  {
973  //Decode the content of the PEM container
974  error = pemDecodeFile(input, length, "EC PRIVATE KEY", buffer, &n,
975  &header, NULL);
976 
977  //Check status code
978  if(!error)
979  {
980  //Check whether the PEM file is encrypted
981  if(pemCompareString(&header.procType.type, "ENCRYPTED"))
982  {
983  //Perform decryption
984  error = pemDecryptMessage(&header, password, buffer, n,
985  buffer, &n);
986  }
987  }
988 
989  //Check status code
990  if(!error)
991  {
992  //Read ECPrivateKey structure
993  error = pkcs8ParseEcPrivateKey(buffer, n, &privateKeyInfo.ecParams,
994  &privateKeyInfo.ecPrivateKey, &privateKeyInfo.ecPublicKey);
995  }
996 
997  //Check status code
998  if(!error)
999  {
1000  //Set public key algorithm identifier
1001  privateKeyInfo.oid.value = EC_PUBLIC_KEY_OID;
1002  privateKeyInfo.oid.length = sizeof(EC_PUBLIC_KEY_OID);
1003 
1004  //Import the EC private key
1005  error = pkcs8ImportEcPrivateKey(privateKey, &privateKeyInfo);
1006  }
1007 
1008  //Release previously allocated memory
1009  cryptoFreeMem(buffer);
1010  }
1011  else
1012  {
1013  //Failed to allocate memory
1014  error = ERROR_OUT_OF_MEMORY;
1015  }
1016  }
1017  else if(pemDecodeFile(input, length, "PRIVATE KEY", NULL, &n, NULL,
1018  NULL) == NO_ERROR)
1019  {
1020  //Allocate a memory buffer to hold the ASN.1 data
1021  buffer = cryptoAllocMem(n);
1022 
1023  //Successful memory allocation?
1024  if(buffer != NULL)
1025  {
1026  //Decode the content of the PEM container
1027  error = pemDecodeFile(input, length, "PRIVATE KEY", buffer, &n,
1028  NULL, NULL);
1029 
1030  //Check status code
1031  if(!error)
1032  {
1033  //Read the PrivateKeyInfo structure (refer to RFC 5208, section 5)
1034  error = pkcs8ParsePrivateKeyInfo(buffer, n, &privateKeyInfo);
1035  }
1036 
1037  //Check status code
1038  if(!error)
1039  {
1040  //Import the EC private key
1041  error = pkcs8ImportEcPrivateKey(privateKey, &privateKeyInfo);
1042  }
1043 
1044  //Release previously allocated memory
1045  cryptoFreeMem(buffer);
1046  }
1047  else
1048  {
1049  //Failed to allocate memory
1050  error = ERROR_OUT_OF_MEMORY;
1051  }
1052  }
1053  else if(pemDecodeFile(input, length, "ENCRYPTED PRIVATE KEY", NULL, &n, NULL,
1054  NULL) == NO_ERROR)
1055  {
1056 #if (PEM_ENCRYPTED_KEY_SUPPORT == ENABLED)
1057  //Allocate a memory buffer to hold the ASN.1 data
1058  buffer = cryptoAllocMem(n);
1059 
1060  //Successful memory allocation?
1061  if(buffer != NULL)
1062  {
1063  uint8_t *data;
1064  Pkcs8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo;
1065 
1066  //Decode the content of the PEM container
1067  error = pemDecodeFile(input, length, "ENCRYPTED PRIVATE KEY", buffer, &n,
1068  NULL, NULL);
1069 
1070  //Check status code
1071  if(!error)
1072  {
1073  //Read the EncryptedPrivateKeyInfo structure (refer to RFC 5208,
1074  //section 6)
1075  error = pkcs8ParseEncryptedPrivateKeyInfo(buffer, n,
1076  &encryptedPrivateKeyInfo);
1077  }
1078 
1079  //Check status code
1080  if(!error)
1081  {
1082  //Point to the encrypted data
1083  data = (uint8_t *) encryptedPrivateKeyInfo.encryptedData.value;
1084  n = encryptedPrivateKeyInfo.encryptedData.length;
1085 
1086  //Decrypt the private key information
1087  error = pkcs5Decrypt(&encryptedPrivateKeyInfo.encryptionAlgo,
1088  password, data, n, data, &n);
1089  }
1090 
1091  //Check status code
1092  if(!error)
1093  {
1094  //Read the PrivateKeyInfo structure (refer to RFC 5208, section 5)
1095  error = pkcs8ParsePrivateKeyInfo(data, n, &privateKeyInfo);
1096  }
1097 
1098  //Check status code
1099  if(!error)
1100  {
1101  //Import the EC private key
1102  error = pkcs8ImportEcPrivateKey(privateKey, &privateKeyInfo);
1103  }
1104 
1105  //Release previously allocated memory
1106  cryptoFreeMem(buffer);
1107  }
1108  else
1109  {
1110  //Failed to allocate memory
1111  error = ERROR_OUT_OF_MEMORY;
1112  }
1113 #else
1114  //The PEM file contains an encrypted private key
1115  error = ERROR_DECRYPTION_FAILED;
1116 #endif
1117  }
1118  else
1119  {
1120  //The PEM file does not contain a valid private key
1121  error = ERROR_END_OF_FILE;
1122  }
1123 
1124  //Any error to report?
1125  if(error)
1126  {
1127  //Clean up side effects
1128  ecFreePrivateKey(privateKey);
1129  }
1130 
1131  //Return status code
1132  return error;
1133 #else
1134  //Not implemented
1135  return ERROR_NOT_IMPLEMENTED;
1136 #endif
1137 }
1138 
1139 
1140 /**
1141  * @brief Decode a PEM file containing a EdDSA public key
1142  * @param[out] publicKey EdDSA public key resulting from the parsing process
1143  * @param[in] input Pointer to the PEM encoding
1144  * @param[in] length Length of the PEM encoding
1145  * @return Error code
1146  **/
1147 
1149  size_t length)
1150 {
1151 #if (ED25519_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
1152  error_t error;
1153  size_t n;
1154  uint8_t *buffer;
1155  X509SubjectPublicKeyInfo publicKeyInfo;
1156 
1157  //Check parameters
1158  if(publicKey == NULL || input == NULL)
1159  return ERROR_INVALID_PARAMETER;
1160 
1161  //Public keys are encoded using the "PUBLIC KEY" label
1162  error = pemDecodeFile(input, length, "PUBLIC KEY", NULL, &n, NULL, NULL);
1163 
1164  //Check status code
1165  if(!error)
1166  {
1167  //Allocate a memory buffer to hold the ASN.1 data
1168  buffer = cryptoAllocMem(n);
1169 
1170  //Successful memory allocation?
1171  if(buffer != NULL)
1172  {
1173  //Decode the content of the PEM container
1174  error = pemDecodeFile(input, length, "PUBLIC KEY", buffer, &n, NULL,
1175  NULL);
1176 
1177  //Check status code
1178  if(!error)
1179  {
1180  //The ASN.1 encoded data of the public key is the SubjectPublicKeyInfo
1181  //structure (refer to RFC 7468, section 13)
1182  error = x509ParseSubjectPublicKeyInfo(buffer, n, &n, &publicKeyInfo);
1183  }
1184 
1185  //Check status code
1186  if(!error)
1187  {
1188  //Import the EdDSA public key
1189  error = x509ImportEddsaPublicKey(publicKey, &publicKeyInfo);
1190  }
1191 
1192  //Release previously allocated memory
1193  cryptoFreeMem(buffer);
1194  }
1195  else
1196  {
1197  //Failed to allocate memory
1198  error = ERROR_OUT_OF_MEMORY;
1199  }
1200  }
1201 
1202  //Any error to report?
1203  if(error)
1204  {
1205  //Clean up side effects
1206  eddsaFreePublicKey(publicKey);
1207  }
1208 
1209  //Return status code
1210  return error;
1211 #else
1212  //Not implemented
1213  return ERROR_NOT_IMPLEMENTED;
1214 #endif
1215 }
1216 
1217 
1218 /**
1219  * @brief Decode a PEM file containing a EdDSA private key
1220  * @param[out] privateKey EdDSA private key resulting from the parsing process
1221  * @param[in] input Pointer to the PEM encoding
1222  * @param[in] length Length of the PEM encoding
1223  * @param[in] password NULL-terminated string containing the password. This
1224  * parameter is required if the private key is encrypted
1225  * @return Error code
1226  **/
1227 
1229  const char_t *input, size_t length, const char_t *password)
1230 {
1231 #if (ED25519_SUPPORT == ENABLED || ED448_SUPPORT == ENABLED)
1232  error_t error;
1233  size_t n;
1234  uint8_t *buffer;
1235  Pkcs8PrivateKeyInfo privateKeyInfo;
1236 
1237  //Check parameters
1238  if(privateKey == NULL || input == NULL)
1239  return ERROR_INVALID_PARAMETER;
1240 
1241  //The type of data encoded is labeled depending on the type label in
1242  //the "-----BEGIN " line (refer to RFC 7468, section 2)
1243  if(pemDecodeFile(input, length, "PRIVATE KEY", NULL, &n, NULL,
1244  NULL) == NO_ERROR)
1245  {
1246  //Allocate a memory buffer to hold the ASN.1 data
1247  buffer = cryptoAllocMem(n);
1248 
1249  //Successful memory allocation?
1250  if(buffer != NULL)
1251  {
1252  //Decode the content of the PEM container
1253  error = pemDecodeFile(input, length, "PRIVATE KEY", buffer, &n,
1254  NULL, NULL);
1255 
1256  //Check status code
1257  if(!error)
1258  {
1259  //Read the PrivateKeyInfo structure (refer to RFC 5208, section 5)
1260  error = pkcs8ParsePrivateKeyInfo(buffer, n, &privateKeyInfo);
1261  }
1262 
1263  //Check status code
1264  if(!error)
1265  {
1266  //Import the EdDSA private key
1267  error = pkcs8ImportEddsaPrivateKey(privateKey, &privateKeyInfo);
1268  }
1269 
1270  //Release previously allocated memory
1271  cryptoFreeMem(buffer);
1272  }
1273  else
1274  {
1275  //Failed to allocate memory
1276  error = ERROR_OUT_OF_MEMORY;
1277  }
1278  }
1279  else if(pemDecodeFile(input, length, "ENCRYPTED PRIVATE KEY", NULL, &n, NULL,
1280  NULL) == NO_ERROR)
1281  {
1282 #if (PEM_ENCRYPTED_KEY_SUPPORT == ENABLED)
1283  //Allocate a memory buffer to hold the ASN.1 data
1284  buffer = cryptoAllocMem(n);
1285 
1286  //Successful memory allocation?
1287  if(buffer != NULL)
1288  {
1289  uint8_t *data;
1290  Pkcs8EncryptedPrivateKeyInfo encryptedPrivateKeyInfo;
1291 
1292  //Decode the content of the PEM container
1293  error = pemDecodeFile(input, length, "ENCRYPTED PRIVATE KEY", buffer, &n,
1294  NULL, NULL);
1295 
1296  //Check status code
1297  if(!error)
1298  {
1299  //Read the EncryptedPrivateKeyInfo structure (refer to RFC 5208,
1300  //section 6)
1301  error = pkcs8ParseEncryptedPrivateKeyInfo(buffer, n,
1302  &encryptedPrivateKeyInfo);
1303  }
1304 
1305  //Check status code
1306  if(!error)
1307  {
1308  //Point to the encrypted data
1309  data = (uint8_t *) encryptedPrivateKeyInfo.encryptedData.value;
1310  n = encryptedPrivateKeyInfo.encryptedData.length;
1311 
1312  //Decrypt the private key information
1313  error = pkcs5Decrypt(&encryptedPrivateKeyInfo.encryptionAlgo,
1314  password, data, n, data, &n);
1315  }
1316 
1317  //Check status code
1318  if(!error)
1319  {
1320  //Read the PrivateKeyInfo structure (refer to RFC 5208, section 5)
1321  error = pkcs8ParsePrivateKeyInfo(data, n, &privateKeyInfo);
1322  }
1323 
1324  //Check status code
1325  if(!error)
1326  {
1327  //Import the EdDSA private key
1328  error = pkcs8ImportEddsaPrivateKey(privateKey, &privateKeyInfo);
1329  }
1330 
1331  //Release previously allocated memory
1332  cryptoFreeMem(buffer);
1333  }
1334  else
1335  {
1336  //Failed to allocate memory
1337  error = ERROR_OUT_OF_MEMORY;
1338  }
1339 #else
1340  //The PEM file contains an encrypted private key
1341  error = ERROR_DECRYPTION_FAILED;
1342 #endif
1343  }
1344  else
1345  {
1346  //The PEM file does not contain a valid private key
1347  error = ERROR_END_OF_FILE;
1348  }
1349 
1350  //Any error to report?
1351  if(error)
1352  {
1353  //Clean up side effects
1354  eddsaFreePrivateKey(privateKey);
1355  }
1356 
1357  //Return status code
1358  return error;
1359 #else
1360  //Not implemented
1361  return ERROR_NOT_IMPLEMENTED;
1362 #endif
1363 }
1364 
1365 
1366 /**
1367  * @brief Extract the public key type from a PEM file
1368  * @param[in] input Pointer to the PEM encoding
1369  * @param[in] length Length of the PEM encoding
1370  * @return Public key type
1371  **/
1372 
1374 {
1375  error_t error;
1376  size_t n;
1377  uint8_t *buffer;
1378  X509KeyType keyType;
1379  X509SubjectPublicKeyInfo publicKeyInfo;
1380 
1381  //Initialize variable
1382  keyType = X509_KEY_TYPE_UNKNOWN;
1383 
1384 #if (RSA_SUPPORT == ENABLED)
1385  //PEM container with "RSA PUBLIC KEY" label?
1386  if(pemDecodeFile(input, length, "RSA PUBLIC KEY", NULL, &n, NULL,
1387  NULL) == NO_ERROR)
1388  {
1389  //The PEM file contains an RSA public key (PKCS #1 format)
1390  keyType = X509_KEY_TYPE_RSA;
1391  }
1392  else
1393 #endif
1394  //PEM container with "PUBLIC KEY" label?
1395  if(pemDecodeFile(input, length, "PUBLIC KEY", NULL, &n, NULL,
1396  NULL) == NO_ERROR)
1397  {
1398  //Allocate a memory buffer to hold the ASN.1 data
1399  buffer = cryptoAllocMem(n);
1400 
1401  //Successful memory allocation?
1402  if(buffer != NULL)
1403  {
1404  //Decode the content of the PEM container
1405  error = pemDecodeFile(input, length, "PUBLIC KEY", buffer, &n,
1406  NULL, NULL);
1407 
1408  //Check status code
1409  if(!error)
1410  {
1411  //The ASN.1 encoded data of the public key is the SubjectPublicKeyInfo
1412  //structure (refer to RFC 7468, section 13)
1413  error = x509ParseSubjectPublicKeyInfo(buffer, n, &n, &publicKeyInfo);
1414  }
1415 
1416  //Check status code
1417  if(!error)
1418  {
1419  //Check public key algorithm identifier
1420  keyType = x509GetPublicKeyType(publicKeyInfo.oid.value,
1421  publicKeyInfo.oid.length);
1422 
1423 #if (EC_SUPPORT == ENABLED)
1424  //EC public key identifier?
1425  if(keyType == X509_KEY_TYPE_EC)
1426  {
1427  //SM2 elliptic curve?
1428  if(OID_COMP(publicKeyInfo.ecParams.namedCurve.value,
1429  publicKeyInfo.ecParams.namedCurve.length, SM2_OID) == 0)
1430  {
1431  //The PEM file contains an SM2 public key
1432  keyType = X509_KEY_TYPE_SM2;
1433  }
1434  }
1435 #endif
1436  }
1437 
1438  //Release previously allocated memory
1439  cryptoFreeMem(buffer);
1440  }
1441  }
1442 
1443  //Return the public key type
1444  return keyType;
1445 }
1446 
1447 
1448 /**
1449  * @brief Extract elliptic curve parameters from a PEM file
1450  * @param[in] input Pointer to the PEM encoding
1451  * @param[in] length Length of the PEM encoding
1452  * @return Elliptic curve parameters
1453  **/
1454 
1455 const EcCurve *pemGetPublicKeyCurve(const char_t *input, size_t length)
1456 {
1457 #if (EC_SUPPORT == ENABLED)
1458  error_t error;
1459  size_t n;
1460  uint8_t *buffer;
1461  const EcCurve *curve;
1462 
1463  //Initialize variable
1464  curve = NULL;
1465 
1466  //The type of data encoded is labeled depending on the type label in
1467  //the "-----BEGIN " line (refer to RFC 7468, section 2)
1468  if(pemDecodeFile(input, length, "EC PARAMETERS", NULL, &n, NULL,
1469  NULL) == NO_ERROR)
1470  {
1471  X509EcParameters ecParams;
1472 
1473  //Allocate a memory buffer to hold the ASN.1 data
1474  buffer = cryptoAllocMem(n);
1475 
1476  //Successful memory allocation?
1477  if(buffer != NULL)
1478  {
1479  //Decode the content of the PEM container
1480  error = pemDecodeFile(input, length, "EC PARAMETERS", buffer, &n,
1481  NULL, NULL);
1482 
1483  //Check status code
1484  if(!error)
1485  {
1486  //Parse ECParameters structure
1487  error = x509ParseEcParameters(buffer, n, &ecParams);
1488  }
1489 
1490  //Check status code
1491  if(!error)
1492  {
1493  //Get the elliptic curve that matches the OID
1494  curve = ecGetCurve(ecParams.namedCurve.value,
1495  ecParams.namedCurve.length);
1496  }
1497 
1498  //Release previously allocated memory
1499  cryptoFreeMem(buffer);
1500  }
1501  }
1502  else if(pemDecodeFile(input, length, "PUBLIC KEY", NULL, &n, NULL,
1503  NULL) == NO_ERROR)
1504  {
1505  X509SubjectPublicKeyInfo publicKeyInfo;
1506 
1507  //Allocate a memory buffer to hold the ASN.1 data
1508  buffer = cryptoAllocMem(n);
1509 
1510  //Successful memory allocation?
1511  if(buffer != NULL)
1512  {
1513  //Decode the content of the PEM container
1514  error = pemDecodeFile(input, length, "PUBLIC KEY", buffer, &n,
1515  NULL, NULL);
1516 
1517  //Check status code
1518  if(!error)
1519  {
1520  //The ASN.1 encoded data of the public key is the SubjectPublicKeyInfo
1521  //structure (refer to RFC 7468, section 13)
1522  error = x509ParseSubjectPublicKeyInfo(buffer, n, &n, &publicKeyInfo);
1523  }
1524 
1525  //Check status code
1526  if(!error)
1527  {
1528  //Get the elliptic curve that matches the OID
1529  curve = ecGetCurve(publicKeyInfo.ecParams.namedCurve.value,
1530  publicKeyInfo.ecParams.namedCurve.length);
1531  }
1532 
1533  //Release previously allocated memory
1534  cryptoFreeMem(buffer);
1535  }
1536  }
1537 
1538  //Return the elliptic curve parameters, if any
1539  return curve;
1540 #else
1541  //Not implemented
1542  return NULL;
1543 #endif
1544 }
1545 
1546 #endif
error_t pkcs8ParsePrivateKeyInfo(const uint8_t *data, size_t length, Pkcs8PrivateKeyInfo *privateKeyInfo)
Parse PrivateKeyInfo structure.
@ X509_KEY_TYPE_RSA
Definition: x509_common.h:635
Pkcs8RsaPrivateKey rsaPrivateKey
error_t x509ImportEcPublicKey(EcPublicKey *publicKey, const X509SubjectPublicKeyInfo *publicKeyInfo)
Import an EC public key.
Private key information.
void rsaFreePublicKey(RsaPublicKey *key)
Release an RSA public key.
Definition: rsa.c:113
error_t pemImportEddsaPrivateKey(EddsaPrivateKey *privateKey, const char_t *input, size_t length, const char_t *password)
Decode a PEM file containing a EdDSA private key.
Definition: pem_import.c:1228
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
@ ERROR_DECRYPTION_FAILED
Definition: error.h:243
error_t x509ParseSubjectPublicKeyInfo(const uint8_t *data, size_t length, size_t *totalLength, X509SubjectPublicKeyInfo *publicKeyInfo)
Parse SubjectPublicKeyInfo structure.
OID (Object Identifier)
void eddsaFreePrivateKey(EddsaPrivateKey *key)
Release an EdDSA private key.
Definition: eddsa.c:95
uint8_t p
Definition: ndp.h:300
X509OctetString oid
Definition: x509_common.h:840
error_t pemDecodeFile(const char_t *input, size_t inputLen, const char_t *label, uint8_t *output, size_t *outputLen, PemHeader *header, size_t *consumed)
Convert PEM container to ASN.1 format.
Definition: pem_common.c:58
void dsaFreePrivateKey(DsaPrivateKey *key)
Release a DSA private key.
Definition: dsa.c:152
error_t pemImportRsaPrivateKey(RsaPrivateKey *privateKey, const char_t *input, size_t length, const char_t *password)
Decode a PEM file containing an RSA private key.
Definition: pem_import.c:379
uint8_t data[]
Definition: ethernet.h:222
const uint8_t EC_PUBLIC_KEY_OID[7]
Definition: ec.c:44
Encrypted private key information.
X509EcParameters ecParams
Definition: x509_common.h:850
X509DsaPublicKey dsaPublicKey
error_t x509ParseRsaPublicKey(const uint8_t *data, size_t length, X509RsaPublicKey *rsaPublicKey)
Parse RSAPublicKey structure.
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
error_t pkcs8ImportDsaPrivateKey(DsaPrivateKey *privateKey, const Pkcs8PrivateKeyInfo *privateKeyInfo)
Import a DSA private key.
error_t x509ImportDsaPublicKey(DsaPublicKey *publicKey, const X509SubjectPublicKeyInfo *publicKeyInfo)
Import a DSA public key.
error_t pemImportDsaPublicKey(DsaPublicKey *publicKey, const char_t *input, size_t length)
Decode a PEM file containing a DSA public key.
Definition: pem_import.c:582
bool_t pemCompareString(const PemString *string, const char_t *value)
Compare a string against the supplied value.
Definition: pem_common.c:418
error_t pemImportDhParameters(DhParameters *params, const char_t *input, size_t length)
Decode a PEM file containing Diffie-Hellman parameters.
Definition: pem_import.c:143
PEM encapsulated header.
Definition: pem_common.h:130
const uint8_t DSA_OID[7]
Definition: dsa.c:51
error_t pemImportDsaPrivateKey(DsaPrivateKey *privateKey, const char_t *input, size_t length, const char_t *password)
Decode a PEM file containing a DSA private key.
Definition: pem_import.c:662
size_t totalLength
Definition: asn1.h:108
size_t length
Definition: asn1.h:106
@ X509_KEY_TYPE_EC
Definition: x509_common.h:638
Pkcs8EcPrivateKey ecPrivateKey
error_t pemImportCertificate(const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen, size_t *consumed)
Decode a PEM file containing a certificate.
Definition: pem_import.c:61
PEM file import functions.
DSA public key.
Definition: dsa.h:61
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
@ X509_KEY_TYPE_SM2
Definition: x509_common.h:639
error_t
Error codes.
Definition: error.h:43
EC parameters.
Definition: x509_common.h:818
void rsaFreePrivateKey(RsaPrivateKey *key)
Release an RSA private key.
Definition: rsa.c:148
EdDSA public key.
Definition: eddsa.h:64
error_t pkcs8ImportRsaPrivateKey(RsaPrivateKey *privateKey, const Pkcs8PrivateKeyInfo *privateKeyInfo)
Import an RSA private key.
ASN.1 tag.
Definition: asn1.h:102
error_t pemDecryptMessage(const PemHeader *header, const char_t *password, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *plaintext, size_t *plaintextLen)
PEM message decryption.
Definition: pem_decrypt.c:361
RSA public key.
Definition: rsa.h:57
X509RsaPublicKey rsaPublicKey
Definition: x509_common.h:843
X509EcPublicKey ecPublicKey
X509DsaParameters dsaParams
error_t x509ImportEddsaPublicKey(EddsaPublicKey *publicKey, const X509SubjectPublicKeyInfo *publicKeyInfo)
Import an EdDSA public key.
error_t pemImportEcPrivateKey(EcPrivateKey *privateKey, const char_t *input, size_t length, const char_t *password)
Decode a PEM file containing an EC private key.
Definition: pem_import.c:945
MPI (Multiple Precision Integer Arithmetic)
Mpi p
Prime modulus.
Definition: dh.h:50
@ ERROR_END_OF_FILE
Definition: error.h:160
General definitions for cryptographic algorithms.
EC private key.
Definition: ec.h:432
DSA private key.
Definition: dsa.h:72
void ecFreePrivateKey(EcPrivateKey *key)
Release an EC private key.
Definition: ec.c:100
uint8_t length
Definition: tcp.h:375
error_t pkcs8ParseRsaPrivateKey(const uint8_t *data, size_t length, Pkcs8RsaPrivateKey *rsaPrivateKey)
Parse RSAPrivateKey structure.
PemString type
Definition: pem_common.h:110
error_t pkcs8ParseDsaPrivateKey(const uint8_t *data, size_t length, X509DsaParameters *dsaParams, Pkcs8DsaPrivateKey *dsaPrivateKey, X509DsaPublicKey *dsaPublicKey)
Parse DSAPrivateKey structure.
PEM file decryption.
X509OctetString namedCurve
Definition: x509_common.h:819
X509KeyType pemGetPublicKeyType(const char_t *input, size_t length)
Extract the public key type from a PEM file.
Definition: pem_import.c:1373
EdDSA private key.
Definition: eddsa.h:75
const uint8_t RSA_ENCRYPTION_OID[9]
Definition: rsa.c:54
error_t pemImportRsaPublicKey(RsaPublicKey *publicKey, const char_t *input, size_t length)
Decode a PEM file containing an RSA public key.
Definition: pem_import.c:252
EC public key.
Definition: ec.h:421
#define TRACE_DEBUG(...)
Definition: debug.h:119
char char_t
Definition: compiler_port.h:55
error_t pkcs8ImportEddsaPrivateKey(EddsaPrivateKey *privateKey, const Pkcs8PrivateKeyInfo *privateKeyInfo)
Import an EdDSA private key.
error_t pkcs8ImportEcPrivateKey(EcPrivateKey *privateKey, const Pkcs8PrivateKeyInfo *privateKeyInfo)
Import an EC private key.
error_t pkcs5Decrypt(const X509AlgoId *encryptionAlgoId, const char_t *password, const uint8_t *ciphertext, size_t ciphertextLen, uint8_t *plaintext, size_t *plaintextLen)
PKCS #5 decryption operation.
Definition: pkcs5_decrypt.c:61
#define OID_COMP(oid1, oidLen1, oid2)
Definition: oid.h:42
error_t x509ImportRsaPublicKey(RsaPublicKey *publicKey, const X509SubjectPublicKeyInfo *publicKeyInfo)
Import an RSA public key.
uint8_t n
RSA private key.
Definition: rsa.h:68
Subject Public Key Information extension.
Definition: x509_common.h:838
error_t pkcs8ParseEncryptedPrivateKeyInfo(const uint8_t *data, size_t length, Pkcs8EncryptedPrivateKeyInfo *encryptedPrivateKeyInfo)
Parse EncryptedPrivateKeyInfo structure.
error_t pemImportEcPublicKey(EcPublicKey *publicKey, const char_t *input, size_t length)
Decode a PEM file containing an EC public key.
Definition: pem_import.c:865
const EcCurve * pemGetPublicKeyCurve(const char_t *input, size_t length)
Extract elliptic curve parameters from a PEM file.
Definition: pem_import.c:1455
error_t asn1ReadMpi(const uint8_t *data, size_t length, Asn1Tag *tag, Mpi *value)
Read a multiple-precision integer from the input stream.
Definition: asn1.c:703
#define cryptoFreeMem(p)
Definition: crypto.h:826
PKCS #8 key parsing.
#define cryptoAllocMem(size)
Definition: crypto.h:821
void eddsaFreePublicKey(EddsaPublicKey *key)
Release an EdDSA public key.
Definition: eddsa.c:63
error_t x509ParseEcParameters(const uint8_t *data, size_t length, X509EcParameters *ecParams)
Parse ECParameters structure.
const EcCurve * ecGetCurve(const uint8_t *oid, size_t length)
Get the elliptic curve that matches the specified OID.
Definition: ec_curves.c:5888
PemProcType procType
Definition: pem_common.h:131
Mpi g
Generator.
Definition: dh.h:51
const uint8_t * value
Definition: x509_common.h:702
@ X509_KEY_TYPE_UNKNOWN
Definition: x509_common.h:634
#define EcCurve
Definition: ec.h:346
Parsing of ASN.1 encoded keys.
Pkcs8DsaPrivateKey dsaPrivateKey
Diffie-Hellman parameters.
Definition: dh.h:49
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:122
#define osMemset(p, value, length)
Definition: os_port.h:138
PKCS #5 decryption routines.
X509KeyType
Public Key types.
Definition: x509_common.h:633
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 pemImportCrl(const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen, size_t *consumed)
Decode a PEM file containing a certificate revocation list.
Definition: pem_import.c:90
X509EcParameters ecParams
X509KeyType x509GetPublicKeyType(const uint8_t *oid, size_t length)
Get the public key type that matches the specified OID.
Definition: x509_common.c:804
error_t pemImportCsr(const char_t *input, size_t inputLen, uint8_t *output, size_t *outputLen)
Decode a PEM file containing a certification signing request.
Definition: pem_import.c:117
X509OctetString oid
error_t pkcs8ParseEcPrivateKey(const uint8_t *data, size_t length, X509EcParameters *ecParams, Pkcs8EcPrivateKey *ecPrivateKey, X509EcPublicKey *ecPublicKey)
Parse ECPrivateKey structure.
void dsaFreePublicKey(DsaPublicKey *key)
Release a DSA public key.
Definition: dsa.c:119
const uint8_t * value
Definition: asn1.h:107
@ NO_ERROR
Success.
Definition: error.h:44
Debugging facilities.
error_t pemImportEddsaPublicKey(EddsaPublicKey *publicKey, const char_t *input, size_t length)
Decode a PEM file containing a EdDSA public key.
Definition: pem_import.c:1148
void ecFreePublicKey(EcPublicKey *key)
Release an EC public key.
Definition: ec.c:68
ASN.1 (Abstract Syntax Notation One)
const uint8_t SM2_OID[8]
Definition: ec_curves.c:106
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64