Fix leak.
[openssl.git] / crypto / dsa / dsa_ameth.c
1 /* Written by Dr Stephen N Henson (shenson@bigfoot.com) for the OpenSSL
2  * project 2006.
3  */
4 /* ====================================================================
5  * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer. 
13  *
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in
16  *    the documentation and/or other materials provided with the
17  *    distribution.
18  *
19  * 3. All advertising materials mentioning features or use of this
20  *    software must display the following acknowledgment:
21  *    "This product includes software developed by the OpenSSL Project
22  *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
23  *
24  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
25  *    endorse or promote products derived from this software without
26  *    prior written permission. For written permission, please contact
27  *    licensing@OpenSSL.org.
28  *
29  * 5. Products derived from this software may not be called "OpenSSL"
30  *    nor may "OpenSSL" appear in their names without prior written
31  *    permission of the OpenSSL Project.
32  *
33  * 6. Redistributions of any form whatsoever must retain the following
34  *    acknowledgment:
35  *    "This product includes software developed by the OpenSSL Project
36  *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
39  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
41  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
42  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
43  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
45  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
47  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
48  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
49  * OF THE POSSIBILITY OF SUCH DAMAGE.
50  * ====================================================================
51  *
52  * This product includes cryptographic software written by Eric Young
53  * (eay@cryptsoft.com).  This product includes software written by Tim
54  * Hudson (tjh@cryptsoft.com).
55  *
56  */
57
58 #include <stdio.h>
59 #include "cryptlib.h"
60 #include <openssl/x509.h>
61 #include <openssl/asn1.h>
62 #include <openssl/dsa.h>
63 #include "asn1_locl.h"
64
65 static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
66         {
67         const unsigned char *p, *pm;
68         int pklen, pmlen;
69         int ptype;
70         void *pval;
71         ASN1_STRING *pstr;
72         X509_ALGOR *palg;
73         ASN1_INTEGER *public_key = NULL;
74
75         DSA *dsa = NULL;
76
77         if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
78                 return 0;
79         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
80
81         if (ptype != V_ASN1_SEQUENCE)
82                 {
83                 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
84                 goto err;
85                 }
86
87         pstr = pval;    
88         pm = pstr->data;
89         pmlen = pstr->length;
90
91         if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
92                 {
93                 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
94                 goto err;
95                 }
96
97         if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
98                 {
99                 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
100                 goto err;
101                 }
102
103         /* We have parameters now set public key */
104         if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
105                 {
106                 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
107                 goto err;
108                 }
109
110         ASN1_INTEGER_free(public_key);
111         EVP_PKEY_assign_DSA(pkey, dsa);
112         return 1;
113
114         err:
115         if (pubkey)
116                 ASN1_INTEGER_free(public_key);
117         if (dsa)
118                 DSA_free(dsa);
119         return 0;
120
121         }
122
123 static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
124         {
125         DSA *dsa;
126         void *pval = NULL;
127         int ptype;
128         unsigned char *penc = NULL;
129         int penclen;
130
131         dsa=pkey->pkey.dsa;
132         if (pkey->save_parameters)
133                 {
134                 ASN1_STRING *str;
135                 str = ASN1_STRING_new();
136                 str->length = i2d_DSAparams(dsa, &str->data);
137                 if (str->length <= 0)
138                         {
139                         DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
140                         goto err;
141                         }
142                 pval = str;
143                 ptype = V_ASN1_SEQUENCE;
144                 }
145         else
146                 ptype = V_ASN1_UNDEF;
147         dsa->write_params=0;
148
149         penclen = i2d_DSAPublicKey(dsa, &penc);
150
151         if (penclen <= 0)
152                 {
153                 DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
154                 goto err;
155                 }
156
157         if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
158                                 ptype, pval, penc, penclen))
159                 return 1;
160
161         err:
162         if (penc)
163                 OPENSSL_free(penc);
164         if (pval)
165                 ASN1_STRING_free(pval);
166
167         return 0;
168         }
169
170 /* In PKCS#8 DSA: you just get a private key integer and parameters in the
171  * AlgorithmIdentifier the pubkey must be recalculated.
172  */
173         
174 static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
175         {
176         const unsigned char *p, *pm;
177         int pklen, pmlen;
178         int ptype;
179         void *pval;
180         ASN1_STRING *pstr;
181         X509_ALGOR *palg;
182         ASN1_INTEGER *privkey = NULL;
183         BN_CTX *ctx = NULL;
184
185         STACK_OF(ASN1_TYPE) *ndsa = NULL;
186         DSA *dsa = NULL;
187
188         if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
189                 return 0;
190         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
191
192         /* Check for broken DSA PKCS#8, UGH! */
193         if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
194                 {
195                 ASN1_TYPE *t1, *t2;
196                 if(!(ndsa = ASN1_seq_unpack_ASN1_TYPE(p, pklen, 
197                                                           d2i_ASN1_TYPE,
198                                                           ASN1_TYPE_free)))
199                         goto decerr;
200                 if (sk_ASN1_TYPE_num(ndsa) != 2)
201                         goto decerr;
202                 /* Handle Two broken types:
203                  * SEQUENCE {parameters, priv_key}
204                  * SEQUENCE {pub_key, priv_key}
205                  */
206
207                 t1 = sk_ASN1_TYPE_value(ndsa, 0);
208                 t2 = sk_ASN1_TYPE_value(ndsa, 1);
209                 if (t1->type == V_ASN1_SEQUENCE)
210                         {
211                         p8->broken = PKCS8_EMBEDDED_PARAM;
212                         pval = t1->value.ptr;
213                         }
214                 else if (ptype == V_ASN1_SEQUENCE)
215                         p8->broken = PKCS8_NS_DB;
216                 else
217                         goto decerr;
218
219                 if (t2->type != V_ASN1_INTEGER)
220                         goto decerr;
221
222                 privkey = t2->value.integer;
223                 }
224         else
225                 {
226                 if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
227                         goto decerr;
228                 if (ptype != V_ASN1_SEQUENCE)
229                         goto decerr;
230                 }
231
232         pstr = pval;    
233         pm = pstr->data;
234         pmlen = pstr->length;
235         if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
236                 goto decerr;
237         /* We have parameters now set private key */
238         if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
239                 {
240                 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
241                 goto dsaerr;
242                 }
243         /* Calculate public key */
244         if (!(dsa->pub_key = BN_new()))
245                 {
246                 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
247                 goto dsaerr;
248                 }
249         if (!(ctx = BN_CTX_new()))
250                 {
251                 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
252                 goto dsaerr;
253                 }
254                         
255         if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx))
256                 {
257                 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
258                 goto dsaerr;
259                 }
260
261         EVP_PKEY_assign_DSA(pkey, dsa);
262         BN_CTX_free (ctx);
263         if(ndsa)
264                 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
265         else
266                 ASN1_INTEGER_free(privkey);
267
268         return 1;
269
270         decerr:
271         DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
272         dsaerr:
273         BN_CTX_free (ctx);
274         if (privkey)
275                 ASN1_INTEGER_free(privkey);
276         sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
277         DSA_free(dsa);
278         return 0;
279         }
280
281 static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
282 {
283         ASN1_STRING *params = NULL;
284         ASN1_INTEGER *prkey = NULL;
285         unsigned char *dp = NULL;
286         int dplen;
287
288         params = ASN1_STRING_new();
289
290         if (!params)
291                 {
292                 DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
293                 goto err;
294                 }
295
296         params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
297         if (params->length <= 0)
298                 {
299                 DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
300                 goto err;
301                 }
302         params->type = V_ASN1_SEQUENCE;
303
304         /* Get private key into integer */
305         prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
306
307         if (!prkey)
308                 {
309                 DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR);
310                 goto err;
311                 }
312
313         dplen = i2d_ASN1_INTEGER(prkey, &dp);
314
315         ASN1_INTEGER_free(prkey);
316
317         if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
318                                 V_ASN1_SEQUENCE, params, dp, dplen))
319                 goto err;
320
321         return 1;
322
323 err:
324         if (dp != NULL)
325                 OPENSSL_free(dp);
326         if (params != NULL)
327                 ASN1_STRING_free(params);
328         if (prkey != NULL)
329                 ASN1_INTEGER_free(prkey);
330         return 0;
331 }
332
333 static int int_dsa_size(const EVP_PKEY *pkey)
334         {
335         return(DSA_size(pkey->pkey.dsa));
336         }
337
338 static int dsa_bits(const EVP_PKEY *pkey)
339         {
340         return BN_num_bits(pkey->pkey.dsa->p);
341         }
342
343 static int dsa_missing_parameters(const EVP_PKEY *pkey)
344         {
345         DSA *dsa;
346         dsa=pkey->pkey.dsa;
347         if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
348                         return 1;
349         return 0;
350         }
351
352 static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
353         {
354         BIGNUM *a;
355
356         if ((a=BN_dup(from->pkey.dsa->p)) == NULL)
357                 return 0;
358         if (to->pkey.dsa->p != NULL)
359                 BN_free(to->pkey.dsa->p);
360         to->pkey.dsa->p=a;
361
362         if ((a=BN_dup(from->pkey.dsa->q)) == NULL)
363                 return 0;
364         if (to->pkey.dsa->q != NULL)
365                 BN_free(to->pkey.dsa->q);
366         to->pkey.dsa->q=a;
367
368         if ((a=BN_dup(from->pkey.dsa->g)) == NULL)
369                 return 0;
370         if (to->pkey.dsa->g != NULL)
371                 BN_free(to->pkey.dsa->g);
372         to->pkey.dsa->g=a;
373         return 1;
374         }
375
376 static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
377         {
378         if (    BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) ||
379                 BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) ||
380                 BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
381                 return 0;
382         else
383                 return 1;
384         }
385
386 static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
387         {
388         if (dsa_cmp_parameters(a, b) == 0)
389                 return 0;
390         if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
391                 return 0;
392         else
393                 return 1;
394         }
395
396 static void int_dsa_free(EVP_PKEY *pkey)
397         {
398         DSA_free(pkey->pkey.dsa);
399         }
400
401 static void update_buflen(const BIGNUM *b, size_t *pbuflen)
402         {
403         int i;
404         if (!b)
405                 return;
406         if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
407                         *pbuflen = i;
408         }
409
410 int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
411         {
412         unsigned char *m=NULL;
413         int ret=0;
414         size_t buf_len=0;
415         const char *ktype = NULL;
416
417         const BIGNUM *priv_key, *pub_key;
418
419         if (ptype == 2)
420                 priv_key = x->priv_key;
421         else
422                 priv_key = NULL;
423
424         if (ptype > 0)
425                 pub_key = x->pub_key;
426         else
427                 pub_key = NULL;
428
429         if (ptype == 2)
430                 ktype = "Private-Key";
431         else if (ptype == 1)
432                 ktype = "Public-Key";
433         else
434                 ktype = "DSA-Parameters";
435
436         if (x->p == NULL)
437                 {
438                 DSAerr(DSA_F_DSA_PRINT,DSA_R_MISSING_PARAMETERS);
439                 goto err;
440                 }
441
442         update_buflen(x->p, &buf_len);
443         update_buflen(x->q, &buf_len);
444         update_buflen(x->g, &buf_len);
445         update_buflen(priv_key, &buf_len);
446         update_buflen(pub_key, &buf_len);
447
448         m=(unsigned char *)OPENSSL_malloc(buf_len+10);
449         if (m == NULL)
450                 {
451                 DSAerr(DSA_F_DSA_PRINT,ERR_R_MALLOC_FAILURE);
452                 goto err;
453                 }
454
455         if (priv_key)
456                 {
457                 if(!BIO_indent(bp,off,128))
458                    goto err;
459                 if (BIO_printf(bp,"%s: (%d bit)\n",ktype, BN_num_bits(x->p))
460                         <= 0) goto err;
461                 }
462
463         if (!ASN1_bn_print(bp,"priv:",priv_key,m,off))
464                 goto err;
465         if (!ASN1_bn_print(bp,"pub: ",pub_key,m,off))
466                 goto err;
467         if (!ASN1_bn_print(bp,"P:   ",x->p,m,off)) goto err;
468         if (!ASN1_bn_print(bp,"Q:   ",x->q,m,off)) goto err;
469         if (!ASN1_bn_print(bp,"G:   ",x->g,m,off)) goto err;
470         ret=1;
471 err:
472         if (m != NULL) OPENSSL_free(m);
473         return(ret);
474         }
475
476 static int dsa_param_decode(EVP_PKEY *pkey,
477                                         const unsigned char **pder, int derlen)
478         {
479         DSA *dsa;
480         if (!(dsa = d2i_DSAparams(NULL, pder, derlen)))
481                 {
482                 DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
483                 return 0;
484                 }
485         EVP_PKEY_assign_DSA(pkey, dsa);
486         return 1;
487         }
488
489 static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
490         {
491         return i2d_DSAparams(pkey->pkey.dsa, pder);
492         }
493
494 static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
495                                                         ASN1_PCTX *ctx)
496         {
497         return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
498         }
499
500 static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
501                                                         ASN1_PCTX *ctx)
502         {
503         return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
504         }
505
506
507 static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
508                                                         ASN1_PCTX *ctx)
509         {
510         return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
511         }
512
513 static int old_dsa_priv_decode(EVP_PKEY *pkey,
514                                         const unsigned char **pder, int derlen)
515         {
516         DSA *dsa;
517         if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen)))
518                 {
519                 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
520                 return 0;
521                 }
522         EVP_PKEY_assign_DSA(pkey, dsa);
523         return 1;
524         }
525
526 static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
527         {
528         return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
529         }
530
531 /* NB these are sorted in pkey_id order, lowest first */
532
533 const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = 
534         {
535
536                 {
537                 EVP_PKEY_DSA2,
538                 EVP_PKEY_DSA,
539                 ASN1_PKEY_ALIAS
540                 },
541
542                 {
543                 EVP_PKEY_DSA1,
544                 EVP_PKEY_DSA,
545                 ASN1_PKEY_ALIAS
546                 },
547
548                 {
549                 EVP_PKEY_DSA4,
550                 EVP_PKEY_DSA,
551                 ASN1_PKEY_ALIAS
552                 },
553
554                 {
555                 EVP_PKEY_DSA3,
556                 EVP_PKEY_DSA,
557                 ASN1_PKEY_ALIAS
558                 },
559
560                 {
561                 EVP_PKEY_DSA,
562                 EVP_PKEY_DSA,
563                 0,
564
565                 "DSA",
566                 "OpenSSL DSA method",
567
568                 dsa_pub_decode,
569                 dsa_pub_encode,
570                 dsa_pub_cmp,
571                 dsa_pub_print,
572
573                 dsa_priv_decode,
574                 dsa_priv_encode,
575                 dsa_priv_print,
576
577                 int_dsa_size,
578                 dsa_bits,
579
580                 dsa_param_decode,
581                 dsa_param_encode,
582                 dsa_missing_parameters,
583                 dsa_copy_parameters,
584                 dsa_cmp_parameters,
585                 dsa_param_print,
586
587                 int_dsa_free,
588                 0,
589                 old_dsa_priv_decode,
590                 old_dsa_priv_encode
591                 }
592         };
593