mbed TLS library
Dependents: HTTPClient-SSL WS_SERVER
pkwrite.c
00001 /* 00002 * Public Key layer for writing key files and structures 00003 * 00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved 00005 * 00006 * This file is part of mbed TLS (https://tls.mbed.org) 00007 * 00008 * This program is free software; you can redistribute it and/or modify 00009 * it under the terms of the GNU General Public License as published by 00010 * the Free Software Foundation; either version 2 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * This program is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU General Public License along 00019 * with this program; if not, write to the Free Software Foundation, Inc., 00020 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00021 */ 00022 00023 #if !defined(POLARSSL_CONFIG_FILE) 00024 #include "polarssl/config.h" 00025 #else 00026 #include POLARSSL_CONFIG_FILE 00027 #endif 00028 00029 #if defined(POLARSSL_PK_WRITE_C) 00030 00031 #include "polarssl/pk.h" 00032 #include "polarssl/asn1write.h" 00033 #include "polarssl/oid.h" 00034 00035 #include <string.h> 00036 00037 #if defined(POLARSSL_RSA_C) 00038 #include "polarssl/rsa.h" 00039 #endif 00040 #if defined(POLARSSL_ECP_C) 00041 #include "polarssl/ecp.h" 00042 #endif 00043 #if defined(POLARSSL_ECDSA_C) 00044 #include "polarssl/ecdsa.h" 00045 #endif 00046 #if defined(POLARSSL_PEM_WRITE_C) 00047 #include "polarssl/pem.h" 00048 #endif 00049 00050 #if defined(POLARSSL_PLATFORM_C) 00051 #include "polarssl/platform.h" 00052 #else 00053 #include <stdlib.h> 00054 #define polarssl_malloc malloc 00055 #define polarssl_free free 00056 #endif 00057 00058 #if defined(POLARSSL_RSA_C) 00059 /* 00060 * RSAPublicKey ::= SEQUENCE { 00061 * modulus INTEGER, -- n 00062 * publicExponent INTEGER -- e 00063 * } 00064 */ 00065 static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, 00066 rsa_context *rsa ) 00067 { 00068 int ret; 00069 size_t len = 0; 00070 00071 ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->E ) ); 00072 ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) ); 00073 00074 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00075 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | 00076 ASN1_SEQUENCE ) ); 00077 00078 return( (int) len ); 00079 } 00080 #endif /* POLARSSL_RSA_C */ 00081 00082 #if defined(POLARSSL_ECP_C) 00083 /* 00084 * EC public key is an EC point 00085 */ 00086 static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, 00087 ecp_keypair *ec ) 00088 { 00089 int ret; 00090 size_t len = 0; 00091 unsigned char buf[POLARSSL_ECP_MAX_PT_LEN]; 00092 00093 if( ( ret = ecp_point_write_binary( &ec->grp , &ec->Q , 00094 POLARSSL_ECP_PF_UNCOMPRESSED, 00095 &len, buf, sizeof( buf ) ) ) != 0 ) 00096 { 00097 return( ret ); 00098 } 00099 00100 if( *p - start < (int) len ) 00101 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00102 00103 *p -= len; 00104 memcpy( *p, buf, len ); 00105 00106 return( (int) len ); 00107 } 00108 00109 /* 00110 * ECParameters ::= CHOICE { 00111 * namedCurve OBJECT IDENTIFIER 00112 * } 00113 */ 00114 static int pk_write_ec_param( unsigned char **p, unsigned char *start, 00115 ecp_keypair *ec ) 00116 { 00117 int ret; 00118 size_t len = 0; 00119 const char *oid; 00120 size_t oid_len; 00121 00122 if( ( ret = oid_get_oid_by_ec_grp( ec->grp .id , &oid, &oid_len ) ) != 0 ) 00123 return( ret ); 00124 00125 ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); 00126 00127 return( (int) len ); 00128 } 00129 #endif /* POLARSSL_ECP_C */ 00130 00131 int pk_write_pubkey( unsigned char **p, unsigned char *start, 00132 const pk_context *key ) 00133 { 00134 int ret; 00135 size_t len = 0; 00136 00137 #if defined(POLARSSL_RSA_C) 00138 if( pk_get_type( key ) == POLARSSL_PK_RSA ) 00139 ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, pk_rsa( *key ) ) ); 00140 else 00141 #endif 00142 #if defined(POLARSSL_ECP_C) 00143 if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) 00144 ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, pk_ec( *key ) ) ); 00145 else 00146 #endif 00147 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); 00148 00149 return( (int) len ); 00150 } 00151 00152 int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size ) 00153 { 00154 int ret; 00155 unsigned char *c; 00156 size_t len = 0, par_len = 0, oid_len; 00157 const char *oid; 00158 00159 c = buf + size; 00160 00161 ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) ); 00162 00163 if( c - buf < 1 ) 00164 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00165 00166 /* 00167 * SubjectPublicKeyInfo ::= SEQUENCE { 00168 * algorithm AlgorithmIdentifier, 00169 * subjectPublicKey BIT STRING } 00170 */ 00171 *--c = 0; 00172 len += 1; 00173 00174 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); 00175 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); 00176 00177 if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ), 00178 &oid, &oid_len ) ) != 0 ) 00179 { 00180 return( ret ); 00181 } 00182 00183 #if defined(POLARSSL_ECP_C) 00184 if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) 00185 { 00186 ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) ); 00187 } 00188 #endif 00189 00190 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len, 00191 par_len ) ); 00192 00193 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); 00194 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | 00195 ASN1_SEQUENCE ) ); 00196 00197 return( (int) len ); 00198 } 00199 00200 int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size ) 00201 { 00202 int ret; 00203 unsigned char *c = buf + size; 00204 size_t len = 0; 00205 00206 #if defined(POLARSSL_RSA_C) 00207 if( pk_get_type( key ) == POLARSSL_PK_RSA ) 00208 { 00209 rsa_context *rsa = pk_rsa( *key ); 00210 00211 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) ); 00212 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) ); 00213 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) ); 00214 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) ); 00215 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) ); 00216 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) ); 00217 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) ); 00218 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) ); 00219 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) ); 00220 00221 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); 00222 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | 00223 ASN1_SEQUENCE ) ); 00224 } 00225 else 00226 #endif /* POLARSSL_RSA_C */ 00227 #if defined(POLARSSL_ECP_C) 00228 if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) 00229 { 00230 ecp_keypair *ec = pk_ec( *key ); 00231 size_t pub_len = 0, par_len = 0; 00232 00233 /* 00234 * RFC 5915, or SEC1 Appendix C.4 00235 * 00236 * ECPrivateKey ::= SEQUENCE { 00237 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), 00238 * privateKey OCTET STRING, 00239 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 00240 * publicKey [1] BIT STRING OPTIONAL 00241 * } 00242 */ 00243 00244 /* publicKey */ 00245 ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); 00246 00247 if( c - buf < 1 ) 00248 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00249 *--c = 0; 00250 pub_len += 1; 00251 00252 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); 00253 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); 00254 00255 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); 00256 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, 00257 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ); 00258 len += pub_len; 00259 00260 /* parameters */ 00261 ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); 00262 00263 ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) ); 00264 ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf, 00265 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ); 00266 len += par_len; 00267 00268 /* privateKey: write as MPI then fix tag */ 00269 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) ); 00270 *c = ASN1_OCTET_STRING; 00271 00272 /* version */ 00273 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) ); 00274 00275 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); 00276 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | 00277 ASN1_SEQUENCE ) ); 00278 } 00279 else 00280 #endif /* POLARSSL_ECP_C */ 00281 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); 00282 00283 return( (int) len ); 00284 } 00285 00286 #if defined(POLARSSL_PEM_WRITE_C) 00287 00288 #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" 00289 #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" 00290 00291 #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" 00292 #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" 00293 #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" 00294 #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" 00295 00296 /* 00297 * Max sizes of key per types. Shown as tag + len (+ content). 00298 */ 00299 00300 #if defined(POLARSSL_RSA_C) 00301 /* 00302 * RSA public keys: 00303 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 00304 * algorithm AlgorithmIdentifier, 1 + 1 (sequence) 00305 * + 1 + 1 + 9 (rsa oid) 00306 * + 1 + 1 (params null) 00307 * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) 00308 * RSAPublicKey ::= SEQUENCE { 1 + 3 00309 * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 00310 * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 00311 * } 00312 */ 00313 #define RSA_PUB_DER_MAX_BYTES 38 + 2 * POLARSSL_MPI_MAX_SIZE 00314 00315 /* 00316 * RSA private keys: 00317 * RSAPrivateKey ::= SEQUENCE { 1 + 3 00318 * version Version, 1 + 1 + 1 00319 * modulus INTEGER, 1 + 3 + MPI_MAX + 1 00320 * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1 00321 * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1 00322 * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00323 * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00324 * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00325 * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00326 * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00327 * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported) 00328 * } 00329 */ 00330 #define MPI_MAX_SIZE_2 POLARSSL_MPI_MAX_SIZE / 2 + \ 00331 POLARSSL_MPI_MAX_SIZE % 2 00332 #define RSA_PRV_DER_MAX_BYTES 47 + 3 * POLARSSL_MPI_MAX_SIZE \ 00333 + 5 * MPI_MAX_SIZE_2 00334 00335 #else /* POLARSSL_RSA_C */ 00336 00337 #define RSA_PUB_DER_MAX_BYTES 0 00338 #define RSA_PRV_DER_MAX_BYTES 0 00339 00340 #endif /* POLARSSL_RSA_C */ 00341 00342 #if defined(POLARSSL_ECP_C) 00343 /* 00344 * EC public keys: 00345 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2 00346 * algorithm AlgorithmIdentifier, 1 + 1 (sequence) 00347 * + 1 + 1 + 7 (ec oid) 00348 * + 1 + 1 + 9 (namedCurve oid) 00349 * subjectPublicKey BIT STRING 1 + 2 + 1 [1] 00350 * + 1 (point format) [1] 00351 * + 2 * ECP_MAX (coords) [1] 00352 * } 00353 */ 00354 #define ECP_PUB_DER_MAX_BYTES 30 + 2 * POLARSSL_ECP_MAX_BYTES 00355 00356 /* 00357 * EC private keys: 00358 * ECPrivateKey ::= SEQUENCE { 1 + 2 00359 * version INTEGER , 1 + 1 + 1 00360 * privateKey OCTET STRING, 1 + 1 + ECP_MAX 00361 * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9) 00362 * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above 00363 * } 00364 */ 00365 #define ECP_PRV_DER_MAX_BYTES 29 + 3 * POLARSSL_ECP_MAX_BYTES 00366 00367 #else /* POLARSSL_ECP_C */ 00368 00369 #define ECP_PUB_DER_MAX_BYTES 0 00370 #define ECP_PRV_DER_MAX_BYTES 0 00371 00372 #endif /* POLARSSL_ECP_C */ 00373 00374 #define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ 00375 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES 00376 #define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \ 00377 RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES 00378 00379 int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size ) 00380 { 00381 int ret; 00382 unsigned char output_buf[PUB_DER_MAX_BYTES]; 00383 size_t olen = 0; 00384 00385 if( ( ret = pk_write_pubkey_der( key, output_buf, 00386 sizeof(output_buf) ) ) < 0 ) 00387 { 00388 return( ret ); 00389 } 00390 00391 if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, 00392 output_buf + sizeof(output_buf) - ret, 00393 ret, buf, size, &olen ) ) != 0 ) 00394 { 00395 return( ret ); 00396 } 00397 00398 return( 0 ); 00399 } 00400 00401 int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size ) 00402 { 00403 int ret; 00404 unsigned char output_buf[PRV_DER_MAX_BYTES]; 00405 const char *begin, *end; 00406 size_t olen = 0; 00407 00408 if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) 00409 return( ret ); 00410 00411 #if defined(POLARSSL_RSA_C) 00412 if( pk_get_type( key ) == POLARSSL_PK_RSA ) 00413 { 00414 begin = PEM_BEGIN_PRIVATE_KEY_RSA; 00415 end = PEM_END_PRIVATE_KEY_RSA; 00416 } 00417 else 00418 #endif 00419 #if defined(POLARSSL_ECP_C) 00420 if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) 00421 { 00422 begin = PEM_BEGIN_PRIVATE_KEY_EC; 00423 end = PEM_END_PRIVATE_KEY_EC; 00424 } 00425 else 00426 #endif 00427 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); 00428 00429 if( ( ret = pem_write_buffer( begin, end, 00430 output_buf + sizeof(output_buf) - ret, 00431 ret, buf, size, &olen ) ) != 0 ) 00432 { 00433 return( ret ); 00434 } 00435 00436 return( 0 ); 00437 } 00438 #endif /* POLARSSL_PEM_WRITE_C */ 00439 00440 #endif /* POLARSSL_PK_WRITE_C */ 00441
Generated on Tue Jul 12 2022 13:50:38 by 1.7.2