1 /* 2 * Public Key layer for writing key files and structures 3 * 4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 5 * SPDX-License-Identifier: GPL-2.0 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License as published by 9 * the Free Software Foundation; either version 2 of the License, or 10 * (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * This file is part of mbed TLS (https://tls.mbed.org) 22 */ 23 24 #if !defined(MBEDTLS_CONFIG_FILE) 25 #include "mbedtls/config.h" 26 #else 27 #include MBEDTLS_CONFIG_FILE 28 #endif 29 30 #if defined(MBEDTLS_PK_WRITE_C) 31 32 #include "mbedtls/pk.h" 33 #include "mbedtls/asn1write.h" 34 #include "mbedtls/oid.h" 35 36 #include <string.h> 37 38 #if defined(MBEDTLS_RSA_C) 39 #include "mbedtls/rsa.h" 40 #endif 41 #if defined(MBEDTLS_ECP_C) 42 #include "mbedtls/ecp.h" 43 #endif 44 #if defined(MBEDTLS_ECDSA_C) 45 #include "mbedtls/ecdsa.h" 46 #endif 47 #if defined(MBEDTLS_PEM_WRITE_C) 48 #include "mbedtls/pem.h" 49 #endif 50 51 #if defined(MBEDTLS_PLATFORM_C) 52 #include "mbedtls/platform.h" 53 #else 54 #include <stdlib.h> 55 #define mbedtls_calloc calloc 56 #define mbedtls_free free 57 #endif 58 59 #if defined(MBEDTLS_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 mbedtls_rsa_context *rsa ) 68 { 69 int ret; 70 size_t len = 0; 71 72 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->E ) ); 73 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->N ) ); 74 75 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 76 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | 77 MBEDTLS_ASN1_SEQUENCE ) ); 78 79 return( (int) len ); 80 } 81 #endif /* MBEDTLS_RSA_C */ 82 83 #if defined(MBEDTLS_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 mbedtls_ecp_keypair *ec ) 89 { 90 int ret; 91 size_t len = 0; 92 unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; 93 94 if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp, &ec->Q, 95 MBEDTLS_ECP_PF_UNCOMPRESSED, 96 &len, buf, sizeof( buf ) ) ) != 0 ) 97 { 98 return( ret ); 99 } 100 101 if( *p < start || (size_t)( *p - start ) < len ) 102 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 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 mbedtls_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 = mbedtls_oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 ) 124 return( ret ); 125 126 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); 127 128 return( (int) len ); 129 } 130 #endif /* MBEDTLS_ECP_C */ 131 132 int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, 133 const mbedtls_pk_context *key ) 134 { 135 int ret; 136 size_t len = 0; 137 138 #if defined(MBEDTLS_RSA_C) 139 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) 140 MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) ); 141 else 142 #endif 143 #if defined(MBEDTLS_ECP_C) 144 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) 145 MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) ); 146 else 147 #endif 148 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 149 150 return( (int) len ); 151 } 152 153 int mbedtls_pk_write_pubkey_der( mbedtls_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 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); 163 164 if( c - buf < 1 ) 165 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 166 167 /* 168 * SubjectPublicKeyInfo ::= SEQUENCE { 169 * algorithm AlgorithmIdentifier, 170 * subjectPublicKey BIT STRING } 171 */ 172 *--c = 0; 173 len += 1; 174 175 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 176 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); 177 178 if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ), 179 &oid, &oid_len ) ) != 0 ) 180 { 181 return( ret ); 182 } 183 184 #if defined(MBEDTLS_ECP_C) 185 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) 186 { 187 MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) ); 188 } 189 #endif 190 191 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len, 192 par_len ) ); 193 194 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 195 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | 196 MBEDTLS_ASN1_SEQUENCE ) ); 197 198 return( (int) len ); 199 } 200 201 int mbedtls_pk_write_key_der( mbedtls_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(MBEDTLS_RSA_C) 208 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) 209 { 210 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); 211 212 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->QP ) ); 213 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DQ ) ); 214 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DP ) ); 215 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->Q ) ); 216 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->P ) ); 217 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->D ) ); 218 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->E ) ); 219 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->N ) ); 220 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); 221 222 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 223 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | 224 MBEDTLS_ASN1_SEQUENCE ) ); 225 } 226 else 227 #endif /* MBEDTLS_RSA_C */ 228 #if defined(MBEDTLS_ECP_C) 229 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) 230 { 231 mbedtls_ecp_keypair *ec = mbedtls_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 MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); 247 248 if( c - buf < 1 ) 249 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 250 *--c = 0; 251 pub_len += 1; 252 253 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); 254 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); 255 256 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); 257 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, 258 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ); 259 len += pub_len; 260 261 /* parameters */ 262 MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); 263 264 MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) ); 265 MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf, 266 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); 267 len += par_len; 268 269 /* privateKey: write as MPI then fix tag */ 270 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) ); 271 *c = MBEDTLS_ASN1_OCTET_STRING; 272 273 /* version */ 274 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); 275 276 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 277 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | 278 MBEDTLS_ASN1_SEQUENCE ) ); 279 } 280 else 281 #endif /* MBEDTLS_ECP_C */ 282 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 283 284 return( (int) len ); 285 } 286 287 #if defined(MBEDTLS_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(MBEDTLS_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 * MBEDTLS_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 MBEDTLS_MPI_MAX_SIZE / 2 + \ 332 MBEDTLS_MPI_MAX_SIZE % 2 333 #define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \ 334 + 5 * MPI_MAX_SIZE_2 335 336 #else /* MBEDTLS_RSA_C */ 337 338 #define RSA_PUB_DER_MAX_BYTES 0 339 #define RSA_PRV_DER_MAX_BYTES 0 340 341 #endif /* MBEDTLS_RSA_C */ 342 343 #if defined(MBEDTLS_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 * MBEDTLS_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 * MBEDTLS_ECP_MAX_BYTES 367 368 #else /* MBEDTLS_ECP_C */ 369 370 #define ECP_PUB_DER_MAX_BYTES 0 371 #define ECP_PRV_DER_MAX_BYTES 0 372 373 #endif /* MBEDTLS_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 mbedtls_pk_write_pubkey_pem( mbedtls_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 = mbedtls_pk_write_pubkey_der( key, output_buf, 387 sizeof(output_buf) ) ) < 0 ) 388 { 389 return( ret ); 390 } 391 392 if( ( ret = mbedtls_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 mbedtls_pk_write_key_pem( mbedtls_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 = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) 410 return( ret ); 411 412 #if defined(MBEDTLS_RSA_C) 413 if( mbedtls_pk_get_type( key ) == MBEDTLS_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(MBEDTLS_ECP_C) 421 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) 422 { 423 begin = PEM_BEGIN_PRIVATE_KEY_EC; 424 end = PEM_END_PRIVATE_KEY_EC; 425 } 426 else 427 #endif 428 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 429 430 if( ( ret = mbedtls_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 /* MBEDTLS_PEM_WRITE_C */ 440 441 #endif /* MBEDTLS_PK_WRITE_C */ 442