diff options
Diffstat (limited to 'src/lib/libcrypto/asn1/x_pubkey.c')
-rw-r--r-- | src/lib/libcrypto/asn1/x_pubkey.c | 236 |
1 files changed, 157 insertions, 79 deletions
diff --git a/src/lib/libcrypto/asn1/x_pubkey.c b/src/lib/libcrypto/asn1/x_pubkey.c index a309cf74a7..d958540120 100644 --- a/src/lib/libcrypto/asn1/x_pubkey.c +++ b/src/lib/libcrypto/asn1/x_pubkey.c | |||
@@ -58,80 +58,33 @@ | |||
58 | 58 | ||
59 | #include <stdio.h> | 59 | #include <stdio.h> |
60 | #include "cryptlib.h" | 60 | #include "cryptlib.h" |
61 | #include "asn1_mac.h" | 61 | #include <openssl/asn1t.h> |
62 | #include <openssl/x509.h> | ||
62 | 63 | ||
63 | /* | 64 | /* Minor tweak to operation: free up EVP_PKEY */ |
64 | * ASN1err(ASN1_F_D2I_X509_PUBKEY,ASN1_R_LENGTH_MISMATCH); | 65 | static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it) |
65 | * ASN1err(ASN1_F_X509_PUBKEY_NEW,ASN1_R_LENGTH_MISMATCH); | 66 | { |
66 | */ | 67 | if(operation == ASN1_OP_FREE_POST) { |
67 | 68 | X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval; | |
68 | int i2d_X509_PUBKEY(a,pp) | 69 | EVP_PKEY_free(pubkey->pkey); |
69 | X509_PUBKEY *a; | ||
70 | unsigned char **pp; | ||
71 | { | ||
72 | M_ASN1_I2D_vars(a); | ||
73 | |||
74 | M_ASN1_I2D_len(a->algor, i2d_X509_ALGOR); | ||
75 | M_ASN1_I2D_len(a->public_key, i2d_ASN1_BIT_STRING); | ||
76 | |||
77 | M_ASN1_I2D_seq_total(); | ||
78 | |||
79 | M_ASN1_I2D_put(a->algor, i2d_X509_ALGOR); | ||
80 | M_ASN1_I2D_put(a->public_key, i2d_ASN1_BIT_STRING); | ||
81 | |||
82 | M_ASN1_I2D_finish(); | ||
83 | } | ||
84 | |||
85 | X509_PUBKEY *d2i_X509_PUBKEY(a,pp,length) | ||
86 | X509_PUBKEY **a; | ||
87 | unsigned char **pp; | ||
88 | long length; | ||
89 | { | ||
90 | M_ASN1_D2I_vars(a,X509_PUBKEY *,X509_PUBKEY_new); | ||
91 | |||
92 | M_ASN1_D2I_Init(); | ||
93 | M_ASN1_D2I_start_sequence(); | ||
94 | M_ASN1_D2I_get(ret->algor,d2i_X509_ALGOR); | ||
95 | M_ASN1_D2I_get(ret->public_key,d2i_ASN1_BIT_STRING); | ||
96 | if (ret->pkey != NULL) | ||
97 | { | ||
98 | EVP_PKEY_free(ret->pkey); | ||
99 | ret->pkey=NULL; | ||
100 | } | ||
101 | M_ASN1_D2I_Finish(a,X509_PUBKEY_free,ASN1_F_D2I_X509_PUBKEY); | ||
102 | } | 70 | } |
71 | return 1; | ||
72 | } | ||
103 | 73 | ||
104 | X509_PUBKEY *X509_PUBKEY_new() | 74 | ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = { |
105 | { | 75 | ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR), |
106 | X509_PUBKEY *ret=NULL; | 76 | ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING) |
107 | 77 | } ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY) | |
108 | M_ASN1_New_Malloc(ret,X509_PUBKEY); | ||
109 | M_ASN1_New(ret->algor,X509_ALGOR_new); | ||
110 | M_ASN1_New(ret->public_key,ASN1_BIT_STRING_new); | ||
111 | ret->pkey=NULL; | ||
112 | return(ret); | ||
113 | M_ASN1_New_Error(ASN1_F_X509_PUBKEY_NEW); | ||
114 | } | ||
115 | 78 | ||
116 | void X509_PUBKEY_free(a) | 79 | IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY) |
117 | X509_PUBKEY *a; | ||
118 | { | ||
119 | if (a == NULL) return; | ||
120 | X509_ALGOR_free(a->algor); | ||
121 | ASN1_BIT_STRING_free(a->public_key); | ||
122 | if (a->pkey != NULL) EVP_PKEY_free(a->pkey); | ||
123 | Free((char *)a); | ||
124 | } | ||
125 | 80 | ||
126 | int X509_PUBKEY_set(x,pkey) | 81 | int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey) |
127 | X509_PUBKEY **x; | ||
128 | EVP_PKEY *pkey; | ||
129 | { | 82 | { |
130 | int ok=0; | 83 | int ok=0; |
131 | X509_PUBKEY *pk; | 84 | X509_PUBKEY *pk; |
132 | X509_ALGOR *a; | 85 | X509_ALGOR *a; |
133 | ASN1_OBJECT *o; | 86 | ASN1_OBJECT *o; |
134 | unsigned char *s,*p; | 87 | unsigned char *s,*p = NULL; |
135 | int i; | 88 | int i; |
136 | 89 | ||
137 | if (x == NULL) return(0); | 90 | if (x == NULL) return(0); |
@@ -156,7 +109,7 @@ EVP_PKEY *pkey; | |||
156 | } | 109 | } |
157 | } | 110 | } |
158 | else | 111 | else |
159 | #ifndef NO_DSA | 112 | #ifndef OPENSSL_NO_DSA |
160 | if (pkey->type == EVP_PKEY_DSA) | 113 | if (pkey->type == EVP_PKEY_DSA) |
161 | { | 114 | { |
162 | unsigned char *pp; | 115 | unsigned char *pp; |
@@ -166,14 +119,14 @@ EVP_PKEY *pkey; | |||
166 | dsa->write_params=0; | 119 | dsa->write_params=0; |
167 | ASN1_TYPE_free(a->parameter); | 120 | ASN1_TYPE_free(a->parameter); |
168 | i=i2d_DSAparams(dsa,NULL); | 121 | i=i2d_DSAparams(dsa,NULL); |
169 | p=(unsigned char *)Malloc(i); | 122 | if ((p=(unsigned char *)OPENSSL_malloc(i)) == NULL) goto err; |
170 | pp=p; | 123 | pp=p; |
171 | i2d_DSAparams(dsa,&pp); | 124 | i2d_DSAparams(dsa,&pp); |
172 | a->parameter=ASN1_TYPE_new(); | 125 | a->parameter=ASN1_TYPE_new(); |
173 | a->parameter->type=V_ASN1_SEQUENCE; | 126 | a->parameter->type=V_ASN1_SEQUENCE; |
174 | a->parameter->value.sequence=ASN1_STRING_new(); | 127 | a->parameter->value.sequence=ASN1_STRING_new(); |
175 | ASN1_STRING_set(a->parameter->value.sequence,p,i); | 128 | ASN1_STRING_set(a->parameter->value.sequence,p,i); |
176 | Free(p); | 129 | OPENSSL_free(p); |
177 | } | 130 | } |
178 | else | 131 | else |
179 | #endif | 132 | #endif |
@@ -182,15 +135,25 @@ EVP_PKEY *pkey; | |||
182 | goto err; | 135 | goto err; |
183 | } | 136 | } |
184 | 137 | ||
185 | i=i2d_PublicKey(pkey,NULL); | 138 | if ((i=i2d_PublicKey(pkey,NULL)) <= 0) goto err; |
186 | if ((s=(unsigned char *)Malloc(i+1)) == NULL) goto err; | 139 | if ((s=(unsigned char *)OPENSSL_malloc(i+1)) == NULL) |
140 | { | ||
141 | X509err(X509_F_X509_PUBKEY_SET,ERR_R_MALLOC_FAILURE); | ||
142 | goto err; | ||
143 | } | ||
187 | p=s; | 144 | p=s; |
188 | i2d_PublicKey(pkey,&p); | 145 | i2d_PublicKey(pkey,&p); |
189 | if (!ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err; | 146 | if (!M_ASN1_BIT_STRING_set(pk->public_key,s,i)) goto err; |
190 | Free(s); | 147 | /* Set number of unused bits to zero */ |
148 | pk->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); | ||
149 | pk->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT; | ||
150 | |||
151 | OPENSSL_free(s); | ||
191 | 152 | ||
153 | #if 0 | ||
192 | CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); | 154 | CRYPTO_add(&pkey->references,1,CRYPTO_LOCK_EVP_PKEY); |
193 | pk->pkey=pkey; | 155 | pk->pkey=pkey; |
156 | #endif | ||
194 | 157 | ||
195 | if (*x != NULL) | 158 | if (*x != NULL) |
196 | X509_PUBKEY_free(*x); | 159 | X509_PUBKEY_free(*x); |
@@ -204,20 +167,24 @@ err: | |||
204 | return(ok); | 167 | return(ok); |
205 | } | 168 | } |
206 | 169 | ||
207 | EVP_PKEY *X509_PUBKEY_get(key) | 170 | EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) |
208 | X509_PUBKEY *key; | ||
209 | { | 171 | { |
210 | EVP_PKEY *ret=NULL; | 172 | EVP_PKEY *ret=NULL; |
211 | long j; | 173 | long j; |
212 | int type; | 174 | int type; |
213 | unsigned char *p; | 175 | unsigned char *p; |
214 | #ifndef NO_DSA | 176 | #ifndef OPENSSL_NO_DSA |
177 | const unsigned char *cp; | ||
215 | X509_ALGOR *a; | 178 | X509_ALGOR *a; |
216 | #endif | 179 | #endif |
217 | 180 | ||
218 | if (key == NULL) goto err; | 181 | if (key == NULL) goto err; |
219 | 182 | ||
220 | if (key->pkey != NULL) return(key->pkey); | 183 | if (key->pkey != NULL) |
184 | { | ||
185 | CRYPTO_add(&key->pkey->references,1,CRYPTO_LOCK_EVP_PKEY); | ||
186 | return(key->pkey); | ||
187 | } | ||
221 | 188 | ||
222 | if (key->public_key == NULL) goto err; | 189 | if (key->public_key == NULL) goto err; |
223 | 190 | ||
@@ -231,22 +198,23 @@ X509_PUBKEY *key; | |||
231 | } | 198 | } |
232 | ret->save_parameters=0; | 199 | ret->save_parameters=0; |
233 | 200 | ||
234 | #ifndef NO_DSA | 201 | #ifndef OPENSSL_NO_DSA |
235 | a=key->algor; | 202 | a=key->algor; |
236 | if (ret->type == EVP_PKEY_DSA) | 203 | if (ret->type == EVP_PKEY_DSA) |
237 | { | 204 | { |
238 | if (a->parameter->type == V_ASN1_SEQUENCE) | 205 | if (a->parameter && (a->parameter->type == V_ASN1_SEQUENCE)) |
239 | { | 206 | { |
240 | ret->pkey.dsa->write_params=0; | 207 | ret->pkey.dsa->write_params=0; |
241 | p=a->parameter->value.sequence->data; | 208 | cp=p=a->parameter->value.sequence->data; |
242 | j=a->parameter->value.sequence->length; | 209 | j=a->parameter->value.sequence->length; |
243 | if (!d2i_DSAparams(&ret->pkey.dsa,&p,(long)j)) | 210 | if (!d2i_DSAparams(&ret->pkey.dsa,&cp,(long)j)) |
244 | goto err; | 211 | goto err; |
245 | } | 212 | } |
246 | ret->save_parameters=1; | 213 | ret->save_parameters=1; |
247 | } | 214 | } |
248 | #endif | 215 | #endif |
249 | key->pkey=ret; | 216 | key->pkey=ret; |
217 | CRYPTO_add(&ret->references,1,CRYPTO_LOCK_EVP_PKEY); | ||
250 | return(ret); | 218 | return(ret); |
251 | err: | 219 | err: |
252 | if (ret != NULL) | 220 | if (ret != NULL) |
@@ -254,3 +222,113 @@ err: | |||
254 | return(NULL); | 222 | return(NULL); |
255 | } | 223 | } |
256 | 224 | ||
225 | /* Now two pseudo ASN1 routines that take an EVP_PKEY structure | ||
226 | * and encode or decode as X509_PUBKEY | ||
227 | */ | ||
228 | |||
229 | EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, unsigned char **pp, | ||
230 | long length) | ||
231 | { | ||
232 | X509_PUBKEY *xpk; | ||
233 | EVP_PKEY *pktmp; | ||
234 | xpk = d2i_X509_PUBKEY(NULL, pp, length); | ||
235 | if(!xpk) return NULL; | ||
236 | pktmp = X509_PUBKEY_get(xpk); | ||
237 | X509_PUBKEY_free(xpk); | ||
238 | if(!pktmp) return NULL; | ||
239 | if(a) { | ||
240 | EVP_PKEY_free(*a); | ||
241 | *a = pktmp; | ||
242 | } | ||
243 | return pktmp; | ||
244 | } | ||
245 | |||
246 | int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp) | ||
247 | { | ||
248 | X509_PUBKEY *xpk=NULL; | ||
249 | int ret; | ||
250 | if(!a) return 0; | ||
251 | if(!X509_PUBKEY_set(&xpk, a)) return 0; | ||
252 | ret = i2d_X509_PUBKEY(xpk, pp); | ||
253 | X509_PUBKEY_free(xpk); | ||
254 | return ret; | ||
255 | } | ||
256 | |||
257 | /* The following are equivalents but which return RSA and DSA | ||
258 | * keys | ||
259 | */ | ||
260 | #ifndef OPENSSL_NO_RSA | ||
261 | RSA *d2i_RSA_PUBKEY(RSA **a, unsigned char **pp, | ||
262 | long length) | ||
263 | { | ||
264 | EVP_PKEY *pkey; | ||
265 | RSA *key; | ||
266 | unsigned char *q; | ||
267 | q = *pp; | ||
268 | pkey = d2i_PUBKEY(NULL, &q, length); | ||
269 | if(!pkey) return NULL; | ||
270 | key = EVP_PKEY_get1_RSA(pkey); | ||
271 | EVP_PKEY_free(pkey); | ||
272 | if(!key) return NULL; | ||
273 | *pp = q; | ||
274 | if(a) { | ||
275 | RSA_free(*a); | ||
276 | *a = key; | ||
277 | } | ||
278 | return key; | ||
279 | } | ||
280 | |||
281 | int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp) | ||
282 | { | ||
283 | EVP_PKEY *pktmp; | ||
284 | int ret; | ||
285 | if(!a) return 0; | ||
286 | pktmp = EVP_PKEY_new(); | ||
287 | if(!pktmp) { | ||
288 | ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE); | ||
289 | return 0; | ||
290 | } | ||
291 | EVP_PKEY_set1_RSA(pktmp, a); | ||
292 | ret = i2d_PUBKEY(pktmp, pp); | ||
293 | EVP_PKEY_free(pktmp); | ||
294 | return ret; | ||
295 | } | ||
296 | #endif | ||
297 | |||
298 | #ifndef OPENSSL_NO_DSA | ||
299 | DSA *d2i_DSA_PUBKEY(DSA **a, unsigned char **pp, | ||
300 | long length) | ||
301 | { | ||
302 | EVP_PKEY *pkey; | ||
303 | DSA *key; | ||
304 | unsigned char *q; | ||
305 | q = *pp; | ||
306 | pkey = d2i_PUBKEY(NULL, &q, length); | ||
307 | if(!pkey) return NULL; | ||
308 | key = EVP_PKEY_get1_DSA(pkey); | ||
309 | EVP_PKEY_free(pkey); | ||
310 | if(!key) return NULL; | ||
311 | *pp = q; | ||
312 | if(a) { | ||
313 | DSA_free(*a); | ||
314 | *a = key; | ||
315 | } | ||
316 | return key; | ||
317 | } | ||
318 | |||
319 | int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp) | ||
320 | { | ||
321 | EVP_PKEY *pktmp; | ||
322 | int ret; | ||
323 | if(!a) return 0; | ||
324 | pktmp = EVP_PKEY_new(); | ||
325 | if(!pktmp) { | ||
326 | ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE); | ||
327 | return 0; | ||
328 | } | ||
329 | EVP_PKEY_set1_DSA(pktmp, a); | ||
330 | ret = i2d_PUBKEY(pktmp, pp); | ||
331 | EVP_PKEY_free(pktmp); | ||
332 | return ret; | ||
333 | } | ||
334 | #endif | ||