blob: 12cc0e17757374a4ba37969af7c6fa7470e14c0c [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 Bakker8eabfc12013-08-25 10:18:25 +020036#if defined(POLARSSL_MEMORY_C)
37#include "polarssl/memory.h"
38#else
39#include <stdlib.h>
40#define polarssl_malloc malloc
41#define polarssl_free free
42#endif
43
Paul Bakker82e29452013-08-25 11:01:31 +020044void x509write_csr_init( x509_csr *ctx )
Paul Bakker8eabfc12013-08-25 10:18:25 +020045{
Paul Bakker82e29452013-08-25 11:01:31 +020046 memset( ctx, 0, sizeof(x509_csr) );
Paul Bakker8eabfc12013-08-25 10:18:25 +020047}
48
Paul Bakker82e29452013-08-25 11:01:31 +020049void x509write_csr_free( x509_csr *ctx )
Paul Bakker8eabfc12013-08-25 10:18:25 +020050{
51 x509_req_name *cur;
Paul Bakkere5eae762013-08-26 12:05:14 +020052 asn1_named_data *cur_ext;
Paul Bakker8eabfc12013-08-25 10:18:25 +020053
54 while( ( cur = ctx->subject ) != NULL )
55 {
56 ctx->subject = cur->next;
57 polarssl_free( cur );
58 }
59
Paul Bakkere5eae762013-08-26 12:05:14 +020060 while( ( cur_ext = ctx->extensions ) != NULL )
61 {
62 ctx->extensions = cur_ext->next;
63 asn1_free_named_data( cur_ext );
64 polarssl_free( cur_ext );
65 }
66
Paul Bakker82e29452013-08-25 11:01:31 +020067 memset( ctx, 0, sizeof(x509_csr) );
Paul Bakker8eabfc12013-08-25 10:18:25 +020068}
69
Paul Bakker82e29452013-08-25 11:01:31 +020070void x509write_csr_set_md_alg( x509_csr *ctx, md_type_t md_alg )
Paul Bakker8eabfc12013-08-25 10:18:25 +020071{
72 ctx->md_alg = md_alg;
73}
74
Paul Bakker82e29452013-08-25 11:01:31 +020075void x509write_csr_set_rsa_key( x509_csr *ctx, rsa_context *rsa )
Paul Bakker8eabfc12013-08-25 10:18:25 +020076{
77 ctx->rsa = rsa;
78}
79
Paul Bakker82e29452013-08-25 11:01:31 +020080int x509write_csr_set_subject_name( x509_csr *ctx, char *subject_name )
Paul Bakker8eabfc12013-08-25 10:18:25 +020081{
82 int ret = 0;
83 char *s = subject_name, *c = s;
84 char *end = s + strlen( s );
85 char *oid = NULL;
86 int in_tag = 1;
Paul Bakker21307962013-08-25 10:33:27 +020087 x509_req_name *cur;
Paul Bakker8eabfc12013-08-25 10:18:25 +020088
89 while( ctx->subject )
90 {
91 cur = ctx->subject;
92 ctx->subject = ctx->subject->next;
93 polarssl_free( cur );
94 }
95
96 while( c <= end )
97 {
98 if( in_tag && *c == '=' )
99 {
100 if( memcmp( s, "CN", 2 ) == 0 && c - s == 2 )
101 oid = OID_AT_CN;
102 else if( memcmp( s, "C", 1 ) == 0 && c - s == 1 )
103 oid = OID_AT_COUNTRY;
104 else if( memcmp( s, "O", 1 ) == 0 && c - s == 1 )
105 oid = OID_AT_ORGANIZATION;
106 else if( memcmp( s, "L", 1 ) == 0 && c - s == 1 )
107 oid = OID_AT_LOCALITY;
108 else if( memcmp( s, "R", 1 ) == 0 && c - s == 1 )
109 oid = OID_PKCS9_EMAIL;
110 else if( memcmp( s, "OU", 2 ) == 0 && c - s == 2 )
111 oid = OID_AT_ORG_UNIT;
112 else if( memcmp( s, "ST", 2 ) == 0 && c - s == 2 )
113 oid = OID_AT_STATE;
114 else
115 {
Paul Bakker0e06c0f2013-08-25 11:21:30 +0200116 ret = POLARSSL_ERR_X509WRITE_UNKNOWN_OID;
Paul Bakker8eabfc12013-08-25 10:18:25 +0200117 goto exit;
118 }
119
120 s = c + 1;
121 in_tag = 0;
122 }
123
124 if( !in_tag && ( *c == ',' || c == end ) )
125 {
126 if( c - s > 127 )
127 {
Paul Bakker0e06c0f2013-08-25 11:21:30 +0200128 ret = POLARSSL_ERR_X509WRITE_BAD_INPUT_DATA;
Paul Bakker8eabfc12013-08-25 10:18:25 +0200129 goto exit;
130 }
131
Paul Bakker21307962013-08-25 10:33:27 +0200132 cur = polarssl_malloc( sizeof(x509_req_name) );
Paul Bakker8eabfc12013-08-25 10:18:25 +0200133
134 if( cur == NULL )
135 {
Paul Bakker0e06c0f2013-08-25 11:21:30 +0200136 ret = POLARSSL_ERR_X509WRITE_MALLOC_FAILED;
Paul Bakker8eabfc12013-08-25 10:18:25 +0200137 goto exit;
138 }
139
140 memset( cur, 0, sizeof(x509_req_name) );
141
Paul Bakker21307962013-08-25 10:33:27 +0200142 cur->next = ctx->subject;
143 ctx->subject = cur;
144
Paul Bakker8eabfc12013-08-25 10:18:25 +0200145 strncpy( cur->oid, oid, strlen( oid ) );
146 strncpy( cur->name, s, c - s );
147
148 s = c + 1;
149 in_tag = 1;
150 }
151 c++;
152 }
153
154exit:
155
156 return( ret );
157}
158
Paul Bakker1c0e5502013-08-26 13:41:01 +0200159int x509write_csr_set_extension( x509_csr *ctx,
160 const char *oid, size_t oid_len,
161 const unsigned char *val, size_t val_len )
Paul Bakkerfde42702013-08-25 14:47:27 +0200162{
Paul Bakkere5eae762013-08-26 12:05:14 +0200163 asn1_named_data *cur;
Paul Bakkere5eae762013-08-26 12:05:14 +0200164
Paul Bakker1c0e5502013-08-26 13:41:01 +0200165 if( ( cur = asn1_find_named_data( ctx->extensions, oid,
166 oid_len ) ) == NULL )
Paul Bakkere5eae762013-08-26 12:05:14 +0200167 {
168 cur = polarssl_malloc( sizeof(asn1_named_data) );
169 if( cur == NULL )
170 return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
171
172 memset( cur, 0, sizeof(asn1_named_data) );
173
Paul Bakker1c0e5502013-08-26 13:41:01 +0200174 cur->oid.len = oid_len;
175 cur->oid.p = polarssl_malloc( oid_len );
Paul Bakkere5eae762013-08-26 12:05:14 +0200176 if( cur->oid.p == NULL )
177 {
Paul Bakker1c0e5502013-08-26 13:41:01 +0200178 polarssl_free( cur );
Paul Bakkere5eae762013-08-26 12:05:14 +0200179 return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
180 }
181
Paul Bakker1c0e5502013-08-26 13:41:01 +0200182 cur->val.len = val_len;
183 cur->val.p = polarssl_malloc( val_len );
Paul Bakkere5eae762013-08-26 12:05:14 +0200184 if( cur->val.p == NULL )
185 {
Paul Bakker1c0e5502013-08-26 13:41:01 +0200186 polarssl_free( cur->oid.p );
187 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 memcpy( cur->oid.p, oid, oid_len );
Paul Bakkere5eae762013-08-26 12:05:14 +0200192
193 cur->next = ctx->extensions;
194 ctx->extensions = cur;
195 }
196
Paul Bakker1c0e5502013-08-26 13:41:01 +0200197 if( cur->val.len != val_len )
198 {
199 polarssl_free( cur->val.p );
200
201 cur->val.len = val_len;
202 cur->val.p = polarssl_malloc( val_len );
203 if( cur->val.p == NULL )
204 {
205 polarssl_free( cur->oid.p );
206 polarssl_free( cur );
207 return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
208 }
209 }
210
211 memcpy( cur->val.p, val, val_len );
212
213 return( 0 );
214}
215
216int x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage )
217{
218 unsigned char buf[4];
219 unsigned char *c;
220 int ret;
221
222 c = buf + 4;
223
Paul Bakker624d03a2013-08-26 14:12:57 +0200224 if( ( ret = asn1_write_bitstring( &c, buf, &key_usage, 7 ) ) != 4 )
Paul Bakker1c0e5502013-08-26 13:41:01 +0200225 return( ret );
226
227 ret = x509write_csr_set_extension( ctx, OID_KEY_USAGE,
228 OID_SIZE( OID_KEY_USAGE ),
229 buf, 4 );
230 if( ret != 0 )
231 return( ret );
232
233 return( 0 );
234}
235
236int x509write_csr_set_ns_cert_type( x509_csr *ctx, unsigned char ns_cert_type )
237{
238 unsigned char buf[4];
239 unsigned char *c;
240 int ret;
241
242 c = buf + 4;
243
244 if( ( ret = asn1_write_bitstring( &c, buf, &ns_cert_type, 8 ) ) != 4 )
245 return( ret );
246
247 ret = x509write_csr_set_extension( ctx, OID_NS_CERT_TYPE,
248 OID_SIZE( OID_NS_CERT_TYPE ),
249 buf, 4 );
250 if( ret != 0 )
251 return( ret );
Paul Bakkere5eae762013-08-26 12:05:14 +0200252
253 return( 0 );
Paul Bakkerfde42702013-08-25 14:47:27 +0200254}
255
Paul Bakker82e29452013-08-25 11:01:31 +0200256int x509write_pubkey_der( rsa_context *rsa, unsigned char *buf, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000257{
258 int ret;
259 unsigned char *c;
260 size_t len = 0;
261
262 c = buf + size - 1;
263
Paul Bakker8eabfc12013-08-25 10:18:25 +0200264 /*
265 * RSAPublicKey ::= SEQUENCE {
266 * modulus INTEGER, -- n
267 * publicExponent INTEGER -- e
268 * }
269 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000270 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
271 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
272
273 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
274 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
275
276 if( c - buf < 1 )
277 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
278
Paul Bakker8eabfc12013-08-25 10:18:25 +0200279 /*
280 * SubjectPublicKeyInfo ::= SEQUENCE {
281 * algorithm AlgorithmIdentifier,
282 * subjectPublicKey BIT STRING }
283 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000284 *--c = 0;
285 len += 1;
286
287 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
288 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
289
290 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, OID_PKCS1_RSA ) );
291
292 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
293 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
294
295 return( len );
296}
297
Paul Bakker82e29452013-08-25 11:01:31 +0200298int x509write_key_der( rsa_context *rsa, unsigned char *buf, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000299{
300 int ret;
301 unsigned char *c;
302 size_t len = 0;
303
304 c = buf + size - 1;
305
306 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) );
307 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) );
308 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) );
309 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) );
310 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) );
311 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) );
312 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
313 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
314 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) );
315
316 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
317 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
318
319 // TODO: Make NON RSA Specific variant later on
320/* *--c = 0;
321 len += 1;
322
323 len += asn1_write_len( &c, len);
324 len += asn1_write_tag( &c, ASN1_BIT_STRING );
325
326 len += asn1_write_oid( &c, OID_PKCS1_RSA );
327
328 len += asn1_write_int( &c, 0 );
329
330 len += asn1_write_len( &c, len);
331 len += asn1_write_tag( &c, ASN1_CONSTRUCTED | ASN1_SEQUENCE );*/
332
333/* for(i = 0; i < len; ++i)
334 {
335 if (i % 16 == 0 ) printf("\n");
336 printf("%02x ", c[i]);
337 }
338 printf("\n");*/
339
340 return( len );
341}
342
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200343static int x509_write_name( unsigned char **p, unsigned char *start, char *oid,
344 char *name )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000345{
346 int ret;
347 size_t string_len = 0;
348 size_t oid_len = 0;
349 size_t len = 0;
350
Paul Bakker05888152012-02-16 10:26:57 +0000351 // Write PrintableString for all except OID_PKCS9_EMAIL
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000352 //
Paul Bakker05888152012-02-16 10:26:57 +0000353 if( OID_SIZE( OID_PKCS9_EMAIL ) == strlen( oid ) &&
354 memcmp( oid, OID_PKCS9_EMAIL, strlen( oid ) ) == 0 )
355 {
356 ASN1_CHK_ADD( string_len, asn1_write_ia5_string( p, start, name ) );
357 }
358 else
359 ASN1_CHK_ADD( string_len, asn1_write_printable_string( p, start, name ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000360
361 // Write OID
362 //
363 ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, oid ) );
364
365 len = oid_len + string_len;
366 ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + string_len ) );
367 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
368
369 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
370 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SET ) );
371
372 return( len );
373}
374
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200375static int x509_write_sig( unsigned char **p, unsigned char *start,
376 const char *oid, unsigned char *sig, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000377{
378 int ret;
379 size_t len = 0;
380
381 if( *p - start < (int) size + 1 )
382 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
383
384 len = size;
385 (*p) -= len;
386 memcpy( *p, sig, len );
387
388 *--(*p) = 0;
389 len += 1;
390
391 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
392 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
393
394 // Write OID
395 //
396 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid ) );
397
398 return( len );
399}
400
Paul Bakker82e29452013-08-25 11:01:31 +0200401int x509write_csr_der( x509_csr *ctx, unsigned char *buf, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000402{
403 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200404 const char *sig_oid;
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000405 unsigned char *c, *c2;
Paul Bakker3cac5e02012-02-16 14:08:06 +0000406 unsigned char hash[64];
407 unsigned char sig[POLARSSL_MPI_MAX_SIZE];
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000408 unsigned char tmp_buf[2048];
Paul Bakkere5eae762013-08-26 12:05:14 +0200409 size_t sub_len = 0, pub_len = 0, sig_len = 0;
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000410 size_t len = 0;
Paul Bakker8eabfc12013-08-25 10:18:25 +0200411 x509_req_name *cur = ctx->subject;
Paul Bakkere5eae762013-08-26 12:05:14 +0200412 asn1_named_data *cur_ext = ctx->extensions;
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000413
414 c = tmp_buf + 2048 - 1;
415
Paul Bakkere5eae762013-08-26 12:05:14 +0200416 while( cur_ext != NULL )
Paul Bakkerfde42702013-08-25 14:47:27 +0200417 {
Paul Bakkere5eae762013-08-26 12:05:14 +0200418 size_t ext_len = 0;
419
420 ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->val.p,
421 cur_ext->val.len ) );
422 ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->val.len ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200423 ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OCTET_STRING ) );
Paul Bakkere5eae762013-08-26 12:05:14 +0200424
425 ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->oid.p,
426 cur_ext->oid.len ) );
427 ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->oid.len ) );
428 ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OID ) );
429
Paul Bakkerfde42702013-08-25 14:47:27 +0200430 ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
431 ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkere5eae762013-08-26 12:05:14 +0200432
433 cur_ext = cur_ext->next;
434
435 len += ext_len;
Paul Bakkerfde42702013-08-25 14:47:27 +0200436 }
437
Paul Bakkere5eae762013-08-26 12:05:14 +0200438 if( len )
Paul Bakkerfde42702013-08-25 14:47:27 +0200439 {
Paul Bakkere5eae762013-08-26 12:05:14 +0200440 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
441 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200442
Paul Bakkere5eae762013-08-26 12:05:14 +0200443 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
444 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SET ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200445
Paul Bakkere5eae762013-08-26 12:05:14 +0200446 ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200447
Paul Bakkere5eae762013-08-26 12:05:14 +0200448 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
449 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200450 }
451
Paul Bakkere5eae762013-08-26 12:05:14 +0200452 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000453 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
454
Paul Bakker8eabfc12013-08-25 10:18:25 +0200455 ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->E ) );
456 ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->N ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000457
458 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
459 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
460
461 if( c - tmp_buf < 1 )
462 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
463
Paul Bakker8eabfc12013-08-25 10:18:25 +0200464 /*
465 * AlgorithmIdentifier ::= SEQUENCE {
466 * algorithm OBJECT IDENTIFIER,
467 * parameters ANY DEFINED BY algorithm OPTIONAL }
468 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000469 *--c = 0;
470 pub_len += 1;
471
472 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
473 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_BIT_STRING ) );
474
475 ASN1_CHK_ADD( pub_len, asn1_write_algorithm_identifier( &c, tmp_buf, OID_PKCS1_RSA ) );
476
477 len += pub_len;
478 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, pub_len ) );
479 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
480
481 while( cur != NULL )
482 {
483 ASN1_CHK_ADD( sub_len, x509_write_name( &c, tmp_buf, cur->oid, cur->name ) );
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200484
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000485 cur = cur->next;
486 }
487
488 len += sub_len;
489 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
490 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
491
Paul Bakker8eabfc12013-08-25 10:18:25 +0200492 /*
493 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
494 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000495 ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) );
496
497 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
498 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200499
Paul Bakker8eabfc12013-08-25 10:18:25 +0200500 md( md_info_from_type( ctx->md_alg ), c, len, hash );
Paul Bakker3cac5e02012-02-16 14:08:06 +0000501
Paul Bakker8eabfc12013-08-25 10:18:25 +0200502 rsa_pkcs1_sign( ctx->rsa, NULL, NULL, RSA_PRIVATE, ctx->md_alg, 0, hash, sig );
Paul Bakker3cac5e02012-02-16 14:08:06 +0000503
504 // Generate correct OID
505 //
Paul Bakker8eabfc12013-08-25 10:18:25 +0200506 ret = oid_get_oid_by_sig_alg( POLARSSL_PK_RSA, ctx->md_alg, &sig_oid );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000507
508 c2 = buf + size - 1;
Paul Bakker8eabfc12013-08-25 10:18:25 +0200509 ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, ctx->rsa->len ) );
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200510
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000511 c2 -= len;
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200512 memcpy( c2, c, len );
513
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000514 len += sig_len;
515 ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
516 ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
517
518 return( len );
519}
520
521#endif