00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "polarssl/config.h"
00027
00028 #if defined(POLARSSL_PK_WRITE_C)
00029
00030 #include "polarssl/pk.h"
00031 #include "polarssl/asn1write.h"
00032 #include "polarssl/oid.h"
00033
00034 #if defined(POLARSSL_RSA_C)
00035 #include "polarssl/rsa.h"
00036 #endif
00037 #if defined(POLARSSL_ECP_C)
00038 #include "polarssl/ecp.h"
00039 #endif
00040 #if defined(POLARSSL_ECDSA_C)
00041 #include "polarssl/ecdsa.h"
00042 #endif
00043 #if defined(POLARSSL_PEM_WRITE_C)
00044 #include "polarssl/pem.h"
00045 #endif
00046
00047 #if defined(POLARSSL_MEMORY_C)
00048 #include "polarssl/memory.h"
00049 #else
00050 #include <stdlib.h>
00051 #define polarssl_malloc malloc
00052 #define polarssl_free free
00053 #endif
00054
00055 #if defined(POLARSSL_RSA_C)
00056
00057
00058
00059
00060
00061
00062 static int pk_write_rsa_pubkey( unsigned char **p, unsigned char *start,
00063 rsa_context *rsa )
00064 {
00065 int ret;
00066 size_t len = 0;
00067
00068 ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->E ) );
00069 ASN1_CHK_ADD( len, asn1_write_mpi( p, start, &rsa->N ) );
00070
00071 ASN1_CHK_ADD( len, asn1_write_len( p, start, len ) );
00072 ASN1_CHK_ADD( len, asn1_write_tag( p, start, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00073
00074 return( (int) len );
00075 }
00076 #endif
00077
00078 #if defined(POLARSSL_ECP_C)
00079
00080
00081
00082 static int pk_write_ec_pubkey( unsigned char **p, unsigned char *start,
00083 ecp_keypair *ec )
00084 {
00085 int ret;
00086 size_t len = 0;
00087 unsigned char buf[POLARSSL_ECP_MAX_PT_LEN];
00088
00089 if( ( ret = ecp_point_write_binary( &ec->grp, &ec->Q,
00090 POLARSSL_ECP_PF_UNCOMPRESSED,
00091 &len, buf, sizeof( buf ) ) ) != 0 )
00092 {
00093 return( ret );
00094 }
00095
00096 if( *p - start < (int) len )
00097 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00098
00099 *p -= len;
00100 memcpy( *p, buf, len );
00101
00102 return( (int) len );
00103 }
00104
00105
00106
00107
00108
00109
00110 static int pk_write_ec_param( unsigned char **p, unsigned char *start,
00111 ecp_keypair *ec )
00112 {
00113 int ret;
00114 size_t len = 0;
00115 const char *oid;
00116 size_t oid_len;
00117
00118 if( ( ret = oid_get_oid_by_ec_grp( ec->grp.id, &oid, &oid_len ) ) != 0 )
00119 return( ret );
00120
00121 ASN1_CHK_ADD( len, asn1_write_oid( p, start, oid, oid_len ) );
00122
00123 return( (int) len );
00124 }
00125 #endif
00126
00127 int pk_write_pubkey( unsigned char **p, unsigned char *start,
00128 const pk_context *key )
00129 {
00130 int ret;
00131 size_t len = 0;
00132
00133 #if defined(POLARSSL_RSA_C)
00134 if( pk_get_type( key ) == POLARSSL_PK_RSA )
00135 ASN1_CHK_ADD( len, pk_write_rsa_pubkey( p, start, pk_rsa( *key ) ) );
00136 else
00137 #endif
00138 #if defined(POLARSSL_ECP_C)
00139 if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
00140 ASN1_CHK_ADD( len, pk_write_ec_pubkey( p, start, pk_ec( *key ) ) );
00141 else
00142 #endif
00143 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
00144
00145 return( (int) len );
00146 }
00147
00148 int pk_write_pubkey_der( pk_context *key, unsigned char *buf, size_t size )
00149 {
00150 int ret;
00151 unsigned char *c;
00152 size_t len = 0, par_len = 0, oid_len;
00153 const char *oid;
00154
00155 c = buf + size;
00156
00157 ASN1_CHK_ADD( len, pk_write_pubkey( &c, buf, key ) );
00158
00159 if( c - buf < 1 )
00160 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00161
00162
00163
00164
00165
00166
00167 *--c = 0;
00168 len += 1;
00169
00170 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
00171 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
00172
00173 if( ( ret = oid_get_oid_by_pk_alg( pk_get_type( key ),
00174 &oid, &oid_len ) ) != 0 )
00175 {
00176 return( ret );
00177 }
00178
00179 #if defined(POLARSSL_ECP_C)
00180 if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
00181 {
00182 ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, pk_ec( *key ) ) );
00183 }
00184 #endif
00185
00186 ASN1_CHK_ADD( len, asn1_write_algorithm_identifier( &c, buf, oid, oid_len,
00187 par_len ) );
00188
00189 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
00190 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00191
00192 return( (int) len );
00193 }
00194
00195 int pk_write_key_der( pk_context *key, unsigned char *buf, size_t size )
00196 {
00197 int ret;
00198 unsigned char *c = buf + size;
00199 size_t len = 0;
00200
00201 #if defined(POLARSSL_RSA_C)
00202 if( pk_get_type( key ) == POLARSSL_PK_RSA )
00203 {
00204 rsa_context *rsa = pk_rsa( *key );
00205
00206 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->QP ) );
00207 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DQ ) );
00208 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->DP ) );
00209 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->Q ) );
00210 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->P ) );
00211 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->D ) );
00212 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->E ) );
00213 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &rsa->N ) );
00214 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 0 ) );
00215
00216 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
00217 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00218 }
00219 else
00220 #endif
00221 #if defined(POLARSSL_ECP_C)
00222 if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
00223 {
00224 ecp_keypair *ec = pk_ec( *key );
00225 size_t pub_len = 0, par_len = 0;
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 ASN1_CHK_ADD( pub_len, pk_write_ec_pubkey( &c, buf, ec ) );
00240
00241 if( c - buf < 1 )
00242 return( POLARSSL_ERR_ASN1_BUF_TOO_SMALL );
00243 *--c = 0;
00244 pub_len += 1;
00245
00246 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) );
00247 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf, ASN1_BIT_STRING ) );
00248
00249 ASN1_CHK_ADD( pub_len, asn1_write_len( &c, buf, pub_len ) );
00250 ASN1_CHK_ADD( pub_len, asn1_write_tag( &c, buf,
00251 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) );
00252 len += pub_len;
00253
00254
00255 ASN1_CHK_ADD( par_len, pk_write_ec_param( &c, buf, ec ) );
00256
00257 ASN1_CHK_ADD( par_len, asn1_write_len( &c, buf, par_len ) );
00258 ASN1_CHK_ADD( par_len, asn1_write_tag( &c, buf,
00259 ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) );
00260 len += par_len;
00261
00262
00263 ASN1_CHK_ADD( len, asn1_write_mpi( &c, buf, &ec->d ) );
00264 *c = ASN1_OCTET_STRING;
00265
00266
00267 ASN1_CHK_ADD( len, asn1_write_int( &c, buf, 1 ) );
00268
00269 ASN1_CHK_ADD( len, asn1_write_len( &c, buf, len ) );
00270 ASN1_CHK_ADD( len, asn1_write_tag( &c, buf, ASN1_CONSTRUCTED | ASN1_SEQUENCE ) );
00271 }
00272 else
00273 #endif
00274 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
00275
00276 return( (int) len );
00277 }
00278
00279 #if defined(POLARSSL_PEM_WRITE_C)
00280
00281 #define PEM_BEGIN_PUBLIC_KEY "-----BEGIN PUBLIC KEY-----\n"
00282 #define PEM_END_PUBLIC_KEY "-----END PUBLIC KEY-----\n"
00283
00284 #define PEM_BEGIN_PRIVATE_KEY_RSA "-----BEGIN RSA PRIVATE KEY-----\n"
00285 #define PEM_END_PRIVATE_KEY_RSA "-----END RSA PRIVATE KEY-----\n"
00286 #define PEM_BEGIN_PRIVATE_KEY_EC "-----BEGIN EC PRIVATE KEY-----\n"
00287 #define PEM_END_PRIVATE_KEY_EC "-----END EC PRIVATE KEY-----\n"
00288
00289 int pk_write_pubkey_pem( pk_context *key, unsigned char *buf, size_t size )
00290 {
00291 int ret;
00292 unsigned char output_buf[4096];
00293 size_t olen = 0;
00294
00295 if( ( ret = pk_write_pubkey_der( key, output_buf,
00296 sizeof(output_buf) ) ) < 0 )
00297 {
00298 return( ret );
00299 }
00300
00301 if( ( ret = pem_write_buffer( PEM_BEGIN_PUBLIC_KEY, PEM_END_PUBLIC_KEY,
00302 output_buf + sizeof(output_buf) - ret,
00303 ret, buf, size, &olen ) ) != 0 )
00304 {
00305 return( ret );
00306 }
00307
00308 return( 0 );
00309 }
00310
00311 int pk_write_key_pem( pk_context *key, unsigned char *buf, size_t size )
00312 {
00313 int ret;
00314 unsigned char output_buf[4096];
00315 const char *begin, *end;
00316 size_t olen = 0;
00317
00318 if( ( ret = pk_write_key_der( key, output_buf, sizeof(output_buf) ) ) < 0 )
00319 return( ret );
00320
00321 #if defined(POLARSSL_RSA_C)
00322 if( pk_get_type( key ) == POLARSSL_PK_RSA )
00323 {
00324 begin = PEM_BEGIN_PRIVATE_KEY_RSA;
00325 end = PEM_END_PRIVATE_KEY_RSA;
00326 }
00327 else
00328 #endif
00329 #if defined(POLARSSL_ECP_C)
00330 if( pk_get_type( key ) == POLARSSL_PK_ECKEY )
00331 {
00332 begin = PEM_BEGIN_PRIVATE_KEY_EC;
00333 end = PEM_END_PRIVATE_KEY_EC;
00334 }
00335 else
00336 #endif
00337 return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
00338
00339 if( ( ret = pem_write_buffer( begin, end,
00340 output_buf + sizeof(output_buf) - ret,
00341 ret, buf, size, &olen ) ) != 0 )
00342 {
00343 return( ret );
00344 }
00345
00346 return( 0 );
00347 }
00348 #endif
00349
00350 #endif