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.
pkwrite.c
00001 /* 00002 * Public Key layer for writing key files and structures 00003 * 00004 * Copyright (C) 2006-2014, Brainspark B.V. 00005 * 00006 * This file is part of PolarSSL (http://www.polarssl.org) 00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00008 * 00009 * All rights reserved. 00010 * 00011 * This program is free software; you can redistribute it and/or modify 00012 * it under the terms of the GNU General Public License as published by 00013 * the Free Software Foundation; either version 2 of the License, or 00014 * (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License along 00022 * with this program; if not, write to the Free Software Foundation, Inc., 00023 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00024 */ 00025 00026 #if !defined(POLARSSL_CONFIG_FILE) 00027 #include "polarssl/config.h" 00028 #else 00029 #include POLARSSL_CONFIG_FILE 00030 #endif 00031 00032 #if defined(POLARSSL_PK_WRITE_C) 00033 00034 #include "polarssl/pk.h" 00035 #include "polarssl/asn1write.h" 00036 #include "polarssl/oid.h" 00037 00038 #if defined(POLARSSL_RSA_C) 00039 #include "polarssl/rsa.h" 00040 #endif 00041 #if defined(POLARSSL_ECP_C) 00042 #include "polarssl/ecp.h" 00043 #endif 00044 #if defined(POLARSSL_ECDSA_C) 00045 #include "polarssl/ecdsa.h" 00046 #endif 00047 #if defined(POLARSSL_PEM_WRITE_C) 00048 #include "polarssl/pem.h" 00049 #endif 00050 00051 #if defined(POLARSSL_PLATFORM_C) 00052 #include "polarssl/platform.h" 00053 #else 00054 #include <stdlib.h> 00055 #define polarssl_malloc malloc 00056 #define polarssl_free free 00057 #endif 00058 00059 #if defined(POLARSSL_RSA_C) 00060 /* 00061 * RSAPublicKey ::= SEQUENCE { 00062 * modulus INTEGER, -- n 00063 * publicExponent INTEGER -- e 00064 * } 00065 */ 00066 static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start, 00067 rsa_context *rsa ) 00068 { 00069 int ret; 00070 size_t len = 0; 00071 00072 ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->E ) ); 00073 ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) ); 00074 00075 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) ); 00076 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | 00077 ASN1_SEQUENCE ) ); 00078 00079 return( (int) len ); 00080 } 00081 #endif /* POLARSSL_RSA_C */ 00082 00083 #if defined(POLARSSL_ECP_C) 00084 /* 00085 * EC public key is an EC point 00086 */ 00087 static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start, 00088 ecp_keypair *ec ) 00089 { 00090 int ret; 00091 size_t len = 0; 00092 unsigned char buf[POLARSSL_ECP_MAX_PT_LEN]; 00093 00094 if( ( ret = ecp_point_write_binary( &ec->grp , &ec->Q , 00095 POLARSSL_ECP_PF_UNCOMPRESSED, 00096 &len, buf, sizeof( buf ) ) ) != 0 ) 00097 { 00098 return( ret ); 00099 } 00100 00101 if( *p - start < (int) len ) 00102 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00103 00104 *p -= len; 00105 memcpy( *p, buf, len ); 00106 00107 return( (int) len ); 00108 } 00109 00110 /* 00111 * ECParameters ::= CHOICE { 00112 * namedCurve OBJECT IDENTIFIER 00113 * } 00114 */ 00115 static int pk_write_ec_param( unsigned char **p, unsigned char *start, 00116 ecp_keypair *ec ) 00117 { 00118 int ret; 00119 size_t len = 0; 00120 const char *oid; 00121 size_t oid_len; 00122 00123 if( ( ret = oid_get_oid_by_ec_grp( ec->grp .id , &oid, &oid_len ) ) != 0 ) 00124 return( ret ); 00125 00126 ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) ); 00127 00128 return( (int) len ); 00129 } 00130 #endif /* POLARSSL_ECP_C */ 00131 00132 int pk_write_pubkey( unsigned char **p, unsigned char *start, 00133 const pk_context *key ) 00134 { 00135 int ret; 00136 size_t len = 0; 00137 00138 #if defined(POLARSSL_RSA_C) 00139 if( pk_get_type( key ) == POLARSSL_PK_RSA ) 00140 ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, pk_rsa( *key ) ) ); 00141 else 00142 #endif 00143 #if defined(POLARSSL_ECP_C) 00144 if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) 00145 ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, pk_ec( *key ) ) ); 00146 else 00147 #endif 00148 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); 00149 00150 return( (int) len ); 00151 } 00152 00153 int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size ) 00154 { 00155 int ret; 00156 unsigned char *c; 00157 size_t len = 0, par_len = 0, oid_len; 00158 const char *oid; 00159 00160 c = buf + size; 00161 00162 ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) ); 00163 00164 if( c - buf < 1 ) 00165 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00166 00167 /* 00168 * SubjectPublicKeyInfo ::= SEQUENCE { 00169 * algorithm AlgorithmIdentifier, 00170 * subjectPublicKey BIT STRING } 00171 */ 00172 *--c = 0; 00173 len += 1; 00174 00175 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); 00176 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); 00177 00178 if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ), 00179 &oid, &oid_len ) ) != 0 ) 00180 { 00181 return( ret ); 00182 } 00183 00184 #if defined(POLARSSL_ECP_C) 00185 if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) 00186 { 00187 ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) ); 00188 } 00189 #endif 00190 00191 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len, 00192 par_len ) ); 00193 00194 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); 00195 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | 00196 ASN1_SEQUENCE ) ); 00197 00198 return( (int) len ); 00199 } 00200 00201 int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size ) 00202 { 00203 int ret; 00204 unsigned char *c = buf + size; 00205 size_t len = 0; 00206 00207 #if defined(POLARSSL_RSA_C) 00208 if( pk_get_type( key ) == POLARSSL_PK_RSA ) 00209 { 00210 rsa_context *rsa = pk_rsa( *key ); 00211 00212 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) ); 00213 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) ); 00214 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) ); 00215 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) ); 00216 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) ); 00217 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) ); 00218 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) ); 00219 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) ); 00220 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) ); 00221 00222 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); 00223 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | 00224 ASN1_SEQUENCE ) ); 00225 } 00226 else 00227 #endif /* POLARSSL_RSA_C */ 00228 #if defined(POLARSSL_ECP_C) 00229 if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) 00230 { 00231 ecp_keypair *ec = pk_ec( *key ); 00232 size_t pub_len = 0, par_len = 0; 00233 00234 /* 00235 * RFC 5915, or SEC1 Appendix C.4 00236 * 00237 * ECPrivateKey ::= SEQUENCE { 00238 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1), 00239 * privateKey OCTET STRING, 00240 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, 00241 * publicKey [1] BIT STRING OPTIONAL 00242 * } 00243 */ 00244 00245 /* publicKey */ 00246 ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) ); 00247 00248 if( c - buf < 1 ) 00249 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL ); 00250 *--c = 0; 00251 pub_len += 1; 00252 00253 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); 00254 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) ); 00255 00256 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) ); 00257 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, 00258 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ); 00259 len += pub_len; 00260 00261 /* parameters */ 00262 ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) ); 00263 00264 ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) ); 00265 ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf, 00266 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ); 00267 len += par_len; 00268 00269 /* privateKey: write as MPI then fix tag */ 00270 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) ); 00271 *c = ASN1_OCTET_STRING; 00272 00273 /* version */ 00274 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) ); 00275 00276 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) ); 00277 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | 00278 ASN1_SEQUENCE ) ); 00279 } 00280 else 00281 #endif /* POLARSSL_ECP_C */ 00282 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); 00283 00284 return( (int) len ); 00285 } 00286 00287 #if defined(POLARSSL_PEM_WRITE_C) 00288 00289 #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n" 00290 #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n" 00291 00292 #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n" 00293 #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n" 00294 #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n" 00295 #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n" 00296 00297 int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size ) 00298 { 00299 int ret; 00300 unsigned char output_buf[4096]; 00301 size_t olen = 0; 00302 00303 if( ( ret = pk_write_pubkey_der( key, output_buf, 00304 sizeof(output_buf) ) ) < 0 ) 00305 { 00306 return( ret ); 00307 } 00308 00309 if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY, 00310 output_buf + sizeof(output_buf) - ret, 00311 ret, buf, size, &olen ) ) != 0 ) 00312 { 00313 return( ret ); 00314 } 00315 00316 return( 0 ); 00317 } 00318 00319 int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size ) 00320 { 00321 int ret; 00322 unsigned char output_buf[4096]; 00323 const char *begin, *end; 00324 size_t olen = 0; 00325 00326 if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 ) 00327 return( ret ); 00328 00329 #if defined(POLARSSL_RSA_C) 00330 if( pk_get_type( key ) == POLARSSL_PK_RSA ) 00331 { 00332 begin = PEM_BEGIN_PRIVATE_KEY_RSA; 00333 end = PEM_END_PRIVATE_KEY_RSA; 00334 } 00335 else 00336 #endif 00337 #if defined(POLARSSL_ECP_C) 00338 if( pk_get_type( key ) == POLARSSL_PK_ECKEY ) 00339 { 00340 begin = PEM_BEGIN_PRIVATE_KEY_EC; 00341 end = PEM_END_PRIVATE_KEY_EC; 00342 } 00343 else 00344 #endif 00345 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE ); 00346 00347 if( ( ret = pem_write_buffer( begin, end, 00348 output_buf + sizeof(output_buf) - ret, 00349 ret, buf, size, &olen ) ) != 0 ) 00350 { 00351 return( ret ); 00352 } 00353 00354 return( 0 ); 00355 } 00356 #endif /* POLARSSL_PEM_WRITE_C */ 00357 00358 #endif /* POLARSSL_PK_WRITE_C */ 00359 00360
Generated on Tue Jul 12 2022 19:40:20 by
1.7.2