[MBEDTLS] Update to version 2.7.10. CORE-15895
[reactos.git] / dll / 3rdparty / mbedtls / x509_csr.c
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 */