Example program to test AES-GCM functionality. Used for a workshop

Dependencies:   mbed

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