[MBEDTLS] Update to version 2.7.12. CORE-16440
[reactos.git] / dll / 3rdparty / mbedtls / x509write_csr.c
1 /*
2 * X.509 Certificate Signing Request writing
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 * References:
25 * - CSRs: PKCS#10 v1.7 aka RFC 2986
26 * - attributes: PKCS#9 v2.0 aka RFC 2985
27 */
28
29 #if !defined(MBEDTLS_CONFIG_FILE)
30 #include "mbedtls/config.h"
31 #else
32 #include MBEDTLS_CONFIG_FILE
33 #endif
34
35 #if defined(MBEDTLS_X509_CSR_WRITE_C)
36
37 #include "mbedtls/x509_csr.h"
38 #include "mbedtls/oid.h"
39 #include "mbedtls/asn1write.h"
40
41 #include <string.h>
42 #include <stdlib.h>
43
44 #if defined(MBEDTLS_PEM_WRITE_C)
45 #include "mbedtls/pem.h"
46 #endif
47
48 /* Implementation that should never be optimized out by the compiler */
49 static void mbedtls_zeroize( void *v, size_t n ) {
50 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
51 }
52
53 /*
54 * For the currently used signature algorithms the buffer to store any signature
55 * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)
56 */
57 #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
58 #define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
59 #else
60 #define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
61 #endif
62
63 void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
64 {
65 memset( ctx, 0, sizeof( mbedtls_x509write_csr ) );
66 }
67
68 void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx )
69 {
70 mbedtls_asn1_free_named_data_list( &ctx->subject );
71 mbedtls_asn1_free_named_data_list( &ctx->extensions );
72
73 mbedtls_zeroize( ctx, sizeof( mbedtls_x509write_csr ) );
74 }
75
76 void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg )
77 {
78 ctx->md_alg = md_alg;
79 }
80
81 void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key )
82 {
83 ctx->key = key;
84 }
85
86 int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
87 const char *subject_name )
88 {
89 return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
90 }
91
92 int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
93 const char *oid, size_t oid_len,
94 const unsigned char *val, size_t val_len )
95 {
96 return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
97 0, val, val_len );
98 }
99
100 static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring,
101 size_t bit_offset )
102 {
103 size_t unused_bits;
104
105 /* Count the unused bits removing trailing 0s */
106 for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
107 if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
108 break;
109
110 return( unused_bits );
111 }
112
113 int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage )
114 {
115 unsigned char buf[4];
116 unsigned char *c;
117 size_t unused_bits;
118 int ret;
119
120 c = buf + 4;
121
122 unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 );
123 ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits );
124
125 if( ret < 0 )
126 return( ret );
127 else if( ret < 3 || ret > 4 )
128 return( MBEDTLS_ERR_X509_INVALID_FORMAT );
129
130 ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
131 MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
132 c, (size_t)ret );
133 if( ret != 0 )
134 return( ret );
135
136 return( 0 );
137 }
138
139 int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
140 unsigned char ns_cert_type )
141 {
142 unsigned char buf[4];
143 unsigned char *c;
144 size_t unused_bits;
145 int ret;
146
147 c = buf + 4;
148
149 unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
150 ret = mbedtls_asn1_write_bitstring( &c,
151 buf,
152 &ns_cert_type,
153 8 - unused_bits );
154
155 if( ret < 0 )
156 return( ret );
157 else if( ret < 3 || ret > 4 )
158 return( ret );
159
160 ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
161 MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
162 c, (size_t)ret );
163 if( ret != 0 )
164 return( ret );
165
166 return( 0 );
167 }
168
169 int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
170 int (*f_rng)(void *, unsigned char *, size_t),
171 void *p_rng )
172 {
173 int ret;
174 const char *sig_oid;
175 size_t sig_oid_len = 0;
176 unsigned char *c, *c2;
177 unsigned char hash[64];
178 unsigned char sig[SIGNATURE_MAX_SIZE];
179 unsigned char tmp_buf[2048];
180 size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
181 size_t len = 0;
182 mbedtls_pk_type_t pk_alg;
183
184 /*
185 * Prepare data to be signed in tmp_buf
186 */
187 c = tmp_buf + sizeof( tmp_buf );
188
189 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
190
191 if( len )
192 {
193 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
194 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
195 MBEDTLS_ASN1_SEQUENCE ) );
196
197 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
198 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
199 MBEDTLS_ASN1_SET ) );
200
201 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
202 MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) );
203
204 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
205 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
206 MBEDTLS_ASN1_SEQUENCE ) );
207 }
208
209 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
210 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
211 MBEDTLS_ASN1_CONTEXT_SPECIFIC ) );
212
213 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key,
214 tmp_buf, c - tmp_buf ) );
215 c -= pub_len;
216 len += pub_len;
217
218 /*
219 * Subject ::= Name
220 */
221 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
222
223 /*
224 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
225 */
226 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) );
227
228 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
229 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
230 MBEDTLS_ASN1_SEQUENCE ) );
231
232 /*
233 * Prepare signature
234 */
235 mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
236
237 if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
238 f_rng, p_rng ) ) != 0 )
239 {
240 return( ret );
241 }
242
243 if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) )
244 pk_alg = MBEDTLS_PK_RSA;
245 else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) )
246 pk_alg = MBEDTLS_PK_ECDSA;
247 else
248 return( MBEDTLS_ERR_X509_INVALID_ALG );
249
250 if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
251 &sig_oid, &sig_oid_len ) ) != 0 )
252 {
253 return( ret );
254 }
255
256 /*
257 * Write data to output buffer
258 */
259 c2 = buf + size;
260 MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
261 sig_oid, sig_oid_len, sig, sig_len ) );
262
263 if( len > (size_t)( c2 - buf ) )
264 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
265
266 c2 -= len;
267 memcpy( c2, c, len );
268
269 len += sig_and_oid_len;
270 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
271 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
272 MBEDTLS_ASN1_SEQUENCE ) );
273
274 return( (int) len );
275 }
276
277 #define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
278 #define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
279
280 #if defined(MBEDTLS_PEM_WRITE_C)
281 int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
282 int (*f_rng)(void *, unsigned char *, size_t),
283 void *p_rng )
284 {
285 int ret;
286 unsigned char output_buf[4096];
287 size_t olen = 0;
288
289 if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf),
290 f_rng, p_rng ) ) < 0 )
291 {
292 return( ret );
293 }
294
295 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
296 output_buf + sizeof(output_buf) - ret,
297 ret, buf, size, &olen ) ) != 0 )
298 {
299 return( ret );
300 }
301
302 return( 0 );
303 }
304 #endif /* MBEDTLS_PEM_WRITE_C */
305
306 #endif /* MBEDTLS_X509_CSR_WRITE_C */