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