2 #include "polarssl/base64.h"
5 #include "polarssl/private-x509parse_c.h"
7 /* PDKIM code (not copied from polarssl) */
9 * Parse a public RSA key
11 OpenSSL RSA public key ASN1 container
12 0:d=0 hl=3 l= 159 cons: SEQUENCE
13 3:d=1 hl=2 l= 13 cons: SEQUENCE
14 5:d=2 hl=2 l= 9 prim: OBJECT:rsaEncryption
15 16:d=2 hl=2 l= 0 prim: NULL
16 18:d=1 hl=3 l= 141 prim: BIT STRING:RSAPublicKey (below)
18 RSAPublicKey ASN1 container
19 0:d=0 hl=3 l= 137 cons: SEQUENCE
20 3:d=1 hl=3 l= 129 prim: INTEGER:Public modulus
21 135:d=1 hl=2 l= 3 prim: INTEGER:Public exponent
24 int rsa_parse_public_key( rsa_context
*rsa
, unsigned char *buf
, int buflen
)
26 unsigned char *p
, *end
;
32 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
33 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 ) {
34 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
37 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
38 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) == 0 ) {
39 /* Skip over embedded rsaEncryption Object */
42 /* The RSAPublicKey ASN1 container is wrapped in a BIT STRING */
43 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
44 ASN1_BIT_STRING
) ) != 0 ) {
45 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
48 /* Limit range to that BIT STRING */
52 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
53 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 ) {
54 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
58 if ( ( ( ret
= asn1_get_mpi( &p
, end
, &(rsa
->N
) ) ) == 0 ) &&
59 ( ( ret
= asn1_get_mpi( &p
, end
, &(rsa
->E
) ) ) == 0 ) ) {
60 rsa
->len
= mpi_size( &rsa
->N
);
64 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
68 * Parse a private RSA key
70 int rsa_parse_key( rsa_context
*rsa
, unsigned char *buf
, int buflen
,
71 unsigned char *pwd
, int pwdlen
)
74 unsigned char *s1
, *s2
;
75 unsigned char *p
, *end
;
77 s1
= (unsigned char *) strstr( (char *) buf
,
78 "-----BEGIN RSA PRIVATE KEY-----" );
82 s2
= (unsigned char *) strstr( (char *) buf
,
83 "-----END RSA PRIVATE KEY-----" );
85 if( s2
== NULL
|| s2
<= s1
)
86 return( POLARSSL_ERR_X509_KEY_INVALID_PEM
);
89 if( *s1
== '\r' ) s1
++;
90 if( *s1
== '\n' ) s1
++;
91 else return( POLARSSL_ERR_X509_KEY_INVALID_PEM
);
95 if( memcmp( s1
, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 )
97 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE
);
101 ret
= base64_decode( NULL
, &len
, s1
, s2
- s1
);
103 if( ret
== POLARSSL_ERR_BASE64_INVALID_CHARACTER
)
104 return( ret
| POLARSSL_ERR_X509_KEY_INVALID_PEM
);
106 if( ( buf
= (unsigned char *) malloc( len
) ) == NULL
)
109 if( ( ret
= base64_decode( buf
, &len
, s1
, s2
- s1
) ) != 0 )
112 return( ret
| POLARSSL_ERR_X509_KEY_INVALID_PEM
);
119 return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE
);
123 memset( rsa
, 0, sizeof( rsa_context
) );
129 * RSAPrivateKey ::= SEQUENCE {
131 * modulus INTEGER, -- n
132 * publicExponent INTEGER, -- e
133 * privateExponent INTEGER, -- d
134 * prime1 INTEGER, -- p
135 * prime2 INTEGER, -- q
136 * exponent1 INTEGER, -- d mod (p-1)
137 * exponent2 INTEGER, -- d mod (q-1)
138 * coefficient INTEGER, -- (inverse of q) mod p
139 * otherPrimeInfos OtherPrimeInfos OPTIONAL
142 if( ( ret
= asn1_get_tag( &p
, end
, &len
,
143 ASN1_CONSTRUCTED
| ASN1_SEQUENCE
) ) != 0 )
149 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
154 if( ( ret
= asn1_get_int( &p
, end
, &rsa
->ver
) ) != 0 )
160 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
| ret
);
169 return( ret
| POLARSSL_ERR_X509_KEY_INVALID_VERSION
);
172 if( ( ret
= asn1_get_mpi( &p
, end
, &rsa
->N
) ) != 0 ||
173 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->E
) ) != 0 ||
174 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->D
) ) != 0 ||
175 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->P
) ) != 0 ||
176 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->Q
) ) != 0 ||
177 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->DP
) ) != 0 ||
178 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->DQ
) ) != 0 ||
179 ( ret
= asn1_get_mpi( &p
, end
, &rsa
->QP
) ) != 0 )
185 return( ret
| POLARSSL_ERR_X509_KEY_INVALID_FORMAT
);
188 rsa
->len
= mpi_size( &rsa
->N
);
196 return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT
|
197 POLARSSL_ERR_ASN1_LENGTH_MISMATCH
);
200 if( ( ret
= rsa_check_privkey( rsa
) ) != 0 )