blob: 1428c67cbf1f35e7f48b462786beb3e710ac7997 [file] [log] [blame]
Paul Bakkerbdb912d2012-02-13 23:11:30 +00001/*
2 * X509 buffer writing functionality
3 *
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +02004 * Copyright (C) 2006-2013, Brainspark B.V.
Paul Bakkerbdb912d2012-02-13 23:11:30 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#include "polarssl/config.h"
27
28#if defined(POLARSSL_X509_WRITE_C)
29
30#include "polarssl/asn1write.h"
31#include "polarssl/x509write.h"
32#include "polarssl/x509.h"
Paul Bakkerc70b9822013-04-07 22:00:46 +020033#include "polarssl/md.h"
34#include "polarssl/oid.h"
Paul Bakkerbdb912d2012-02-13 23:11:30 +000035
Paul Bakker135f1e92013-08-26 16:54:13 +020036#if defined(POLARSSL_BASE64_C)
37#include "polarssl/base64.h"
38#endif
39
Paul Bakker8eabfc12013-08-25 10:18:25 +020040#if defined(POLARSSL_MEMORY_C)
41#include "polarssl/memory.h"
42#else
43#include <stdlib.h>
44#define polarssl_malloc malloc
45#define polarssl_free free
46#endif
47
Paul Bakker9397dcb2013-09-06 09:55:26 +020048static int x509write_string_to_names( x509_req_name **head, char *name )
Paul Bakker8eabfc12013-08-25 10:18:25 +020049{
50 int ret = 0;
Paul Bakker9397dcb2013-09-06 09:55:26 +020051 char *s = name, *c = s;
Paul Bakker8eabfc12013-08-25 10:18:25 +020052 char *end = s + strlen( s );
53 char *oid = NULL;
54 int in_tag = 1;
Paul Bakker21307962013-08-25 10:33:27 +020055 x509_req_name *cur;
Paul Bakker8eabfc12013-08-25 10:18:25 +020056
Paul Bakker9397dcb2013-09-06 09:55:26 +020057 while( *head != NULL )
Paul Bakker8eabfc12013-08-25 10:18:25 +020058 {
Paul Bakker9397dcb2013-09-06 09:55:26 +020059 cur = *head;
60 *head = cur->next;
Paul Bakker8eabfc12013-08-25 10:18:25 +020061 polarssl_free( cur );
62 }
63
64 while( c <= end )
65 {
66 if( in_tag && *c == '=' )
67 {
68 if( memcmp( s, "CN", 2 ) == 0 && c - s == 2 )
69 oid = OID_AT_CN;
70 else if( memcmp( s, "C", 1 ) == 0 && c - s == 1 )
71 oid = OID_AT_COUNTRY;
72 else if( memcmp( s, "O", 1 ) == 0 && c - s == 1 )
73 oid = OID_AT_ORGANIZATION;
74 else if( memcmp( s, "L", 1 ) == 0 && c - s == 1 )
75 oid = OID_AT_LOCALITY;
76 else if( memcmp( s, "R", 1 ) == 0 && c - s == 1 )
77 oid = OID_PKCS9_EMAIL;
78 else if( memcmp( s, "OU", 2 ) == 0 && c - s == 2 )
79 oid = OID_AT_ORG_UNIT;
80 else if( memcmp( s, "ST", 2 ) == 0 && c - s == 2 )
81 oid = OID_AT_STATE;
82 else
83 {
Paul Bakker0e06c0f2013-08-25 11:21:30 +020084 ret = POLARSSL_ERR_X509WRITE_UNKNOWN_OID;
Paul Bakker8eabfc12013-08-25 10:18:25 +020085 goto exit;
86 }
87
88 s = c + 1;
89 in_tag = 0;
90 }
91
92 if( !in_tag && ( *c == ',' || c == end ) )
93 {
94 if( c - s > 127 )
95 {
Paul Bakker0e06c0f2013-08-25 11:21:30 +020096 ret = POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA;
Paul Bakker8eabfc12013-08-25 10:18:25 +020097 goto exit;
98 }
99
Paul Bakker21307962013-08-25 10:33:27 +0200100 cur = polarssl_malloc( sizeof(x509_req_name) );
Paul Bakker8eabfc12013-08-25 10:18:25 +0200101
102 if( cur == NULL )
103 {
Paul Bakker0e06c0f2013-08-25 11:21:30 +0200104 ret = POLARSSL_ERR_X509WRITE_MALLOC_FAILED;
Paul Bakker8eabfc12013-08-25 10:18:25 +0200105 goto exit;
106 }
107
108 memset( cur, 0, sizeof(x509_req_name) );
109
Paul Bakker9397dcb2013-09-06 09:55:26 +0200110 cur->next = *head;
111 *head = cur;
Paul Bakker21307962013-08-25 10:33:27 +0200112
Paul Bakker8eabfc12013-08-25 10:18:25 +0200113 strncpy( cur->oid, oid, strlen( oid ) );
114 strncpy( cur->name, s, c - s );
115
116 s = c + 1;
117 in_tag = 1;
118 }
119 c++;
120 }
121
122exit:
123
124 return( ret );
125}
126
Paul Bakker9397dcb2013-09-06 09:55:26 +0200127void x509write_csr_init( x509_csr *ctx )
128{
129 memset( ctx, 0, sizeof(x509_csr) );
130}
131
132void x509write_csr_free( x509_csr *ctx )
133{
134 x509_req_name *cur;
135 asn1_named_data *cur_ext;
136
137 while( ( cur = ctx->subject ) != NULL )
138 {
139 ctx->subject = cur->next;
140 polarssl_free( cur );
141 }
142
143 while( ( cur_ext = ctx->extensions ) != NULL )
144 {
145 ctx->extensions = cur_ext->next;
146 asn1_free_named_data( cur_ext );
147 polarssl_free( cur_ext );
148 }
149
150 memset( ctx, 0, sizeof(x509_csr) );
151}
152
153void x509write_csr_set_md_alg( x509_csr *ctx, md_type_t md_alg )
154{
155 ctx->md_alg = md_alg;
156}
157
158void x509write_csr_set_rsa_key( x509_csr *ctx, rsa_context *rsa )
159{
160 ctx->rsa = rsa;
161}
162
163int x509write_csr_set_subject_name( x509_csr *ctx, char *subject_name )
164{
165 return x509write_string_to_names( &ctx->subject, subject_name );
166}
167
Paul Bakker1c0e5502013-08-26 13:41:01 +0200168int x509write_csr_set_extension( x509_csr *ctx,
169 const char *oid, size_t oid_len,
170 const unsigned char *val, size_t val_len )
Paul Bakkerfde42702013-08-25 14:47:27 +0200171{
Paul Bakkere5eae762013-08-26 12:05:14 +0200172 asn1_named_data *cur;
Paul Bakkere5eae762013-08-26 12:05:14 +0200173
Paul Bakker1c0e5502013-08-26 13:41:01 +0200174 if( ( cur = asn1_find_named_data( ctx->extensions, oid,
175 oid_len ) ) == NULL )
Paul Bakkere5eae762013-08-26 12:05:14 +0200176 {
177 cur = polarssl_malloc( sizeof(asn1_named_data) );
178 if( cur == NULL )
179 return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
180
181 memset( cur, 0, sizeof(asn1_named_data) );
182
Paul Bakker1c0e5502013-08-26 13:41:01 +0200183 cur->oid.len = oid_len;
184 cur->oid.p = polarssl_malloc( oid_len );
Paul Bakkere5eae762013-08-26 12:05:14 +0200185 if( cur->oid.p == NULL )
186 {
Paul Bakker1c0e5502013-08-26 13:41:01 +0200187 polarssl_free( cur );
Paul Bakkere5eae762013-08-26 12:05:14 +0200188 return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
189 }
190
Paul Bakker1c0e5502013-08-26 13:41:01 +0200191 cur->val.len = val_len;
192 cur->val.p = polarssl_malloc( val_len );
Paul Bakkere5eae762013-08-26 12:05:14 +0200193 if( cur->val.p == NULL )
194 {
Paul Bakker1c0e5502013-08-26 13:41:01 +0200195 polarssl_free( cur->oid.p );
196 polarssl_free( cur );
Paul Bakkere5eae762013-08-26 12:05:14 +0200197 return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
198 }
199
Paul Bakker1c0e5502013-08-26 13:41:01 +0200200 memcpy( cur->oid.p, oid, oid_len );
Paul Bakkere5eae762013-08-26 12:05:14 +0200201
202 cur->next = ctx->extensions;
203 ctx->extensions = cur;
204 }
205
Paul Bakker1c0e5502013-08-26 13:41:01 +0200206 if( cur->val.len != val_len )
207 {
208 polarssl_free( cur->val.p );
209
210 cur->val.len = val_len;
211 cur->val.p = polarssl_malloc( val_len );
212 if( cur->val.p == NULL )
213 {
214 polarssl_free( cur->oid.p );
215 polarssl_free( cur );
216 return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
217 }
218 }
219
220 memcpy( cur->val.p, val, val_len );
221
222 return( 0 );
223}
224
225int x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage )
226{
227 unsigned char buf[4];
228 unsigned char *c;
229 int ret;
230
231 c = buf + 4;
232
Paul Bakker624d03a2013-08-26 14:12:57 +0200233 if( ( ret = asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 )
Paul Bakker1c0e5502013-08-26 13:41:01 +0200234 return( ret );
235
236 ret = x509write_csr_set_extension( ctx, OID_KEY_USAGE,
237 OID_SIZE( OID_KEY_USAGE ),
238 buf, 4 );
239 if( ret != 0 )
240 return( ret );
241
242 return( 0 );
243}
244
245int x509write_csr_set_ns_cert_type( x509_csr *ctx, unsigned char ns_cert_type )
246{
247 unsigned char buf[4];
248 unsigned char *c;
249 int ret;
250
251 c = buf + 4;
252
253 if( ( ret = asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 )
254 return( ret );
255
256 ret = x509write_csr_set_extension( ctx, OID_NS_CERT_TYPE,
257 OID_SIZE( OID_NS_CERT_TYPE ),
258 buf, 4 );
259 if( ret != 0 )
260 return( ret );
Paul Bakkere5eae762013-08-26 12:05:14 +0200261
262 return( 0 );
Paul Bakkerfde42702013-08-25 14:47:27 +0200263}
264
Paul Bakker9397dcb2013-09-06 09:55:26 +0200265void x509write_crt_init( x509write_cert *ctx )
266{
267 memset( ctx, 0, sizeof(x509write_cert) );
268
269 mpi_init( &ctx->serial );
270 ctx->version = X509_CRT_VERSION_3;
271}
272
273void x509write_crt_free( x509write_cert *ctx )
274{
275 x509_req_name *cur;
276 asn1_named_data *cur_ext;
277
278 mpi_free( &ctx->serial );
279
280 while( ( cur = ctx->subject ) != NULL )
281 {
282 ctx->subject = cur->next;
283 polarssl_free( cur );
284 }
285
286 while( ( cur = ctx->issuer ) != NULL )
287 {
288 ctx->issuer = cur->next;
289 polarssl_free( cur );
290 }
291
292 while( ( cur_ext = ctx->extensions ) != NULL )
293 {
294 ctx->extensions = cur_ext->next;
295 asn1_free_named_data( cur_ext );
296 polarssl_free( cur_ext );
297 }
298
299 memset( ctx, 0, sizeof(x509_csr) );
300}
301
302void x509write_crt_set_md_alg( x509write_cert *ctx, md_type_t md_alg )
303{
304 ctx->md_alg = md_alg;
305}
306
307void x509write_crt_set_subject_key( x509write_cert *ctx, rsa_context *rsa )
308{
309 ctx->subject_key = rsa;
310}
311
312void x509write_crt_set_issuer_key( x509write_cert *ctx, rsa_context *rsa )
313{
314 ctx->issuer_key = rsa;
315}
316
317int x509write_crt_set_subject_name( x509write_cert *ctx, char *subject_name )
318{
319 return x509write_string_to_names( &ctx->subject, subject_name );
320}
321
322int x509write_crt_set_issuer_name( x509write_cert *ctx, char *issuer_name )
323{
324 return x509write_string_to_names( &ctx->issuer, issuer_name );
325}
326
327int x509write_crt_set_serial( x509write_cert *ctx, const mpi *serial )
328{
329 int ret;
330
331 if( ( ret = mpi_copy( &ctx->serial, serial ) ) != 0 )
332 return( ret );
333
334 return( 0 );
335}
336
337int x509write_crt_set_validity( x509write_cert *ctx, char *not_before,
338 char *not_after )
339{
340 if( strlen(not_before) != X509_RFC5280_UTC_TIME_LEN - 1 ||
341 strlen(not_after) != X509_RFC5280_UTC_TIME_LEN - 1 )
342 {
343 return( POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA );
344 }
345 strncpy( ctx->not_before, not_before, X509_RFC5280_UTC_TIME_LEN );
346 strncpy( ctx->not_after , not_after , X509_RFC5280_UTC_TIME_LEN );
347 ctx->not_before[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
348 ctx->not_after[X509_RFC5280_UTC_TIME_LEN - 1] = 'Z';
349
350 return( 0 );
351}
352
Paul Bakker82e29452013-08-25 11:01:31 +0200353int x509write_pubkey_der( rsa_context *rsa, unsigned char *buf, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000354{
355 int ret;
356 unsigned char *c;
357 size_t len = 0;
358
359 c = buf + size - 1;
360
Paul Bakker8eabfc12013-08-25 10:18:25 +0200361 /*
362 * RSAPublicKey ::= SEQUENCE {
363 * modulus INTEGER, -- n
364 * publicExponent INTEGER -- e
365 * }
366 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000367 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
368 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
369
370 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
371 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
372
373 if( c - buf < 1 )
374 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
375
Paul Bakker8eabfc12013-08-25 10:18:25 +0200376 /*
377 * SubjectPublicKeyInfo ::= SEQUENCE {
378 * algorithm AlgorithmIdentifier,
379 * subjectPublicKey BIT STRING }
380 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000381 *--c = 0;
382 len += 1;
383
384 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
385 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
386
387 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, OID_PKCS1_RSA ) );
388
389 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
390 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
391
392 return( len );
393}
394
Paul Bakker82e29452013-08-25 11:01:31 +0200395int x509write_key_der( rsa_context *rsa, unsigned char *buf, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000396{
397 int ret;
398 unsigned char *c;
399 size_t len = 0;
400
401 c = buf + size - 1;
402
403 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) );
404 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) );
405 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) );
406 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) );
407 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) );
408 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) );
409 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
410 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
411 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) );
412
413 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
414 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
415
416 // TODO: Make NON RSA Specific variant later on
417/* *--c = 0;
418 len += 1;
419
420 len += asn1_write_len( &c, len);
421 len += asn1_write_tag( &c, ASN1_BIT_STRING );
422
423 len += asn1_write_oid( &c, OID_PKCS1_RSA );
424
425 len += asn1_write_int( &c, 0 );
426
427 len += asn1_write_len( &c, len);
428 len += asn1_write_tag( &c, ASN1_CONSTRUCTED | ASN1_SEQUENCE );*/
429
430/* for(i = 0; i < len; ++i)
431 {
432 if (i % 16 == 0 ) printf("\n");
433 printf("%02x ", c[i]);
434 }
435 printf("\n");*/
436
437 return( len );
438}
439
Paul Bakker9397dcb2013-09-06 09:55:26 +0200440/*
441 * RelativeDistinguishedName ::=
442 * SET OF AttributeTypeAndValue
443 *
444 * AttributeTypeAndValue ::= SEQUENCE {
445 * type AttributeType,
446 * value AttributeValue }
447 *
448 * AttributeType ::= OBJECT IDENTIFIER
449 *
450 * AttributeValue ::= ANY DEFINED BY AttributeType
451 */
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200452static int x509_write_name( unsigned char **p, unsigned char *start, char *oid,
453 char *name )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000454{
455 int ret;
456 size_t string_len = 0;
457 size_t oid_len = 0;
458 size_t len = 0;
459
Paul Bakker05888152012-02-16 10:26:57 +0000460 // Write PrintableString for all except OID_PKCS9_EMAIL
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000461 //
Paul Bakker05888152012-02-16 10:26:57 +0000462 if( OID_SIZE( OID_PKCS9_EMAIL ) == strlen( oid ) &&
463 memcmp( oid, OID_PKCS9_EMAIL, strlen( oid ) ) == 0 )
464 {
465 ASN1_CHK_ADD( string_len, asn1_write_ia5_string( p, start, name ) );
466 }
467 else
468 ASN1_CHK_ADD( string_len, asn1_write_printable_string( p, start, name ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000469
470 // Write OID
471 //
472 ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, oid ) );
473
474 len = oid_len + string_len;
475 ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + string_len ) );
476 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
477
478 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
479 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SET ) );
480
481 return( len );
482}
483
Paul Bakker9397dcb2013-09-06 09:55:26 +0200484static int x509_write_names( unsigned char **p, unsigned char *start,
485 x509_req_name *first )
486{
487 int ret;
488 size_t len = 0;
489 x509_req_name *cur = first;
490
491 while( cur != NULL )
492 {
493 ASN1_CHK_ADD( len, x509_write_name( p, start, cur->oid, cur->name ) );
494 cur = cur->next;
495 }
496
497 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
498 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
499
500 return( len );
501}
502
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200503static int x509_write_sig( unsigned char **p, unsigned char *start,
504 const char *oid, unsigned char *sig, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000505{
506 int ret;
507 size_t len = 0;
508
509 if( *p - start < (int) size + 1 )
510 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
511
512 len = size;
513 (*p) -= len;
514 memcpy( *p, sig, len );
515
516 *--(*p) = 0;
517 len += 1;
518
519 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
520 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
521
522 // Write OID
523 //
524 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid ) );
525
526 return( len );
527}
528
Paul Bakker9397dcb2013-09-06 09:55:26 +0200529static int x509_write_time( unsigned char **p, unsigned char *start,
530 const char *time, size_t size )
531{
532 int ret;
533 size_t len = 0;
534
535 ASN1_CHK_ADD( len, asn1_write_raw_buffer( p, start,
536 (const unsigned char *) time,
537 size ) );
538 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
539 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_GENERALIZED_TIME ) );
540
541 return( len );
542}
543
Paul Bakker82e29452013-08-25 11:01:31 +0200544int x509write_csr_der( x509_csr *ctx, unsigned char *buf, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000545{
546 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200547 const char *sig_oid;
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000548 unsigned char *c, *c2;
Paul Bakker3cac5e02012-02-16 14:08:06 +0000549 unsigned char hash[64];
550 unsigned char sig[POLARSSL_MPI_MAX_SIZE];
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000551 unsigned char tmp_buf[2048];
Paul Bakker9397dcb2013-09-06 09:55:26 +0200552 size_t pub_len = 0, sig_len = 0;
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000553 size_t len = 0;
Paul Bakkere5eae762013-08-26 12:05:14 +0200554 asn1_named_data *cur_ext = ctx->extensions;
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000555
556 c = tmp_buf + 2048 - 1;
557
Paul Bakkere5eae762013-08-26 12:05:14 +0200558 while( cur_ext != NULL )
Paul Bakkerfde42702013-08-25 14:47:27 +0200559 {
Paul Bakkere5eae762013-08-26 12:05:14 +0200560 size_t ext_len = 0;
561
562 ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->val.p,
563 cur_ext->val.len ) );
564 ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->val.len ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200565 ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OCTET_STRING ) );
Paul Bakkere5eae762013-08-26 12:05:14 +0200566
567 ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->oid.p,
568 cur_ext->oid.len ) );
569 ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->oid.len ) );
570 ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OID ) );
571
Paul Bakkerfde42702013-08-25 14:47:27 +0200572 ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
573 ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkere5eae762013-08-26 12:05:14 +0200574
575 cur_ext = cur_ext->next;
576
577 len += ext_len;
Paul Bakkerfde42702013-08-25 14:47:27 +0200578 }
579
Paul Bakkere5eae762013-08-26 12:05:14 +0200580 if( len )
Paul Bakkerfde42702013-08-25 14:47:27 +0200581 {
Paul Bakkere5eae762013-08-26 12:05:14 +0200582 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
583 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200584
Paul Bakkere5eae762013-08-26 12:05:14 +0200585 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
586 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SET ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200587
Paul Bakkere5eae762013-08-26 12:05:14 +0200588 ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200589
Paul Bakkere5eae762013-08-26 12:05:14 +0200590 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
591 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200592 }
593
Paul Bakkere5eae762013-08-26 12:05:14 +0200594 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000595 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
596
Paul Bakker8eabfc12013-08-25 10:18:25 +0200597 ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->E ) );
598 ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->N ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000599
600 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
601 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
602
603 if( c - tmp_buf < 1 )
604 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
605
Paul Bakker8eabfc12013-08-25 10:18:25 +0200606 /*
607 * AlgorithmIdentifier ::= SEQUENCE {
608 * algorithm OBJECT IDENTIFIER,
609 * parameters ANY DEFINED BY algorithm OPTIONAL }
610 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000611 *--c = 0;
612 pub_len += 1;
613
614 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
615 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_BIT_STRING ) );
616
617 ASN1_CHK_ADD( pub_len, asn1_write_algorithm_identifier( &c, tmp_buf, OID_PKCS1_RSA ) );
618
619 len += pub_len;
620 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, pub_len ) );
621 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
622
Paul Bakker9397dcb2013-09-06 09:55:26 +0200623 /*
624 * Subject ::= Name
625 */
626 ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000627
Paul Bakker8eabfc12013-08-25 10:18:25 +0200628 /*
629 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
630 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000631 ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) );
632
633 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
634 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200635
Paul Bakker8eabfc12013-08-25 10:18:25 +0200636 md( md_info_from_type( ctx->md_alg ), c, len, hash );
Paul Bakker3cac5e02012-02-16 14:08:06 +0000637
Paul Bakker8eabfc12013-08-25 10:18:25 +0200638 rsa_pkcs1_sign( ctx->rsa, NULL, NULL, RSA_PRIVATE, ctx->md_alg, 0, hash, sig );
Paul Bakker3cac5e02012-02-16 14:08:06 +0000639
640 // Generate correct OID
641 //
Paul Bakker8eabfc12013-08-25 10:18:25 +0200642 ret = oid_get_oid_by_sig_alg( POLARSSL_PK_RSA, ctx->md_alg, &sig_oid );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000643
644 c2 = buf + size - 1;
Paul Bakker8eabfc12013-08-25 10:18:25 +0200645 ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, ctx->rsa->len ) );
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200646
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000647 c2 -= len;
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200648 memcpy( c2, c, len );
649
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000650 len += sig_len;
651 ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
652 ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
653
654 return( len );
655}
656
Paul Bakker9397dcb2013-09-06 09:55:26 +0200657int x509write_crt_der( x509write_cert *ctx, unsigned char *buf, size_t size )
658{
659 int ret;
660 const char *sig_oid;
661 unsigned char *c, *c2;
662 unsigned char hash[64];
663 unsigned char sig[POLARSSL_MPI_MAX_SIZE];
664 unsigned char tmp_buf[2048];
665 size_t sub_len = 0, pub_len = 0, sig_len = 0;
666 size_t len = 0;
667 asn1_named_data *cur_ext = ctx->extensions;
668
669 c = tmp_buf + 2048 - 1;
670
671 // Generate correct OID
672 //
673 ret = oid_get_oid_by_sig_alg( POLARSSL_PK_RSA, ctx->md_alg, &sig_oid );
674 if( ret != 0 )
675 return( ret );
676
677
678 /*
679 * SubjectPublicKeyInfo ::= SEQUENCE {
680 * algorithm AlgorithmIdentifier,
681 * subjectPublicKey BIT STRING }
682 */
683 ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->subject_key->E ) );
684 ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->subject_key->N ) );
685
686 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
687 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
688
689 if( c - tmp_buf < 1 )
690 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
691
692 *--c = 0;
693 pub_len += 1;
694
695 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
696 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_BIT_STRING ) );
697
698 ASN1_CHK_ADD( pub_len, asn1_write_algorithm_identifier( &c, tmp_buf, OID_PKCS1_RSA ) );
699
700 len += pub_len;
701 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, pub_len ) );
702 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
703
704 /*
705 * Subject ::= Name
706 */
707 ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->subject ) );
708
709 /*
710 * Validity ::= SEQUENCE {
711 * notBefore Time,
712 * notAfter Time }
713 */
714 sub_len = 0;
715
716 ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_after,
717 X509_RFC5280_UTC_TIME_LEN ) );
718
719 ASN1_CHK_ADD( sub_len, x509_write_time( &c, tmp_buf, ctx->not_before,
720 X509_RFC5280_UTC_TIME_LEN ) );
721
722 len += sub_len;
723 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
724 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
725
726 /*
727 * Issuer ::= Name
728 */
729 ASN1_CHK_ADD( len, x509_write_names( &c, tmp_buf, ctx->issuer ) );
730
731 /*
732 * Signature ::= AlgorithmIdentifier
733 */
734 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, tmp_buf,
735 sig_oid ) );
736
737 /*
738 * Serial ::= INTEGER
739 */
740 ASN1_CHK_ADD( len, asn1_write_mpi( &c, tmp_buf, &ctx->serial ) );
741
742 /*
743 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
744 */
745 sub_len = 0;
746 ASN1_CHK_ADD( sub_len, asn1_write_int( &c, tmp_buf, ctx->version ) );
747 len += sub_len;
748 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
749 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) );
750
751 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
752 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
753
754 md( md_info_from_type( ctx->md_alg ), c, len, hash );
755
756 rsa_pkcs1_sign( ctx->issuer_key, NULL, NULL, RSA_PRIVATE, ctx->md_alg, 0, hash, sig );
757
758 c2 = buf + size - 1;
759 ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, ctx->issuer_key->len ) );
760
761 c2 -= len;
762 memcpy( c2, c, len );
763
764 len += sig_len;
765 ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
766 ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
767
768 return( len );
769}
770
771#define PEM_BEGIN_CRT "-----BEGIN CERTIFICATE-----\n"
772#define PEM_END_CRT "-----END CERTIFICATE-----\n"
773
Paul Bakkerf3df61a2013-08-26 17:22:23 +0200774#define PEM_BEGIN_CSR "-----BEGIN CERTIFICATE REQUEST-----\n"
775#define PEM_END_CSR "-----END CERTIFICATE REQUEST-----\n"
776
777#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
778#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
779
780#define PEM_BEGIN_PRIVATE_KEY "-----BEGIN RSA PRIVATE KEY-----\n"
781#define PEM_END_PRIVATE_KEY "-----END RSA PRIVATE KEY-----\n"
Paul Bakker135f1e92013-08-26 16:54:13 +0200782
783#if defined(POLARSSL_BASE64_C)
Paul Bakkerf3df61a2013-08-26 17:22:23 +0200784static int x509write_pemify( const char *begin_str, const char *end_str,
785 const unsigned char *der_data, size_t der_len,
786 unsigned char *buf, size_t size )
Paul Bakker135f1e92013-08-26 16:54:13 +0200787{
788 int ret;
Paul Bakker135f1e92013-08-26 16:54:13 +0200789 unsigned char base_buf[4096];
Paul Bakkerf3df61a2013-08-26 17:22:23 +0200790 unsigned char *c = base_buf, *p = buf;
791 size_t len = 0, olen = sizeof(base_buf);
Paul Bakker135f1e92013-08-26 16:54:13 +0200792
Paul Bakkerf3df61a2013-08-26 17:22:23 +0200793 if( ( ret = base64_encode( base_buf, &olen, der_data, der_len ) ) != 0 )
Paul Bakker135f1e92013-08-26 16:54:13 +0200794 return( ret );
795
Paul Bakkerf3df61a2013-08-26 17:22:23 +0200796 if( olen + strlen( begin_str ) + strlen( end_str ) +
Paul Bakker135f1e92013-08-26 16:54:13 +0200797 olen / 64 > size )
798 {
799 return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
800 }
801
Paul Bakkerf3df61a2013-08-26 17:22:23 +0200802 memcpy( p, begin_str, strlen( begin_str ) );
803 p += strlen( begin_str );
Paul Bakker135f1e92013-08-26 16:54:13 +0200804
805 while( olen )
806 {
807 len = ( olen > 64 ) ? 64 : olen;
808 memcpy( p, c, len );
809 olen -= len;
810 p += len;
811 c += len;
812 *p++ = '\n';
813 }
814
Paul Bakkerf3df61a2013-08-26 17:22:23 +0200815 memcpy( p, end_str, strlen( end_str ) );
816 p += strlen( end_str );
Paul Bakker135f1e92013-08-26 16:54:13 +0200817
818 *p = '\0';
819
820 return( 0 );
821}
Paul Bakkerf3df61a2013-08-26 17:22:23 +0200822
Paul Bakker9397dcb2013-09-06 09:55:26 +0200823int x509write_crt_pem( x509write_cert *crt, unsigned char *buf, size_t size )
824{
825 int ret;
826 unsigned char output_buf[4096];
827
828 if( ( ret = x509write_crt_der( crt, output_buf,
829 sizeof(output_buf) ) ) < 0 )
830 {
831 return( ret );
832 }
833
834 if( ( ret = x509write_pemify( PEM_BEGIN_CRT, PEM_END_CRT,
835 output_buf + sizeof(output_buf) - 1 - ret,
836 ret, buf, size ) ) != 0 )
837 {
838 return( ret );
839 }
840
841 return( 0 );
842}
843
Paul Bakkerf3df61a2013-08-26 17:22:23 +0200844int x509write_pubkey_pem( rsa_context *rsa, unsigned char *buf, size_t size )
845{
846 int ret;
847 unsigned char output_buf[4096];
848
849 if( ( ret = x509write_pubkey_der( rsa, output_buf,
850 sizeof(output_buf) ) ) < 0 )
851 {
852 return( ret );
853 }
854
855 if( ( ret = x509write_pemify( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
856 output_buf + sizeof(output_buf) - 1 - ret,
857 ret, buf, size ) ) != 0 )
858 {
859 return( ret );
860 }
861
862 return( 0 );
863}
864
865int x509write_key_pem( rsa_context *rsa, unsigned char *buf, size_t size )
866{
867 int ret;
868 unsigned char output_buf[4096];
869
870 if( ( ret = x509write_key_der( rsa, output_buf,
871 sizeof(output_buf) ) ) < 0 )
872 {
873 return( ret );
874 }
875
876 if( ( ret = x509write_pemify( PEM_BEGIN_PRIVATE_KEY, PEM_END_PRIVATE_KEY,
877 output_buf + sizeof(output_buf) - 1 - ret,
878 ret, buf, size ) ) != 0 )
879 {
880 return( ret );
881 }
882
883 return( 0 );
884}
885
886int x509write_csr_pem( x509_csr *ctx, unsigned char *buf, size_t size )
887{
888 int ret;
889 unsigned char output_buf[4096];
890
891 if( ( ret = x509write_csr_der( ctx, output_buf,
892 sizeof(output_buf) ) ) < 0 )
893 {
894 return( ret );
895 }
896
897 if( ( ret = x509write_pemify( PEM_BEGIN_CSR, PEM_END_CSR,
898 output_buf + sizeof(output_buf) - 1 - ret,
899 ret, buf, size ) ) != 0 )
900 {
901 return( ret );
902 }
903
904 return( 0 );
905}
Paul Bakker135f1e92013-08-26 16:54:13 +0200906#endif /* POLARSSL_BASE64_C */
907
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000908#endif