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.2
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 "encoding/asn1.h"
38 #include "debug.h"
39 
40 //Check crypto library configuration
41 #if (PEM_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Decode a PEM file containing a certificate
46  * @param[in] input Pointer to the PEM string
47  * @param[in] inputLen Length of the PEM string
48  * @param[out] output Pointer to the DER-encoded certificate
49  * @param[out] outputLen Length of the DER-encoded certificate, in bytes
50  * @param[out] consumed Total number of characters that have been consumed
51  * (optional parameter)
52  * @return Error code
53  **/
54 
55 error_t pemImportCertificate(const char_t *input, size_t inputLen,
56  uint8_t *output, size_t *outputLen, size_t *consumed)
57 {
58  error_t error;
59 
60  //Check parameters
61  if(input == NULL || outputLen == NULL)
63 
64  //X.509 certificates are encoded using the "CERTIFICATE" label
65  error = pemDecodeFile(input, inputLen, "CERTIFICATE", output, outputLen,
66  NULL, consumed);
67 
68  //Return status code
69  return error;
70 }
71 
72 
73 /**
74  * @brief Decode a PEM file containing a certificate revocation list
75  * @param[in] input Pointer to the PEM string
76  * @param[in] inputLen Length of the PEM string
77  * @param[out] output Pointer to the DER-encoded CRL
78  * @param[out] outputLen Length of the DER-encoded CRL, in bytes
79  * @param[out] consumed Total number of characters that have been consumed
80  * (optional parameter)
81  * @return Error code
82  **/
83 
84 error_t pemImportCrl(const char_t *input, size_t inputLen,
85  uint8_t *output, size_t *outputLen, size_t *consumed)
86 {
87  error_t error;
88 
89  //Check parameters
90  if(input == NULL || outputLen == NULL)
92 
93  //CRLs are encoded using the "X509 CRL" label
94  error = pemDecodeFile(input, inputLen, "X509 CRL", output, outputLen,
95  NULL, consumed);
96 
97  //Return status code
98  return error;
99 }
100 
101 
102 /**
103  * @brief Decode a PEM file containing a certification signing request
104  * @param[in] input Pointer to the PEM string
105  * @param[in] inputLen Length of the PEM string
106  * @param[out] output Pointer to the DER-encoded CSR
107  * @param[out] outputLen Length of the DER-encoded CSR, in bytes
108  * @return Error code
109  **/
110 
111 error_t pemImportCsr(const char_t *input, size_t inputLen,
112  uint8_t *output, size_t *outputLen)
113 {
114  error_t error;
115 
116  //Check parameters
117  if(input == NULL || outputLen == NULL)
119 
120  //CSRs are encoded using the "CERTIFICATE REQUEST" label
121  error = pemDecodeFile(input, inputLen, "CERTIFICATE REQUEST", output,
122  outputLen, NULL, NULL);
123 
124  //Return status code
125  return error;
126 }
127 
128 
129 /**
130  * @brief Decode a PEM file containing Diffie-Hellman parameters
131  * @param[out] params Diffie-Hellman parameters resulting from the parsing process
132  * @param[in] input Pointer to the PEM string
133  * @param[in] length Length of the PEM string
134  * @return Error code
135  **/
136 
138  size_t length)
139 {
140 #if (DH_SUPPORT == ENABLED)
141  error_t error;
142  size_t n;
143  uint8_t *buffer;
144  const uint8_t *p;
145  Asn1Tag tag;
146 
147  //Check parameters
148  if(params == NULL || input == NULL)
150 
151  //Initialize variables
152  p = NULL;
153  n = 0;
154 
155  //Diffie-Hellman parameters are encoded using the "DH PARAMETERS" label
156  error = pemDecodeFile(input, length, "DH PARAMETERS", NULL, &n, NULL, NULL);
157 
158  //Check status code
159  if(!error)
160  {
161  //Allocate a memory buffer to hold the ASN.1 data
162  buffer = cryptoAllocMem(n);
163 
164  //Successful memory allocation?
165  if(buffer != NULL)
166  {
167  //Decode the content of the PEM container
168  error = pemDecodeFile(input, length, "DH PARAMETERS", buffer, &n,
169  NULL, NULL);
170 
171  //Check status code
172  if(!error)
173  {
174  //The Diffie-Hellman parameters are encapsulated within a sequence
175  error = asn1ReadSequence(buffer, n, &tag);
176  }
177 
178  //Check status code
179  if(!error)
180  {
181  //Point to the first field of the sequence
182  p = tag.value;
183  n = tag.length;
184 
185  //Read the prime modulus
186  error = asn1ReadMpi(p, n, &tag, &params->p);
187  }
188 
189  //Check status code
190  if(!error)
191  {
192  //Point to the next field
193  p += tag.totalLength;
194  n -= tag.totalLength;
195 
196  //Read the generator
197  error = asn1ReadMpi(p, n, &tag, &params->g);
198  }
199 
200  //Check status code
201  if(!error)
202  {
203  //Debug message
204  TRACE_DEBUG("Diffie-Hellman parameters:\r\n");
205  TRACE_DEBUG(" Prime modulus:\r\n");
206  TRACE_DEBUG_MPI(" ", &params->p);
207  TRACE_DEBUG(" Generator:\r\n");
208  TRACE_DEBUG_MPI(" ", &params->g);
209  }
210 
211  //Release previously allocated memory
212  cryptoFreeMem(buffer);
213  }
214  else
215  {
216  //Failed to allocate memory
217  error = ERROR_OUT_OF_MEMORY;
218  }
219  }
220 
221  //Any error to report?
222  if(error)
223  {
224  //Clean up side effects
225  mpiFree(&params->p);
226  mpiFree(&params->g);
227  }
228 
229  //Return status code
230  return error;
231 #else
232  //Not implemented
233  return ERROR_NOT_IMPLEMENTED;
234 #endif
235 }
236 
237 #endif
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
uint8_t p
Definition: ndp.h:300
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
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
error_t pemImportDhParameters(DhParameters *params, const char_t *input, size_t length)
Decode a PEM file containing Diffie-Hellman parameters.
Definition: pem_import.c:137
size_t totalLength
Definition: asn1.h:111
size_t length
Definition: asn1.h:109
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:55
PEM file import functions.
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t
Error codes.
Definition: error.h:43
ASN.1 tag.
Definition: asn1.h:105
Mpi p
Prime modulus.
Definition: dh.h:50
General definitions for cryptographic algorithms.
uint8_t length
Definition: tcp.h:375
#define TRACE_DEBUG(...)
Definition: debug.h:119
char char_t
Definition: compiler_port.h:55
uint8_t n
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:842
#define cryptoFreeMem(p)
Definition: crypto.h:833
#define cryptoAllocMem(size)
Definition: crypto.h:828
Mpi g
Generator.
Definition: dh.h:51
Diffie-Hellman parameters.
Definition: dh.h:49
#define TRACE_DEBUG_MPI(p, a)
Definition: debug.h:122
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:84
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:111
const uint8_t * value
Definition: asn1.h:110
Debugging facilities.
ASN.1 (Abstract Syntax Notation One)
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:64