blob: f761ea04cc7bc485364fd4ff99652eddca1ad8a1 [file] [log] [blame]
Paul Bakkerc7bb02b2013-09-15 14:54:56 +02001/*
2 * Public Key layer for writing key files and structures
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerc7bb02b2013-09-15 14:54:56 +02005 *
Manuel Pégourié-Gonnard860b5162015-01-28 17:12:07 +00006 * This file is part of mbed TLS (https://polarssl.org)
Paul Bakkerc7bb02b2013-09-15 14:54:56 +02007 *
Paul Bakkerc7bb02b2013-09-15 14:54:56 +02008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020023#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakkerc7bb02b2013-09-15 14:54:56 +020024#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020025#else
26#include POLARSSL_CONFIG_FILE
27#endif
Paul Bakkerc7bb02b2013-09-15 14:54:56 +020028
Paul Bakker4606c732013-09-15 17:04:23 +020029#if defined(POLARSSL_PK_WRITE_C)
Paul Bakkerc7bb02b2013-09-15 14:54:56 +020030
31#include "polarssl/pk.h"
32#include "polarssl/asn1write.h"
33#include "polarssl/oid.h"
34
35#if defined(POLARSSL_RSA_C)
36#include "polarssl/rsa.h"
37#endif
38#if defined(POLARSSL_ECP_C)
39#include "polarssl/ecp.h"
40#endif
41#if defined(POLARSSL_ECDSA_C)
42#include "polarssl/ecdsa.h"
43#endif
Paul Bakkercff68422013-09-15 20:43:33 +020044#if defined(POLARSSL_PEM_WRITE_C)
Paul Bakker77e23fb2013-09-15 20:03:26 +020045#include "polarssl/pem.h"
Paul Bakkerc7bb02b2013-09-15 14:54:56 +020046#endif
47
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#if defined(POLARSSL_PLATFORM_C)
49#include "polarssl/platform.h"
Paul Bakkerc7bb02b2013-09-15 14:54:56 +020050#else
51#include <stdlib.h>
52#define polarssl_malloc malloc
53#define polarssl_free free
54#endif
55
56#if defined(POLARSSL_RSA_C)
57/*
58 * RSAPublicKey ::= SEQUENCE {
59 * modulus INTEGER, -- n
60 * publicExponent INTEGER -- e
61 * }
62 */
63static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
64 rsa_context *rsa )
65{
66 int ret;
67 size_t len = 0;
68
69 ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->E ) );
70 ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) );
71
72 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +020073 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED |
74 ASN1_SEQUENCE ) );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +020075
Paul Bakkerb9cfaa02013-10-11 18:58:55 +020076 return( (int) len );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +020077}
78#endif /* POLARSSL_RSA_C */
79
80#if defined(POLARSSL_ECP_C)
81/*
82 * EC public key is an EC point
83 */
84static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
85 ecp_keypair *ec )
86{
87 int ret;
88 size_t len = 0;
89 unsigned char buf[POLARSSL_ECP_MAX_PT_LEN];
90
91 if( ( ret = ecp_point_write_binary( &ec->grp, &ec->Q,
92 POLARSSL_ECP_PF_UNCOMPRESSED,
93 &len, buf, sizeof( buf ) ) ) != 0 )
94 {
95 return( ret );
96 }
97
98 if( *p - start < (int) len )
99 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
100
101 *p -= len;
102 memcpy( *p, buf, len );
103
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200104 return( (int) len );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200105}
106
107/*
108 * ECParameters ::= CHOICE {
109 * namedCurve OBJECT IDENTIFIER
110 * }
111 */
112static int pk_write_ec_param( unsigned char **p, unsigned char *start,
113 ecp_keypair *ec )
114{
115 int ret;
116 size_t len = 0;
117 const char *oid;
118 size_t oid_len;
119
120 if( ( ret = oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
121 return( ret );
122
123 ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
124
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200125 return( (int) len );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200126}
127#endif /* POLARSSL_ECP_C */
128
129int pk_write_pubkey( unsigned char **p, unsigned char *start,
130 const pk_context *key )
131{
132 int ret;
133 size_t len = 0;
134
135#if defined(POLARSSL_RSA_C)
136 if( pk_get_type( key ) == POLARSSL_PK_RSA )
137 ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, pk_rsa( *key ) ) );
138 else
139#endif
140#if defined(POLARSSL_ECP_C)
141 if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
142 ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, pk_ec( *key ) ) );
143 else
144#endif
145 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
146
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200147 return( (int) len );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200148}
149
150int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size )
151{
152 int ret;
153 unsigned char *c;
154 size_t len = 0, par_len = 0, oid_len;
155 const char *oid;
156
157 c = buf + size;
158
159 ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) );
160
161 if( c - buf < 1 )
162 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
163
164 /*
165 * SubjectPublicKeyInfo ::= SEQUENCE {
166 * algorithm AlgorithmIdentifier,
167 * subjectPublicKey BIT STRING }
168 */
169 *--c = 0;
170 len += 1;
171
172 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
173 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
174
175 if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ),
176 &oid, &oid_len ) ) != 0 )
177 {
178 return( ret );
179 }
180
181#if defined(POLARSSL_ECP_C)
182 if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
183 {
184 ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) );
185 }
186#endif
187
188 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
189 par_len ) );
190
191 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200192 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED |
193 ASN1_SEQUENCE ) );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200194
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200195 return( (int) len );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200196}
197
198int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size )
199{
200 int ret;
201 unsigned char *c = buf + size;
202 size_t len = 0;
203
204#if defined(POLARSSL_RSA_C)
205 if( pk_get_type( key ) == POLARSSL_PK_RSA )
206 {
207 rsa_context *rsa = pk_rsa( *key );
208
209 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) );
210 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) );
211 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) );
212 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) );
213 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) );
214 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) );
215 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
216 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
217 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) );
218
219 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200220 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED |
221 ASN1_SEQUENCE ) );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200222 }
223 else
Paul Bakker9af723c2014-05-01 13:03:14 +0200224#endif /* POLARSSL_RSA_C */
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200225#if defined(POLARSSL_ECP_C)
226 if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
227 {
228 ecp_keypair *ec = pk_ec( *key );
229 size_t pub_len = 0, par_len = 0;
230
231 /*
232 * RFC 5915, or SEC1 Appendix C.4
233 *
234 * ECPrivateKey ::= SEQUENCE {
235 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
236 * privateKey OCTET STRING,
237 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
238 * publicKey [1] BIT STRING OPTIONAL
239 * }
240 */
241
242 /* publicKey */
243 ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
244
245 if( c - buf < 1 )
246 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
247 *--c = 0;
248 pub_len += 1;
249
250 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) );
251 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
252
253 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) );
254 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf,
255 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) );
256 len += pub_len;
257
258 /* parameters */
259 ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
260
261 ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) );
262 ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf,
263 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) );
264 len += par_len;
265
266 /* privateKey: write as MPI then fix tag */
267 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) );
268 *c = ASN1_OCTET_STRING;
269
270 /* version */
271 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) );
272
273 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +0200274 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED |
275 ASN1_SEQUENCE ) );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200276 }
277 else
Paul Bakker9af723c2014-05-01 13:03:14 +0200278#endif /* POLARSSL_ECP_C */
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200279 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
280
Paul Bakkerb9cfaa02013-10-11 18:58:55 +0200281 return( (int) len );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200282}
283
Paul Bakkercff68422013-09-15 20:43:33 +0200284#if defined(POLARSSL_PEM_WRITE_C)
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200285
286#define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
287#define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
288
289#define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
290#define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
291#define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
292#define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
293
Manuel Pégourié-Gonnard192253a2014-07-21 16:37:15 +0200294/*
295 * Max sizes of key per types. Shown as tag + len (+ content).
296 */
297
298#if defined(POLARSSL_RSA_C)
299/*
300 * RSA public keys:
301 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
302 * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
303 * + 1 + 1 + 9 (rsa oid)
304 * + 1 + 1 (params null)
305 * subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
306 * RSAPublicKey ::= SEQUENCE { 1 + 3
307 * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
308 * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
309 * }
310 */
311#define RSA_PUB_DER_MAX_BYTES 38 + 2 * POLARSSL_MPI_MAX_SIZE
312
313/*
314 * RSA private keys:
315 * RSAPrivateKey ::= SEQUENCE { 1 + 3
316 * version Version, 1 + 1 + 1
317 * modulus INTEGER, 1 + 3 + MPI_MAX + 1
318 * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1
319 * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1
320 * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
321 * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
322 * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
323 * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
324 * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1
325 * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
326 * }
327 */
328#define MPI_MAX_SIZE_2 POLARSSL_MPI_MAX_SIZE / 2 + \
329 POLARSSL_MPI_MAX_SIZE % 2
330#define RSA_PRV_DER_MAX_BYTES 47 + 3 * POLARSSL_MPI_MAX_SIZE \
331 + 5 * MPI_MAX_SIZE_2
332
333#else /* POLARSSL_RSA_C */
334
335#define RSA_PUB_DER_MAX_BYTES 0
336#define RSA_PRV_DER_MAX_BYTES 0
337
338#endif /* POLARSSL_RSA_C */
339
340#if defined(POLARSSL_ECP_C)
341/*
342 * EC public keys:
343 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
344 * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
345 * + 1 + 1 + 7 (ec oid)
346 * + 1 + 1 + 9 (namedCurve oid)
347 * subjectPublicKey BIT STRING 1 + 2 + 1 [1]
348 * + 1 (point format) [1]
349 * + 2 * ECP_MAX (coords) [1]
350 * }
351 */
352#define ECP_PUB_DER_MAX_BYTES 30 + 2 * POLARSSL_ECP_MAX_BYTES
353
354/*
355 * EC private keys:
356 * ECPrivateKey ::= SEQUENCE { 1 + 2
357 * version INTEGER , 1 + 1 + 1
358 * privateKey OCTET STRING, 1 + 1 + ECP_MAX
359 * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9)
360 * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
361 * }
362 */
363#define ECP_PRV_DER_MAX_BYTES 29 + 3 * POLARSSL_ECP_MAX_BYTES
364
365#else /* POLARSSL_ECP_C */
366
367#define ECP_PUB_DER_MAX_BYTES 0
368#define ECP_PRV_DER_MAX_BYTES 0
369
370#endif /* POLARSSL_ECP_C */
371
372#define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
373 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
374#define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
375 RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
376
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200377int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size )
378{
379 int ret;
Manuel Pégourié-Gonnard192253a2014-07-21 16:37:15 +0200380 unsigned char output_buf[PUB_DER_MAX_BYTES];
Paul Bakker77e23fb2013-09-15 20:03:26 +0200381 size_t olen = 0;
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200382
383 if( ( ret = pk_write_pubkey_der( key, output_buf,
Paul Bakker77e23fb2013-09-15 20:03:26 +0200384 sizeof(output_buf) ) ) < 0 )
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200385 {
386 return( ret );
387 }
388
Paul Bakker77e23fb2013-09-15 20:03:26 +0200389 if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200390 output_buf + sizeof(output_buf) - ret,
Paul Bakker77e23fb2013-09-15 20:03:26 +0200391 ret, buf, size, &olen ) ) != 0 )
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200392 {
393 return( ret );
394 }
395
396 return( 0 );
397}
398
399int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size )
400{
401 int ret;
Manuel Pégourié-Gonnard192253a2014-07-21 16:37:15 +0200402 unsigned char output_buf[PRV_DER_MAX_BYTES];
Paul Bakkerfcc17212013-10-11 09:36:52 +0200403 const char *begin, *end;
Paul Bakker77e23fb2013-09-15 20:03:26 +0200404 size_t olen = 0;
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200405
Paul Bakker77e23fb2013-09-15 20:03:26 +0200406 if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200407 return( ret );
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200408
409#if defined(POLARSSL_RSA_C)
410 if( pk_get_type( key ) == POLARSSL_PK_RSA )
411 {
412 begin = PEM_BEGIN_PRIVATE_KEY_RSA;
413 end = PEM_END_PRIVATE_KEY_RSA;
414 }
415 else
416#endif
417#if defined(POLARSSL_ECP_C)
418 if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
419 {
420 begin = PEM_BEGIN_PRIVATE_KEY_EC;
421 end = PEM_END_PRIVATE_KEY_EC;
422 }
423 else
424#endif
425 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
426
Paul Bakker77e23fb2013-09-15 20:03:26 +0200427 if( ( ret = pem_write_buffer( begin, end,
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200428 output_buf + sizeof(output_buf) - ret,
Paul Bakker77e23fb2013-09-15 20:03:26 +0200429 ret, buf, size, &olen ) ) != 0 )
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200430 {
431 return( ret );
432 }
433
434 return( 0 );
435}
Paul Bakkercff68422013-09-15 20:43:33 +0200436#endif /* POLARSSL_PEM_WRITE_C */
Paul Bakkerc7bb02b2013-09-15 14:54:56 +0200437
Paul Bakker4606c732013-09-15 17:04:23 +0200438#endif /* POLARSSL_PK_WRITE_C */