a39f4ceac83bd57f365c3c23222c3c68ed6e5b1a
[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 #ifndef OPENSSL_NO_CMS
64 #include <openssl/cms.h>
65 #endif
66 #include "asn1_locl.h"
67
68 static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
69         {
70         const unsigned char *p, *pm;
71         int pklen, pmlen;
72         int ptype;
73         void *pval;
74         ASN1_STRING *pstr;
75         X509_ALGOR *palg;
76         ASN1_INTEGER *public_key = NULL;
77
78         DSA *dsa = NULL;
79
80         if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
81                 return 0;
82         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
83
84
85         if (ptype == V_ASN1_SEQUENCE)
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                 }
98         else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF))
99                 {
100                 if (!(dsa = DSA_new()))
101                         {
102                         DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
103                         goto err;
104                         }
105                 }
106         else
107                 {
108                 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
109                 goto err;
110                 }
111
112         if (!(public_key=d2i_ASN1_INTEGER(NULL, &p, pklen)))
113                 {
114                 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
115                 goto err;
116                 }
117
118         if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)))
119                 {
120                 DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
121                 goto err;
122                 }
123
124         ASN1_INTEGER_free(public_key);
125         EVP_PKEY_assign_DSA(pkey, dsa);
126         return 1;
127
128         err:
129         if (public_key)
130                 ASN1_INTEGER_free(public_key);
131         if (dsa)
132                 DSA_free(dsa);
133         return 0;
134
135         }
136
137 static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
138         {
139         DSA *dsa;
140         void *pval = NULL;
141         int ptype;
142         unsigned char *penc = NULL;
143         int penclen;
144
145         dsa=pkey->pkey.dsa;
146         if (pkey->save_parameters && dsa->p && dsa->q && dsa->g)
147                 {
148                 ASN1_STRING *str;
149                 str = ASN1_STRING_new();
150                 str->length = i2d_DSAparams(dsa, &str->data);
151                 if (str->length <= 0)
152                         {
153                         DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
154                         goto err;
155                         }
156                 pval = str;
157                 ptype = V_ASN1_SEQUENCE;
158                 }
159         else
160                 ptype = V_ASN1_UNDEF;
161
162         dsa->write_params=0;
163
164         penclen = i2d_DSAPublicKey(dsa, &penc);
165
166         if (penclen <= 0)
167                 {
168                 DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
169                 goto err;
170                 }
171
172         if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
173                                 ptype, pval, penc, penclen))
174                 return 1;
175
176         err:
177         if (penc)
178                 OPENSSL_free(penc);
179         if (pval)
180                 ASN1_STRING_free(pval);
181
182         return 0;
183         }
184
185 /* In PKCS#8 DSA: you just get a private key integer and parameters in the
186  * AlgorithmIdentifier the pubkey must be recalculated.
187  */
188         
189 static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
190         {
191         const unsigned char *p, *pm;
192         int pklen, pmlen;
193         int ptype;
194         void *pval;
195         ASN1_STRING *pstr;
196         X509_ALGOR *palg;
197         ASN1_INTEGER *privkey = NULL;
198         BN_CTX *ctx = NULL;
199
200         STACK_OF(ASN1_TYPE) *ndsa = NULL;
201         DSA *dsa = NULL;
202
203         if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
204                 return 0;
205         X509_ALGOR_get0(NULL, &ptype, &pval, palg);
206
207         /* Check for broken DSA PKCS#8, UGH! */
208         if (*p == (V_ASN1_SEQUENCE|V_ASN1_CONSTRUCTED))
209                 {
210                 ASN1_TYPE *t1, *t2;
211                 if(!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)));
212                         goto decerr;
213                 if (sk_ASN1_TYPE_num(ndsa) != 2)
214                         goto decerr;
215                 /* Handle Two broken types:
216                  * SEQUENCE {parameters, priv_key}
217                  * SEQUENCE {pub_key, priv_key}
218                  */
219
220                 t1 = sk_ASN1_TYPE_value(ndsa, 0);
221                 t2 = sk_ASN1_TYPE_value(ndsa, 1);
222                 if (t1->type == V_ASN1_SEQUENCE)
223                         {
224                         p8->broken = PKCS8_EMBEDDED_PARAM;
225                         pval = t1->value.ptr;
226                         }
227                 else if (ptype == V_ASN1_SEQUENCE)
228                         p8->broken = PKCS8_NS_DB;
229                 else
230                         goto decerr;
231
232                 if (t2->type != V_ASN1_INTEGER)
233                         goto decerr;
234
235                 privkey = t2->value.integer;
236                 }
237         else
238                 {
239                 if (!(privkey=d2i_ASN1_INTEGER(NULL, &p, pklen)))
240                         goto decerr;
241                 if (ptype != V_ASN1_SEQUENCE)
242                         goto decerr;
243                 }
244
245         pstr = pval;    
246         pm = pstr->data;
247         pmlen = pstr->length;
248         if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
249                 goto decerr;
250         /* We have parameters now set private key */
251         if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL)))
252                 {
253                 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
254                 goto dsaerr;
255                 }
256         /* Calculate public key */
257         if (!(dsa->pub_key = BN_new()))
258                 {
259                 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
260                 goto dsaerr;
261                 }
262         if (!(ctx = BN_CTX_new()))
263                 {
264                 DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
265                 goto dsaerr;
266                 }
267                         
268         if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx))
269                 {
270                 DSAerr(DSA_F_DSA_PRIV_DECODE,DSA_R_BN_ERROR);
271                 goto dsaerr;
272                 }
273
274         EVP_PKEY_assign_DSA(pkey, dsa);
275         BN_CTX_free (ctx);
276         if(ndsa)
277                 sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
278         else
279                 ASN1_INTEGER_free(privkey);
280
281         return 1;
282
283         decerr:
284         DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
285         dsaerr:
286         BN_CTX_free (ctx);
287         if (privkey)
288                 ASN1_INTEGER_free(privkey);
289         sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
290         DSA_free(dsa);
291         return 0;
292         }
293
294 static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
295 {
296         ASN1_STRING *params = NULL;
297         ASN1_INTEGER *prkey = NULL;
298         unsigned char *dp = NULL;
299         int dplen;
300
301         params = ASN1_STRING_new();
302
303         if (!params)
304                 {
305                 DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
306                 goto err;
307                 }
308
309         params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
310         if (params->length <= 0)
311                 {
312                 DSAerr(DSA_F_DSA_PRIV_ENCODE,ERR_R_MALLOC_FAILURE);
313                 goto err;
314                 }
315         params->type = V_ASN1_SEQUENCE;
316
317         /* Get private key into integer */
318         prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
319
320         if (!prkey)
321                 {
322                 DSAerr(DSA_F_DSA_PRIV_ENCODE,DSA_R_BN_ERROR);
323                 goto err;
324                 }
325
326         dplen = i2d_ASN1_INTEGER(prkey, &dp);
327
328         ASN1_INTEGER_free(prkey);
329
330         if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
331                                 V_ASN1_SEQUENCE, params, dp, dplen))
332                 goto err;
333
334         return 1;
335
336 err:
337         if (dp != NULL)
338                 OPENSSL_free(dp);
339         if (params != NULL)
340                 ASN1_STRING_free(params);
341         if (prkey != NULL)
342                 ASN1_INTEGER_free(prkey);
343         return 0;
344 }
345
346 static int int_dsa_size(const EVP_PKEY *pkey)
347         {
348         return(DSA_size(pkey->pkey.dsa));
349         }
350
351 static int dsa_bits(const EVP_PKEY *pkey)
352         {
353         return BN_num_bits(pkey->pkey.dsa->p);
354         }
355
356 static int dsa_missing_parameters(const EVP_PKEY *pkey)
357         {
358         DSA *dsa;
359         dsa=pkey->pkey.dsa;
360         if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
361                         return 1;
362         return 0;
363         }
364
365 static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
366         {
367         BIGNUM *a;
368
369         if ((a=BN_dup(from->pkey.dsa->p)) == NULL)
370                 return 0;
371         if (to->pkey.dsa->p != NULL)
372                 BN_free(to->pkey.dsa->p);
373         to->pkey.dsa->p=a;
374
375         if ((a=BN_dup(from->pkey.dsa->q)) == NULL)
376                 return 0;
377         if (to->pkey.dsa->q != NULL)
378                 BN_free(to->pkey.dsa->q);
379         to->pkey.dsa->q=a;
380
381         if ((a=BN_dup(from->pkey.dsa->g)) == NULL)
382                 return 0;
383         if (to->pkey.dsa->g != NULL)
384                 BN_free(to->pkey.dsa->g);
385         to->pkey.dsa->g=a;
386         return 1;
387         }
388
389 static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
390         {
391         if (    BN_cmp(a->pkey.dsa->p,b->pkey.dsa->p) ||
392                 BN_cmp(a->pkey.dsa->q,b->pkey.dsa->q) ||
393                 BN_cmp(a->pkey.dsa->g,b->pkey.dsa->g))
394                 return 0;
395         else
396                 return 1;
397         }
398
399 static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
400         {
401         if (BN_cmp(b->pkey.dsa->pub_key,a->pkey.dsa->pub_key) != 0)
402                 return 0;
403         else
404                 return 1;
405         }
406
407 static void int_dsa_free(EVP_PKEY *pkey)
408         {
409         DSA_free(pkey->pkey.dsa);
410         }
411
412 static void update_buflen(const BIGNUM *b, size_t *pbuflen)
413         {
414         size_t i;
415         if (!b)
416                 return;
417         if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
418                         *pbuflen = i;
419         }
420
421 static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
422         {
423         unsigned char *m=NULL;
424         int ret=0;
425         size_t buf_len=0;
426         const char *ktype = NULL;
427
428         const BIGNUM *priv_key, *pub_key;
429
430         if (ptype == 2)
431                 priv_key = x->priv_key;
432         else
433                 priv_key = NULL;
434
435         if (ptype > 0)
436                 pub_key = x->pub_key;
437         else
438                 pub_key = NULL;
439
440         if (ptype == 2)
441                 ktype = "Private-Key";
442         else if (ptype == 1)
443                 ktype = "Public-Key";
444         else
445                 ktype = "DSA-Parameters";
446
447         update_buflen(x->p, &buf_len);
448         update_buflen(x->q, &buf_len);
449         update_buflen(x->g, &buf_len);
450         update_buflen(priv_key, &buf_len);
451         update_buflen(pub_key, &buf_len);
452
453         m=(unsigned char *)OPENSSL_malloc(buf_len+10);
454         if (m == NULL)
455                 {
456                 DSAerr(DSA_F_DO_DSA_PRINT,ERR_R_MALLOC_FAILURE);
457                 goto err;
458                 }
459
460         if (priv_key)
461                 {
462                 if(!BIO_indent(bp,off,128))
463                    goto err;
464                 if (BIO_printf(bp,"%s: (%d bit)\n",ktype, BN_num_bits(x->p))
465                         <= 0) goto err;
466                 }
467
468         if (!ASN1_bn_print(bp,"priv:",priv_key,m,off))
469                 goto err;
470         if (!ASN1_bn_print(bp,"pub: ",pub_key,m,off))
471                 goto err;
472         if (!ASN1_bn_print(bp,"P:   ",x->p,m,off)) goto err;
473         if (!ASN1_bn_print(bp,"Q:   ",x->q,m,off)) goto err;
474         if (!ASN1_bn_print(bp,"G:   ",x->g,m,off)) goto err;
475         ret=1;
476 err:
477         if (m != NULL) OPENSSL_free(m);
478         return(ret);
479         }
480
481 static int dsa_param_decode(EVP_PKEY *pkey,
482                                         const unsigned char **pder, int derlen)
483         {
484         DSA *dsa;
485         if (!(dsa = d2i_DSAparams(NULL, pder, derlen)))
486                 {
487                 DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
488                 return 0;
489                 }
490         EVP_PKEY_assign_DSA(pkey, dsa);
491         return 1;
492         }
493
494 static int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
495         {
496         return i2d_DSAparams(pkey->pkey.dsa, pder);
497         }
498
499 static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
500                                                         ASN1_PCTX *ctx)
501         {
502         return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
503         }
504
505 static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
506                                                         ASN1_PCTX *ctx)
507         {
508         return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
509         }
510
511
512 static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
513                                                         ASN1_PCTX *ctx)
514         {
515         return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
516         }
517
518 static int old_dsa_priv_decode(EVP_PKEY *pkey,
519                                         const unsigned char **pder, int derlen)
520         {
521         DSA *dsa;
522         if (!(dsa = d2i_DSAPrivateKey (NULL, pder, derlen)))
523                 {
524                 DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
525                 return 0;
526                 }
527         EVP_PKEY_assign_DSA(pkey, dsa);
528         return 1;
529         }
530
531 static int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
532         {
533         return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
534         }
535
536 static int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
537         {
538         switch (op)
539                 {
540                 case ASN1_PKEY_CTRL_PKCS7_SIGN:
541                 if (arg1 == 0)
542                         {
543                         int snid, hnid;
544                         X509_ALGOR *alg1, *alg2;
545                         PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
546                         if (alg1 == NULL || alg1->algorithm == NULL)
547                                 return -1;
548                         hnid = OBJ_obj2nid(alg1->algorithm);
549                         if (hnid == NID_undef)
550                                 return -1;
551                         if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
552                                 return -1; 
553                         X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
554                         }
555                 return 1;
556 #ifndef OPENSSL_NO_CMS
557                 case ASN1_PKEY_CTRL_CMS_SIGN:
558                 if (arg1 == 0)
559                         {
560                         int snid, hnid;
561                         X509_ALGOR *alg1, *alg2;
562                         CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
563                         if (alg1 == NULL || alg1->algorithm == NULL)
564                                 return -1;
565                         hnid = OBJ_obj2nid(alg1->algorithm);
566                         if (hnid == NID_undef)
567                                 return -1;
568                         if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
569                                 return -1; 
570                         X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
571                         }
572                 return 1;
573 #endif
574
575                 case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
576                 *(int *)arg2 = NID_sha1;
577                 return 2;
578
579                 default:
580                 return -2;
581
582                 }
583
584         }
585
586 /* NB these are sorted in pkey_id order, lowest first */
587
588 const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = 
589         {
590
591                 {
592                 EVP_PKEY_DSA2,
593                 EVP_PKEY_DSA,
594                 ASN1_PKEY_ALIAS
595                 },
596
597                 {
598                 EVP_PKEY_DSA1,
599                 EVP_PKEY_DSA,
600                 ASN1_PKEY_ALIAS
601                 },
602
603                 {
604                 EVP_PKEY_DSA4,
605                 EVP_PKEY_DSA,
606                 ASN1_PKEY_ALIAS
607                 },
608
609                 {
610                 EVP_PKEY_DSA3,
611                 EVP_PKEY_DSA,
612                 ASN1_PKEY_ALIAS
613                 },
614
615                 {
616                 EVP_PKEY_DSA,
617                 EVP_PKEY_DSA,
618                 0,
619
620                 "DSA",
621                 "OpenSSL DSA method",
622
623                 dsa_pub_decode,
624                 dsa_pub_encode,
625                 dsa_pub_cmp,
626                 dsa_pub_print,
627
628                 dsa_priv_decode,
629                 dsa_priv_encode,
630                 dsa_priv_print,
631
632                 int_dsa_size,
633                 dsa_bits,
634
635                 dsa_param_decode,
636                 dsa_param_encode,
637                 dsa_missing_parameters,
638                 dsa_copy_parameters,
639                 dsa_cmp_parameters,
640                 dsa_param_print,
641
642                 int_dsa_free,
643                 dsa_pkey_ctrl,
644                 old_dsa_priv_decode,
645                 old_dsa_priv_encode
646                 }
647         };
648