Commit | Line | Data |
---|---|---|
ac3ad426 AM |
1 | #include "pdkim-rsa.h" |
2 | #include "polarssl/base64.h" | |
3 | #include <stdlib.h> | |
4 | #include <string.h> | |
5 | #include "polarssl/private-x509parse_c.h" | |
6 | ||
7 | /* PDKIM code (not copied from polarssl) */ | |
8 | /* | |
9 | * Parse a public RSA key | |
10 | ||
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) | |
17 | ||
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 | |
22 | */ | |
23 | ||
24 | int rsa_parse_public_key( rsa_context *rsa, unsigned char *buf, int buflen ) | |
25 | { | |
26 | unsigned char *p, *end; | |
27 | int ret, len; | |
28 | ||
29 | p = buf; | |
30 | end = buf+buflen; | |
31 | ||
32 | if( ( ret = asn1_get_tag( &p, end, &len, | |
33 | ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { | |
34 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); | |
35 | } | |
36 | ||
37 | if( ( ret = asn1_get_tag( &p, end, &len, | |
38 | ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) == 0 ) { | |
39 | /* Skip over embedded rsaEncryption Object */ | |
40 | p+=len; | |
41 | ||
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 ); | |
46 | } | |
47 | ||
48 | /* Limit range to that BIT STRING */ | |
49 | end = p + len; | |
50 | p++; | |
51 | ||
52 | if( ( ret = asn1_get_tag( &p, end, &len, | |
53 | ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) { | |
54 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); | |
55 | } | |
56 | } | |
57 | ||
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 ); | |
61 | return 0; | |
62 | } | |
63 | ||
64 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); | |
65 | } | |
66 | ||
67 | /* | |
68 | * Parse a private RSA key | |
69 | */ | |
70 | int rsa_parse_key( rsa_context *rsa, unsigned char *buf, int buflen, | |
71 | unsigned char *pwd, int pwdlen ) | |
72 | { | |
73 | int ret, len, enc; | |
74 | unsigned char *s1, *s2; | |
75 | unsigned char *p, *end; | |
76 | ||
77 | s1 = (unsigned char *) strstr( (char *) buf, | |
78 | "-----BEGIN RSA PRIVATE KEY-----" ); | |
79 | ||
80 | if( s1 != NULL ) | |
81 | { | |
82 | s2 = (unsigned char *) strstr( (char *) buf, | |
83 | "-----END RSA PRIVATE KEY-----" ); | |
84 | ||
85 | if( s2 == NULL || s2 <= s1 ) | |
86 | return( POLARSSL_ERR_X509_KEY_INVALID_PEM ); | |
87 | ||
88 | s1 += 31; | |
89 | if( *s1 == '\r' ) s1++; | |
90 | if( *s1 == '\n' ) s1++; | |
91 | else return( POLARSSL_ERR_X509_KEY_INVALID_PEM ); | |
92 | ||
93 | enc = 0; | |
94 | ||
95 | if( memcmp( s1, "Proc-Type: 4,ENCRYPTED", 22 ) == 0 ) | |
96 | { | |
97 | return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); | |
98 | } | |
99 | ||
100 | len = 0; | |
101 | ret = base64_decode( NULL, &len, s1, s2 - s1 ); | |
102 | ||
103 | if( ret == POLARSSL_ERR_BASE64_INVALID_CHARACTER ) | |
104 | return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM ); | |
105 | ||
106 | if( ( buf = (unsigned char *) malloc( len ) ) == NULL ) | |
107 | return( 1 ); | |
108 | ||
109 | if( ( ret = base64_decode( buf, &len, s1, s2 - s1 ) ) != 0 ) | |
110 | { | |
111 | free( buf ); | |
112 | return( ret | POLARSSL_ERR_X509_KEY_INVALID_PEM ); | |
113 | } | |
114 | ||
115 | buflen = len; | |
116 | ||
117 | if( enc != 0 ) | |
118 | { | |
119 | return( POLARSSL_ERR_X509_FEATURE_UNAVAILABLE ); | |
120 | } | |
121 | } | |
122 | ||
123 | memset( rsa, 0, sizeof( rsa_context ) ); | |
124 | ||
125 | p = buf; | |
126 | end = buf + buflen; | |
127 | ||
128 | /* | |
129 | * RSAPrivateKey ::= SEQUENCE { | |
130 | * version Version, | |
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 | |
140 | * } | |
141 | */ | |
142 | if( ( ret = asn1_get_tag( &p, end, &len, | |
143 | ASN1_CONSTRUCTED | ASN1_SEQUENCE ) ) != 0 ) | |
144 | { | |
145 | if( s1 != NULL ) | |
146 | free( buf ); | |
147 | ||
148 | rsa_free( rsa ); | |
149 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); | |
150 | } | |
151 | ||
152 | end = p + len; | |
153 | ||
154 | if( ( ret = asn1_get_int( &p, end, &rsa->ver ) ) != 0 ) | |
155 | { | |
156 | if( s1 != NULL ) | |
157 | free( buf ); | |
158 | ||
159 | rsa_free( rsa ); | |
160 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | ret ); | |
161 | } | |
162 | ||
163 | if( rsa->ver != 0 ) | |
164 | { | |
165 | if( s1 != NULL ) | |
166 | free( buf ); | |
167 | ||
168 | rsa_free( rsa ); | |
169 | return( ret | POLARSSL_ERR_X509_KEY_INVALID_VERSION ); | |
170 | } | |
171 | ||
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 ) | |
180 | { | |
181 | if( s1 != NULL ) | |
182 | free( buf ); | |
183 | ||
184 | rsa_free( rsa ); | |
185 | return( ret | POLARSSL_ERR_X509_KEY_INVALID_FORMAT ); | |
186 | } | |
187 | ||
188 | rsa->len = mpi_size( &rsa->N ); | |
189 | ||
190 | if( p != end ) | |
191 | { | |
192 | if( s1 != NULL ) | |
193 | free( buf ); | |
194 | ||
195 | rsa_free( rsa ); | |
196 | return( POLARSSL_ERR_X509_KEY_INVALID_FORMAT | | |
197 | POLARSSL_ERR_ASN1_LENGTH_MISMATCH ); | |
198 | } | |
199 | ||
200 | if( ( ret = rsa_check_privkey( rsa ) ) != 0 ) | |
201 | { | |
202 | if( s1 != NULL ) | |
203 | free( buf ); | |
204 | ||
205 | rsa_free( rsa ); | |
206 | return( ret ); | |
207 | } | |
208 | ||
209 | if( s1 != NULL ) | |
210 | free( buf ); | |
211 | ||
212 | return( 0 ); | |
213 | } |