summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/asn1/x_pubkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/asn1/x_pubkey.c')
-rw-r--r--src/lib/libcrypto/asn1/x_pubkey.c236
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); 65static 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;
68int i2d_X509_PUBKEY(a,pp) 69 EVP_PKEY_free(pubkey->pkey);
69X509_PUBKEY *a;
70unsigned 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
85X509_PUBKEY *d2i_X509_PUBKEY(a,pp,length)
86X509_PUBKEY **a;
87unsigned char **pp;
88long 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
104X509_PUBKEY *X509_PUBKEY_new() 74ASN1_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
116void X509_PUBKEY_free(a) 79IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
117X509_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
126int X509_PUBKEY_set(x,pkey) 81int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
127X509_PUBKEY **x;
128EVP_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
207EVP_PKEY *X509_PUBKEY_get(key) 170EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
208X509_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);
251err: 219err:
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
229EVP_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
246int 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
261RSA *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
281int 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
299DSA *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
319int 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