blob: 0ca7733b2b6bcaf243acc2a5ad4b9f38812a8494 [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 Bakkere5eae762013-08-26 12:05:14 +0200159int x509write_csr_set_key_usage( x509_csr *ctx, unsigned char key_usage )
Paul Bakkerfde42702013-08-25 14:47:27 +0200160{
Paul Bakkere5eae762013-08-26 12:05:14 +0200161 asn1_named_data *cur;
162 unsigned char *c;
163 int len;
164
165 if( ( cur = asn1_find_named_data( ctx->extensions, OID_KEY_USAGE,
166 OID_SIZE( OID_KEY_USAGE ) ) ) == NULL )
167 {
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
174 cur->oid.len = OID_SIZE( OID_KEY_USAGE );
175 cur->oid.p = polarssl_malloc( cur->oid.len );
176 if( cur->oid.p == NULL )
177 {
178 free( cur );
179 return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
180 }
181
182 cur->val.len = 4;
183 cur->val.p = polarssl_malloc( cur->val.len );
184 if( cur->val.p == NULL )
185 {
186 free( cur->oid.p );
187 free( cur );
188 return( POLARSSL_ERR_X509WRITE_MALLOC_FAILED );
189 }
190
191 memcpy( cur->oid.p, OID_KEY_USAGE, OID_SIZE( OID_KEY_USAGE ) );
192
193 cur->next = ctx->extensions;
194 ctx->extensions = cur;
195 }
196
197 c = cur->val.p + cur->val.len;
198 if( ( len = asn1_write_bitstring( &c, cur->val.p, &key_usage, 6 ) ) < 0 )
199exit(1);
200
201 return( 0 );
Paul Bakkerfde42702013-08-25 14:47:27 +0200202}
203
Paul Bakker82e29452013-08-25 11:01:31 +0200204int x509write_pubkey_der( rsa_context *rsa, unsigned char *buf, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000205{
206 int ret;
207 unsigned char *c;
208 size_t len = 0;
209
210 c = buf + size - 1;
211
Paul Bakker8eabfc12013-08-25 10:18:25 +0200212 /*
213 * RSAPublicKey ::= SEQUENCE {
214 * modulus INTEGER, -- n
215 * publicExponent INTEGER -- e
216 * }
217 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000218 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
219 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
220
221 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
222 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
223
224 if( c - buf < 1 )
225 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
226
Paul Bakker8eabfc12013-08-25 10:18:25 +0200227 /*
228 * SubjectPublicKeyInfo ::= SEQUENCE {
229 * algorithm AlgorithmIdentifier,
230 * subjectPublicKey BIT STRING }
231 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000232 *--c = 0;
233 len += 1;
234
235 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
236 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
237
238 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, OID_PKCS1_RSA ) );
239
240 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
241 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
242
243 return( len );
244}
245
Paul Bakker82e29452013-08-25 11:01:31 +0200246int x509write_key_der( rsa_context *rsa, unsigned char *buf, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000247{
248 int ret;
249 unsigned char *c;
250 size_t len = 0;
251
252 c = buf + size - 1;
253
254 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) );
255 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) );
256 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) );
257 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) );
258 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) );
259 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) );
260 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
261 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
262 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) );
263
264 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
265 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
266
267 // TODO: Make NON RSA Specific variant later on
268/* *--c = 0;
269 len += 1;
270
271 len += asn1_write_len( &c, len);
272 len += asn1_write_tag( &c, ASN1_BIT_STRING );
273
274 len += asn1_write_oid( &c, OID_PKCS1_RSA );
275
276 len += asn1_write_int( &c, 0 );
277
278 len += asn1_write_len( &c, len);
279 len += asn1_write_tag( &c, ASN1_CONSTRUCTED | ASN1_SEQUENCE );*/
280
281/* for(i = 0; i < len; ++i)
282 {
283 if (i % 16 == 0 ) printf("\n");
284 printf("%02x ", c[i]);
285 }
286 printf("\n");*/
287
288 return( len );
289}
290
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200291static int x509_write_name( unsigned char **p, unsigned char *start, char *oid,
292 char *name )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000293{
294 int ret;
295 size_t string_len = 0;
296 size_t oid_len = 0;
297 size_t len = 0;
298
Paul Bakker05888152012-02-16 10:26:57 +0000299 // Write PrintableString for all except OID_PKCS9_EMAIL
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000300 //
Paul Bakker05888152012-02-16 10:26:57 +0000301 if( OID_SIZE( OID_PKCS9_EMAIL ) == strlen( oid ) &&
302 memcmp( oid, OID_PKCS9_EMAIL, strlen( oid ) ) == 0 )
303 {
304 ASN1_CHK_ADD( string_len, asn1_write_ia5_string( p, start, name ) );
305 }
306 else
307 ASN1_CHK_ADD( string_len, asn1_write_printable_string( p, start, name ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000308
309 // Write OID
310 //
311 ASN1_CHK_ADD( oid_len, asn1_write_oid( p, start, oid ) );
312
313 len = oid_len + string_len;
314 ASN1_CHK_ADD( len, asn1_write_len( p, start, oid_len + string_len ) );
315 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
316
317 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
318 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SET ) );
319
320 return( len );
321}
322
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200323static int x509_write_sig( unsigned char **p, unsigned char *start,
324 const char *oid, unsigned char *sig, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000325{
326 int ret;
327 size_t len = 0;
328
329 if( *p - start < (int) size + 1 )
330 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
331
332 len = size;
333 (*p) -= len;
334 memcpy( *p, sig, len );
335
336 *--(*p) = 0;
337 len += 1;
338
339 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
340 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_BIT_STRING ) );
341
342 // Write OID
343 //
344 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( p, start, oid ) );
345
346 return( len );
347}
348
Paul Bakker82e29452013-08-25 11:01:31 +0200349int x509write_csr_der( x509_csr *ctx, unsigned char *buf, size_t size )
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000350{
351 int ret;
Paul Bakkerc70b9822013-04-07 22:00:46 +0200352 const char *sig_oid;
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000353 unsigned char *c, *c2;
Paul Bakker3cac5e02012-02-16 14:08:06 +0000354 unsigned char hash[64];
355 unsigned char sig[POLARSSL_MPI_MAX_SIZE];
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000356 unsigned char tmp_buf[2048];
Paul Bakkere5eae762013-08-26 12:05:14 +0200357 size_t sub_len = 0, pub_len = 0, sig_len = 0;
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000358 size_t len = 0;
Paul Bakker8eabfc12013-08-25 10:18:25 +0200359 x509_req_name *cur = ctx->subject;
Paul Bakkere5eae762013-08-26 12:05:14 +0200360 asn1_named_data *cur_ext = ctx->extensions;
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000361
362 c = tmp_buf + 2048 - 1;
363
Paul Bakkere5eae762013-08-26 12:05:14 +0200364 while( cur_ext != NULL )
Paul Bakkerfde42702013-08-25 14:47:27 +0200365 {
Paul Bakkere5eae762013-08-26 12:05:14 +0200366 size_t ext_len = 0;
367
368 ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->val.p,
369 cur_ext->val.len ) );
370 ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->val.len ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200371 ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OCTET_STRING ) );
Paul Bakkere5eae762013-08-26 12:05:14 +0200372
373 ASN1_CHK_ADD( ext_len, asn1_write_raw_buffer( &c, tmp_buf, cur_ext->oid.p,
374 cur_ext->oid.len ) );
375 ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, cur_ext->oid.len ) );
376 ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_OID ) );
377
Paul Bakkerfde42702013-08-25 14:47:27 +0200378 ASN1_CHK_ADD( ext_len, asn1_write_len( &c, tmp_buf, ext_len ) );
379 ASN1_CHK_ADD( ext_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkere5eae762013-08-26 12:05:14 +0200380
381 cur_ext = cur_ext->next;
382
383 len += ext_len;
Paul Bakkerfde42702013-08-25 14:47:27 +0200384 }
385
Paul Bakkere5eae762013-08-26 12:05:14 +0200386 if( len )
Paul Bakkerfde42702013-08-25 14:47:27 +0200387 {
Paul Bakkere5eae762013-08-26 12:05:14 +0200388 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
389 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200390
Paul Bakkere5eae762013-08-26 12:05:14 +0200391 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
392 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SET ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200393
Paul Bakkere5eae762013-08-26 12:05:14 +0200394 ASN1_CHK_ADD( len, asn1_write_oid( &c, tmp_buf, OID_PKCS9_CSR_EXT_REQ ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200395
Paul Bakkere5eae762013-08-26 12:05:14 +0200396 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
397 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkerfde42702013-08-25 14:47:27 +0200398 }
399
Paul Bakkere5eae762013-08-26 12:05:14 +0200400 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000401 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_CONTEXT_SPECIFIC ) );
402
Paul Bakker8eabfc12013-08-25 10:18:25 +0200403 ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->E ) );
404 ASN1_CHK_ADD( pub_len, asn1_write_mpi( &c, tmp_buf, &ctx->rsa->N ) );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000405
406 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
407 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
408
409 if( c - tmp_buf < 1 )
410 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
411
Paul Bakker8eabfc12013-08-25 10:18:25 +0200412 /*
413 * AlgorithmIdentifier ::= SEQUENCE {
414 * algorithm OBJECT IDENTIFIER,
415 * parameters ANY DEFINED BY algorithm OPTIONAL }
416 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000417 *--c = 0;
418 pub_len += 1;
419
420 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, tmp_buf, pub_len ) );
421 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, tmp_buf, ASN1_BIT_STRING ) );
422
423 ASN1_CHK_ADD( pub_len, asn1_write_algorithm_identifier( &c, tmp_buf, OID_PKCS1_RSA ) );
424
425 len += pub_len;
426 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, pub_len ) );
427 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
428
429 while( cur != NULL )
430 {
431 ASN1_CHK_ADD( sub_len, x509_write_name( &c, tmp_buf, cur->oid, cur->name ) );
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200432
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000433 cur = cur->next;
434 }
435
436 len += sub_len;
437 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, sub_len ) );
438 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
439
Paul Bakker8eabfc12013-08-25 10:18:25 +0200440 /*
441 * Version ::= INTEGER { v1(0), v2(1), v3(2) }
442 */
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000443 ASN1_CHK_ADD( len, asn1_write_int( &c, tmp_buf, 0 ) );
444
445 ASN1_CHK_ADD( len, asn1_write_len( &c, tmp_buf, len ) );
446 ASN1_CHK_ADD( len, asn1_write_tag( &c, tmp_buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200447
Paul Bakker8eabfc12013-08-25 10:18:25 +0200448 md( md_info_from_type( ctx->md_alg ), c, len, hash );
Paul Bakker3cac5e02012-02-16 14:08:06 +0000449
Paul Bakker8eabfc12013-08-25 10:18:25 +0200450 rsa_pkcs1_sign( ctx->rsa, NULL, NULL, RSA_PRIVATE, ctx->md_alg, 0, hash, sig );
Paul Bakker3cac5e02012-02-16 14:08:06 +0000451
452 // Generate correct OID
453 //
Paul Bakker8eabfc12013-08-25 10:18:25 +0200454 ret = oid_get_oid_by_sig_alg( POLARSSL_PK_RSA, ctx->md_alg, &sig_oid );
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000455
456 c2 = buf + size - 1;
Paul Bakker8eabfc12013-08-25 10:18:25 +0200457 ASN1_CHK_ADD( sig_len, x509_write_sig( &c2, buf, sig_oid, sig, ctx->rsa->len ) );
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200458
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000459 c2 -= len;
Paul Bakkerb6c5d2e2013-06-25 16:25:17 +0200460 memcpy( c2, c, len );
461
Paul Bakkerbdb912d2012-02-13 23:11:30 +0000462 len += sig_len;
463 ASN1_CHK_ADD( len, asn1_write_len( &c2, buf, len ) );
464 ASN1_CHK_ADD( len, asn1_write_tag( &c2, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
465
466 return( len );
467}
468
469#endif