PolarSSL v1.3.9
pkwrite.c
Go to the documentation of this file.
1 /*
2  * Public Key layer for writing key files and structures
3  *
4  * Copyright (C) 2006-2014, Brainspark B.V.
5  *
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 #if !defined(POLARSSL_CONFIG_FILE)
27 #include "polarssl/config.h"
28 #else
29 #include POLARSSL_CONFIG_FILE
30 #endif
31 
32 #if defined(POLARSSL_PK_WRITE_C)
33 
34 #include "polarssl/pk.h"
35 #include "polarssl/asn1write.h"
36 #include "polarssl/oid.h"
37 
38 #if defined(POLARSSL_RSA_C)
39 #include "polarssl/rsa.h"
40 #endif
41 #if defined(POLARSSL_ECP_C)
42 #include "polarssl/ecp.h"
43 #endif
44 #if defined(POLARSSL_ECDSA_C)
45 #include "polarssl/ecdsa.h"
46 #endif
47 #if defined(POLARSSL_PEM_WRITE_C)
48 #include "polarssl/pem.h"
49 #endif
50 
51 #if defined(POLARSSL_PLATFORM_C)
52 #include "polarssl/platform.h"
53 #else
54 #include <stdlib.h>
55 #define polarssl_malloc malloc
56 #define polarssl_free free
57 #endif
58 
59 #if defined(POLARSSL_RSA_C)
60 /*
61  * RSAPublicKey ::= SEQUENCE {
62  * modulus INTEGER, -- n
63  * publicExponent INTEGER -- e
64  * }
65  */
66 static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
67  rsa_context *rsa )
68 {
69  int ret;
70  size_t len = 0;
71 
72  ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->E ) );
73  ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) );
74 
75  ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
77  ASN1_SEQUENCE ) );
78 
79  return( (int) len );
80 }
81 #endif /* POLARSSL_RSA_C */
82 
83 #if defined(POLARSSL_ECP_C)
84 /*
85  * EC public key is an EC point
86  */
87 static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
88  ecp_keypair *ec )
89 {
90  int ret;
91  size_t len = 0;
92  unsigned char buf[POLARSSL_ECP_MAX_PT_LEN];
93 
94  if( ( ret = ecp_point_write_binary( &ec->grp, &ec->Q,
96  &len, buf, sizeof( buf ) ) ) != 0 )
97  {
98  return( ret );
99  }
100 
101  if( *p - start < (int) len )
103 
104  *p -= len;
105  memcpy( *p, buf, len );
106 
107  return( (int) len );
108 }
109 
110 /*
111  * ECParameters ::= CHOICE {
112  * namedCurve OBJECT IDENTIFIER
113  * }
114  */
115 static int pk_write_ec_param( unsigned char **p, unsigned char *start,
116  ecp_keypair *ec )
117 {
118  int ret;
119  size_t len = 0;
120  const char *oid;
121  size_t oid_len;
122 
123  if( ( ret = oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
124  return( ret );
125 
126  ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
127 
128  return( (int) len );
129 }
130 #endif /* POLARSSL_ECP_C */
131 
132 int pk_write_pubkey( unsigned char **p, unsigned char *start,
133  const pk_context *key )
134 {
135  int ret;
136  size_t len = 0;
137 
138 #if defined(POLARSSL_RSA_C)
139  if( pk_get_type( key ) == POLARSSL_PK_RSA )
140  ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, pk_rsa( *key ) ) );
141  else
142 #endif
143 #if defined(POLARSSL_ECP_C)
144  if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
145  ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, pk_ec( *key ) ) );
146  else
147 #endif
149 
150  return( (int) len );
151 }
152 
153 int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size )
154 {
155  int ret;
156  unsigned char *c;
157  size_t len = 0, par_len = 0, oid_len;
158  const char *oid;
159 
160  c = buf + size;
161 
162  ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) );
163 
164  if( c - buf < 1 )
166 
167  /*
168  * SubjectPublicKeyInfo ::= SEQUENCE {
169  * algorithm AlgorithmIdentifier,
170  * subjectPublicKey BIT STRING }
171  */
172  *--c = 0;
173  len += 1;
174 
175  ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
176  ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
177 
178  if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ),
179  &oid, &oid_len ) ) != 0 )
180  {
181  return( ret );
182  }
183 
184 #if defined(POLARSSL_ECP_C)
185  if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
186  {
187  ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) );
188  }
189 #endif
190 
191  ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
192  par_len ) );
193 
194  ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
196  ASN1_SEQUENCE ) );
197 
198  return( (int) len );
199 }
200 
201 int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size )
202 {
203  int ret;
204  unsigned char *c = buf + size;
205  size_t len = 0;
206 
207 #if defined(POLARSSL_RSA_C)
208  if( pk_get_type( key ) == POLARSSL_PK_RSA )
209  {
210  rsa_context *rsa = pk_rsa( *key );
211 
212  ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) );
213  ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) );
214  ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) );
215  ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) );
216  ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) );
217  ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) );
218  ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
219  ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
220  ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) );
221 
222  ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
224  ASN1_SEQUENCE ) );
225  }
226  else
227 #endif /* POLARSSL_RSA_C */
228 #if defined(POLARSSL_ECP_C)
229  if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
230  {
231  ecp_keypair *ec = pk_ec( *key );
232  size_t pub_len = 0, par_len = 0;
233 
234  /*
235  * RFC 5915, or SEC1 Appendix C.4
236  *
237  * ECPrivateKey ::= SEQUENCE {
238  * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
239  * privateKey OCTET STRING,
240  * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
241  * publicKey [1] BIT STRING OPTIONAL
242  * }
243  */
244 
245  /* publicKey */
246  ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
247 
248  if( c - buf < 1 )
250  *--c = 0;
251  pub_len += 1;
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, ASN1_BIT_STRING ) );
255 
256  ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) );
257  ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf,
259  len += pub_len;
260 
261  /* parameters */
262  ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
263 
264  ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) );
265  ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf,
267  len += par_len;
268 
269  /* privateKey: write as MPI then fix tag */
270  ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) );
271  *c = ASN1_OCTET_STRING;
272 
273  /* version */
274  ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) );
275 
276  ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
278  ASN1_SEQUENCE ) );
279  }
280  else
281 #endif /* POLARSSL_ECP_C */
283 
284  return( (int) len );
285 }
286 
287 #if defined(POLARSSL_PEM_WRITE_C)
288 
289 #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
290 #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
291 
292 #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
293 #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
294 #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
295 #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
296 
297 /*
298  * Max sizes of key per types. Shown as tag + len (+ content).
299  */
300 
301 #if defined(POLARSSL_RSA_C)
302 /*
303  * RSA public keys:
304  * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3
305  * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
306  * + 1 + 1 + 9 (rsa oid)
307  * + 1 + 1 (params null)
308  * subjectPublicKey BIT STRING } 1 + 3 + (1 + below)
309  * RSAPublicKey ::= SEQUENCE { 1 + 3
310  * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1
311  * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1
312  * }
313  */
314 #define RSA_PUB_DER_MAX_BYTES 38 + 2 * POLARSSL_MPI_MAX_SIZE
315 
316 /*
317  * RSA private keys:
318  * RSAPrivateKey ::= SEQUENCE { 1 + 3
319  * version Version, 1 + 1 + 1
320  * modulus INTEGER, 1 + 3 + MPI_MAX + 1
321  * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1
322  * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1
323  * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
324  * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
325  * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
326  * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1
327  * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1
328  * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported)
329  * }
330  */
331 #define MPI_MAX_SIZE_2 POLARSSL_MPI_MAX_SIZE / 2 + \
332  POLARSSL_MPI_MAX_SIZE % 2
333 #define RSA_PRV_DER_MAX_BYTES 47 + 3 * POLARSSL_MPI_MAX_SIZE \
334  + 5 * MPI_MAX_SIZE_2
335 
336 #else /* POLARSSL_RSA_C */
337 
338 #define RSA_PUB_DER_MAX_BYTES 0
339 #define RSA_PRV_DER_MAX_BYTES 0
340 
341 #endif /* POLARSSL_RSA_C */
342 
343 #if defined(POLARSSL_ECP_C)
344 /*
345  * EC public keys:
346  * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2
347  * algorithm AlgorithmIdentifier, 1 + 1 (sequence)
348  * + 1 + 1 + 7 (ec oid)
349  * + 1 + 1 + 9 (namedCurve oid)
350  * subjectPublicKey BIT STRING 1 + 2 + 1 [1]
351  * + 1 (point format) [1]
352  * + 2 * ECP_MAX (coords) [1]
353  * }
354  */
355 #define ECP_PUB_DER_MAX_BYTES 30 + 2 * POLARSSL_ECP_MAX_BYTES
356 
357 /*
358  * EC private keys:
359  * ECPrivateKey ::= SEQUENCE { 1 + 2
360  * version INTEGER , 1 + 1 + 1
361  * privateKey OCTET STRING, 1 + 1 + ECP_MAX
362  * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9)
363  * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above
364  * }
365  */
366 #define ECP_PRV_DER_MAX_BYTES 29 + 3 * POLARSSL_ECP_MAX_BYTES
367 
368 #else /* POLARSSL_ECP_C */
369 
370 #define ECP_PUB_DER_MAX_BYTES 0
371 #define ECP_PRV_DER_MAX_BYTES 0
372 
373 #endif /* POLARSSL_ECP_C */
374 
375 #define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \
376  RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES
377 #define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \
378  RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES
379 
380 int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size )
381 {
382  int ret;
383  unsigned char output_buf[PUB_DER_MAX_BYTES];
384  size_t olen = 0;
385 
386  if( ( ret = pk_write_pubkey_der( key, output_buf,
387  sizeof(output_buf) ) ) < 0 )
388  {
389  return( ret );
390  }
391 
392  if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
393  output_buf + sizeof(output_buf) - ret,
394  ret, buf, size, &olen ) ) != 0 )
395  {
396  return( ret );
397  }
398 
399  return( 0 );
400 }
401 
402 int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size )
403 {
404  int ret;
405  unsigned char output_buf[PRV_DER_MAX_BYTES];
406  const char *begin, *end;
407  size_t olen = 0;
408 
409  if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
410  return( ret );
411 
412 #if defined(POLARSSL_RSA_C)
413  if( pk_get_type( key ) == POLARSSL_PK_RSA )
414  {
415  begin = PEM_BEGIN_PRIVATE_KEY_RSA;
416  end = PEM_END_PRIVATE_KEY_RSA;
417  }
418  else
419 #endif
420 #if defined(POLARSSL_ECP_C)
421  if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
422  {
423  begin = PEM_BEGIN_PRIVATE_KEY_EC;
424  end = PEM_END_PRIVATE_KEY_EC;
425  }
426  else
427 #endif
429 
430  if( ( ret = pem_write_buffer( begin, end,
431  output_buf + sizeof(output_buf) - ret,
432  ret, buf, size, &olen ) ) != 0 )
433  {
434  return( ret );
435  }
436 
437  return( 0 );
438 }
439 #endif /* POLARSSL_PEM_WRITE_C */
440 
441 #endif /* POLARSSL_PK_WRITE_C */
int pk_write_key_der(pk_context *ctx, unsigned char *buf, size_t size)
Write a private key to a PKCS#1 or SEC1 DER structure Note: data is written at the end of the buffer!...
#define pk_ec(pk)
Quick access to an EC context inside a PK context.
Definition: pk.h:84
int oid_get_oid_by_ec_grp(ecp_group_id grp_id, const char **oid, size_t *olen)
Translate EC group identifier into NamedCurve OID.
Elliptic curves over GF(p)
int pk_write_key_pem(pk_context *ctx, unsigned char *buf, size_t size)
Write a private key to a PKCS#1 or SEC1 PEM string.
Elliptic curve DSA.
ecp_group grp
Definition: ecp.h:165
#define POLARSSL_ERR_ASN1_BUF_TOO_SMALL
Buffer too small when writing ASN.1 data structure.
Definition: asn1.h:60
int oid_get_oid_by_pk_alg(pk_type_t pk_alg, const char **oid, size_t *olen)
Translate pk_type into PublicKeyAlgorithm OID.
#define ASN1_SEQUENCE
Definition: asn1.h:82
#define POLARSSL_ECP_PF_UNCOMPRESSED
Uncompressed point format.
Definition: ecp.h:233
mpi DQ
Definition: rsa.h:95
Configuration options (set of defines)
#define ASN1_CONSTRUCTED
Definition: asn1.h:92
ECP key pair structure.
Definition: ecp.h:163
mpi d
Definition: ecp.h:166
PolarSSL Platform abstraction layer.
pk_type_t pk_get_type(const pk_context *ctx)
Get the key type.
Object Identifier (OID) database.
Public Key abstraction layer.
int asn1_write_len(unsigned char **p, unsigned char *start, size_t len)
Write a length field in ASN.1 format Note: function works backwards in data buffer.
mpi P
Definition: rsa.h:92
mpi Q
Definition: rsa.h:93
#define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE
Unavailable feature, e.g.
Definition: pk.h:63
int pk_write_pubkey(unsigned char **p, unsigned char *start, const pk_context *key)
Write a subjectPublicKey to ASN.1 data Note: function works backwards in data buffer.
int pk_write_pubkey_der(pk_context *ctx, unsigned char *buf, size_t size)
Write a public key to a SubjectPublicKeyInfo DER structure Note: data is written at the end of the bu...
RSA context structure.
Definition: rsa.h:83
mpi D
Definition: rsa.h:91
ecp_group_id id
Definition: ecp.h:138
mpi QP
Definition: rsa.h:96
Privacy Enhanced Mail (PEM) decoding.
#define POLARSSL_ECP_MAX_PT_LEN
Definition: ecp.h:187
mpi N
Definition: rsa.h:88
mpi E
Definition: rsa.h:89
mpi DP
Definition: rsa.h:94
#define ASN1_BIT_STRING
Definition: asn1.h:77
#define ASN1_CONTEXT_SPECIFIC
Definition: asn1.h:93
int asn1_write_mpi(unsigned char **p, unsigned char *start, mpi *X)
Write a big number (ASN1_INTEGER) in ASN.1 format Note: function works backwards in data buffer...
int asn1_write_int(unsigned char **p, unsigned char *start, int val)
Write an int tag (ASN1_INTEGER) and value in ASN.1 format Note: function works backwards in data buff...
The RSA public-key cryptosystem.
int ecp_point_write_binary(const ecp_group *grp, const ecp_point *P, int format, size_t *olen, unsigned char *buf, size_t buflen)
Export a point into unsigned binary data.
#define ASN1_CHK_ADD(g, f)
Definition: asn1write.h:32
int asn1_write_algorithm_identifier(unsigned char **p, unsigned char *start, const char *oid, size_t oid_len, size_t par_len)
Write an AlgorithmIdentifier sequence in ASN.1 format Note: function works backwards in data buffer...
ASN.1 buffer writing functionality.
ecp_point Q
Definition: ecp.h:167
int asn1_write_oid(unsigned char **p, unsigned char *start, const char *oid, size_t oid_len)
Write an OID tag (ASN1_OID) and data in ASN.1 format Note: function works backwards in data buffer...
#define ASN1_OCTET_STRING
Definition: asn1.h:78
int pk_write_pubkey_pem(pk_context *ctx, unsigned char *buf, size_t size)
Write a public key to a PEM string.
int asn1_write_tag(unsigned char **p, unsigned char *start, unsigned char tag)
Write a ASN.1 tag in ASN.1 format Note: function works backwards in data buffer.
Public key container.
Definition: pk.h:194
#define pk_rsa(pk)
Quick access to an RSA context inside a PK context.
Definition: pk.h:74