PolarSSL v1.3.9
pkparse.c
Go to the documentation of this file.
1/*
2 * Public Key layer for parsing key files and structures
3 *
4 * Copyright (C) 2006-2014, Brainspark B.V.
5 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
7 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
8 *
9 * All rights reserved.
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25
26#if !defined(POLARSSL_CONFIG_FILE)
27#include "polarssl/config.h"
28#else
29#include POLARSSL_CONFIG_FILE
30#endif
31
32#if defined(POLARSSL_PK_PARSE_C)
33
34#include "polarssl/pk.h"
35#include "polarssl/asn1.h"
36#include "polarssl/oid.h"
37
38#if defined(POLARSSL_RSA_C)
39#include "polarssl/rsa.h"
40#endif
41#if defined(POLARSSL_ECP_C)
42#include "polarssl/ecp.h"
43#endif
44#if defined(POLARSSL_ECDSA_C)
45#include "polarssl/ecdsa.h"
46#endif
47#if defined(POLARSSL_PEM_PARSE_C)
48#include "polarssl/pem.h"
49#endif
50#if defined(POLARSSL_PKCS5_C)
51#include "polarssl/pkcs5.h"
52#endif
53#if defined(POLARSSL_PKCS12_C)
54#include "polarssl/pkcs12.h"
55#endif
56
57#if defined(POLARSSL_PLATFORM_C)
58#include "polarssl/platform.h"
59#else
60#include <stdlib.h>
61#define polarssl_malloc malloc
62#define polarssl_free free
63#endif
64
65#if defined(POLARSSL_FS_IO)
66/* Implementation that should never be optimized out by the compiler */
67static void polarssl_zeroize( void *v, size_t n ) {
68 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
69}
70
71/*
72 * Load all data from a file into a given buffer.
73 */
74static int load_file( const char *path, unsigned char **buf, size_t *n )
75{
76 FILE *f;
77 long size;
78
79 if( ( f = fopen( path, "rb" ) ) == NULL )
81
82 fseek( f, 0, SEEK_END );
83 if( ( size = ftell( f ) ) == -1 )
84 {
85 fclose( f );
87 }
88 fseek( f, 0, SEEK_SET );
89
90 *n = (size_t) size;
91
92 if( *n + 1 == 0 ||
93 ( *buf = (unsigned char *) polarssl_malloc( *n + 1 ) ) == NULL )
94 {
95 fclose( f );
97 }
98
99 if( fread( *buf, 1, *n, f ) != *n )
100 {
101 fclose( f );
102 polarssl_free( *buf );
104 }
105
106 fclose( f );
107
108 (*buf)[*n] = '\0';
109
110 return( 0 );
111}
112
113/*
114 * Load and parse a private key
115 */
117 const char *path, const char *pwd )
118{
119 int ret;
120 size_t n;
121 unsigned char *buf;
122
123 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
124 return( ret );
125
126 if( pwd == NULL )
127 ret = pk_parse_key( ctx, buf, n, NULL, 0 );
128 else
129 ret = pk_parse_key( ctx, buf, n,
130 (const unsigned char *) pwd, strlen( pwd ) );
131
132 polarssl_zeroize( buf, n + 1 );
133 polarssl_free( buf );
134
135 return( ret );
136}
137
138/*
139 * Load and parse a public key
140 */
141int pk_parse_public_keyfile( pk_context *ctx, const char *path )
142{
143 int ret;
144 size_t n;
145 unsigned char *buf;
146
147 if( ( ret = load_file( path, &buf, &n ) ) != 0 )
148 return( ret );
149
150 ret = pk_parse_public_key( ctx, buf, n );
151
152 polarssl_zeroize( buf, n + 1 );
153 polarssl_free( buf );
154
155 return( ret );
156}
157#endif /* POLARSSL_FS_IO */
158
159#if defined(POLARSSL_ECP_C)
160/* Minimally parse an ECParameters buffer to and asn1_buf
161 *
162 * ECParameters ::= CHOICE {
163 * namedCurve OBJECT IDENTIFIER
164 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
165 * -- implicitCurve NULL
166 * }
167 */
168static int pk_get_ecparams( unsigned char **p, const unsigned char *end,
169 asn1_buf *params )
170{
171 int ret;
172
173 /* Tag may be either OID or SEQUENCE */
174 params->tag = **p;
175 if( params->tag != ASN1_OID
177 && params->tag != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE )
178#endif
179 )
180 {
183 }
184
185 if( ( ret = asn1_get_tag( p, end, &params->len, params->tag ) ) != 0 )
186 {
188 }
189
190 params->p = *p;
191 *p += params->len;
192
193 if( *p != end )
196
197 return( 0 );
198}
199
200#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
201/*
202 * Parse a SpecifiedECDomain (SEC 1 C.2) and (mostly) fill the group with it.
203 * WARNING: the resulting group should only be used with
204 * pk_group_id_from_specified(), since its base point may not be set correctly
205 * if it was encoded compressed.
206 *
207 * SpecifiedECDomain ::= SEQUENCE {
208 * version SpecifiedECDomainVersion(ecdpVer1 | ecdpVer2 | ecdpVer3, ...),
209 * fieldID FieldID {{FieldTypes}},
210 * curve Curve,
211 * base ECPoint,
212 * order INTEGER,
213 * cofactor INTEGER OPTIONAL,
214 * hash HashAlgorithm OPTIONAL,
215 * ...
216 * }
217 *
218 * We only support prime-field as field type, and ignore hash and cofactor.
219 */
220static int pk_group_from_specified( const asn1_buf *params, ecp_group *grp )
221{
222 int ret;
223 unsigned char *p = params->p;
224 const unsigned char * const end = params->p + params->len;
225 const unsigned char *end_field, *end_curve;
226 size_t len;
227 int ver;
228
229 /* SpecifiedECDomainVersion ::= INTEGER { 1, 2, 3 } */
230 if( ( ret = asn1_get_int( &p, end, &ver ) ) != 0 )
232
233 if( ver < 1 || ver > 3 )
235
236 /*
237 * FieldID { FIELD-ID:IOSet } ::= SEQUENCE { -- Finite field
238 * fieldType FIELD-ID.&id({IOSet}),
239 * parameters FIELD-ID.&Type({IOSet}{@fieldType})
240 * }
241 */
242 if( ( ret = asn1_get_tag( &p, end, &len,
244 return( ret );
245
246 end_field = p + len;
247
248 /*
249 * FIELD-ID ::= TYPE-IDENTIFIER
250 * FieldTypes FIELD-ID ::= {
251 * { Prime-p IDENTIFIED BY prime-field } |
252 * { Characteristic-two IDENTIFIED BY characteristic-two-field }
253 * }
254 * prime-field OBJECT IDENTIFIER ::= { id-fieldType 1 }
255 */
256 if( ( ret = asn1_get_tag( &p, end_field, &len, ASN1_OID ) ) != 0 )
257 return( ret );
258
259 if( len != OID_SIZE( OID_ANSI_X9_62_PRIME_FIELD ) ||
260 memcmp( p, OID_ANSI_X9_62_PRIME_FIELD, len ) != 0 )
261 {
263 }
264
265 p += len;
266
267 /* Prime-p ::= INTEGER -- Field of size p. */
268 if( ( ret = asn1_get_mpi( &p, end_field, &grp->P ) ) != 0 )
270
271 grp->pbits = mpi_msb( &grp->P );
272
273 if( p != end_field )
276
277 /*
278 * Curve ::= SEQUENCE {
279 * a FieldElement,
280 * b FieldElement,
281 * seed BIT STRING OPTIONAL
282 * -- Shall be present if used in SpecifiedECDomain
283 * -- with version equal to ecdpVer2 or ecdpVer3
284 * }
285 */
286 if( ( ret = asn1_get_tag( &p, end, &len,
288 return( ret );
289
290 end_curve = p + len;
291
292 /*
293 * FieldElement ::= OCTET STRING
294 * containing an integer in the case of a prime field
295 */
296 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
297 ( ret = mpi_read_binary( &grp->A, p, len ) ) != 0 )
298 {
300 }
301
302 p += len;
303
304 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_OCTET_STRING ) ) != 0 ||
305 ( ret = mpi_read_binary( &grp->B, p, len ) ) != 0 )
306 {
308 }
309
310 p += len;
311
312 /* Ignore seed BIT STRING OPTIONAL */
313 if( ( ret = asn1_get_tag( &p, end_curve, &len, ASN1_BIT_STRING ) ) == 0 )
314 p += len;
315
316 if( p != end_curve )
319
320 /*
321 * ECPoint ::= OCTET STRING
322 */
323 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
325
326 if( ( ret = ecp_point_read_binary( grp, &grp->G,
327 ( const unsigned char *) p, len ) ) != 0 )
328 {
329 /*
330 * If we can't read the point because it's compressed, cheat by
331 * reading only the X coordinate and the parity bit of Y.
332 */
334 ( p[0] != 0x02 && p[0] != 0x03 ) ||
335 len != mpi_size( &grp->P ) + 1 ||
336 mpi_read_binary( &grp->G.X, p + 1, len - 1 ) != 0 ||
337 mpi_lset( &grp->G.Y, p[0] - 2 ) != 0 ||
338 mpi_lset( &grp->G.Z, 1 ) != 0 )
339 {
341 }
342 }
343
344 p += len;
345
346 /*
347 * order INTEGER
348 */
349 if( ( ret = asn1_get_mpi( &p, end, &grp->N ) ) )
351
352 grp->nbits = mpi_msb( &grp->N );
353
354 /*
355 * Allow optional elements by purposefully not enforcing p == end here.
356 */
357
358 return( 0 );
359}
360
361/*
362 * Find the group id associated with an (almost filled) group as generated by
363 * pk_group_from_specified(), or return an error if unknown.
364 */
365static int pk_group_id_from_group( const ecp_group *grp, ecp_group_id *grp_id )
366{
367 int ret = 0;
368 ecp_group ref;
369 const ecp_group_id *id;
370
371 ecp_group_init( &ref );
372
373 for( id = ecp_grp_id_list(); *id != POLARSSL_ECP_DP_NONE; id++ )
374 {
375 /* Load the group associated to that id */
376 ecp_group_free( &ref );
377 MPI_CHK( ecp_use_known_dp( &ref, *id ) );
378
379 /* Compare to the group we were given, starting with easy tests */
380 if( grp->pbits == ref.pbits && grp->nbits == ref.nbits &&
381 mpi_cmp_mpi( &grp->P, &ref.P ) == 0 &&
382 mpi_cmp_mpi( &grp->A, &ref.A ) == 0 &&
383 mpi_cmp_mpi( &grp->B, &ref.B ) == 0 &&
384 mpi_cmp_mpi( &grp->N, &ref.N ) == 0 &&
385 mpi_cmp_mpi( &grp->G.X, &ref.G.X ) == 0 &&
386 mpi_cmp_mpi( &grp->G.Z, &ref.G.Z ) == 0 &&
387 /* For Y we may only know the parity bit, so compare only that */
388 mpi_get_bit( &grp->G.Y, 0 ) == mpi_get_bit( &ref.G.Y, 0 ) )
389 {
390 break;
391 }
392
393 }
394
395cleanup:
396 ecp_group_free( &ref );
397
398 *grp_id = *id;
399
400 if( ret == 0 && *id == POLARSSL_ECP_DP_NONE )
402
403 return( ret );
404}
405
406/*
407 * Parse a SpecifiedECDomain (SEC 1 C.2) and find the associated group ID
408 */
409static int pk_group_id_from_specified( const asn1_buf *params,
410 ecp_group_id *grp_id )
411{
412 int ret;
413 ecp_group grp;
414
415 ecp_group_init( &grp );
416
417 if( ( ret = pk_group_from_specified( params, &grp ) ) != 0 )
418 goto cleanup;
419
420 ret = pk_group_id_from_group( &grp, grp_id );
421
422cleanup:
423 ecp_group_free( &grp );
424
425 return( ret );
426}
427#endif /* POLARSSL_PK_PARSE_EC_EXTENDED */
428
429/*
430 * Use EC parameters to initialise an EC group
431 *
432 * ECParameters ::= CHOICE {
433 * namedCurve OBJECT IDENTIFIER
434 * specifiedCurve SpecifiedECDomain -- = SEQUENCE { ... }
435 * -- implicitCurve NULL
436 */
437static int pk_use_ecparams( const asn1_buf *params, ecp_group *grp )
438{
439 int ret;
440 ecp_group_id grp_id;
441
442 if( params->tag == ASN1_OID )
443 {
444 if( oid_get_ec_grp( params, &grp_id ) != 0 )
446 }
447 else
448 {
449#if defined(POLARSSL_PK_PARSE_EC_EXTENDED)
450 if( ( ret = pk_group_id_from_specified( params, &grp_id ) ) != 0 )
451 return( ret );
452#else
454#endif
455 }
456
457 /*
458 * grp may already be initilialized; if so, make sure IDs match
459 */
460 if( grp->id != POLARSSL_ECP_DP_NONE && grp->id != grp_id )
462
463 if( ( ret = ecp_use_known_dp( grp, grp_id ) ) != 0 )
464 return( ret );
465
466 return( 0 );
467}
468
469/*
470 * EC public key is an EC point
471 *
472 * The caller is responsible for clearing the structure upon failure if
473 * desired. Take care to pass along the possible ECP_FEATURE_UNAVAILABLE
474 * return code of ecp_point_read_binary() and leave p in a usable state.
475 */
476static int pk_get_ecpubkey( unsigned char **p, const unsigned char *end,
477 ecp_keypair *key )
478{
479 int ret;
480
481 if( ( ret = ecp_point_read_binary( &key->grp, &key->Q,
482 (const unsigned char *) *p, end - *p ) ) == 0 )
483 {
484 ret = ecp_check_pubkey( &key->grp, &key->Q );
485 }
486
487 /*
488 * We know ecp_point_read_binary consumed all bytes or failed
489 */
490 *p = (unsigned char *) end;
491
492 return( ret );
493}
494#endif /* POLARSSL_ECP_C */
495
496#if defined(POLARSSL_RSA_C)
497/*
498 * RSAPublicKey ::= SEQUENCE {
499 * modulus INTEGER, -- n
500 * publicExponent INTEGER -- e
501 * }
502 */
503static int pk_get_rsapubkey( unsigned char **p,
504 const unsigned char *end,
505 rsa_context *rsa )
506{
507 int ret;
508 size_t len;
509
510 if( ( ret = asn1_get_tag( p, end, &len,
512 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
513
514 if( *p + len != end )
517
518 if( ( ret = asn1_get_mpi( p, end, &rsa->N ) ) != 0 ||
519 ( ret = asn1_get_mpi( p, end, &rsa->E ) ) != 0 )
520 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
521
522 if( *p != end )
525
526 if( ( ret = rsa_check_pubkey( rsa ) ) != 0 )
528
529 rsa->len = mpi_size( &rsa->N );
530
531 return( 0 );
532}
533#endif /* POLARSSL_RSA_C */
534
535/* Get a PK algorithm identifier
536 *
537 * AlgorithmIdentifier ::= SEQUENCE {
538 * algorithm OBJECT IDENTIFIER,
539 * parameters ANY DEFINED BY algorithm OPTIONAL }
540 */
541static int pk_get_pk_alg( unsigned char **p,
542 const unsigned char *end,
543 pk_type_t *pk_alg, asn1_buf *params )
544{
545 int ret;
546 asn1_buf alg_oid;
547
548 memset( params, 0, sizeof(asn1_buf) );
549
550 if( ( ret = asn1_get_alg( p, end, &alg_oid, params ) ) != 0 )
551 return( POLARSSL_ERR_PK_INVALID_ALG + ret );
552
553 if( oid_get_pk_alg( &alg_oid, pk_alg ) != 0 )
555
556 /*
557 * No parameters with RSA (only for EC)
558 */
559 if( *pk_alg == POLARSSL_PK_RSA &&
560 ( ( params->tag != ASN1_NULL && params->tag != 0 ) ||
561 params->len != 0 ) )
562 {
564 }
565
566 return( 0 );
567}
568
569/*
570 * SubjectPublicKeyInfo ::= SEQUENCE {
571 * algorithm AlgorithmIdentifier,
572 * subjectPublicKey BIT STRING }
573 */
574int pk_parse_subpubkey( unsigned char **p, const unsigned char *end,
575 pk_context *pk )
576{
577 int ret;
578 size_t len;
579 asn1_buf alg_params;
581 const pk_info_t *pk_info;
582
583 if( ( ret = asn1_get_tag( p, end, &len,
585 {
587 }
588
589 end = *p + len;
590
591 if( ( ret = pk_get_pk_alg( p, end, &pk_alg, &alg_params ) ) != 0 )
592 return( ret );
593
594 if( ( ret = asn1_get_bitstring_null( p, end, &len ) ) != 0 )
595 return( POLARSSL_ERR_PK_INVALID_PUBKEY + ret );
596
597 if( *p + len != end )
600
601 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
603
604 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
605 return( ret );
606
607#if defined(POLARSSL_RSA_C)
608 if( pk_alg == POLARSSL_PK_RSA )
609 {
610 ret = pk_get_rsapubkey( p, end, pk_rsa( *pk ) );
611 } else
612#endif /* POLARSSL_RSA_C */
613#if defined(POLARSSL_ECP_C)
614 if( pk_alg == POLARSSL_PK_ECKEY_DH || pk_alg == POLARSSL_PK_ECKEY )
615 {
616 ret = pk_use_ecparams( &alg_params, &pk_ec( *pk )->grp );
617 if( ret == 0 )
618 ret = pk_get_ecpubkey( p, end, pk_ec( *pk ) );
619 } else
620#endif /* POLARSSL_ECP_C */
622
623 if( ret == 0 && *p != end )
626
627 if( ret != 0 )
628 pk_free( pk );
629
630 return( ret );
631}
632
633#if defined(POLARSSL_RSA_C)
634/*
635 * Parse a PKCS#1 encoded private RSA key
636 */
637static int pk_parse_key_pkcs1_der( rsa_context *rsa,
638 const unsigned char *key,
639 size_t keylen )
640{
641 int ret;
642 size_t len;
643 unsigned char *p, *end;
644
645 p = (unsigned char *) key;
646 end = p + keylen;
647
648 /*
649 * This function parses the RSAPrivateKey (PKCS#1)
650 *
651 * RSAPrivateKey ::= SEQUENCE {
652 * version Version,
653 * modulus INTEGER, -- n
654 * publicExponent INTEGER, -- e
655 * privateExponent INTEGER, -- d
656 * prime1 INTEGER, -- p
657 * prime2 INTEGER, -- q
658 * exponent1 INTEGER, -- d mod (p-1)
659 * exponent2 INTEGER, -- d mod (q-1)
660 * coefficient INTEGER, -- (inverse of q) mod p
661 * otherPrimeInfos OtherPrimeInfos OPTIONAL
662 * }
663 */
664 if( ( ret = asn1_get_tag( &p, end, &len,
666 {
668 }
669
670 end = p + len;
671
672 if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 )
673 {
675 }
676
677 if( rsa->ver != 0 )
678 {
680 }
681
682 if( ( ret = asn1_get_mpi( &p, end, &rsa->N ) ) != 0 ||
683 ( ret = asn1_get_mpi( &p, end, &rsa->E ) ) != 0 ||
684 ( ret = asn1_get_mpi( &p, end, &rsa->D ) ) != 0 ||
685 ( ret = asn1_get_mpi( &p, end, &rsa->P ) ) != 0 ||
686 ( ret = asn1_get_mpi( &p, end, &rsa->Q ) ) != 0 ||
687 ( ret = asn1_get_mpi( &p, end, &rsa->DP ) ) != 0 ||
688 ( ret = asn1_get_mpi( &p, end, &rsa->DQ ) ) != 0 ||
689 ( ret = asn1_get_mpi( &p, end, &rsa->QP ) ) != 0 )
690 {
691 rsa_free( rsa );
693 }
694
695 rsa->len = mpi_size( &rsa->N );
696
697 if( p != end )
698 {
699 rsa_free( rsa );
702 }
703
704 if( ( ret = rsa_check_privkey( rsa ) ) != 0 )
705 {
706 rsa_free( rsa );
707 return( ret );
708 }
709
710 return( 0 );
711}
712#endif /* POLARSSL_RSA_C */
713
714#if defined(POLARSSL_ECP_C)
715/*
716 * Parse a SEC1 encoded private EC key
717 */
718static int pk_parse_key_sec1_der( ecp_keypair *eck,
719 const unsigned char *key,
720 size_t keylen )
721{
722 int ret;
723 int version, pubkey_done;
724 size_t len;
725 asn1_buf params;
726 unsigned char *p = (unsigned char *) key;
727 unsigned char *end = p + keylen;
728 unsigned char *end2;
729
730 /*
731 * RFC 5915, or SEC1 Appendix C.4
732 *
733 * ECPrivateKey ::= SEQUENCE {
734 * version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
735 * privateKey OCTET STRING,
736 * parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
737 * publicKey [1] BIT STRING OPTIONAL
738 * }
739 */
740 if( ( ret = asn1_get_tag( &p, end, &len,
742 {
744 }
745
746 end = p + len;
747
748 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
750
751 if( version != 1 )
753
754 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
756
757 if( ( ret = mpi_read_binary( &eck->d, p, len ) ) != 0 )
758 {
759 ecp_keypair_free( eck );
761 }
762
763 p += len;
764
765 /*
766 * Is 'parameters' present?
767 */
768 if( ( ret = asn1_get_tag( &p, end, &len,
770 {
771 if( ( ret = pk_get_ecparams( &p, p + len, &params) ) != 0 ||
772 ( ret = pk_use_ecparams( &params, &eck->grp ) ) != 0 )
773 {
774 ecp_keypair_free( eck );
775 return( ret );
776 }
777 }
778 else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
779 {
780 ecp_keypair_free( eck );
782 }
783
784 /*
785 * Is 'publickey' present? If not, or if we can't read it (eg because it
786 * is compressed), create it from the private key.
787 */
788 pubkey_done = 0;
789 if( ( ret = asn1_get_tag( &p, end, &len,
791 {
792 end2 = p + len;
793
794 if( ( ret = asn1_get_bitstring_null( &p, end2, &len ) ) != 0 )
796
797 if( p + len != end2 )
800
801 if( ( ret = pk_get_ecpubkey( &p, end2, eck ) ) == 0 )
802 pubkey_done = 1;
803 else
804 {
805 /*
806 * The only acceptable failure mode of pk_get_ecpubkey() above
807 * is if the point format is not recognized.
808 */
811 }
812 }
813 else if( ret != POLARSSL_ERR_ASN1_UNEXPECTED_TAG )
814 {
815 ecp_keypair_free( eck );
817 }
818
819 if( ! pubkey_done &&
820 ( ret = ecp_mul( &eck->grp, &eck->Q, &eck->d, &eck->grp.G,
821 NULL, NULL ) ) != 0 )
822 {
823 ecp_keypair_free( eck );
825 }
826
827 if( ( ret = ecp_check_privkey( &eck->grp, &eck->d ) ) != 0 )
828 {
829 ecp_keypair_free( eck );
830 return( ret );
831 }
832
833 return( 0 );
834}
835#endif /* POLARSSL_ECP_C */
836
837/*
838 * Parse an unencrypted PKCS#8 encoded private key
839 */
840static int pk_parse_key_pkcs8_unencrypted_der(
841 pk_context *pk,
842 const unsigned char* key,
843 size_t keylen )
844{
845 int ret, version;
846 size_t len;
847 asn1_buf params;
848 unsigned char *p = (unsigned char *) key;
849 unsigned char *end = p + keylen;
851 const pk_info_t *pk_info;
852
853 /*
854 * This function parses the PrivatKeyInfo object (PKCS#8 v1.2 = RFC 5208)
855 *
856 * PrivateKeyInfo ::= SEQUENCE {
857 * version Version,
858 * privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
859 * privateKey PrivateKey,
860 * attributes [0] IMPLICIT Attributes OPTIONAL }
861 *
862 * Version ::= INTEGER
863 * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
864 * PrivateKey ::= OCTET STRING
865 *
866 * The PrivateKey OCTET STRING is a SEC1 ECPrivateKey
867 */
868
869 if( ( ret = asn1_get_tag( &p, end, &len,
871 {
873 }
874
875 end = p + len;
876
877 if( ( ret = asn1_get_int( &p, end, &version ) ) != 0 )
879
880 if( version != 0 )
882
883 if( ( ret = pk_get_pk_alg( &p, end, &pk_alg, &params ) ) != 0 )
885
886 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
888
889 if( len < 1 )
892
893 if( ( pk_info = pk_info_from_type( pk_alg ) ) == NULL )
895
896 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 )
897 return( ret );
898
899#if defined(POLARSSL_RSA_C)
900 if( pk_alg == POLARSSL_PK_RSA )
901 {
902 if( ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), p, len ) ) != 0 )
903 {
904 pk_free( pk );
905 return( ret );
906 }
907 } else
908#endif /* POLARSSL_RSA_C */
909#if defined(POLARSSL_ECP_C)
910 if( pk_alg == POLARSSL_PK_ECKEY || pk_alg == POLARSSL_PK_ECKEY_DH )
911 {
912 if( ( ret = pk_use_ecparams( &params, &pk_ec( *pk )->grp ) ) != 0 ||
913 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), p, len ) ) != 0 )
914 {
915 pk_free( pk );
916 return( ret );
917 }
918 } else
919#endif /* POLARSSL_ECP_C */
921
922 return( 0 );
923}
924
925/*
926 * Parse an encrypted PKCS#8 encoded private key
927 */
928static int pk_parse_key_pkcs8_encrypted_der(
929 pk_context *pk,
930 const unsigned char *key, size_t keylen,
931 const unsigned char *pwd, size_t pwdlen )
932{
933 int ret, decrypted = 0;
934 size_t len;
935 unsigned char buf[2048];
936 unsigned char *p, *end;
937 asn1_buf pbe_alg_oid, pbe_params;
938#if defined(POLARSSL_PKCS12_C)
939 cipher_type_t cipher_alg;
940 md_type_t md_alg;
941#endif
942
943 memset( buf, 0, sizeof( buf ) );
944
945 p = (unsigned char *) key;
946 end = p + keylen;
947
948 if( pwdlen == 0 )
950
951 /*
952 * This function parses the EncryptedPrivatKeyInfo object (PKCS#8)
953 *
954 * EncryptedPrivateKeyInfo ::= SEQUENCE {
955 * encryptionAlgorithm EncryptionAlgorithmIdentifier,
956 * encryptedData EncryptedData
957 * }
958 *
959 * EncryptionAlgorithmIdentifier ::= AlgorithmIdentifier
960 *
961 * EncryptedData ::= OCTET STRING
962 *
963 * The EncryptedData OCTET STRING is a PKCS#8 PrivateKeyInfo
964 */
965 if( ( ret = asn1_get_tag( &p, end, &len,
967 {
969 }
970
971 end = p + len;
972
973 if( ( ret = asn1_get_alg( &p, end, &pbe_alg_oid, &pbe_params ) ) != 0 )
975
976 if( ( ret = asn1_get_tag( &p, end, &len, ASN1_OCTET_STRING ) ) != 0 )
978
979 if( len > sizeof( buf ) )
981
982 /*
983 * Decrypt EncryptedData with appropriate PDE
984 */
985#if defined(POLARSSL_PKCS12_C)
986 if( oid_get_pkcs12_pbe_alg( &pbe_alg_oid, &md_alg, &cipher_alg ) == 0 )
987 {
988 if( ( ret = pkcs12_pbe( &pbe_params, PKCS12_PBE_DECRYPT,
989 cipher_alg, md_alg,
990 pwd, pwdlen, p, len, buf ) ) != 0 )
991 {
994
995 return( ret );
996 }
997
998 decrypted = 1;
999 }
1000 else if( OID_CMP( OID_PKCS12_PBE_SHA1_RC4_128, &pbe_alg_oid ) )
1001 {
1002 if( ( ret = pkcs12_pbe_sha1_rc4_128( &pbe_params,
1004 pwd, pwdlen,
1005 p, len, buf ) ) != 0 )
1006 {
1007 return( ret );
1008 }
1009
1010 // Best guess for password mismatch when using RC4. If first tag is
1011 // not ASN1_CONSTRUCTED | ASN1_SEQUENCE
1012 //
1013 if( *buf != ( ASN1_CONSTRUCTED | ASN1_SEQUENCE ) )
1015
1016 decrypted = 1;
1017 }
1018 else
1019#endif /* POLARSSL_PKCS12_C */
1020#if defined(POLARSSL_PKCS5_C)
1021 if( OID_CMP( OID_PKCS5_PBES2, &pbe_alg_oid ) )
1022 {
1023 if( ( ret = pkcs5_pbes2( &pbe_params, PKCS5_DECRYPT, pwd, pwdlen,
1024 p, len, buf ) ) != 0 )
1025 {
1028
1029 return( ret );
1030 }
1031
1032 decrypted = 1;
1033 }
1034 else
1035#endif /* POLARSSL_PKCS5_C */
1036 {
1037 ((void) pwd);
1038 }
1039
1040 if( decrypted == 0 )
1042
1043 return( pk_parse_key_pkcs8_unencrypted_der( pk, buf, len ) );
1044}
1045
1046/*
1047 * Parse a private key
1048 */
1049int pk_parse_key( pk_context *pk,
1050 const unsigned char *key, size_t keylen,
1051 const unsigned char *pwd, size_t pwdlen )
1052{
1053 int ret;
1054 const pk_info_t *pk_info;
1055
1056#if defined(POLARSSL_PEM_PARSE_C)
1057 size_t len;
1058 pem_context pem;
1059
1060 pem_init( &pem );
1061
1062#if defined(POLARSSL_RSA_C)
1063 ret = pem_read_buffer( &pem,
1064 "-----BEGIN RSA PRIVATE KEY-----",
1065 "-----END RSA PRIVATE KEY-----",
1066 key, pwd, pwdlen, &len );
1067 if( ret == 0 )
1068 {
1069 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
1071
1072 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1073 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ),
1074 pem.buf, pem.buflen ) ) != 0 )
1075 {
1076 pk_free( pk );
1077 }
1078
1079 pem_free( &pem );
1080 return( ret );
1081 }
1082 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
1084 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
1087 return( ret );
1088#endif /* POLARSSL_RSA_C */
1089
1090#if defined(POLARSSL_ECP_C)
1091 ret = pem_read_buffer( &pem,
1092 "-----BEGIN EC PRIVATE KEY-----",
1093 "-----END EC PRIVATE KEY-----",
1094 key, pwd, pwdlen, &len );
1095 if( ret == 0 )
1096 {
1097 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
1099
1100 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1101 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ),
1102 pem.buf, pem.buflen ) ) != 0 )
1103 {
1104 pk_free( pk );
1105 }
1106
1107 pem_free( &pem );
1108 return( ret );
1109 }
1110 else if( ret == POLARSSL_ERR_PEM_PASSWORD_MISMATCH )
1112 else if( ret == POLARSSL_ERR_PEM_PASSWORD_REQUIRED )
1115 return( ret );
1116#endif /* POLARSSL_ECP_C */
1117
1118 ret = pem_read_buffer( &pem,
1119 "-----BEGIN PRIVATE KEY-----",
1120 "-----END PRIVATE KEY-----",
1121 key, NULL, 0, &len );
1122 if( ret == 0 )
1123 {
1124 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk,
1125 pem.buf, pem.buflen ) ) != 0 )
1126 {
1127 pk_free( pk );
1128 }
1129
1130 pem_free( &pem );
1131 return( ret );
1132 }
1134 return( ret );
1135
1136 ret = pem_read_buffer( &pem,
1137 "-----BEGIN ENCRYPTED PRIVATE KEY-----",
1138 "-----END ENCRYPTED PRIVATE KEY-----",
1139 key, NULL, 0, &len );
1140 if( ret == 0 )
1141 {
1142 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk,
1143 pem.buf, pem.buflen,
1144 pwd, pwdlen ) ) != 0 )
1145 {
1146 pk_free( pk );
1147 }
1148
1149 pem_free( &pem );
1150 return( ret );
1151 }
1153 return( ret );
1154#else
1155 ((void) pwd);
1156 ((void) pwdlen);
1157#endif /* POLARSSL_PEM_PARSE_C */
1158
1159 /*
1160 * At this point we only know it's not a PEM formatted key. Could be any
1161 * of the known DER encoded private key formats
1162 *
1163 * We try the different DER format parsers to see if one passes without
1164 * error
1165 */
1166 if( ( ret = pk_parse_key_pkcs8_encrypted_der( pk, key, keylen,
1167 pwd, pwdlen ) ) == 0 )
1168 {
1169 return( 0 );
1170 }
1171
1172 pk_free( pk );
1173
1175 {
1176 return( ret );
1177 }
1178
1179 if( ( ret = pk_parse_key_pkcs8_unencrypted_der( pk, key, keylen ) ) == 0 )
1180 return( 0 );
1181
1182 pk_free( pk );
1183
1184#if defined(POLARSSL_RSA_C)
1185 if( ( pk_info = pk_info_from_type( POLARSSL_PK_RSA ) ) == NULL )
1187
1188 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1189 ( ret = pk_parse_key_pkcs1_der( pk_rsa( *pk ), key, keylen ) ) == 0 )
1190 {
1191 return( 0 );
1192 }
1193
1194 pk_free( pk );
1195#endif /* POLARSSL_RSA_C */
1196
1197#if defined(POLARSSL_ECP_C)
1198 if( ( pk_info = pk_info_from_type( POLARSSL_PK_ECKEY ) ) == NULL )
1200
1201 if( ( ret = pk_init_ctx( pk, pk_info ) ) != 0 ||
1202 ( ret = pk_parse_key_sec1_der( pk_ec( *pk ), key, keylen ) ) == 0 )
1203 {
1204 return( 0 );
1205 }
1206
1207 pk_free( pk );
1208#endif /* POLARSSL_ECP_C */
1209
1211}
1212
1213/*
1214 * Parse a public key
1215 */
1217 const unsigned char *key, size_t keylen )
1218{
1219 int ret;
1220 unsigned char *p;
1221#if defined(POLARSSL_PEM_PARSE_C)
1222 size_t len;
1223 pem_context pem;
1224
1225 pem_init( &pem );
1226 ret = pem_read_buffer( &pem,
1227 "-----BEGIN PUBLIC KEY-----",
1228 "-----END PUBLIC KEY-----",
1229 key, NULL, 0, &len );
1230
1231 if( ret == 0 )
1232 {
1233 /*
1234 * Was PEM encoded
1235 */
1236 key = pem.buf;
1237 keylen = pem.buflen;
1238 }
1240 {
1241 pem_free( &pem );
1242 return( ret );
1243 }
1244#endif /* POLARSSL_PEM_PARSE_C */
1245 p = (unsigned char *) key;
1246
1247 ret = pk_parse_subpubkey( &p, p + keylen, ctx );
1248
1249#if defined(POLARSSL_PEM_PARSE_C)
1250 pem_free( &pem );
1251#endif
1252
1253 return( ret );
1254}
1255
1256#endif /* POLARSSL_PK_PARSE_C */
Generic ASN.1 parsing.
int mpi_lset(mpi *X, t_sint z)
Set value from integer.
int mpi_read_binary(mpi *X, const unsigned char *buf, size_t buflen)
Import X from unsigned binary data, big endian.
#define MPI_CHK(f)
Definition bignum.h:65
size_t mpi_msb(const mpi *X)
Return the number of bits up to and including the most significant '1' bit'.
size_t mpi_size(const mpi *X)
Return the total size in bytes.
int mpi_get_bit(const mpi *X, size_t pos)
Get a specific bit from X.
int mpi_cmp_mpi(const mpi *X, const mpi *Y)
Compare signed values.
cipher_type_t
Definition cipher.h:82
#define POLARSSL_PK_PARSE_EC_EXTENDED
Configuration options (set of defines)
Elliptic curve DSA.
Elliptic curves over GF(p)
int ecp_check_pubkey(const ecp_group *grp, const ecp_point *pt)
Check that a point is a valid public key on this curve.
int ecp_mul(ecp_group *grp, ecp_point *R, const mpi *m, const ecp_point *P, int(*f_rng)(void *, unsigned char *, size_t), void *p_rng)
Multiplication by an integer: R = m * P (Not thread-safe to use same group in multiple threads)
int ecp_point_read_binary(const ecp_group *grp, ecp_point *P, const unsigned char *buf, size_t ilen)
Import a point from unsigned binary data.
ecp_group_id
Domain parameters (curve, subgroup and generator) identifiers.
Definition ecp.h:58
@ POLARSSL_ECP_DP_NONE
Definition ecp.h:59
#define POLARSSL_ERR_ECP_FEATURE_UNAVAILABLE
Requested curve not available.
Definition ecp.h:37
void ecp_keypair_free(ecp_keypair *key)
Free the components of a key pair.
int ecp_check_privkey(const ecp_group *grp, const mpi *d)
Check that an mpi is a valid private key for this curve.
void ecp_group_init(ecp_group *grp)
Initialize a group (to something meaningless)
void ecp_group_free(ecp_group *grp)
Free the components of an ECP group.
const ecp_group_id * ecp_grp_id_list(void)
Get the list of supported curves in order of preferrence (grp_id only)
int ecp_use_known_dp(ecp_group *grp, ecp_group_id index)
Set a group using well-known domain parameters.
#define POLARSSL_ERR_ASN1_OUT_OF_DATA
Out of data when parsing an ASN1 data structure.
Definition asn1.h:54
#define OID_CMP(oid_str, oid_buf)
Compares an asn1_buf structure to a reference OID.
Definition asn1.h:108
#define ASN1_BIT_STRING
Definition asn1.h:77
int tag
ASN1 type, e.g.
Definition asn1.h:126
#define POLARSSL_ERR_ASN1_UNEXPECTED_TAG
ASN1 tag was of an unexpected value.
Definition asn1.h:55
#define ASN1_NULL
Definition asn1.h:79
#define ASN1_OID
Definition asn1.h:80
size_t len
ASN1 length, e.g.
Definition asn1.h:127
int asn1_get_alg(unsigned char **p, const unsigned char *end, asn1_buf *alg, asn1_buf *params)
Retrieve an AlgorithmIdentifier ASN.1 sequence.
int asn1_get_bitstring_null(unsigned char **p, const unsigned char *end, size_t *len)
Retrieve a bitstring ASN.1 tag without unused bits and its value.
unsigned char * p
ASN1 data, e.g.
Definition asn1.h:128
#define OID_SIZE(x)
Returns the size of the binary string, without the trailing \0.
Definition asn1.h:98
#define ASN1_CONSTRUCTED
Definition asn1.h:92
int asn1_get_mpi(unsigned char **p, const unsigned char *end, mpi *X)
Retrieve a MPI value from an integer ASN.1 tag.
#define ASN1_SEQUENCE
Definition asn1.h:82
#define ASN1_CONTEXT_SPECIFIC
Definition asn1.h:93
int asn1_get_int(unsigned char **p, const unsigned char *end, int *val)
Retrieve an integer ASN.1 tag and its value.
#define ASN1_OCTET_STRING
Definition asn1.h:78
int asn1_get_tag(unsigned char **p, const unsigned char *end, size_t *len, int tag)
Get the tag and length of the tag.
#define POLARSSL_ERR_ASN1_LENGTH_MISMATCH
Actual length differs from expected length.
Definition asn1.h:57
md_type_t
Definition md.h:51
Object Identifier (OID) database.
int oid_get_ec_grp(const asn1_buf *oid, ecp_group_id *grp_id)
Translate NamedCurve OID into an EC group identifier.
#define OID_PKCS5_PBES2
id-PBES2 OBJECT IDENTIFIER ::= {pkcs-5 13}
Definition oid.h:240
int oid_get_pk_alg(const asn1_buf *oid, pk_type_t *pk_alg)
Translate PublicKeyAlgorithm OID into pk_type.
#define OID_ANSI_X9_62_PRIME_FIELD
Definition oid.h:343
int oid_get_pkcs12_pbe_alg(const asn1_buf *oid, md_type_t *md_alg, cipher_type_t *cipher_alg)
Translate PKCS#12 PBE algorithm OID into md_type and cipher_type.
#define OID_PKCS12_PBE_SHA1_RC4_128
pbeWithSHAAnd128BitRC4 OBJECT IDENTIFIER ::= {pkcs-12PbeIds 1}
Definition oid.h:263
Privacy Enhanced Mail (PEM) decoding.
#define POLARSSL_ERR_PEM_PASSWORD_MISMATCH
Given private key password does not allow for correct decryption.
Definition pem.h:44
#define POLARSSL_ERR_PEM_NO_HEADER_FOOTER_PRESENT
No PEM header or footer found.
Definition pem.h:38
#define POLARSSL_ERR_PEM_PASSWORD_REQUIRED
Private key password can't be empty.
Definition pem.h:43
Public Key abstraction layer.
#define POLARSSL_ERR_PK_KEY_INVALID_VERSION
Unsupported key version.
Definition pk.h:55
const pk_info_t * pk_info_from_type(pk_type_t pk_type)
Return information associated with the given PK type.
#define POLARSSL_ERR_PK_KEY_INVALID_FORMAT
Invalid key tag or value.
Definition pk.h:56
#define POLARSSL_ERR_PK_UNKNOWN_NAMED_CURVE
Elliptic curve is unsupported (only NIST curves are supported).
Definition pk.h:62
int pk_init_ctx(pk_context *ctx, const pk_info_t *info)
Initialize a PK context with the information given and allocates the type-specific PK subcontext.
int pk_parse_key(pk_context *ctx, const unsigned char *key, size_t keylen, const unsigned char *pwd, size_t pwdlen)
Parse a private key.
#define POLARSSL_ERR_PK_FEATURE_UNAVAILABLE
Unavailable feature, e.g.
Definition pk.h:63
#define pk_rsa(pk)
Quick access to an RSA context inside a PK context.
Definition pk.h:74
#define POLARSSL_ERR_PK_INVALID_ALG
The algorithm tag or value is invalid.
Definition pk.h:61
#define POLARSSL_ERR_PK_PASSWORD_REQUIRED
Private key password can't be empty.
Definition pk.h:58
int pk_parse_keyfile(pk_context *ctx, const char *path, const char *password)
Load and parse a private key.
#define POLARSSL_ERR_PK_FILE_IO_ERROR
Read/write of file failed.
Definition pk.h:54
int pk_parse_public_key(pk_context *ctx, const unsigned char *key, size_t keylen)
Parse a public key.
void pk_free(pk_context *ctx)
Free a pk_context.
#define POLARSSL_ERR_PK_UNKNOWN_PK_ALG
Key algorithm is unsupported (only RSA and EC are supported).
Definition pk.h:57
int pk_parse_subpubkey(unsigned char **p, const unsigned char *end, pk_context *pk)
Parse a SubjectPublicKeyInfo DER structure.
#define POLARSSL_ERR_PK_PASSWORD_MISMATCH
Given private key password does not allow for correct decryption.
Definition pk.h:59
#define pk_ec(pk)
Quick access to an EC context inside a PK context.
Definition pk.h:84
int pk_parse_public_keyfile(pk_context *ctx, const char *path)
Load and parse a public key.
#define POLARSSL_ERR_PK_MALLOC_FAILED
Memory alloation failed.
Definition pk.h:51
#define POLARSSL_ERR_PK_INVALID_PUBKEY
The pubkey tag or value is invalid (only RSA and EC are supported).
Definition pk.h:60
#define POLARSSL_ERR_PK_BAD_INPUT_DATA
Bad input parameters to function.
Definition pk.h:53
pk_type_t
Public key types.
Definition pk.h:95
@ POLARSSL_PK_ECKEY
Definition pk.h:98
@ POLARSSL_PK_ECKEY_DH
Definition pk.h:99
@ POLARSSL_PK_RSA
Definition pk.h:97
@ POLARSSL_PK_NONE
Definition pk.h:96
PKCS#12 Personal Information Exchange Syntax.
#define PKCS12_PBE_DECRYPT
Definition pkcs12.h:45
int pkcs12_pbe_sha1_rc4_128(asn1_buf *pbe_params, int mode, const unsigned char *pwd, size_t pwdlen, const unsigned char *input, size_t len, unsigned char *output)
PKCS12 Password Based function (encryption / decryption) for pbeWithSHAAnd128BitRC4.
int pkcs12_pbe(asn1_buf *pbe_params, int mode, cipher_type_t cipher_type, md_type_t md_type, const unsigned char *pwd, size_t pwdlen, const unsigned char *input, size_t len, unsigned char *output)
PKCS12 Password Based function (encryption / decryption) for cipher-based and md-based PBE's.
#define POLARSSL_ERR_PKCS12_PASSWORD_MISMATCH
Given private key password does not allow for correct decryption.
Definition pkcs12.h:39
PKCS#5 functions.
int pkcs5_pbes2(asn1_buf *pbe_params, int mode, const unsigned char *pwd, size_t pwdlen, const unsigned char *data, size_t datalen, unsigned char *output)
PKCS#5 PBES2 function.
#define POLARSSL_ERR_PKCS5_PASSWORD_MISMATCH
Given private key password does not allow for correct decryption.
Definition pkcs5.h:47
#define PKCS5_DECRYPT
Definition pkcs5.h:49
PolarSSL Platform abstraction layer.
The RSA public-key cryptosystem.
int rsa_check_privkey(const rsa_context *ctx)
Check a private RSA key.
void rsa_free(rsa_context *ctx)
Free the components of an RSA key.
int rsa_check_pubkey(const rsa_context *ctx)
Check a public RSA key.
Type-length-value structure that allows for ASN1 using DER.
Definition asn1.h:125
ECP group structure.
Definition ecp.h:137
mpi A
Definition ecp.h:140
size_t nbits
Definition ecp.h:145
size_t pbits
Definition ecp.h:144
mpi N
Definition ecp.h:143
mpi B
Definition ecp.h:141
ecp_group_id id
Definition ecp.h:138
mpi P
Definition ecp.h:139
ecp_point G
Definition ecp.h:142
ECP key pair structure.
Definition ecp.h:164
ecp_point Q
Definition ecp.h:167
mpi d
Definition ecp.h:166
ecp_group grp
Definition ecp.h:165
mpi Y
Definition ecp.h:107
mpi Z
Definition ecp.h:108
mpi X
Definition ecp.h:106
Public key container.
Definition pk.h:195
Public key information and operations.
Definition pk.h:143
RSA context structure.
Definition rsa.h:84
mpi N
Definition rsa.h:88
mpi P
Definition rsa.h:92
mpi QP
Definition rsa.h:96
mpi DQ
Definition rsa.h:95
size_t len
Definition rsa.h:86
mpi Q
Definition rsa.h:93
mpi E
Definition rsa.h:89
int ver
Definition rsa.h:85
mpi DP
Definition rsa.h:94
mpi D
Definition rsa.h:91
#define polarssl_malloc
#define polarssl_free