mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pkwrite.c Source File

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