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