Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbedtls by
pkwrite.c
00001 /* 00002 * Public Key layer for writing key files and structures 00003 * 00004 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00005 * SPDX-License-Identifier: Apache-2.0 00006 * 00007 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00008 * not use this file except in compliance with the License. 00009 * You may obtain a copy of the License at 00010 * 00011 * http://www.apache.org/licenses/LICENSE-2.0 00012 * 00013 * Unless required by applicable law or agreed to in writing, software 00014 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00015 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00016 * See the License for the specific language governing permissions and 00017 * limitations under the License. 00018 * 00019 * This file is part of mbed TLS (https://tls.mbed.org) 00020 */ 00021 00022 #if !defined(MBEDTLS_CONFIG_FILE) 00023 #include "mbedtls/config.h" 00024 #else 00025 #include MBEDTLS_CONFIG_FILE 00026 #endif 00027 00028 #if defined(MBEDTLS_PK_WRITE_C) 00029 00030 #include "mbedtls/pk.h" 00031 #include "mbedtls/asn1write.h" 00032 #include "mbedtls/oid.h" 00033 00034 #include <string.h> 00035 00036 #if defined(MBEDTLS_RSA_C) 00037 #include "mbedtls/rsa.h" 00038 #endif 00039 #if defined(MBEDTLS_ECP_C) 00040 #include "mbedtls/ecp.h" 00041 #endif 00042 #if defined(MBEDTLS_ECDSA_C) 00043 #include "mbedtls/ecdsa.h" 00044 #endif 00045 #if defined(MBEDTLS_PEM_WRITE_C) 00046 #include "mbedtls/pem.h" 00047 #endif 00048 00049 #if defined(MBEDTLS_PLATFORM_C) 00050 #include "mbedtls/platform.h" 00051 #else 00052 #include <stdlib.h> 00053 #define mbedtls_calloc calloc 00054 #define mbedtls_free free 00055 #endif 00056 00057 #if defined(MBEDTLS_RSA_C) 00058 /* 00059 * RSAPublicKey ::= SEQUENCE { 00060 * modulus INTEGER, -- n 00061 * publicExponent INTEGER -- e 00062 * } 00063 */ 00064 static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, 00065 mbedtls_rsa_context *rsa ) 00066 { 00067 int ret; 00068 size_t len = 0; 00069 00070 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->E ) ); 00071 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( p, start, &rsa->N ) ); 00072 00073 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( p, start, len ) ); 00074 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( p, start, MBEDTLS_ASN1_CONSTRUCTED | 00075 MBEDTLS_ASN1_SEQUENCE ) ); 00076 00077 return( (int) len ); 00078 } 00079 #endif /* MBEDTLS_RSA_C */ 00080 00081 #if defined(MBEDTLS_ECP_C) 00082 /* 00083 * EC public key is an EC point 00084 */ 00085 static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, 00086 mbedtls_ecp_keypair *ec ) 00087 { 00088 int ret; 00089 size_t len = 0; 00090 unsigned char buf[MBEDTLS_ECP_MAX_PT_LEN]; 00091 00092 if( ( ret = mbedtls_ecp_point_write_binary( &ec->grp , &ec->Q , 00093 MBEDTLS_ECP_PF_UNCOMPRESSED, 00094 &len, buf, sizeof( buf ) ) ) != 0 ) 00095 { 00096 return( ret ); 00097 } 00098 00099 if( *p < start || (size_t)( *p - start ) < len ) 00100 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00101 00102 *p -= len; 00103 memcpy( *p, buf, len ); 00104 00105 return( (int) len ); 00106 } 00107 00108 /* 00109 * ECParameters ::= CHOICE { 00110 * namedCurve OBJECT IDENTIFIER 00111 * } 00112 */ 00113 static int pk_write_ec_param( unsigned char **p, unsigned char *start, 00114 mbedtls_ecp_keypair *ec ) 00115 { 00116 int ret; 00117 size_t len = 0; 00118 const char *oid; 00119 size_t oid_len; 00120 00121 if( ( ret = mbedtls_oid_get_oid_by_ec_grp( ec->grp .id , &oid, &oid_len ) ) != 0 ) 00122 return( ret ); 00123 00124 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_oid( p, start, oid, oid_len ) ); 00125 00126 return( (int) len ); 00127 } 00128 #endif /* MBEDTLS_ECP_C */ 00129 00130 int mbedtls_pk_write_pubkey( unsigned char **p, unsigned char *start, 00131 const mbedtls_pk_context *key ) 00132 { 00133 int ret; 00134 size_t len = 0; 00135 00136 #if defined(MBEDTLS_RSA_C) 00137 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) 00138 MBEDTLS_ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, mbedtls_pk_rsa( *key ) ) ); 00139 else 00140 #endif 00141 #if defined(MBEDTLS_ECP_C) 00142 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) 00143 MBEDTLS_ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, mbedtls_pk_ec( *key ) ) ); 00144 else 00145 #endif 00146 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 00147 00148 return( (int) len ); 00149 } 00150 00151 int mbedtls_pk_write_pubkey_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) 00152 { 00153 int ret; 00154 unsigned char *c; 00155 size_t len = 0, par_len = 0, oid_len; 00156 const char *oid; 00157 00158 c = buf + size; 00159 00160 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_pk_write_pubkey( &c, buf, key ) ); 00161 00162 if( c - buf < 1 ) 00163 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00164 00165 /* 00166 * SubjectPublicKeyInfo ::= SEQUENCE { 00167 * algorithm AlgorithmIdentifier, 00168 * subjectPublicKey BIT STRING } 00169 */ 00170 *--c = 0; 00171 len += 1; 00172 00173 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00174 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); 00175 00176 if( ( ret = mbedtls_oid_get_oid_by_pk_alg( mbedtls_pk_get_type( key ), 00177 &oid, &oid_len ) ) != 0 ) 00178 { 00179 return( ret ); 00180 } 00181 00182 #if defined(MBEDTLS_ECP_C) 00183 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) 00184 { 00185 MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, mbedtls_pk_ec( *key ) ) ); 00186 } 00187 #endif 00188 00189 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_algorithm_identifier( &c, buf, oid, oid_len, 00190 par_len ) ); 00191 00192 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00193 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | 00194 MBEDTLS_ASN1_SEQUENCE ) ); 00195 00196 return( (int) len ); 00197 } 00198 00199 int mbedtls_pk_write_key_der( mbedtls_pk_context *key, unsigned char *buf, size_t size ) 00200 { 00201 int ret; 00202 unsigned char *c = buf + size; 00203 size_t len = 0; 00204 00205 #if defined(MBEDTLS_RSA_C) 00206 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) 00207 { 00208 mbedtls_rsa_context *rsa = mbedtls_pk_rsa( *key ); 00209 00210 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->QP ) ); 00211 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DQ ) ); 00212 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->DP ) ); 00213 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->Q ) ); 00214 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->P ) ); 00215 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->D ) ); 00216 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->E ) ); 00217 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &rsa->N ) ); 00218 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 0 ) ); 00219 00220 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00221 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | 00222 MBEDTLS_ASN1_SEQUENCE ) ); 00223 } 00224 else 00225 #endif /* MBEDTLS_RSA_C */ 00226 #if defined(MBEDTLS_ECP_C) 00227 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) 00228 { 00229 mbedtls_ecp_keypair *ec = mbedtls_pk_ec( *key ); 00230 size_t pub_len = 0, par_len = 0; 00231 00232 /* 00233 * RFC 5915, or SEC1 Appendix C.4 00234 * 00235 * ECPrivateKey ::= SEQUENCE { 00236 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), 00237 * privateKey OCTET STRING, 00238 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 00239 * publicKey [1] BIT STRING OPTIONAL 00240 * } 00241 */ 00242 00243 /* publicKey */ 00244 MBEDTLS_ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); 00245 00246 if( c - buf < 1 ) 00247 return( MBEDTLS_ERR_ASN1_BUF_TOO_SMALL ); 00248 *--c = 0; 00249 pub_len += 1; 00250 00251 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); 00252 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_BIT_STRING ) ); 00253 00254 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_len( &c, buf, pub_len ) ); 00255 MBEDTLS_ASN1_CHK_ADD( pub_len, mbedtls_asn1_write_tag( &c, buf, 00256 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 1 ) ); 00257 len += pub_len; 00258 00259 /* parameters */ 00260 MBEDTLS_ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); 00261 00262 MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_len( &c, buf, par_len ) ); 00263 MBEDTLS_ASN1_CHK_ADD( par_len, mbedtls_asn1_write_tag( &c, buf, 00264 MBEDTLS_ASN1_CONTEXT_SPECIFIC | MBEDTLS_ASN1_CONSTRUCTED | 0 ) ); 00265 len += par_len; 00266 00267 /* privateKey: write as MPI then fix tag */ 00268 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_mpi( &c, buf, &ec->d ) ); 00269 *c = MBEDTLS_ASN1_OCTET_STRING; 00270 00271 /* version */ 00272 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_int( &c, buf, 1 ) ); 00273 00274 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_len( &c, buf, len ) ); 00275 MBEDTLS_ASN1_CHK_ADD( len, mbedtls_asn1_write_tag( &c, buf, MBEDTLS_ASN1_CONSTRUCTED | 00276 MBEDTLS_ASN1_SEQUENCE ) ); 00277 } 00278 else 00279 #endif /* MBEDTLS_ECP_C */ 00280 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 00281 00282 return( (int) len ); 00283 } 00284 00285 #if defined(MBEDTLS_PEM_WRITE_C) 00286 00287 #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" 00288 #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" 00289 00290 #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" 00291 #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" 00292 #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" 00293 #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" 00294 00295 /* 00296 * Max sizes of key per types. Shown as tag + len (+ content). 00297 */ 00298 00299 #if defined(MBEDTLS_RSA_C) 00300 /* 00301 * RSA public keys: 00302 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 3 00303 * algorithm AlgorithmIdentifier, 1 + 1 (sequence) 00304 * + 1 + 1 + 9 (rsa oid) 00305 * + 1 + 1 (params null) 00306 * subjectPublicKey BIT STRING } 1 + 3 + (1 + below) 00307 * RSAPublicKey ::= SEQUENCE { 1 + 3 00308 * modulus INTEGER, -- n 1 + 3 + MPI_MAX + 1 00309 * publicExponent INTEGER -- e 1 + 3 + MPI_MAX + 1 00310 * } 00311 */ 00312 #define RSA_PUB_DER_MAX_BYTES 38 + 2 * MBEDTLS_MPI_MAX_SIZE 00313 00314 /* 00315 * RSA private keys: 00316 * RSAPrivateKey ::= SEQUENCE { 1 + 3 00317 * version Version, 1 + 1 + 1 00318 * modulus INTEGER, 1 + 3 + MPI_MAX + 1 00319 * publicExponent INTEGER, 1 + 3 + MPI_MAX + 1 00320 * privateExponent INTEGER, 1 + 3 + MPI_MAX + 1 00321 * prime1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00322 * prime2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00323 * exponent1 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00324 * exponent2 INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00325 * coefficient INTEGER, 1 + 3 + MPI_MAX / 2 + 1 00326 * otherPrimeInfos OtherPrimeInfos OPTIONAL 0 (not supported) 00327 * } 00328 */ 00329 #define MPI_MAX_SIZE_2 MBEDTLS_MPI_MAX_SIZE / 2 + \ 00330 MBEDTLS_MPI_MAX_SIZE % 2 00331 #define RSA_PRV_DER_MAX_BYTES 47 + 3 * MBEDTLS_MPI_MAX_SIZE \ 00332 + 5 * MPI_MAX_SIZE_2 00333 00334 #else /* MBEDTLS_RSA_C */ 00335 00336 #define RSA_PUB_DER_MAX_BYTES 0 00337 #define RSA_PRV_DER_MAX_BYTES 0 00338 00339 #endif /* MBEDTLS_RSA_C */ 00340 00341 #if defined(MBEDTLS_ECP_C) 00342 /* 00343 * EC public keys: 00344 * SubjectPublicKeyInfo ::= SEQUENCE { 1 + 2 00345 * algorithm AlgorithmIdentifier, 1 + 1 (sequence) 00346 * + 1 + 1 + 7 (ec oid) 00347 * + 1 + 1 + 9 (namedCurve oid) 00348 * subjectPublicKey BIT STRING 1 + 2 + 1 [1] 00349 * + 1 (point format) [1] 00350 * + 2 * ECP_MAX (coords) [1] 00351 * } 00352 */ 00353 #define ECP_PUB_DER_MAX_BYTES 30 + 2 * MBEDTLS_ECP_MAX_BYTES 00354 00355 /* 00356 * EC private keys: 00357 * ECPrivateKey ::= SEQUENCE { 1 + 2 00358 * version INTEGER , 1 + 1 + 1 00359 * privateKey OCTET STRING, 1 + 1 + ECP_MAX 00360 * parameters [0] ECParameters OPTIONAL, 1 + 1 + (1 + 1 + 9) 00361 * publicKey [1] BIT STRING OPTIONAL 1 + 2 + [1] above 00362 * } 00363 */ 00364 #define ECP_PRV_DER_MAX_BYTES 29 + 3 * MBEDTLS_ECP_MAX_BYTES 00365 00366 #else /* MBEDTLS_ECP_C */ 00367 00368 #define ECP_PUB_DER_MAX_BYTES 0 00369 #define ECP_PRV_DER_MAX_BYTES 0 00370 00371 #endif /* MBEDTLS_ECP_C */ 00372 00373 #define PUB_DER_MAX_BYTES RSA_PUB_DER_MAX_BYTES > ECP_PUB_DER_MAX_BYTES ? \ 00374 RSA_PUB_DER_MAX_BYTES : ECP_PUB_DER_MAX_BYTES 00375 #define PRV_DER_MAX_BYTES RSA_PRV_DER_MAX_BYTES > ECP_PRV_DER_MAX_BYTES ? \ 00376 RSA_PRV_DER_MAX_BYTES : ECP_PRV_DER_MAX_BYTES 00377 00378 int mbedtls_pk_write_pubkey_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) 00379 { 00380 int ret; 00381 unsigned char output_buf[PUB_DER_MAX_BYTES]; 00382 size_t olen = 0; 00383 00384 if( ( ret = mbedtls_pk_write_pubkey_der( key, output_buf, 00385 sizeof(output_buf) ) ) < 0 ) 00386 { 00387 return( ret ); 00388 } 00389 00390 if( ( ret = mbedtls_pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, 00391 output_buf + sizeof(output_buf) - ret, 00392 ret, buf, size, &olen ) ) != 0 ) 00393 { 00394 return( ret ); 00395 } 00396 00397 return( 0 ); 00398 } 00399 00400 int mbedtls_pk_write_key_pem( mbedtls_pk_context *key, unsigned char *buf, size_t size ) 00401 { 00402 int ret; 00403 unsigned char output_buf[PRV_DER_MAX_BYTES]; 00404 const char *begin, *end; 00405 size_t olen = 0; 00406 00407 if( ( ret = mbedtls_pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) 00408 return( ret ); 00409 00410 #if defined(MBEDTLS_RSA_C) 00411 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_RSA ) 00412 { 00413 begin = PEM_BEGIN_PRIVATE_KEY_RSA; 00414 end = PEM_END_PRIVATE_KEY_RSA; 00415 } 00416 else 00417 #endif 00418 #if defined(MBEDTLS_ECP_C) 00419 if( mbedtls_pk_get_type( key ) == MBEDTLS_PK_ECKEY ) 00420 { 00421 begin = PEM_BEGIN_PRIVATE_KEY_EC; 00422 end = PEM_END_PRIVATE_KEY_EC; 00423 } 00424 else 00425 #endif 00426 return( MBEDTLS_ERR_PK_FEATURE_UNAVAILABLE ); 00427 00428 if( ( ret = mbedtls_pem_write_buffer( begin, end, 00429 output_buf + sizeof(output_buf) - ret, 00430 ret, buf, size, &olen ) ) != 0 ) 00431 { 00432 return( ret ); 00433 } 00434 00435 return( 0 ); 00436 } 00437 #endif /* MBEDTLS_PEM_WRITE_C */ 00438 00439 #endif /* MBEDTLS_PK_WRITE_C */
Generated on Tue Jul 12 2022 17:25:42 by
