4 #include "polarssl/private-x509parse_c.h"
6 /* PDKIM code (not copied from polarssl) */
8 * Parse a public RSA key
10 OpenSSL RSA public key ASN1 container
11 0:d=0 hl=3 l= 159 cons: SEQUENCE
12 3:d=1 hl=2 l= 13 cons: SEQUENCE
13 5:d=2 hl=2 l= 9 prim: OBJECT:rsaEncryption
14 16:d=2 hl=2 l= 0 prim: NULL
15 18:d=1 hl=3 l= 141 prim: BIT STRING:RSAPublicKey (below)
17 RSAPublicKey ASN1 container
18 0:d=0 hl=3 l= 137 cons: SEQUENCE
19 3:d=1 hl=3 l= 129 prim: INTEGER:Public modulus
20 135:d=1 hl=2 l= 3 prim: INTEGER:Public exponent
23 int rsa_parse_public_key( rsa_context
*rsa
, unsigned char *buf
, int buflen
)
25 unsigned char *p
, *end
;
31 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
32 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 ) {
33 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
36 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
37 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) == 0 ) {
38 /* Skip over embedded rsaEncryption Object */
41 /* The RSAPublicKey ASN1 container is wrapped in a BIT STRING */
42 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
43 ASN1_BIT_STRING
) ) != 0 ) {
44 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
47 /* Limit range to that BIT STRING */
51 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
52 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 ) {
53 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
57 if ( ( ( ret
= asn1_get_mpi( &p
, end
, &(rsa
->N
) ) ) == 0 ) &&
58 ( ( ret
= asn1_get_mpi( &p
, end
, &(rsa
->E
) ) ) == 0 ) ) {
59 rsa
->len
= mpi_size( &rsa
->N
);
63 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
67 * Parse a private RSA key
69 int rsa_parse_key( rsa_context
*rsa
, unsigned char *buf
, int buflen
,
70 unsigned char *pwd
, int pwdlen
)
73 unsigned char *s1
, *s2
;
74 unsigned char *p
, *end
;
76 s1
= (unsigned char *) strstr( (char *) buf
,
77 "-----BEGIN RSA PRIVATE KEY-----" );
81 s2
= (unsigned char *) strstr( (char *) buf
,
82 "-----END RSA PRIVATE KEY-----" );
84 if( s2
== NULL
|| s2
<= s1
)
85 return( POLARSSL_ERR_X509_KEY_INVALID_PEM
);
88 if( *s1
== '\r' ) s1
++;
89 if( *s1
== '\n' ) s1
++;
90 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM
);
94 if( memcmp( s1
, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
96 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE
);
101 extern unsigned char * string_copyn(const unsigned char *, int);
102 extern int b64decode(unsigned char *, unsigned char **);
103 #define POLARSSL_ERR_BASE64_INVALID_CHARACTER 0x0012
105 s1
= string_copyn(s1
, s2
-s1
); /* need nul-terminated string */
106 if ((len
= b64decode(s1
, &buf
)) < 0)
107 return POLARSSL_ERR_BASE64_INVALID_CHARACTER
108 | POLARSSL_ERR_X509_KEY_INVALID_PEM
;
115 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE
);
119 memset( rsa
, 0, sizeof( rsa_context
) );
125 * RSAPrivateKey ::= SEQUENCE {
127 * modulus INTEGER, -- n
128 * publicExponent INTEGER, -- e
129 * privateExponent INTEGER, -- d
130 * prime1 INTEGER, -- p
131 * prime2 INTEGER, -- q
132 * exponent1 INTEGER, -- d mod (p-1)
133 * exponent2 INTEGER, -- d mod (q-1)
134 * coefficient INTEGER, -- (inverse of q) mod p
135 * otherPrimeInfos OtherPrimeInfos OPTIONAL
138 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
139 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
142 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
147 if( ( ret
= asn1_get_int( &p
, end
, &rsa
->ver
) ) != 0 )
150 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
156 return( ret
| POLARSSL_ERR_X509_KEY_INVALID_VERSION
);
159 if( ( ret
= asn1_get_mpi( &p
, end
, &rsa
->N
) ) != 0 ||
160 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->E
) ) != 0 ||
161 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->D
) ) != 0 ||
162 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->P
) ) != 0 ||
163 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->Q
) ) != 0 ||
164 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->DP
) ) != 0 ||
165 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->DQ
) ) != 0 ||
166 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->QP
) ) != 0 )
169 return( ret
| POLARSSL_ERR_X509_KEY_INVALID_FORMAT
);
172 rsa
->len
= mpi_size( &rsa
->N
);
177 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
|
178 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
181 if( ( ret
= rsa_check_privkey( rsa
) ) != 0 )