1 /*
2  *  X.509 certificate 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  * - certificates: RFC 5280, updated by RFC 6818
26  * - CSRs: PKCS#10 v1.7 aka RFC 2986
27  * - attributes: PKCS#9 v2.0 aka RFC 2985
28  */
29 
30 #if !defined(MBEDTLS_CONFIG_FILE)
31 #include "mbedtls/config.h"
32 #else
33 #include MBEDTLS_CONFIG_FILE
34 #endif
35 
36 #if defined(MBEDTLS_X509_CRT_WRITE_C)
37 
38 #include "mbedtls/x509_crt.h"
39 #include "mbedtls/oid.h"
40 #include "mbedtls/asn1write.h"
41 #include "mbedtls/sha1.h"
42 
43 #include <string.h>
44 
45 #if defined(MBEDTLS_PEM_WRITE_C)
46 #include "mbedtls/pem.h"
47 #endif /* MBEDTLS_PEM_WRITE_C */
48 
49 /* Implementation that should never be optimized out by the compiler */
50 static void mbedtls_zeroize( void *v, size_t n ) {
51     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
52 }
53 
54 void mbedtls_x509write_crt_init( mbedtls_x509write_cert *ctx )
55 {
56     memset( ctx, 0, sizeof(mbedtls_x509write_cert) );
57 
58     mbedtls_mpi_init( &ctx->serial );
59     ctx->version = MBEDTLS_X509_CRT_VERSION_3;
60 }
61 
62 void mbedtls_x509write_crt_free( mbedtls_x509write_cert *ctx )
63 {
64     mbedtls_mpi_free( &ctx->serial );
65 
66     mbedtls_asn1_free_named_data_list( &ctx->subject );
67     mbedtls_asn1_free_named_data_list( &ctx->issuer );
68     mbedtls_asn1_free_named_data_list( &ctx->extensions );
69 
70     mbedtls_zeroize( ctx, sizeof(mbedtls_x509write_cert) );
71 }
72 
73 void mbedtls_x509write_crt_set_version( mbedtls_x509write_cert *ctx, int version )
74 {
75     ctx->version = version;
76 }
77 
78 void mbedtls_x509write_crt_set_md_alg( mbedtls_x509write_cert *ctx, mbedtls_md_type_t md_alg )
79 {
80     ctx->md_alg = md_alg;
81 }
82 
83 void mbedtls_x509write_crt_set_subject_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key )
84 {
85     ctx->subject_key = key;
86 }
87 
88 void mbedtls_x509write_crt_set_issuer_key( mbedtls_x509write_cert *ctx, mbedtls_pk_context *key )
89 {
90     ctx->issuer_key = key;
91 }
92 
93 int mbedtls_x509write_crt_set_subject_name( mbedtls_x509write_cert *ctx,
94                                     const char *subject_name )
95 {
96     return mbedtls_x509_string_to_names( &ctx->subject, subject_name );
97 }
98 
99 int mbedtls_x509write_crt_set_issuer_name( mbedtls_x509write_cert *ctx,
100                                    const char *issuer_name )
101 {
102     return mbedtls_x509_string_to_names( &ctx->issuer, issuer_name );
103 }
104 
105 int mbedtls_x509write_crt_set_serial( mbedtls_x509write_cert *ctx, const mbedtls_mpi *serial )
106 {
107     int ret;
108 
109     if( ( ret = mbedtls_mpi_copy( &ctx->serial, serial ) ) != 0 )
110         return( ret );
111 
112     return( 0 );
113 }
114 
115 int mbedtls_x509write_crt_set_validity( mbedtls_x509write_cert *ctx, const char *not_before,
116                                 const char *not_after )
117 {
118     if( strlen( not_before ) != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 ||
119         strlen( not_after )  != MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1 )
120     {
121         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
122     }
123     strncpy( ctx->not_before, not_before, MBEDTLS_X509_RFC5280_UTC_TIME_LEN );
124     strncpy( ctx->not_after , not_after , MBEDTLS_X509_RFC5280_UTC_TIME_LEN );
125     ctx->not_before[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
126     ctx->not_after[MBEDTLS_X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
127 
128     return( 0 );
129 }
130 
131 int mbedtls_x509write_crt_set_extension( mbedtls_x509write_cert *ctx,
132                                  const char *oid, size_t oid_len,
133                                  int critical,
134                                  const unsigned char *val, size_t val_len )
135 {
136     return mbedtls_x509_set_extension( &ctx->extensions, oid, oid_len,
137                                critical, val, val_len );
138 }
139 
140 int mbedtls_x509write_crt_set_basic_constraints( mbedtls_x509write_cert *ctx,
141                                          int is_ca, int max_pathlen )
142 {
143     int ret;
144     unsigned char buf[9];
145     unsigned char *c = buf + sizeof(buf);
146     size_t len = 0;
147 
148     memset( buf, 0, sizeof(buf) );
149 
150     if( is_ca && max_pathlen > 127 )
151         return( MBEDTLS_ERR_X509_BAD_INPUT_DATA );
152 
153     if( is_ca )
154     {
155         if( max_pathlen >= 0 )
156         {
157             MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, max_pathlen ) );
158         }
159         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_bool( &c, buf, 1 ) );
160     }
161 
162     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
163     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
164                                                 MBEDTLS_ASN1_SEQUENCE ) );
165 
166     return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_BASIC_CONSTRAINTS,
167                                         MBEDTLS_OID_SIZE( MBEDTLS_OID_BASIC_CONSTRAINTS ),
168                                         0, buf + sizeof(buf) - len, len );
169 }
170 
171 #if defined(MBEDTLS_SHA1_C)
172 int mbedtls_x509write_crt_set_subject_key_identifier( mbedtls_x509write_cert *ctx )
173 {
174     int ret;
175     unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
176     unsigned char *c = buf + sizeof(buf);
177     size_t len = 0;
178 
179     memset( buf, 0, sizeof(buf) );
180     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->subject_key ) );
181 
182     mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
183     c = buf + sizeof(buf) - 20;
184     len = 20;
185 
186     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
187     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_OCTET_STRING ) );
188 
189     return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER,
190                                         MBEDTLS_OID_SIZE( MBEDTLS_OID_SUBJECT_KEY_IDENTIFIER ),
191                                         0, buf + sizeof(buf) - len, len );
192 }
193 
194 int mbedtls_x509write_crt_set_authority_key_identifier( mbedtls_x509write_cert *ctx )
195 {
196     int ret;
197     unsigned char buf[MBEDTLS_MPI_MAX_SIZE * 2 + 20]; /* tag, length + 2xMPI */
198     unsigned char *c = buf + sizeof(buf);
199     size_t len = 0;
200 
201     memset( buf, 0, sizeof(buf) );
202     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, ctx->issuer_key ) );
203 
204     mbedtls_sha1( buf + sizeof(buf) - len, len, buf + sizeof(buf) - 20 );
205     c = buf + sizeof(buf) - 20;
206     len = 20;
207 
208     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
209     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC | 0 ) );
210 
211     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) );
212     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED |
213                                                 MBEDTLS_ASN1_SEQUENCE ) );
214 
215     return mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER,
216                                    MBEDTLS_OID_SIZE( MBEDTLS_OID_AUTHORITY_KEY_IDENTIFIER ),
217                                    0, buf + sizeof(buf) - len, len );
218 }
219 #endif /* MBEDTLS_SHA1_C */
220 
221 int mbedtls_x509write_crt_set_key_usage( mbedtls_x509write_cert *ctx,
222                                          unsigned int key_usage )
223 {
224     unsigned char buf[4], ku;
225     unsigned char *c;
226     int ret;
227 
228     /* We currently only support 7 bits, from 0x80 to 0x02 */
229     if( ( key_usage & ~0xfe ) != 0 )
230         return( MBEDTLS_ERR_X509_FEATURE_UNAVAILABLE );
231 
232     c = buf + 4;
233     ku = (unsigned char) key_usage;
234 
235     if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ku, 7 ) ) != 4 )
236         return( ret );
237 
238     ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_KEY_USAGE,
239                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_KEY_USAGE ),
240                                        1, buf, 4 );
241     if( ret != 0 )
242         return( ret );
243 
244     return( 0 );
245 }
246 
247 int mbedtls_x509write_crt_set_ns_cert_type( mbedtls_x509write_cert *ctx,
248                                     unsigned char ns_cert_type )
249 {
250     unsigned char buf[4];
251     unsigned char *c;
252     int ret;
253 
254     c = buf + 4;
255 
256     if( ( ret = mbedtls_asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 )
257         return( ret );
258 
259     ret = mbedtls_x509write_crt_set_extension( ctx, MBEDTLS_OID_NS_CERT_TYPE,
260                                        MBEDTLS_OID_SIZE( MBEDTLS_OID_NS_CERT_TYPE ),
261                                        0, buf, 4 );
262     if( ret != 0 )
263         return( ret );
264 
265     return( 0 );
266 }
267 
268 static int x509_write_time( unsigned char **p, unsigned char *start,
269                             const char *t, size_t size )
270 {
271     int ret;
272     size_t len = 0;
273 
274     /*
275      * write MBEDTLS_ASN1_UTC_TIME if year < 2050 (2 bytes shorter)
276      */
277     if( t[0] == '2' && t[1] == '0' && t[2] < '5' )
278     {
279         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
280                                              (const unsigned char *) t + 2,
281                                              size - 2 ) );
282         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
283         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_UTC_TIME ) );
284     }
285     else
286     {
287         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_raw_buffer( p, start,
288                                                   (const unsigned char *) t,
289                                                   size ) );
290         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) );
291         MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_GENERALIZED_TIME ) );
292     }
293 
294     return( (int) len );
295 }
296 
297 int mbedtls_x509write_crt_der( mbedtls_x509write_cert *ctx, unsigned char *buf, size_t size,
298                        int (*f_rng)(void *, unsigned char *, size_t),
299                        void *p_rng )
300 {
301     int ret;
302     const char *sig_oid;
303     size_t sig_oid_len = 0;
304     unsigned char *c, *c2;
305     unsigned char hash[64];
306     unsigned char sig[MBEDTLS_MPI_MAX_SIZE];
307     unsigned char tmp_buf[2048];
308     size_t sub_len = 0, pub_len = 0, sig_and_oid_len = 0, sig_len;
309     size_t len = 0;
310     mbedtls_pk_type_t pk_alg;
311 
312     /*
313      * Prepare data to be signed in tmp_buf
314      */
315     c = tmp_buf + sizeof( tmp_buf );
316 
317     /* Signature algorithm needed in TBS, and later for actual signature */
318     pk_alg = mbedtls_pk_get_type( ctx->issuer_key );
319     if( pk_alg == MBEDTLS_PK_ECKEY )
320         pk_alg = MBEDTLS_PK_ECDSA;
321 
322     if( ( ret = mbedtls_oid_get_oid_by_sig_alg( pk_alg, ctx->md_alg,
323                                         &sig_oid, &sig_oid_len ) ) != 0 )
324     {
325         return( ret );
326     }
327 
328     /*
329      *  Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
330      */
331     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_extensions( &c, tmp_buf, ctx->extensions ) );
332     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
333     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
334                                                     MBEDTLS_ASN1_SEQUENCE ) );
335     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
336     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
337                                                     MBEDTLS_ASN1_CONSTRUCTED | 3 ) );
338 
339     /*
340      *  SubjectPublicKeyInfo
341      */
342     MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_pk_write_pubkey_der( ctx->subject_key,
343                                                 tmp_buf, c - tmp_buf ) );
344     c -= pub_len;
345     len += pub_len;
346 
347     /*
348      *  Subject  ::=  Name
349      */
350     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->subject ) );
351 
352     /*
353      *  Validity ::= SEQUENCE {
354      *       notBefore      Time,
355      *       notAfter       Time }
356      */
357     sub_len = 0;
358 
359     MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after,
360                                             MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
361 
362     MBEDTLS_ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before,
363                                             MBEDTLS_X509_RFC5280_UTC_TIME_LEN ) );
364 
365     len += sub_len;
366     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) );
367     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
368                                                     MBEDTLS_ASN1_SEQUENCE ) );
369 
370     /*
371      *  Issuer  ::=  Name
372      */
373     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_x509_write_names( &c, tmp_buf, ctx->issuer ) );
374 
375     /*
376      *  Signature   ::=  AlgorithmIdentifier
377      */
378     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, tmp_buf,
379                        sig_oid, strlen( sig_oid ), 0 ) );
380 
381     /*
382      *  Serial   ::=  INTEGER
383      */
384     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, tmp_buf, &ctx->serial ) );
385 
386     /*
387      *  Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
388      */
389     sub_len = 0;
390     MBEDTLS_ASN1_CHK_ADD( sub_len, mbedtls_asn1_write_int( &c, tmp_buf, ctx->version ) );
391     len += sub_len;
392     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, sub_len ) );
393     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONTEXT_SPECIFIC |
394                                                     MBEDTLS_ASN1_CONSTRUCTED | 0 ) );
395 
396     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, tmp_buf, len ) );
397     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, tmp_buf, MBEDTLS_ASN1_CONSTRUCTED |
398                                                     MBEDTLS_ASN1_SEQUENCE ) );
399 
400     /*
401      * Make signature
402      */
403     mbedtls_md( mbedtls_md_info_from_type( ctx->md_alg ), c, len, hash );
404 
405     if( ( ret = mbedtls_pk_sign( ctx->issuer_key, ctx->md_alg, hash, 0, sig, &sig_len,
406                          f_rng, p_rng ) ) != 0 )
407     {
408         return( ret );
409     }
410 
411     /*
412      * Write data to output buffer
413      */
414     c2 = buf + size;
415     MBEDTLS_ASN1_CHK_ADD( sig_and_oid_len, mbedtls_x509_write_sig( &c2, buf,
416                                         sig_oid, sig_oid_len, sig, sig_len ) );
417 
418     if( len > (size_t)( c2 - buf ) )
419         return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL );
420 
421     c2 -= len;
422     memcpy( c2, c, len );
423 
424     len += sig_and_oid_len;
425     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c2, buf, len ) );
426     MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c2, buf, MBEDTLS_ASN1_CONSTRUCTED |
427                                                  MBEDTLS_ASN1_SEQUENCE ) );
428 
429     return( (int) len );
430 }
431 
432 #define PEM_BEGIN_CRT           "-----BEGIN CERTIFICATE-----\n"
433 #define PEM_END_CRT             "-----END CERTIFICATE-----\n"
434 
435 #if defined(MBEDTLS_PEM_WRITE_C)
436 int mbedtls_x509write_crt_pem( mbedtls_x509write_cert *crt, unsigned char *buf, size_t size,
437                        int (*f_rng)(void *, unsigned char *, size_t),
438                        void *p_rng )
439 {
440     int ret;
441     unsigned char output_buf[4096];
442     size_t olen = 0;
443 
444     if( ( ret = mbedtls_x509write_crt_der( crt, output_buf, sizeof(output_buf),
445                                    f_rng, p_rng ) ) < 0 )
446     {
447         return( ret );
448     }
449 
450     if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_CRT, PEM_END_CRT,
451                                   output_buf + sizeof(output_buf) - ret,
452                                   ret, buf, size, &olen ) ) != 0 )
453     {
454         return( ret );
455     }
456 
457     return( 0 );
458 }
459 #endif /* MBEDTLS_PEM_WRITE_C */
460 
461 #endif /* MBEDTLS_X509_CRT_WRITE_C */
462