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