mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Committer:
ansond
Date:
Thu Jun 11 03:27:03 2015 +0000
Revision:
0:137634ff4186
initial commit

Who changed what in which revision?

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