1 /*
2  *  X.509 Certificate Signing Request (CSR) parsing
3  *
4  *  Copyright The Mbed TLS Contributors
5  *  SPDX-License-Identifier: Apache-2.0
6  *
7  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
8  *  not use this file except in compliance with the License.
9  *  You may obtain a copy of the License at
10  *
11  *  http://www.apache.org/licenses/LICENSE-2.0
12  *
13  *  Unless required by applicable law or agreed to in writing, software
14  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  *  See the License for the specific language governing permissions and
17  *  limitations under the License.
18  */
19 /*
20  *  The ITU-T X.509 standard defines a certificate format for PKI.
21  *
22  *  http://www.ietf.org/rfc/rfc5280.txt (Certificates and CRLs)
23  *  http://www.ietf.org/rfc/rfc3279.txt (Alg IDs for CRLs)
24  *  http://www.ietf.org/rfc/rfc2986.txt (CSRs, aka PKCS#10)
25  *
26  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.680-0207.pdf
27  *  http://www.itu.int/ITU-T/studygroups/com17/languages/X.690-0207.pdf
28  */
29 
30 #include "common.h"
31 
32 #if defined(MBEDTLS_X509_CSR_PARSE_C)
33 
34 #include "mbedtls/x509_csr.h"
35 #include "mbedtls/error.h"
36 #include "mbedtls/oid.h"
37 #include "mbedtls/platform_util.h"
38 
39 #include <string.h>
40 
41 #if defined(MBEDTLS_PEM_PARSE_C)
42 #include "mbedtls/pem.h"
43 #endif
44 
45 #include "mbedtls/platform.h"
46 
47 #if defined(MBEDTLS_FS_IO) || defined(EFIX64) || defined(EFI32)
48 #include <stdio.h>
49 #endif
50 
51 /*
52  *  Version  ::=  INTEGER  {  v1(0)  }
53  */
x509_csr_get_version(unsigned char ** p,const unsigned char * end,int * ver)54 static int x509_csr_get_version( unsigned char **p,
55                              const unsigned char *end,
56                              int *ver )
57 {
58     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
59 
60     if( ( ret = mbedtls_asn1_get_int( p, end, ver ) ) != 0 )
61     {
62         if( ret == MBEDTLS_ERR_ASN1_UNEXPECTED_TAG )
63         {
64             *ver = 0;
65             return( 0 );
66         }
67 
68         return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_VERSION, ret ) );
69     }
70 
71     return( 0 );
72 }
73 
74 /*
75  * Parse a CSR in DER format
76  */
mbedtls_x509_csr_parse_der(mbedtls_x509_csr * csr,const unsigned char * buf,size_t buflen)77 int mbedtls_x509_csr_parse_der( mbedtls_x509_csr *csr,
78                         const unsigned char *buf, size_t buflen )
79 {
80     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
81     size_t len;
82     unsigned char *p, *end;
83     mbedtls_x509_buf sig_params;
84 
85     memset( &sig_params, 0, sizeof( mbedtls_x509_buf ) );
86 
87     /*
88      * Check for valid input
89      */
90     if( csr == NULL || buf == NULL || buflen == 0 )
91         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
92 
93     mbedtls_x509_csr_init( csr );
94 
95     /*
96      * first copy the raw DER data
97      */
98     p = mbedtls_calloc( 1, len = buflen );
99 
100     if( p == NULL )
101         return( MBEDTLS_ERR_X509_ALLOC_FAILED );
102 
103     memcpy( p, buf, buflen );
104 
105     csr->raw.p = p;
106     csr->raw.len = len;
107     end = p + len;
108 
109     /*
110      *  CertificationRequest ::= SEQUENCE {
111      *       certificationRequestInfo CertificationRequestInfo,
112      *       signatureAlgorithm AlgorithmIdentifier,
113      *       signature          BIT STRING
114      *  }
115      */
116     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
117             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
118     {
119         mbedtls_x509_csr_free( csr );
120         return( MBEDTLS_ERR_X509_INVALID_FORMAT );
121     }
122 
123     if( len != (size_t) ( end - p ) )
124     {
125         mbedtls_x509_csr_free( csr );
126         return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
127                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
128     }
129 
130     /*
131      *  CertificationRequestInfo ::= SEQUENCE {
132      */
133     csr->cri.p = p;
134 
135     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
136             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
137     {
138         mbedtls_x509_csr_free( csr );
139         return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
140     }
141 
142     end = p + len;
143     csr->cri.len = end - csr->cri.p;
144 
145     /*
146      *  Version  ::=  INTEGER {  v1(0) }
147      */
148     if( ( ret = x509_csr_get_version( &p, end, &csr->version ) ) != 0 )
149     {
150         mbedtls_x509_csr_free( csr );
151         return( ret );
152     }
153 
154     if( csr->version != 0 )
155     {
156         mbedtls_x509_csr_free( csr );
157         return( MBEDTLS_ERR_X509_UNKNOWN_VERSION );
158     }
159 
160     csr->version++;
161 
162     /*
163      *  subject               Name
164      */
165     csr->subject_raw.p = p;
166 
167     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
168             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE ) ) != 0 )
169     {
170         mbedtls_x509_csr_free( csr );
171         return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
172     }
173 
174     if( ( ret = mbedtls_x509_get_name( &p, p + len, &csr->subject ) ) != 0 )
175     {
176         mbedtls_x509_csr_free( csr );
177         return( ret );
178     }
179 
180     csr->subject_raw.len = p - csr->subject_raw.p;
181 
182     /*
183      *  subjectPKInfo SubjectPublicKeyInfo
184      */
185     if( ( ret = mbedtls_pk_parse_subpubkey( &p, end, &csr->pk ) ) != 0 )
186     {
187         mbedtls_x509_csr_free( csr );
188         return( ret );
189     }
190 
191     /*
192      *  attributes    [0] Attributes
193      *
194      *  The list of possible attributes is open-ended, though RFC 2985
195      *  (PKCS#9) defines a few in section 5.4. We currently don't support any,
196      *  so we just ignore them. This is a safe thing to do as the worst thing
197      *  that could happen is that we issue a certificate that does not match
198      *  the requester's expectations - this cannot cause a violation of our
199      *  signature policies.
200      */
201     if( ( ret = mbedtls_asn1_get_tag( &p, end, &len,
202             MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC ) ) != 0 )
203     {
204         mbedtls_x509_csr_free( csr );
205         return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT, ret ) );
206     }
207 
208     p += len;
209 
210     end = csr->raw.p + csr->raw.len;
211 
212     /*
213      *  signatureAlgorithm   AlgorithmIdentifier,
214      *  signature            BIT STRING
215      */
216     if( ( ret = mbedtls_x509_get_alg( &p, end, &csr->sig_oid, &sig_params ) ) != 0 )
217     {
218         mbedtls_x509_csr_free( csr );
219         return( ret );
220     }
221 
222     if( ( ret = mbedtls_x509_get_sig_alg( &csr->sig_oid, &sig_params,
223                                   &csr->sig_md, &csr->sig_pk,
224                                   &csr->sig_opts ) ) != 0 )
225     {
226         mbedtls_x509_csr_free( csr );
227         return( MBEDTLS_ERR_X509_UNKNOWN_SIG_ALG );
228     }
229 
230     if( ( ret = mbedtls_x509_get_sig( &p, end, &csr->sig ) ) != 0 )
231     {
232         mbedtls_x509_csr_free( csr );
233         return( ret );
234     }
235 
236     if( p != end )
237     {
238         mbedtls_x509_csr_free( csr );
239         return( MBEDTLS_ERROR_ADD( MBEDTLS_ERR_X509_INVALID_FORMAT,
240                 MBEDTLS_ERR_ASN1_LENGTH_MISMATCH ) );
241     }
242 
243     return( 0 );
244 }
245 
246 /*
247  * Parse a CSR, allowing for PEM or raw DER encoding
248  */
mbedtls_x509_csr_parse(mbedtls_x509_csr * csr,const unsigned char * buf,size_t buflen)249 int mbedtls_x509_csr_parse( mbedtls_x509_csr *csr, const unsigned char *buf, size_t buflen )
250 {
251 #if defined(MBEDTLS_PEM_PARSE_C)
252     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
253     size_t use_len;
254     mbedtls_pem_context pem;
255 #endif
256 
257     /*
258      * Check for valid input
259      */
260     if( csr == NULL || buf == NULL || buflen == 0 )
261         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
262 
263 #if defined(MBEDTLS_PEM_PARSE_C)
264     /* Avoid calling mbedtls_pem_read_buffer() on non-null-terminated string */
265     if( buf[buflen - 1] == '\0' )
266     {
267         mbedtls_pem_init( &pem );
268         ret = mbedtls_pem_read_buffer( &pem,
269                                        "-----BEGIN CERTIFICATE REQUEST-----",
270                                        "-----END CERTIFICATE REQUEST-----",
271                                        buf, NULL, 0, &use_len );
272         if( ret == MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
273         {
274             ret = mbedtls_pem_read_buffer( &pem,
275                                            "-----BEGIN NEW CERTIFICATE REQUEST-----",
276                                            "-----END NEW CERTIFICATE REQUEST-----",
277                                            buf, NULL, 0, &use_len );
278         }
279 
280         if( ret == 0 )
281         {
282             /*
283              * Was PEM encoded, parse the result
284              */
285             ret = mbedtls_x509_csr_parse_der( csr, pem.buf, pem.buflen );
286         }
287 
288         mbedtls_pem_free( &pem );
289         if( ret != MBEDTLS_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
290             return( ret );
291     }
292 #endif /* MBEDTLS_PEM_PARSE_C */
293     return( mbedtls_x509_csr_parse_der( csr, buf, buflen ) );
294 }
295 
296 #if defined(MBEDTLS_FS_IO)
297 /*
298  * Load a CSR into the structure
299  */
mbedtls_x509_csr_parse_file(mbedtls_x509_csr * csr,const char * path)300 int mbedtls_x509_csr_parse_file( mbedtls_x509_csr *csr, const char *path )
301 {
302     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
303     size_t n;
304     unsigned char *buf;
305 
306     if( ( ret = mbedtls_pk_load_file( path, &buf, &n ) ) != 0 )
307         return( ret );
308 
309     ret = mbedtls_x509_csr_parse( csr, buf, n );
310 
311     mbedtls_platform_zeroize( buf, n );
312     mbedtls_free( buf );
313 
314     return( ret );
315 }
316 #endif /* MBEDTLS_FS_IO */
317 
318 #if !defined(MBEDTLS_X509_REMOVE_INFO)
319 #define BEFORE_COLON    14
320 #define BC              "14"
321 /*
322  * Return an informational string about the CSR.
323  */
mbedtls_x509_csr_info(char * buf,size_t size,const char * prefix,const mbedtls_x509_csr * csr)324 int mbedtls_x509_csr_info( char *buf, size_t size, const char *prefix,
325                    const mbedtls_x509_csr *csr )
326 {
327     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
328     size_t n;
329     char *p;
330     char key_size_str[BEFORE_COLON];
331 
332     p = buf;
333     n = size;
334 
335     ret = mbedtls_snprintf( p, n, "%sCSR version   : %d",
336                                prefix, csr->version );
337     MBEDTLS_X509_SAFE_SNPRINTF;
338 
339     ret = mbedtls_snprintf( p, n, "\n%ssubject name  : ", prefix );
340     MBEDTLS_X509_SAFE_SNPRINTF;
341     ret = mbedtls_x509_dn_gets( p, n, &csr->subject );
342     MBEDTLS_X509_SAFE_SNPRINTF;
343 
344     ret = mbedtls_snprintf( p, n, "\n%ssigned using  : ", prefix );
345     MBEDTLS_X509_SAFE_SNPRINTF;
346 
347     ret = mbedtls_x509_sig_alg_gets( p, n, &csr->sig_oid, csr->sig_pk, csr->sig_md,
348                              csr->sig_opts );
349     MBEDTLS_X509_SAFE_SNPRINTF;
350 
351     if( ( ret = mbedtls_x509_key_size_helper( key_size_str, BEFORE_COLON,
352                                       mbedtls_pk_get_name( &csr->pk ) ) ) != 0 )
353     {
354         return( ret );
355     }
356 
357     ret = mbedtls_snprintf( p, n, "\n%s%-" BC "s: %d bits\n", prefix, key_size_str,
358                           (int) mbedtls_pk_get_bitlen( &csr->pk ) );
359     MBEDTLS_X509_SAFE_SNPRINTF;
360 
361     return( (int) ( size - n ) );
362 }
363 #endif /* MBEDTLS_X509_REMOVE_INFO */
364 
365 /*
366  * Initialize a CSR
367  */
mbedtls_x509_csr_init(mbedtls_x509_csr * csr)368 void mbedtls_x509_csr_init( mbedtls_x509_csr *csr )
369 {
370     memset( csr, 0, sizeof(mbedtls_x509_csr) );
371 }
372 
373 /*
374  * Unallocate all CSR data
375  */
mbedtls_x509_csr_free(mbedtls_x509_csr * csr)376 void mbedtls_x509_csr_free( mbedtls_x509_csr *csr )
377 {
378     if( csr == NULL )
379         return;
380 
381     mbedtls_pk_free( &csr->pk );
382 
383 #if defined(MBEDTLS_X509_RSASSA_PSS_SUPPORT)
384     mbedtls_free( csr->sig_opts );
385 #endif
386 
387     mbedtls_asn1_free_named_data_list_shallow( csr->subject.next );
388 
389     if( csr->raw.p != NULL )
390     {
391         mbedtls_platform_zeroize( csr->raw.p, csr->raw.len );
392         mbedtls_free( csr->raw.p );
393     }
394 
395     mbedtls_platform_zeroize( csr, sizeof( mbedtls_x509_csr ) );
396 }
397 
398 #endif /* MBEDTLS_X509_CSR_PARSE_C */
399