mbed TLS library

Dependents:   HTTPClient-SSL WS_SERVER

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers pkparse.c Source File

pkparse.c

00001 /*
00002  *  Public Key layer for parsing 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_PARSE_C)
00030 
00031 #include "polarssl/pk.h"
00032 #include "polarssl/asn1.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_PARSE_C)
00047 #include "polarssl/pem.h"
00048 #endif
00049 #if defined(POLARSSL_PKCS5_C)
00050 #include "polarssl/pkcs5.h"
00051 #endif
00052 #if defined(POLARSSL_PKCS12_C)
00053 #include "polarssl/pkcs12.h"
00054 #endif
00055 
00056 #if defined(POLARSSL_PLATFORM_C)
00057 #include "polarssl/platform.h"
00058 #else
00059 #include <stdlib.h>
00060 #define polarssl_malloc     malloc
00061 #define polarssl_free       free
00062 #endif
00063 
00064 #if defined(POLARSSL_FS_IO)
00065 /* Implementation that should never be optimized out by the compiler */
00066 static void polarssl_zeroize( void *v, size_t n ) {
00067     volatile unsigned char *p = v; while( n-- ) *p++ = 0;
00068 }
00069 
00070 /*
00071  * Load all data from a file into a given buffer.
00072  */
00073 int pk_load_file( const char *path, unsigned char **buf, size_t *n )
00074 {
00075     FILE *f;
00076     long size;
00077 
00078     if( ( f = fopen( path, "rb" ) ) == NULL )
00079         return( POLARSSL_ERR_PK_FILE_IO_ERROR );
00080 
00081     fseek( f, 0, SEEK_END );
00082     if( ( size = ftell( f ) ) == -1 )
00083     {
00084         fclose( f );
00085         return( POLARSSL_ERR_PK_FILE_IO_ERROR );
00086     }
00087     fseek( f, 0, SEEK_SET );
00088 
00089     *n = (size_t) size;
00090 
00091     if( *n + 1 == 0 ||
00092         ( *buf = polarssl_malloc( *n + 1 ) ) == NULL )
00093     {
00094         fclose( f );
00095         return( POLARSSL_ERR_PK_MALLOC_FAILED );
00096     }
00097 
00098     if( fread( *buf, 1, *n, f ) != *n )
00099     {
00100         fclose( f );
00101         polarssl_free( *buf );
00102         return( POLARSSL_ERR_PK_FILE_IO_ERROR );
00103     }
00104 
00105     fclose( f );
00106 
00107     (*buf)[*n] = '\0';
00108 
00109     return( 0 );
00110 }
00111 
00112 /*
00113  * Load and parse a private key
00114  */
00115 int pk_parse_keyfile( pk_context *ctx,
00116                       const char *path, const char *pwd )
00117 {
00118     int ret;
00119     size_t n;
00120     unsigned char *buf;
00121 
00122     if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
00123         return( ret );
00124 
00125     if( pwd == NULL )
00126         ret = pk_parse_key( ctx, buf, n, NULL, 0 );
00127     else
00128         ret = pk_parse_key( ctx, buf, n,
00129                 (const unsigned char *) pwd, strlen( pwd ) );
00130 
00131     polarssl_zeroize( buf, n + 1 );
00132     polarssl_free( buf );
00133 
00134     return( ret );
00135 }
00136 
00137 /*
00138  * Load and parse a public key
00139  */
00140 int pk_parse_public_keyfile( pk_context *ctx, const char *path )
00141 {
00142     int ret;
00143     size_t n;
00144     unsigned char *buf;
00145 
00146     if( ( ret = pk_load_file( path, &buf, &n ) ) != 0 )
00147         return( ret );
00148 
00149     ret = pk_parse_public_key( ctx, buf, n );
00150 
00151     polarssl_zeroize( buf, n + 1 );
00152     polarssl_free( buf );
00153 
00154     return( ret );
00155 }
00156 #endif /* POLARSSL_FS_IO */
00157 
00158 #if defined(POLARSSL_ECP_C)
00159 /* Minimally parse an ECParameters buffer to and asn1_buf
00160  *
00161  * ECParameters ::= CHOICE {
00162  *   namedCurve         OBJECT IDENTIFIER
00163  *   specifiedCurve     SpecifiedECDomain -- = SEQUENCE { ... }
00164  *   -- implicitCurve   NULL
00165  * }
00166  */
00167 static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
00168                             asn1_buf *params )
00169 {
00170     int ret;
00171 
00172     /* Tag may be either OID or SEQUENCE */
00173     params->tag = **p;
00174     if( params->tag != ASN1_OID
00175 #if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
00176             && params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE )
00177 #endif
00178             )
00179     {
00180         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
00181                 POLARSSL_ERR_ASN1_UNEXPECTED_TAG );
00182     }
00183 
00184     if( ( ret = asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
00185     {
00186         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00187     }
00188 
00189     params->p = *p;
00190     *p += params->len;
00191 
00192     if( *p != end )
00193         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
00194                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00195 
00196     return( 0 );
00197 }
00198 
00199 #if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
00200 /*
00201  * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
00202  * WARNING: the resulting group should only be used with
00203  * pk_group_id_from_specified(), since its base point may not be set correctly
00204  * if it was encoded compressed.
00205  *
00206  *  SpecifiedECDomain ::= SEQUENCE {
00207  *      version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
00208  *      fieldID FieldID {{FieldTypes}},
00209  *      curve Curve,
00210  *      base ECPoint,
00211  *      order INTEGER,
00212  *      cofactor INTEGER OPTIONAL,
00213  *      hash HashAlgorithm OPTIONAL,
00214  *      ...
00215  *  }
00216  *
00217  * We only support prime-field as field type, and ignore hash and cofactor.
00218  */
00219 static int pk_group_from_specified( const asn1_buf *params, ecp_group *grp )
00220 {
00221     int ret;
00222     unsigned char *p = params->p;
00223     const unsigned char * const end = params->p + params->len;
00224     const unsigned char *end_field, *end_curve;
00225     size_t len;
00226     int ver;
00227 
00228     /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
00229     if( ( ret = asn1_get_int( &p, end, &ver ) ) != 0 )
00230         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00231 
00232     if( ver < 1 || ver > 3 )
00233         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
00234 
00235     /*
00236      * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
00237      *       fieldType FIELD-ID.&id({IOSet}),
00238      *       parameters FIELD-ID.&Type({IOSet}{@fieldType})
00239      * }
00240      */
00241     if( ( ret = asn1_get_tag( &p, end, &len,
00242             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00243         return( ret );
00244 
00245     end_field = p + len;
00246 
00247     /*
00248      * FIELD-ID ::= TYPE-IDENTIFIER
00249      * FieldTypes FIELD-ID ::= {
00250      *       { Prime-p IDENTIFIED BY prime-field } |
00251      *       { Characteristic-two IDENTIFIED BY characteristic-two-field }
00252      * }
00253      * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
00254      */
00255     if( ( ret = asn1_get_tag( &p, end_field, &len, ASN1_OID ) ) != 0 )
00256         return( ret );
00257 
00258     if( len != OID_SIZE( OID_ANSI_X9_62_PRIME_FIELD ) ||
00259         memcmp( p, OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
00260     {
00261         return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
00262     }
00263 
00264     p += len;
00265 
00266     /* Prime-p ::= INTEGER -- Field of size p. */
00267     if( ( ret = asn1_get_mpi( &p, end_field, &grp->P  ) ) != 0 )
00268         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00269 
00270     grp->pbits  = mpi_msb( &grp->P  );
00271 
00272     if( p != end_field )
00273         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
00274                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00275 
00276     /*
00277      * Curve ::= SEQUENCE {
00278      *       a FieldElement,
00279      *       b FieldElement,
00280      *       seed BIT STRING OPTIONAL
00281      *       -- Shall be present if used in SpecifiedECDomain
00282      *       -- with version equal to ecdpVer2 or ecdpVer3
00283      * }
00284      */
00285     if( ( ret = asn1_get_tag( &p, end, &len,
00286             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00287         return( ret );
00288 
00289     end_curve = p + len;
00290 
00291     /*
00292      * FieldElement ::= OCTET STRING
00293      * containing an integer in the case of a prime field
00294      */
00295     if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
00296         ( ret = mpi_read_binary( &grp->A , p, len ) ) != 0 )
00297     {
00298         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00299     }
00300 
00301     p += len;
00302 
00303     if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
00304         ( ret = mpi_read_binary( &grp->B , p, len ) ) != 0 )
00305     {
00306         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00307     }
00308 
00309     p += len;
00310 
00311     /* Ignore seed BIT STRING OPTIONAL */
00312     if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_BIT_STRING ) ) == 0 )
00313         p += len;
00314 
00315     if( p != end_curve )
00316         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
00317                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00318 
00319     /*
00320      * ECPoint ::= OCTET STRING
00321      */
00322     if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
00323         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00324 
00325     if( ( ret = ecp_point_read_binary( grp, &grp->G ,
00326                                       ( const unsigned char *) p, len ) ) != 0 )
00327     {
00328         /*
00329          * If we can't read the point because it's compressed, cheat by
00330          * reading only the X coordinate and the parity bit of Y.
00331          */
00332         if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE ||
00333             ( p[0] != 0x02 && p[0] != 0x03 ) ||
00334             len != mpi_size( &grp->P  ) + 1 ||
00335             mpi_read_binary( &grp->G .X , p + 1, len - 1 ) != 0 ||
00336             mpi_lset( &grp->G .Y , p[0] - 2 ) != 0 ||
00337             mpi_lset( &grp->G .Z , 1 ) != 0 )
00338         {
00339             return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
00340         }
00341     }
00342 
00343     p += len;
00344 
00345     /*
00346      * order INTEGER
00347      */
00348     if( ( ret = asn1_get_mpi( &p, end, &grp->N  ) ) != 0 )
00349         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00350 
00351     grp->nbits  = mpi_msb( &grp->N  );
00352 
00353     /*
00354      * Allow optional elements by purposefully not enforcing p == end here.
00355      */
00356 
00357     return( 0 );
00358 }
00359 
00360 /*
00361  * Find the group id associated with an (almost filled) group as generated by
00362  * pk_group_from_specified(), or return an error if unknown.
00363  */
00364 static int pk_group_id_from_group( const ecp_group *grp, ecp_group_id *grp_id )
00365 {
00366     int ret = 0;
00367     ecp_group ref;
00368     const ecp_group_id *id;
00369 
00370     ecp_group_init( &ref );
00371 
00372     for( id = ecp_grp_id_list(); *id != POLARSSL_ECP_DP_NONE; id++ )
00373     {
00374         /* Load the group associated to that id */
00375         ecp_group_free( &ref );
00376         MPI_CHK( ecp_use_known_dp( &ref, *id ) );
00377 
00378         /* Compare to the group we were given, starting with easy tests */
00379         if( grp->pbits  == ref.pbits  && grp->nbits  == ref.nbits  &&
00380             mpi_cmp_mpi( &grp->P , &ref.P  ) == 0 &&
00381             mpi_cmp_mpi( &grp->A , &ref.A  ) == 0 &&
00382             mpi_cmp_mpi( &grp->B , &ref.B  ) == 0 &&
00383             mpi_cmp_mpi( &grp->N , &ref.N  ) == 0 &&
00384             mpi_cmp_mpi( &grp->G .X , &ref.G .X  ) == 0 &&
00385             mpi_cmp_mpi( &grp->G .Z , &ref.G .Z  ) == 0 &&
00386             /* For Y we may only know the parity bit, so compare only that */
00387             mpi_get_bit( &grp->G .Y , 0 ) == mpi_get_bit( &ref.G .Y , 0 ) )
00388         {
00389             break;
00390         }
00391 
00392     }
00393 
00394 cleanup:
00395     ecp_group_free( &ref );
00396 
00397     *grp_id = *id;
00398 
00399     if( ret == 0 && *id == POLARSSL_ECP_DP_NONE )
00400         ret = POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE;
00401 
00402     return( ret );
00403 }
00404 
00405 /*
00406  * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
00407  */
00408 static int pk_group_id_from_specified( const asn1_buf *params,
00409                                        ecp_group_id *grp_id )
00410 {
00411     int ret;
00412     ecp_group grp;
00413 
00414     ecp_group_init( &grp );
00415 
00416     if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 )
00417         goto cleanup;
00418 
00419     ret = pk_group_id_from_group( &grp, grp_id );
00420 
00421 cleanup:
00422     ecp_group_free( &grp );
00423 
00424     return( ret );
00425 }
00426 #endif /* POLARSSL_PK_PARSE_EC_EXTENDED */
00427 
00428 /*
00429  * Use EC parameters to initialise an EC group
00430  *
00431  * ECParameters ::= CHOICE {
00432  *   namedCurve         OBJECT IDENTIFIER
00433  *   specifiedCurve     SpecifiedECDomain -- = SEQUENCE { ... }
00434  *   -- implicitCurve   NULL
00435  */
00436 static int pk_use_ecparams( const asn1_buf *params, ecp_group *grp )
00437 {
00438     int ret;
00439     ecp_group_id grp_id;
00440 
00441     if( params->tag == ASN1_OID )
00442     {
00443         if( oid_get_ec_grp( params, &grp_id ) != 0 )
00444             return( POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE );
00445     }
00446     else
00447     {
00448 #if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
00449         if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 )
00450             return( ret );
00451 #else
00452         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
00453 #endif
00454     }
00455 
00456     /*
00457      * grp may already be initilialized; if so, make sure IDs match
00458      */
00459     if( grp->id  != POLARSSL_ECP_DP_NONE && grp->id  != grp_id )
00460         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
00461 
00462     if( ( ret = ecp_use_known_dp( grp, grp_id ) ) != 0 )
00463         return( ret );
00464 
00465     return( 0 );
00466 }
00467 
00468 /*
00469  * EC public key is an EC point
00470  *
00471  * The caller is responsible for clearing the structure upon failure if
00472  * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
00473  * return code of ecp_point_read_binary() and leave p in a usable state.
00474  */
00475 static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
00476                             ecp_keypair *key )
00477 {
00478     int ret;
00479 
00480     if( ( ret = ecp_point_read_binary( &key->grp , &key->Q ,
00481                     (const unsigned char *) *p, end - *p ) ) == 0 )
00482     {
00483         ret = ecp_check_pubkey( &key->grp , &key->Q  );
00484     }
00485 
00486     /*
00487      * We know ecp_point_read_binary consumed all bytes or failed
00488      */
00489     *p = (unsigned char *) end;
00490 
00491     return( ret );
00492 }
00493 #endif /* POLARSSL_ECP_C */
00494 
00495 #if defined(POLARSSL_RSA_C)
00496 /*
00497  *  RSAPublicKey ::= SEQUENCE {
00498  *      modulus           INTEGER,  -- n
00499  *      publicExponent    INTEGER   -- e
00500  *  }
00501  */
00502 static int pk_get_rsapubkey( unsigned char **p,
00503                              const unsigned char *end,
00504                              rsa_context *rsa )
00505 {
00506     int ret;
00507     size_t len;
00508 
00509     if( ( ret = asn1_get_tag( p, end, &len,
00510             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00511         return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
00512 
00513     if( *p + len != end )
00514         return( POLARSSL_ERR_PK_INVALID_PUBKEY +
00515                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00516 
00517     if( ( ret = asn1_get_mpi( p, end, &rsa->N  ) ) != 0 ||
00518         ( ret = asn1_get_mpi( p, end, &rsa->E  ) ) != 0 )
00519         return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
00520 
00521     if( *p != end )
00522         return( POLARSSL_ERR_PK_INVALID_PUBKEY +
00523                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00524 
00525     if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
00526         return( POLARSSL_ERR_PK_INVALID_PUBKEY );
00527 
00528     rsa->len  = mpi_size( &rsa->N  );
00529 
00530     return( 0 );
00531 }
00532 #endif /* POLARSSL_RSA_C */
00533 
00534 /* Get a PK algorithm identifier
00535  *
00536  *  AlgorithmIdentifier  ::=  SEQUENCE  {
00537  *       algorithm               OBJECT IDENTIFIER,
00538  *       parameters              ANY DEFINED BY algorithm OPTIONAL  }
00539  */
00540 static int pk_get_pk_alg( unsigned char **p,
00541                           const unsigned char *end,
00542                           pk_type_t *pk_alg, asn1_buf *params )
00543 {
00544     int ret;
00545     asn1_buf alg_oid;
00546 
00547     memset( params, 0, sizeof(asn1_buf) );
00548 
00549     if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
00550         return( POLARSSL_ERR_PK_INVALID_ALG + ret );
00551 
00552     if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
00553         return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
00554 
00555     /*
00556      * No parameters with RSA (only for EC)
00557      */
00558     if( *pk_alg == POLARSSL_PK_RSA &&
00559             ( ( params->tag != ASN1_NULL && params->tag != 0 ) ||
00560                 params->len != 0 ) )
00561     {
00562         return( POLARSSL_ERR_PK_INVALID_ALG );
00563     }
00564 
00565     return( 0 );
00566 }
00567 
00568 /*
00569  *  SubjectPublicKeyInfo  ::=  SEQUENCE  {
00570  *       algorithm            AlgorithmIdentifier,
00571  *       subjectPublicKey     BIT STRING }
00572  */
00573 int pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
00574                         pk_context *pk )
00575 {
00576     int ret;
00577     size_t len;
00578     asn1_buf alg_params;
00579     pk_type_t pk_alg = POLARSSL_PK_NONE;
00580     const pk_info_t *pk_info;
00581 
00582     if( ( ret = asn1_get_tag( p, end, &len,
00583                     ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00584     {
00585         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00586     }
00587 
00588     end = *p + len;
00589 
00590     if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
00591         return( ret );
00592 
00593     if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
00594         return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
00595 
00596     if( *p + len != end )
00597         return( POLARSSL_ERR_PK_INVALID_PUBKEY +
00598                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00599 
00600     if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
00601         return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
00602 
00603     if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
00604         return( ret );
00605 
00606 #if defined(POLARSSL_RSA_C)
00607     if( pk_alg == POLARSSL_PK_RSA )
00608     {
00609         ret = pk_get_rsapubkey( p, end, pk_rsa( *pk ) );
00610     } else
00611 #endif /* POLARSSL_RSA_C */
00612 #if defined(POLARSSL_ECP_C)
00613     if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY )
00614     {
00615         ret = pk_use_ecparams( &alg_params, &pk_ec( *pk )->grp );
00616         if( ret == 0 )
00617             ret = pk_get_ecpubkey( p, end, pk_ec( *pk ) );
00618     } else
00619 #endif /* POLARSSL_ECP_C */
00620         ret = POLARSSL_ERR_PK_UNKNOWN_PK_ALG;
00621 
00622     if( ret == 0 && *p != end )
00623         ret = POLARSSL_ERR_PK_INVALID_PUBKEY
00624               POLARSSL_ERR_ASN1_LENGTH_MISMATCH;
00625 
00626     if( ret != 0 )
00627         pk_free( pk );
00628 
00629     return( ret );
00630 }
00631 
00632 #if defined(POLARSSL_RSA_C)
00633 /*
00634  * Parse a PKCS#1 encoded private RSA key
00635  */
00636 static int pk_parse_key_pkcs1_der( rsa_context *rsa,
00637                                    const unsigned char *key,
00638                                    size_t keylen )
00639 {
00640     int ret;
00641     size_t len;
00642     unsigned char *p, *end;
00643 
00644     p = (unsigned char *) key;
00645     end = p + keylen;
00646 
00647     /*
00648      * This function parses the RSAPrivateKey (PKCS#1)
00649      *
00650      *  RSAPrivateKey ::= SEQUENCE {
00651      *      version           Version,
00652      *      modulus           INTEGER,  -- n
00653      *      publicExponent    INTEGER,  -- e
00654      *      privateExponent   INTEGER,  -- d
00655      *      prime1            INTEGER,  -- p
00656      *      prime2            INTEGER,  -- q
00657      *      exponent1         INTEGER,  -- d mod (p-1)
00658      *      exponent2         INTEGER,  -- d mod (q-1)
00659      *      coefficient       INTEGER,  -- (inverse of q) mod p
00660      *      otherPrimeInfos   OtherPrimeInfos OPTIONAL
00661      *  }
00662      */
00663     if( ( ret = asn1_get_tag( &p, end, &len,
00664             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00665     {
00666         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00667     }
00668 
00669     end = p + len;
00670 
00671     if( ( ret = asn1_get_int( &p, end, &rsa->ver  ) ) != 0 )
00672     {
00673         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00674     }
00675 
00676     if( rsa->ver  != 0 )
00677     {
00678         return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
00679     }
00680 
00681     if( ( ret = asn1_get_mpi( &p, end, &rsa->N   ) ) != 0 ||
00682         ( ret = asn1_get_mpi( &p, end, &rsa->E   ) ) != 0 ||
00683         ( ret = asn1_get_mpi( &p, end, &rsa->D   ) ) != 0 ||
00684         ( ret = asn1_get_mpi( &p, end, &rsa->P   ) ) != 0 ||
00685         ( ret = asn1_get_mpi( &p, end, &rsa->Q   ) ) != 0 ||
00686         ( ret = asn1_get_mpi( &p, end, &rsa->DP  ) ) != 0 ||
00687         ( ret = asn1_get_mpi( &p, end, &rsa->DQ  ) ) != 0 ||
00688         ( ret = asn1_get_mpi( &p, end, &rsa->QP  ) ) != 0 )
00689     {
00690         rsa_free( rsa );
00691         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00692     }
00693 
00694     rsa->len  = mpi_size( &rsa->N  );
00695 
00696     if( p != end )
00697     {
00698         rsa_free( rsa );
00699         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
00700                 POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00701     }
00702 
00703     if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
00704     {
00705         rsa_free( rsa );
00706         return( ret );
00707     }
00708 
00709     return( 0 );
00710 }
00711 #endif /* POLARSSL_RSA_C */
00712 
00713 #if defined(POLARSSL_ECP_C)
00714 /*
00715  * Parse a SEC1 encoded private EC key
00716  */
00717 static int pk_parse_key_sec1_der( ecp_keypair *eck,
00718                                   const unsigned char *key,
00719                                   size_t keylen )
00720 {
00721     int ret;
00722     int version, pubkey_done;
00723     size_t len;
00724     asn1_buf params;
00725     unsigned char *p = (unsigned char *) key;
00726     unsigned char *end = p + keylen;
00727     unsigned char *end2;
00728 
00729     /*
00730      * RFC 5915, or SEC1 Appendix C.4
00731      *
00732      * ECPrivateKey ::= SEQUENCE {
00733      *      version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
00734      *      privateKey     OCTET STRING,
00735      *      parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
00736      *      publicKey  [1] BIT STRING OPTIONAL
00737      *    }
00738      */
00739     if( ( ret = asn1_get_tag( &p, end, &len,
00740             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00741     {
00742         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00743     }
00744 
00745     end = p + len;
00746 
00747     if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
00748         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00749 
00750     if( version != 1 )
00751         return( POLARSSL_ERR_PK_KEY_INVALID_VERSION );
00752 
00753     if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
00754         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00755 
00756     if( ( ret = mpi_read_binary( &eck->d , p, len ) ) != 0 )
00757     {
00758         ecp_keypair_free( eck );
00759         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00760     }
00761 
00762     p += len;
00763 
00764     pubkey_done = 0;
00765     if( p != end )
00766     {
00767         /*
00768          * Is 'parameters' present?
00769          */
00770         if( ( ret = asn1_get_tag( &p, end, &len,
00771                         ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 0 ) ) == 0 )
00772         {
00773             if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
00774                 ( ret = pk_use_ecparams( &params, &eck->grp  )  ) != 0 )
00775             {
00776                 ecp_keypair_free( eck );
00777                 return( ret );
00778             }
00779         }
00780         else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00781         {
00782             ecp_keypair_free( eck );
00783             return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00784         }
00785 
00786         /*
00787          * Is 'publickey' present? If not, or if we can't read it (eg because it
00788          * is compressed), create it from the private key.
00789          */
00790         if( ( ret = asn1_get_tag( &p, end, &len,
00791                         ASN1_CONTEXT_SPECIFIC | ASN1_CONSTRUCTED | 1 ) ) == 0 )
00792         {
00793             end2 = p + len;
00794 
00795             if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
00796                 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00797 
00798             if( p + len != end2 )
00799                 return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
00800                         POLARSSL_ERR_ASN1_LENGTH_MISMATCH );
00801 
00802             if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
00803                 pubkey_done = 1;
00804             else
00805             {
00806                 /*
00807                  * The only acceptable failure mode of pk_get_ecpubkey() above
00808                  * is if the point format is not recognized.
00809                  */
00810                 if( ret != POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE )
00811                     return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
00812             }
00813         }
00814         else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
00815         {
00816             ecp_keypair_free( eck );
00817             return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00818         }
00819     }
00820 
00821     if( ! pubkey_done &&
00822         ( ret = ecp_mul( &eck->grp , &eck->Q , &eck->d , &eck->grp .G ,
00823                                                       NULL, NULL ) ) != 0 )
00824     {
00825         ecp_keypair_free( eck );
00826         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00827     }
00828 
00829     if( ( ret = ecp_check_privkey( &eck->grp , &eck->d  ) ) != 0 )
00830     {
00831         ecp_keypair_free( eck );
00832         return( ret );
00833     }
00834 
00835     return( 0 );
00836 }
00837 #endif /* POLARSSL_ECP_C */
00838 
00839 /*
00840  * Parse an unencrypted PKCS#8 encoded private key
00841  */
00842 static int pk_parse_key_pkcs8_unencrypted_der(
00843                                     pk_context *pk,
00844                                     const unsigned char* key,
00845                                     size_t keylen )
00846 {
00847     int ret, version;
00848     size_t len;
00849     asn1_buf params;
00850     unsigned char *p = (unsigned char *) key;
00851     unsigned char *end = p + keylen;
00852     pk_type_t pk_alg = POLARSSL_PK_NONE;
00853     const pk_info_t *pk_info;
00854 
00855     /*
00856      * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
00857      *
00858      *    PrivateKeyInfo ::= SEQUENCE {
00859      *      version                   Version,
00860      *      privateKeyAlgorithm       PrivateKeyAlgorithmIdentifier,
00861      *      privateKey                PrivateKey,
00862      *      attributes           [0]  IMPLICIT Attributes OPTIONAL }
00863      *
00864      *    Version ::= INTEGER
00865      *    PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
00866      *    PrivateKey ::= OCTET STRING
00867      *
00868      *  The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
00869      */
00870 
00871     if( ( ret = asn1_get_tag( &p, end, &len,
00872             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00873     {
00874         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00875     }
00876 
00877     end = p + len;
00878 
00879     if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
00880         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00881 
00882     if( version != 0 )
00883         return( POLARSSL_ERR_PK_KEY_INVALID_VERSION + ret );
00884 
00885     if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
00886         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00887 
00888     if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
00889         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00890 
00891     if( len < 1 )
00892         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT +
00893                 POLARSSL_ERR_ASN1_OUT_OF_DATA );
00894 
00895     if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
00896         return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
00897 
00898     if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
00899         return( ret );
00900 
00901 #if defined(POLARSSL_RSA_C)
00902     if( pk_alg == POLARSSL_PK_RSA )
00903     {
00904         if( ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), p, len ) ) != 0 )
00905         {
00906             pk_free( pk );
00907             return( ret );
00908         }
00909     } else
00910 #endif /* POLARSSL_RSA_C */
00911 #if defined(POLARSSL_ECP_C)
00912     if( pk_alg == POLARSSL_PK_ECKEY || pk_alg == POLARSSL_PK_ECKEY_DH )
00913     {
00914         if( ( ret = pk_use_ecparams( &params, &pk_ec( *pk )->grp ) ) != 0 ||
00915             ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), p, len )  ) != 0 )
00916         {
00917             pk_free( pk );
00918             return( ret );
00919         }
00920     } else
00921 #endif /* POLARSSL_ECP_C */
00922         return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
00923 
00924     return( 0 );
00925 }
00926 
00927 /*
00928  * Parse an encrypted PKCS#8 encoded private key
00929  */
00930 #if defined(POLARSSL_PKCS12_C) || defined(POLARSSL_PKCS5_C)
00931 static int pk_parse_key_pkcs8_encrypted_der(
00932                                     pk_context *pk,
00933                                     const unsigned char *key, size_t keylen,
00934                                     const unsigned char *pwd, size_t pwdlen )
00935 {
00936     int ret, decrypted = 0;
00937     size_t len;
00938     unsigned char buf[2048];
00939     unsigned char *p, *end;
00940     asn1_buf pbe_alg_oid, pbe_params;
00941 #if defined(POLARSSL_PKCS12_C)
00942     cipher_type_t cipher_alg;
00943     md_type_t md_alg;
00944 #endif
00945 
00946     memset( buf, 0, sizeof( buf ) );
00947 
00948     p = (unsigned char *) key;
00949     end = p + keylen;
00950 
00951     if( pwdlen == 0 )
00952         return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
00953 
00954     /*
00955      * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
00956      *
00957      *  EncryptedPrivateKeyInfo ::= SEQUENCE {
00958      *    encryptionAlgorithm  EncryptionAlgorithmIdentifier,
00959      *    encryptedData        EncryptedData
00960      *  }
00961      *
00962      *  EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
00963      *
00964      *  EncryptedData ::= OCTET STRING
00965      *
00966      *  The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
00967      */
00968     if( ( ret = asn1_get_tag( &p, end, &len,
00969             ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 )
00970     {
00971         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00972     }
00973 
00974     end = p + len;
00975 
00976     if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
00977         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00978 
00979     if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
00980         return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT + ret );
00981 
00982     if( len > sizeof( buf ) )
00983         return( POLARSSL_ERR_PK_BAD_INPUT_DATA );
00984 
00985     /*
00986      * Decrypt EncryptedData with appropriate PDE
00987      */
00988 #if defined(POLARSSL_PKCS12_C)
00989     if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
00990     {
00991         if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
00992                                 cipher_alg, md_alg,
00993                                 pwd, pwdlen, p, len, buf ) ) != 0 )
00994         {
00995             if( ret == POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH )
00996                 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
00997 
00998             return( ret );
00999         }
01000 
01001         decrypted = 1;
01002     }
01003     else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
01004     {
01005         if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
01006                                              PKCS12_PBE_DECRYPT,
01007                                              pwd, pwdlen,
01008                                              p, len, buf ) ) != 0 )
01009         {
01010             return( ret );
01011         }
01012 
01013         // Best guess for password mismatch when using RC4. If first tag is
01014         // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
01015         //
01016         if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
01017             return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
01018 
01019         decrypted = 1;
01020     }
01021     else
01022 #endif /* POLARSSL_PKCS12_C */
01023 #if defined(POLARSSL_PKCS5_C)
01024     if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
01025     {
01026         if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
01027                                   p, len, buf ) ) != 0 )
01028         {
01029             if( ret == POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH )
01030                 return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
01031 
01032             return( ret );
01033         }
01034 
01035         decrypted = 1;
01036     }
01037     else
01038 #endif /* POLARSSL_PKCS5_C */
01039     {
01040         ((void) pwd);
01041     }
01042 
01043     if( decrypted == 0 )
01044         return( POLARSSL_ERR_PK_FEATURE_UNAVAILABLE );
01045 
01046     return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
01047 }
01048 #endif /* POLARSSL_PKCS12_C || POLARSSL_PKCS5_C */
01049 
01050 /*
01051  * Parse a private key
01052  */
01053 int pk_parse_key( pk_context *pk,
01054                   const unsigned char *key, size_t keylen,
01055                   const unsigned char *pwd, size_t pwdlen )
01056 {
01057     int ret;
01058     const pk_info_t *pk_info;
01059 
01060 #if defined(POLARSSL_PEM_PARSE_C)
01061     size_t len;
01062     pem_context pem;
01063 
01064     pem_init( &pem );
01065 
01066 #if defined(POLARSSL_RSA_C)
01067     ret = pem_read_buffer( &pem,
01068                            "-----BEGIN RSA PRIVATE KEY-----",
01069                            "-----END RSA PRIVATE KEY-----",
01070                            key, pwd, pwdlen, &len );
01071     if( ret == 0 )
01072     {
01073         if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
01074             return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
01075 
01076         if( ( ret = pk_init_ctx( pk, pk_info                    ) ) != 0 ||
01077             ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ),
01078                                             pem.buf , pem.buflen  ) ) != 0 )
01079         {
01080             pk_free( pk );
01081         }
01082 
01083         pem_free( &pem );
01084         return( ret );
01085     }
01086     else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
01087         return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
01088     else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
01089         return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
01090     else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
01091         return( ret );
01092 #endif /* POLARSSL_RSA_C */
01093 
01094 #if defined(POLARSSL_ECP_C)
01095     ret = pem_read_buffer( &pem,
01096                            "-----BEGIN EC PRIVATE KEY-----",
01097                            "-----END EC PRIVATE KEY-----",
01098                            key, pwd, pwdlen, &len );
01099     if( ret == 0 )
01100     {
01101         if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
01102             return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
01103 
01104         if( ( ret = pk_init_ctx( pk, pk_info                   ) ) != 0 ||
01105             ( ret = pk_parse_key_sec1_der( pk_ec( *pk ),
01106                                            pem.buf , pem.buflen  ) ) != 0 )
01107         {
01108             pk_free( pk );
01109         }
01110 
01111         pem_free( &pem );
01112         return( ret );
01113     }
01114     else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
01115         return( POLARSSL_ERR_PK_PASSWORD_MISMATCH );
01116     else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
01117         return( POLARSSL_ERR_PK_PASSWORD_REQUIRED );
01118     else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
01119         return( ret );
01120 #endif /* POLARSSL_ECP_C */
01121 
01122     ret = pem_read_buffer( &pem,
01123                            "-----BEGIN PRIVATE KEY-----",
01124                            "-----END PRIVATE KEY-----",
01125                            key, NULL, 0, &len );
01126     if( ret == 0 )
01127     {
01128         if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
01129                                                 pem.buf , pem.buflen  ) ) != 0 )
01130         {
01131             pk_free( pk );
01132         }
01133 
01134         pem_free( &pem );
01135         return( ret );
01136     }
01137     else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
01138         return( ret );
01139 
01140 #if defined(POLARSSL_PKCS12_C) || defined(POLARSSL_PKCS5_C)
01141     ret = pem_read_buffer( &pem,
01142                            "-----BEGIN ENCRYPTED PRIVATE KEY-----",
01143                            "-----END ENCRYPTED PRIVATE KEY-----",
01144                            key, NULL, 0, &len );
01145     if( ret == 0 )
01146     {
01147         if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
01148                                                       pem.buf , pem.buflen ,
01149                                                       pwd, pwdlen ) ) != 0 )
01150         {
01151             pk_free( pk );
01152         }
01153 
01154         pem_free( &pem );
01155         return( ret );
01156     }
01157     else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
01158         return( ret );
01159 #endif /* POLARSSL_PKCS12_C || POLARSSL_PKCS5_C */
01160 #else
01161     ((void) pwd);
01162     ((void) pwdlen);
01163 #endif /* POLARSSL_PEM_PARSE_C */
01164 
01165     /*
01166     * At this point we only know it's not a PEM formatted key. Could be any
01167     * of the known DER encoded private key formats
01168     *
01169     * We try the different DER format parsers to see if one passes without
01170     * error
01171     */
01172 #if defined(POLARSSL_PKCS12_C) || defined(POLARSSL_PKCS5_C)
01173     if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
01174                                                   pwd, pwdlen ) ) == 0 )
01175     {
01176         return( 0 );
01177     }
01178 
01179     pk_free( pk );
01180 
01181     if( ret == POLARSSL_ERR_PK_PASSWORD_MISMATCH )
01182     {
01183         return( ret );
01184     }
01185 #endif /* POLARSSL_PKCS12_C || POLARSSL_PKCS5_C */
01186 
01187     if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
01188         return( 0 );
01189 
01190     pk_free( pk );
01191 
01192 #if defined(POLARSSL_RSA_C)
01193     if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
01194         return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
01195 
01196     if( ( ret = pk_init_ctx( pk, pk_info                           ) ) != 0 ||
01197         ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), key, keylen ) ) == 0 )
01198     {
01199         return( 0 );
01200     }
01201 
01202     pk_free( pk );
01203 #endif /* POLARSSL_RSA_C */
01204 
01205 #if defined(POLARSSL_ECP_C)
01206     if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
01207         return( POLARSSL_ERR_PK_UNKNOWN_PK_ALG );
01208 
01209     if( ( ret = pk_init_ctx( pk, pk_info                         ) ) != 0 ||
01210         ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), key, keylen ) ) == 0 )
01211     {
01212         return( 0 );
01213     }
01214 
01215     pk_free( pk );
01216 #endif /* POLARSSL_ECP_C */
01217 
01218     return( POLARSSL_ERR_PK_KEY_INVALID_FORMAT );
01219 }
01220 
01221 /*
01222  * Parse a public key
01223  */
01224 int pk_parse_public_key( pk_context *ctx,
01225                          const unsigned char *key, size_t keylen )
01226 {
01227     int ret;
01228     unsigned char *p;
01229 #if defined(POLARSSL_PEM_PARSE_C)
01230     size_t len;
01231     pem_context pem;
01232 
01233     pem_init( &pem );
01234     ret = pem_read_buffer( &pem,
01235             "-----BEGIN PUBLIC KEY-----",
01236             "-----END PUBLIC KEY-----",
01237             key, NULL, 0, &len );
01238 
01239     if( ret == 0 )
01240     {
01241         /*
01242          * Was PEM encoded
01243          */
01244         key = pem.buf ;
01245         keylen = pem.buflen ;
01246     }
01247     else if( ret != POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT )
01248     {
01249         pem_free( &pem );
01250         return( ret );
01251     }
01252 #endif /* POLARSSL_PEM_PARSE_C */
01253     p = (unsigned char *) key;
01254 
01255     ret = pk_parse_subpubkey( &p, p + keylen, ctx );
01256 
01257 #if defined(POLARSSL_PEM_PARSE_C)
01258     pem_free( &pem );
01259 #endif
01260 
01261     return( ret );
01262 }
01263 
01264 #endif /* POLARSSL_PK_PARSE_C */
01265