1 /*
2  *  X.509 Certificate Signing Request writing
3  *
4  *  Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6  *
7  *  This file is provided under the Apache License 2.0, or the
8  *  GNU General Public License v2.0 or later.
9  *
10  *  **********
11  *  Apache License 2.0:
12  *
13  *  Licensed under the Apache License, Version 2.0 (the "License"); you may
14  *  not use this file except in compliance with the License.
15  *  You may obtain a copy of the License at
16  *
17  *  http://www.apache.org/licenses/LICENSE-2.0
18  *
19  *  Unless required by applicable law or agreed to in writing, software
20  *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
21  *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22  *  See the License for the specific language governing permissions and
23  *  limitations under the License.
24  *
25  *  **********
26  *
27  *  **********
28  *  GNU General Public License v2.0 or later:
29  *
30  *  This program is free software; you can redistribute it and/or modify
31  *  it under the terms of the GNU General Public License as published by
32  *  the Free Software Foundation; either version 2 of the License, or
33  *  (at your option) any later version.
34  *
35  *  This program is distributed in the hope that it will be useful,
36  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
37  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
38  *  GNU General Public License for more details.
39  *
40  *  You should have received a copy of the GNU General Public License along
41  *  with this program; if not, write to the Free Software Foundation, Inc.,
42  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
43  *
44  *  **********
45  *
46  *  This file is part of mbed TLS (https://tls.mbed.org)
47  */
48 /*
49  * References:
50  * - CSRs: PKCS#10 v1.7 aka RFC 2986
51  * - attributes: PKCS#9 v2.0 aka RFC 2985
52  */
53 
54 #if !defined(MBEDTLS_CONFIG_FILE)
55 #include "mbedtls/config.h"
56 #else
57 #include MBEDTLS_CONFIG_FILE
58 #endif
59 
60 #if defined(MBEDTLS_X509_CSR_WRITE_C)
61 
62 #include "mbedtls/x509_csr.h"
63 #include "mbedtls/oid.h"
64 #include "mbedtls/asn1write.h"
65 
66 #include <string.h>
67 #include <stdlib.h>
68 
69 #if defined(MBEDTLS_PEM_WRITE_C)
70 #include "mbedtls/pem.h"
71 #endif
72 
73 /* Implementation that should never be optimized out by the compiler */
74 static void mbedtls_zeroize( void *v, size_t n ) {
75     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
76 }
77 
78 /*
79  * For the currently used signature algorithms the buffer to store any signature
80  * must be at least of size MAX(MBEDTLS_ECDSA_MAX_LEN, MBEDTLS_MPI_MAX_SIZE)
81  */
82 #if MBEDTLS_ECDSA_MAX_LEN > MBEDTLS_MPI_MAX_SIZE
83 #define SIGNATURE_MAX_SIZE MBEDTLS_ECDSA_MAX_LEN
84 #else
85 #define SIGNATURE_MAX_SIZE MBEDTLS_MPI_MAX_SIZE
86 #endif
87 
88 void mbedtls_x509write_csr_init( mbedtls_x509write_csr *ctx )
89 {
90     memset( ctx, 0, sizeof( mbedtls_x509write_csr ) );
91 }
92 
93 void mbedtls_x509write_csr_free( mbedtls_x509write_csr *ctx )
94 {
95     mbedtls_asn1_free_named_data_list( &ctx->subject );
96     mbedtls_asn1_free_named_data_list( &ctx->extensions );
97 
98     mbedtls_zeroize( ctx, sizeof( mbedtls_x509write_csr ) );
99 }
100 
101 void mbedtls_x509write_csr_set_md_alg( mbedtls_x509write_csr *ctx, mbedtls_md_type_t md_alg )
102 {
103     ctx->md_alg = md_alg;
104 }
105 
106 void mbedtls_x509write_csr_set_key( mbedtls_x509write_csr *ctx, mbedtls_pk_context *key )
107 {
108     ctx->key = key;
109 }
110 
111 int mbedtls_x509write_csr_set_subject_name( mbedtls_x509write_csr *ctx,
112                                     const char *subject_name )
113 {
114     return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
115 }
116 
117 int mbedtls_x509write_csr_set_extension( mbedtls_x509write_csr *ctx,
118                                  const char *oid, size_t oid_len,
119                                  const unsigned char *val, size_t val_len )
120 {
121     return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
122                                0, val, val_len );
123 }
124 
125 static size_t csr_get_unused_bits_for_named_bitstring( unsigned char bitstring,
126                                                        size_t bit_offset )
127 {
128     size_t unused_bits;
129 
130      /* Count the unused bits removing trailing 0s */
131     for( unused_bits = bit_offset; unused_bits < 8; unused_bits++ )
132         if( ( ( bitstring >> unused_bits ) & 0x1 ) != 0 )
133             break;
134 
135      return( unused_bits );
136 }
137 
138 int mbedtls_x509write_csr_set_key_usage( mbedtls_x509write_csr *ctx, unsigned char key_usage )
139 {
140     unsigned char buf[4];
141     unsigned char *c;
142     size_t unused_bits;
143     int ret;
144 
145     c = buf + 4;
146 
147     unused_bits = csr_get_unused_bits_for_named_bitstring( key_usage, 0 );
148     ret = mbedtls_asn1_write_bitstring( &c, buf, &key_usage, 8 - unused_bits );
149 
150     if( ret < 0 )
151         return( ret );
152     else if( ret < 3 || ret > 4 )
153         return( MBEDTLS_ERR_X509_INVALID_FORMAT );
154 
155     ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
156                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
157                                        c, (size_t)ret );
158     if( ret != 0 )
159         return( ret );
160 
161     return( 0 );
162 }
163 
164 int mbedtls_x509write_csr_set_ns_cert_type( mbedtls_x509write_csr *ctx,
165                                     unsigned char ns_cert_type )
166 {
167     unsigned char buf[4];
168     unsigned char *c;
169     size_t unused_bits;
170     int ret;
171 
172     c = buf + 4;
173 
174     unused_bits = csr_get_unused_bits_for_named_bitstring( ns_cert_type, 0 );
175     ret = mbedtls_asn1_write_bitstring( &c,
176                                         buf,
177                                         &ns_cert_type,
178                                         8 - unused_bits );
179 
180     if( ret < 0 )
181         return( ret );
182     else if( ret < 3 || ret > 4 )
183         return( ret );
184 
185     ret = mbedtls_x509write_csr_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
186                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
187                                        c, (size_t)ret );
188     if( ret != 0 )
189         return( ret );
190 
191     return( 0 );
192 }
193 
194 int mbedtls_x509write_csr_der( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
195                        int (*f_rng)(void *, unsigned char *, size_t),
196                        void *p_rng )
197 {
198     int ret;
199     const char *sig_oid;
200     size_t sig_oid_len = 0;
201     unsigned char *c, *c2;
202     unsigned char hash[64];
203     unsigned char sig[SIGNATURE_MAX_SIZE];
204     unsigned char tmp_buf[2048];
205     size_t pub_len = 0, sig_and_oid_len = 0, sig_len;
206     size_t len = 0;
207     mbedtls_pk_type_t pk_alg;
208 
209     /*
210      * Prepare data to be signed in tmp_buf
211      */
212     c = tmp_buf + sizeof( tmp_buf );
213 
214     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
215 
216     if( len )
217     {
218         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
219         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
220                                                         MBEDTLS_ASN1_SEQUENCE ) );
221 
222         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
223         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
224                                                         MBEDTLS_ASN1_SET ) );
225 
226         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( &c, tmp_buf, MBEDTLS_OID_PKCS9_CSR_EXT_REQ,
227                                           MBEDTLS_OID_SIZE( MBEDTLS_OID_PKCS9_CSR_EXT_REQ ) ) );
228 
229         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
230         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
231                                                         MBEDTLS_ASN1_SEQUENCE ) );
232     }
233 
234     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
235     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
236                                                     MBEDTLS_ASN1_CONTEXT_SPECIFIC ) );
237 
238     MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->key,
239                                                 tmp_buf, c - tmp_buf ) );
240     c -= pub_len;
241     len += pub_len;
242 
243     /*
244      *  Subject  ::=  Name
245      */
246     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
247 
248     /*
249      *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
250      */
251     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, tmp_buf, 0 ) );
252 
253     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
254     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
255                                                     MBEDTLS_ASN1_SEQUENCE ) );
256 
257     /*
258      * Prepare signature
259      */
260     ret = mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
261     if( ret != 0 )
262         return( ret );
263 
264     if( ( ret = mbedtls_pk_sign( ctx->key, ctx->md_alg, hash, 0, sig, &sig_len,
265                                  f_rng, p_rng ) ) != 0 )
266     {
267         return( ret );
268     }
269 
270     if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_RSA ) )
271         pk_alg = MBEDTLS_PK_RSA;
272     else if( mbedtls_pk_can_do( ctx->key, MBEDTLS_PK_ECDSA ) )
273         pk_alg = MBEDTLS_PK_ECDSA;
274     else
275         return( MBEDTLS_ERR_X509_INVALID_ALG );
276 
277     if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
278                                                 &sig_oid, &sig_oid_len ) ) != 0 )
279     {
280         return( ret );
281     }
282 
283     /*
284      * Write data to output buffer
285      */
286     c2 = buf + size;
287     MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
288                                         sig_oid, sig_oid_len, sig, sig_len ) );
289 
290     if( len > (size_t)( c2 - buf ) )
291         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
292 
293     c2 -= len;
294     memcpy( c2, c, len );
295 
296     len += sig_and_oid_len;
297     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
298     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
299                                                  MBEDTLS_ASN1_SEQUENCE ) );
300 
301     return( (int) len );
302 }
303 
304 #define PEM_BEGIN_CSR           "-----BEGIN CERTIFICATE REQUEST-----\n"
305 #define PEM_END_CSR             "-----END CERTIFICATE REQUEST-----\n"
306 
307 #if defined(MBEDTLS_PEM_WRITE_C)
308 int mbedtls_x509write_csr_pem( mbedtls_x509write_csr *ctx, unsigned char *buf, size_t size,
309                        int (*f_rng)(void *, unsigned char *, size_t),
310                        void *p_rng )
311 {
312     int ret;
313     unsigned char output_buf[4096];
314     size_t olen = 0;
315 
316     if( ( ret = mbedtls_x509write_csr_der( ctx, output_buf, sizeof(output_buf),
317                                    f_rng, p_rng ) ) < 0 )
318     {
319         return( ret );
320     }
321 
322     if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CSR, PEM_END_CSR,
323                                   output_buf + sizeof(output_buf) - ret,
324                                   ret, buf, size, &olen ) ) != 0 )
325     {
326         return( ret );
327     }
328 
329     return( 0 );
330 }
331 #endif /* MBEDTLS_PEM_WRITE_C */
332 
333 #endif /* MBEDTLS_X509_CSR_WRITE_C */
334