1280304Sjkim/*
2280304Sjkim * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
3280304Sjkim * 2006.
4238384Sjkim */
5238384Sjkim/* ====================================================================
6238384Sjkim * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
7238384Sjkim *
8238384Sjkim * Redistribution and use in source and binary forms, with or without
9238384Sjkim * modification, are permitted provided that the following conditions
10238384Sjkim * are met:
11238384Sjkim *
12238384Sjkim * 1. Redistributions of source code must retain the above copyright
13280304Sjkim *    notice, this list of conditions and the following disclaimer.
14238384Sjkim *
15238384Sjkim * 2. Redistributions in binary form must reproduce the above copyright
16238384Sjkim *    notice, this list of conditions and the following disclaimer in
17238384Sjkim *    the documentation and/or other materials provided with the
18238384Sjkim *    distribution.
19238384Sjkim *
20238384Sjkim * 3. All advertising materials mentioning features or use of this
21238384Sjkim *    software must display the following acknowledgment:
22238384Sjkim *    "This product includes software developed by the OpenSSL Project
23238384Sjkim *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24238384Sjkim *
25238384Sjkim * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26238384Sjkim *    endorse or promote products derived from this software without
27238384Sjkim *    prior written permission. For written permission, please contact
28238384Sjkim *    licensing@OpenSSL.org.
29238384Sjkim *
30238384Sjkim * 5. Products derived from this software may not be called "OpenSSL"
31238384Sjkim *    nor may "OpenSSL" appear in their names without prior written
32238384Sjkim *    permission of the OpenSSL Project.
33238384Sjkim *
34238384Sjkim * 6. Redistributions of any form whatsoever must retain the following
35238384Sjkim *    acknowledgment:
36238384Sjkim *    "This product includes software developed by the OpenSSL Project
37238384Sjkim *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38238384Sjkim *
39238384Sjkim * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40238384Sjkim * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41238384Sjkim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42238384Sjkim * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43238384Sjkim * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44238384Sjkim * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45238384Sjkim * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46238384Sjkim * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47238384Sjkim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48238384Sjkim * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49238384Sjkim * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50238384Sjkim * OF THE POSSIBILITY OF SUCH DAMAGE.
51238384Sjkim * ====================================================================
52238384Sjkim *
53238384Sjkim * This product includes cryptographic software written by Eric Young
54238384Sjkim * (eay@cryptsoft.com).  This product includes software written by Tim
55238384Sjkim * Hudson (tjh@cryptsoft.com).
56238384Sjkim *
57238384Sjkim */
58238384Sjkim
59238384Sjkim#include <stdio.h>
60238384Sjkim#include "cryptlib.h"
61238384Sjkim#include <openssl/x509.h>
62238384Sjkim#include <openssl/asn1.h>
63238384Sjkim#include <openssl/dsa.h>
64238384Sjkim#include <openssl/bn.h>
65238384Sjkim#ifndef OPENSSL_NO_CMS
66280304Sjkim# include <openssl/cms.h>
67238384Sjkim#endif
68238384Sjkim#include "asn1_locl.h"
69238384Sjkim
70238384Sjkimstatic int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
71280304Sjkim{
72280304Sjkim    const unsigned char *p, *pm;
73280304Sjkim    int pklen, pmlen;
74280304Sjkim    int ptype;
75280304Sjkim    void *pval;
76280304Sjkim    ASN1_STRING *pstr;
77280304Sjkim    X509_ALGOR *palg;
78280304Sjkim    ASN1_INTEGER *public_key = NULL;
79238384Sjkim
80280304Sjkim    DSA *dsa = NULL;
81238384Sjkim
82280304Sjkim    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
83280304Sjkim        return 0;
84280304Sjkim    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
85238384Sjkim
86280304Sjkim    if (ptype == V_ASN1_SEQUENCE) {
87280304Sjkim        pstr = pval;
88280304Sjkim        pm = pstr->data;
89280304Sjkim        pmlen = pstr->length;
90238384Sjkim
91280304Sjkim        if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) {
92280304Sjkim            DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
93280304Sjkim            goto err;
94280304Sjkim        }
95238384Sjkim
96280304Sjkim    } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) {
97280304Sjkim        if (!(dsa = DSA_new())) {
98280304Sjkim            DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
99280304Sjkim            goto err;
100280304Sjkim        }
101280304Sjkim    } else {
102280304Sjkim        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
103280304Sjkim        goto err;
104280304Sjkim    }
105238384Sjkim
106280304Sjkim    if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) {
107280304Sjkim        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
108280304Sjkim        goto err;
109280304Sjkim    }
110238384Sjkim
111280304Sjkim    if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
112280304Sjkim        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
113280304Sjkim        goto err;
114280304Sjkim    }
115238384Sjkim
116280304Sjkim    ASN1_INTEGER_free(public_key);
117280304Sjkim    EVP_PKEY_assign_DSA(pkey, dsa);
118280304Sjkim    return 1;
119238384Sjkim
120280304Sjkim err:
121280304Sjkim    if (public_key)
122280304Sjkim        ASN1_INTEGER_free(public_key);
123280304Sjkim    if (dsa)
124280304Sjkim        DSA_free(dsa);
125280304Sjkim    return 0;
126238384Sjkim
127280304Sjkim}
128238384Sjkim
129238384Sjkimstatic int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
130280304Sjkim{
131280304Sjkim    DSA *dsa;
132280304Sjkim    int ptype;
133280304Sjkim    unsigned char *penc = NULL;
134280304Sjkim    int penclen;
135280304Sjkim    ASN1_STRING *str = NULL;
136238384Sjkim
137280304Sjkim    dsa = pkey->pkey.dsa;
138280304Sjkim    if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
139280304Sjkim        str = ASN1_STRING_new();
140280304Sjkim        if (!str) {
141280304Sjkim            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
142280304Sjkim            goto err;
143280304Sjkim        }
144280304Sjkim        str->length = i2d_DSAparams(dsa, &str->data);
145280304Sjkim        if (str->length <= 0) {
146280304Sjkim            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
147280304Sjkim            goto err;
148280304Sjkim        }
149280304Sjkim        ptype = V_ASN1_SEQUENCE;
150280304Sjkim    } else
151280304Sjkim        ptype = V_ASN1_UNDEF;
152238384Sjkim
153280304Sjkim    dsa->write_params = 0;
154238384Sjkim
155280304Sjkim    penclen = i2d_DSAPublicKey(dsa, &penc);
156238384Sjkim
157280304Sjkim    if (penclen <= 0) {
158280304Sjkim        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
159280304Sjkim        goto err;
160280304Sjkim    }
161238384Sjkim
162280304Sjkim    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
163280304Sjkim                               ptype, str, penc, penclen))
164280304Sjkim        return 1;
165238384Sjkim
166280304Sjkim err:
167280304Sjkim    if (penc)
168280304Sjkim        OPENSSL_free(penc);
169280304Sjkim    if (str)
170280304Sjkim        ASN1_STRING_free(str);
171238384Sjkim
172280304Sjkim    return 0;
173280304Sjkim}
174238384Sjkim
175280304Sjkim/*
176280304Sjkim * In PKCS#8 DSA: you just get a private key integer and parameters in the
177238384Sjkim * AlgorithmIdentifier the pubkey must be recalculated.
178238384Sjkim */
179280304Sjkim
180238384Sjkimstatic int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
181280304Sjkim{
182280304Sjkim    const unsigned char *p, *pm;
183280304Sjkim    int pklen, pmlen;
184280304Sjkim    int ptype;
185280304Sjkim    void *pval;
186280304Sjkim    ASN1_STRING *pstr;
187280304Sjkim    X509_ALGOR *palg;
188280304Sjkim    ASN1_INTEGER *privkey = NULL;
189280304Sjkim    BN_CTX *ctx = NULL;
190238384Sjkim
191280304Sjkim    STACK_OF(ASN1_TYPE) *ndsa = NULL;
192280304Sjkim    DSA *dsa = NULL;
193238384Sjkim
194296317Sdelphij    int ret = 0;
195296317Sdelphij
196280304Sjkim    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
197280304Sjkim        return 0;
198280304Sjkim    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
199238384Sjkim
200280304Sjkim    /* Check for broken DSA PKCS#8, UGH! */
201280304Sjkim    if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
202280304Sjkim        ASN1_TYPE *t1, *t2;
203280304Sjkim        if (!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)))
204280304Sjkim            goto decerr;
205280304Sjkim        if (sk_ASN1_TYPE_num(ndsa) != 2)
206280304Sjkim            goto decerr;
207280304Sjkim        /*-
208280304Sjkim         * Handle Two broken types:
209280304Sjkim         * SEQUENCE {parameters, priv_key}
210280304Sjkim         * SEQUENCE {pub_key, priv_key}
211280304Sjkim         */
212238384Sjkim
213280304Sjkim        t1 = sk_ASN1_TYPE_value(ndsa, 0);
214280304Sjkim        t2 = sk_ASN1_TYPE_value(ndsa, 1);
215280304Sjkim        if (t1->type == V_ASN1_SEQUENCE) {
216280304Sjkim            p8->broken = PKCS8_EMBEDDED_PARAM;
217280304Sjkim            pval = t1->value.ptr;
218280304Sjkim        } else if (ptype == V_ASN1_SEQUENCE)
219280304Sjkim            p8->broken = PKCS8_NS_DB;
220280304Sjkim        else
221280304Sjkim            goto decerr;
222238384Sjkim
223280304Sjkim        if (t2->type != V_ASN1_INTEGER)
224280304Sjkim            goto decerr;
225238384Sjkim
226280304Sjkim        privkey = t2->value.integer;
227280304Sjkim    } else {
228280304Sjkim        const unsigned char *q = p;
229280304Sjkim        if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)))
230280304Sjkim            goto decerr;
231280304Sjkim        if (privkey->type == V_ASN1_NEG_INTEGER) {
232280304Sjkim            p8->broken = PKCS8_NEG_PRIVKEY;
233280304Sjkim            ASN1_STRING_clear_free(privkey);
234280304Sjkim            if (!(privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen)))
235280304Sjkim                goto decerr;
236280304Sjkim        }
237280304Sjkim        if (ptype != V_ASN1_SEQUENCE)
238280304Sjkim            goto decerr;
239280304Sjkim    }
240238384Sjkim
241280304Sjkim    pstr = pval;
242280304Sjkim    pm = pstr->data;
243280304Sjkim    pmlen = pstr->length;
244280304Sjkim    if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
245280304Sjkim        goto decerr;
246280304Sjkim    /* We have parameters now set private key */
247280304Sjkim    if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
248280304Sjkim        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
249280304Sjkim        goto dsaerr;
250280304Sjkim    }
251280304Sjkim    /* Calculate public key */
252280304Sjkim    if (!(dsa->pub_key = BN_new())) {
253280304Sjkim        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
254280304Sjkim        goto dsaerr;
255280304Sjkim    }
256280304Sjkim    if (!(ctx = BN_CTX_new())) {
257280304Sjkim        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
258280304Sjkim        goto dsaerr;
259280304Sjkim    }
260238384Sjkim
261280304Sjkim    if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
262280304Sjkim        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
263280304Sjkim        goto dsaerr;
264280304Sjkim    }
265238384Sjkim
266280304Sjkim    EVP_PKEY_assign_DSA(pkey, dsa);
267238384Sjkim
268296317Sdelphij    ret = 1;
269296317Sdelphij    goto done;
270238384Sjkim
271280304Sjkim decerr:
272280304Sjkim    DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
273280304Sjkim dsaerr:
274296317Sdelphij    DSA_free(dsa);
275296317Sdelphij done:
276280304Sjkim    BN_CTX_free(ctx);
277296317Sdelphij    if (ndsa)
278296317Sdelphij        sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
279296317Sdelphij    else
280280304Sjkim        ASN1_STRING_clear_free(privkey);
281296317Sdelphij    return ret;
282280304Sjkim}
283280304Sjkim
284238384Sjkimstatic int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
285238384Sjkim{
286280304Sjkim    ASN1_STRING *params = NULL;
287280304Sjkim    ASN1_INTEGER *prkey = NULL;
288280304Sjkim    unsigned char *dp = NULL;
289280304Sjkim    int dplen;
290238384Sjkim
291280304Sjkim    if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
292280304Sjkim        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_MISSING_PARAMETERS);
293280304Sjkim        goto err;
294280304Sjkim    }
295273149Sjkim
296280304Sjkim    params = ASN1_STRING_new();
297238384Sjkim
298280304Sjkim    if (!params) {
299280304Sjkim        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
300280304Sjkim        goto err;
301280304Sjkim    }
302238384Sjkim
303280304Sjkim    params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
304280304Sjkim    if (params->length <= 0) {
305280304Sjkim        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
306280304Sjkim        goto err;
307280304Sjkim    }
308280304Sjkim    params->type = V_ASN1_SEQUENCE;
309238384Sjkim
310280304Sjkim    /* Get private key into integer */
311280304Sjkim    prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
312238384Sjkim
313280304Sjkim    if (!prkey) {
314280304Sjkim        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR);
315280304Sjkim        goto err;
316280304Sjkim    }
317238384Sjkim
318280304Sjkim    dplen = i2d_ASN1_INTEGER(prkey, &dp);
319238384Sjkim
320280304Sjkim    ASN1_STRING_clear_free(prkey);
321291721Sjkim    prkey = NULL;
322238384Sjkim
323280304Sjkim    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
324280304Sjkim                         V_ASN1_SEQUENCE, params, dp, dplen))
325280304Sjkim        goto err;
326238384Sjkim
327280304Sjkim    return 1;
328238384Sjkim
329280304Sjkim err:
330280304Sjkim    if (dp != NULL)
331280304Sjkim        OPENSSL_free(dp);
332280304Sjkim    if (params != NULL)
333280304Sjkim        ASN1_STRING_free(params);
334280304Sjkim    if (prkey != NULL)
335280304Sjkim        ASN1_STRING_clear_free(prkey);
336280304Sjkim    return 0;
337238384Sjkim}
338238384Sjkim
339238384Sjkimstatic int int_dsa_size(const EVP_PKEY *pkey)
340280304Sjkim{
341280304Sjkim    return (DSA_size(pkey->pkey.dsa));
342280304Sjkim}
343238384Sjkim
344238384Sjkimstatic int dsa_bits(const EVP_PKEY *pkey)
345280304Sjkim{
346280304Sjkim    return BN_num_bits(pkey->pkey.dsa->p);
347280304Sjkim}
348238384Sjkim
349238384Sjkimstatic int dsa_missing_parameters(const EVP_PKEY *pkey)
350280304Sjkim{
351280304Sjkim    DSA *dsa;
352280304Sjkim    dsa = pkey->pkey.dsa;
353280304Sjkim    if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
354280304Sjkim        return 1;
355280304Sjkim    return 0;
356280304Sjkim}
357238384Sjkim
358238384Sjkimstatic int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
359280304Sjkim{
360280304Sjkim    BIGNUM *a;
361238384Sjkim
362280304Sjkim    if ((a = BN_dup(from->pkey.dsa->p)) == NULL)
363280304Sjkim        return 0;
364280304Sjkim    if (to->pkey.dsa->p != NULL)
365280304Sjkim        BN_free(to->pkey.dsa->p);
366280304Sjkim    to->pkey.dsa->p = a;
367238384Sjkim
368280304Sjkim    if ((a = BN_dup(from->pkey.dsa->q)) == NULL)
369280304Sjkim        return 0;
370280304Sjkim    if (to->pkey.dsa->q != NULL)
371280304Sjkim        BN_free(to->pkey.dsa->q);
372280304Sjkim    to->pkey.dsa->q = a;
373238384Sjkim
374280304Sjkim    if ((a = BN_dup(from->pkey.dsa->g)) == NULL)
375280304Sjkim        return 0;
376280304Sjkim    if (to->pkey.dsa->g != NULL)
377280304Sjkim        BN_free(to->pkey.dsa->g);
378280304Sjkim    to->pkey.dsa->g = a;
379280304Sjkim    return 1;
380280304Sjkim}
381238384Sjkim
382238384Sjkimstatic int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
383280304Sjkim{
384280304Sjkim    if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) ||
385280304Sjkim        BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) ||
386280304Sjkim        BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g))
387280304Sjkim        return 0;
388280304Sjkim    else
389280304Sjkim        return 1;
390280304Sjkim}
391238384Sjkim
392238384Sjkimstatic int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
393280304Sjkim{
394280304Sjkim    if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0)
395280304Sjkim        return 0;
396280304Sjkim    else
397280304Sjkim        return 1;
398280304Sjkim}
399238384Sjkim
400238384Sjkimstatic void int_dsa_free(EVP_PKEY *pkey)
401280304Sjkim{
402280304Sjkim    DSA_free(pkey->pkey.dsa);
403280304Sjkim}
404238384Sjkim
405238384Sjkimstatic void update_buflen(const BIGNUM *b, size_t *pbuflen)
406280304Sjkim{
407280304Sjkim    size_t i;
408280304Sjkim    if (!b)
409280304Sjkim        return;
410280304Sjkim    if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
411280304Sjkim        *pbuflen = i;
412280304Sjkim}
413238384Sjkim
414238384Sjkimstatic int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
415280304Sjkim{
416280304Sjkim    unsigned char *m = NULL;
417280304Sjkim    int ret = 0;
418280304Sjkim    size_t buf_len = 0;
419280304Sjkim    const char *ktype = NULL;
420238384Sjkim
421280304Sjkim    const BIGNUM *priv_key, *pub_key;
422238384Sjkim
423280304Sjkim    if (ptype == 2)
424280304Sjkim        priv_key = x->priv_key;
425280304Sjkim    else
426280304Sjkim        priv_key = NULL;
427238384Sjkim
428280304Sjkim    if (ptype > 0)
429280304Sjkim        pub_key = x->pub_key;
430280304Sjkim    else
431280304Sjkim        pub_key = NULL;
432238384Sjkim
433280304Sjkim    if (ptype == 2)
434280304Sjkim        ktype = "Private-Key";
435280304Sjkim    else if (ptype == 1)
436280304Sjkim        ktype = "Public-Key";
437280304Sjkim    else
438280304Sjkim        ktype = "DSA-Parameters";
439238384Sjkim
440280304Sjkim    update_buflen(x->p, &buf_len);
441280304Sjkim    update_buflen(x->q, &buf_len);
442280304Sjkim    update_buflen(x->g, &buf_len);
443280304Sjkim    update_buflen(priv_key, &buf_len);
444280304Sjkim    update_buflen(pub_key, &buf_len);
445238384Sjkim
446280304Sjkim    m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
447280304Sjkim    if (m == NULL) {
448280304Sjkim        DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE);
449280304Sjkim        goto err;
450280304Sjkim    }
451238384Sjkim
452280304Sjkim    if (priv_key) {
453280304Sjkim        if (!BIO_indent(bp, off, 128))
454280304Sjkim            goto err;
455280304Sjkim        if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p))
456280304Sjkim            <= 0)
457280304Sjkim            goto err;
458280304Sjkim    }
459238384Sjkim
460280304Sjkim    if (!ASN1_bn_print(bp, "priv:", priv_key, m, off))
461280304Sjkim        goto err;
462280304Sjkim    if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off))
463280304Sjkim        goto err;
464280304Sjkim    if (!ASN1_bn_print(bp, "P:   ", x->p, m, off))
465280304Sjkim        goto err;
466280304Sjkim    if (!ASN1_bn_print(bp, "Q:   ", x->q, m, off))
467280304Sjkim        goto err;
468280304Sjkim    if (!ASN1_bn_print(bp, "G:   ", x->g, m, off))
469280304Sjkim        goto err;
470280304Sjkim    ret = 1;
471280304Sjkim err:
472280304Sjkim    if (m != NULL)
473280304Sjkim        OPENSSL_free(m);
474280304Sjkim    return (ret);
475280304Sjkim}
476238384Sjkim
477238384Sjkimstatic int dsa_param_decode(EVP_PKEY *pkey,
478280304Sjkim                            const unsigned char **pder, int derlen)
479280304Sjkim{
480280304Sjkim    DSA *dsa;
481280304Sjkim    if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) {
482280304Sjkim        DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
483280304Sjkim        return 0;
484280304Sjkim    }
485280304Sjkim    EVP_PKEY_assign_DSA(pkey, dsa);
486280304Sjkim    return 1;
487280304Sjkim}
488238384Sjkim
489238384Sjkimstatic int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
490280304Sjkim{
491280304Sjkim    return i2d_DSAparams(pkey->pkey.dsa, pder);
492280304Sjkim}
493238384Sjkim
494238384Sjkimstatic int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
495280304Sjkim                           ASN1_PCTX *ctx)
496280304Sjkim{
497280304Sjkim    return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
498280304Sjkim}
499238384Sjkim
500238384Sjkimstatic int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
501280304Sjkim                         ASN1_PCTX *ctx)
502280304Sjkim{
503280304Sjkim    return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
504280304Sjkim}
505238384Sjkim
506238384Sjkimstatic int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
507280304Sjkim                          ASN1_PCTX *ctx)
508280304Sjkim{
509280304Sjkim    return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
510280304Sjkim}
511238384Sjkim
512238384Sjkimstatic int old_dsa_priv_decode(EVP_PKEY *pkey,
513280304Sjkim                               const unsigned char **pder, int derlen)
514280304Sjkim{
515280304Sjkim    DSA *dsa;
516280304Sjkim    if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) {
517280304Sjkim        DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
518280304Sjkim        return 0;
519280304Sjkim    }
520280304Sjkim    EVP_PKEY_assign_DSA(pkey, dsa);
521280304Sjkim    return 1;
522280304Sjkim}
523238384Sjkim
524238384Sjkimstatic int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
525280304Sjkim{
526280304Sjkim    return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
527280304Sjkim}
528238384Sjkim
529238384Sjkimstatic int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
530280304Sjkim                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
531280304Sjkim{
532280304Sjkim    DSA_SIG *dsa_sig;
533280304Sjkim    const unsigned char *p;
534280304Sjkim    if (!sig) {
535280304Sjkim        if (BIO_puts(bp, "\n") <= 0)
536280304Sjkim            return 0;
537280304Sjkim        else
538280304Sjkim            return 1;
539280304Sjkim    }
540280304Sjkim    p = sig->data;
541280304Sjkim    dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
542280304Sjkim    if (dsa_sig) {
543280304Sjkim        int rv = 0;
544280304Sjkim        size_t buf_len = 0;
545280304Sjkim        unsigned char *m = NULL;
546280304Sjkim        update_buflen(dsa_sig->r, &buf_len);
547280304Sjkim        update_buflen(dsa_sig->s, &buf_len);
548280304Sjkim        m = OPENSSL_malloc(buf_len + 10);
549280304Sjkim        if (m == NULL) {
550280304Sjkim            DSAerr(DSA_F_DSA_SIG_PRINT, ERR_R_MALLOC_FAILURE);
551280304Sjkim            goto err;
552280304Sjkim        }
553238384Sjkim
554280304Sjkim        if (BIO_write(bp, "\n", 1) != 1)
555280304Sjkim            goto err;
556238384Sjkim
557280304Sjkim        if (!ASN1_bn_print(bp, "r:   ", dsa_sig->r, m, indent))
558280304Sjkim            goto err;
559280304Sjkim        if (!ASN1_bn_print(bp, "s:   ", dsa_sig->s, m, indent))
560280304Sjkim            goto err;
561280304Sjkim        rv = 1;
562280304Sjkim err:
563280304Sjkim        if (m)
564280304Sjkim            OPENSSL_free(m);
565280304Sjkim        DSA_SIG_free(dsa_sig);
566280304Sjkim        return rv;
567280304Sjkim    }
568280304Sjkim    return X509_signature_dump(bp, sig, indent);
569280304Sjkim}
570238384Sjkim
571238384Sjkimstatic int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
572280304Sjkim{
573280304Sjkim    switch (op) {
574280304Sjkim    case ASN1_PKEY_CTRL_PKCS7_SIGN:
575280304Sjkim        if (arg1 == 0) {
576280304Sjkim            int snid, hnid;
577280304Sjkim            X509_ALGOR *alg1, *alg2;
578280304Sjkim            PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
579280304Sjkim            if (alg1 == NULL || alg1->algorithm == NULL)
580280304Sjkim                return -1;
581280304Sjkim            hnid = OBJ_obj2nid(alg1->algorithm);
582280304Sjkim            if (hnid == NID_undef)
583280304Sjkim                return -1;
584280304Sjkim            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
585280304Sjkim                return -1;
586280304Sjkim            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
587280304Sjkim        }
588280304Sjkim        return 1;
589238384Sjkim#ifndef OPENSSL_NO_CMS
590280304Sjkim    case ASN1_PKEY_CTRL_CMS_SIGN:
591280304Sjkim        if (arg1 == 0) {
592280304Sjkim            int snid, hnid;
593280304Sjkim            X509_ALGOR *alg1, *alg2;
594280304Sjkim            CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
595280304Sjkim            if (alg1 == NULL || alg1->algorithm == NULL)
596280304Sjkim                return -1;
597280304Sjkim            hnid = OBJ_obj2nid(alg1->algorithm);
598280304Sjkim            if (hnid == NID_undef)
599280304Sjkim                return -1;
600280304Sjkim            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
601280304Sjkim                return -1;
602280304Sjkim            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
603280304Sjkim        }
604280304Sjkim        return 1;
605238384Sjkim#endif
606238384Sjkim
607280304Sjkim    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
608280304Sjkim        *(int *)arg2 = NID_sha1;
609280304Sjkim        return 2;
610238384Sjkim
611280304Sjkim    default:
612280304Sjkim        return -2;
613238384Sjkim
614280304Sjkim    }
615238384Sjkim
616280304Sjkim}
617238384Sjkim
618238384Sjkim/* NB these are sorted in pkey_id order, lowest first */
619238384Sjkim
620280304Sjkimconst EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = {
621238384Sjkim
622280304Sjkim    {
623280304Sjkim     EVP_PKEY_DSA2,
624280304Sjkim     EVP_PKEY_DSA,
625280304Sjkim     ASN1_PKEY_ALIAS},
626238384Sjkim
627280304Sjkim    {
628280304Sjkim     EVP_PKEY_DSA1,
629280304Sjkim     EVP_PKEY_DSA,
630280304Sjkim     ASN1_PKEY_ALIAS},
631238384Sjkim
632280304Sjkim    {
633280304Sjkim     EVP_PKEY_DSA4,
634280304Sjkim     EVP_PKEY_DSA,
635280304Sjkim     ASN1_PKEY_ALIAS},
636238384Sjkim
637280304Sjkim    {
638280304Sjkim     EVP_PKEY_DSA3,
639280304Sjkim     EVP_PKEY_DSA,
640280304Sjkim     ASN1_PKEY_ALIAS},
641238384Sjkim
642280304Sjkim    {
643280304Sjkim     EVP_PKEY_DSA,
644280304Sjkim     EVP_PKEY_DSA,
645280304Sjkim     0,
646238384Sjkim
647280304Sjkim     "DSA",
648280304Sjkim     "OpenSSL DSA method",
649238384Sjkim
650280304Sjkim     dsa_pub_decode,
651280304Sjkim     dsa_pub_encode,
652280304Sjkim     dsa_pub_cmp,
653280304Sjkim     dsa_pub_print,
654238384Sjkim
655280304Sjkim     dsa_priv_decode,
656280304Sjkim     dsa_priv_encode,
657280304Sjkim     dsa_priv_print,
658238384Sjkim
659280304Sjkim     int_dsa_size,
660280304Sjkim     dsa_bits,
661238384Sjkim
662280304Sjkim     dsa_param_decode,
663280304Sjkim     dsa_param_encode,
664280304Sjkim     dsa_missing_parameters,
665280304Sjkim     dsa_copy_parameters,
666280304Sjkim     dsa_cmp_parameters,
667280304Sjkim     dsa_param_print,
668280304Sjkim     dsa_sig_print,
669238384Sjkim
670280304Sjkim     int_dsa_free,
671280304Sjkim     dsa_pkey_ctrl,
672280304Sjkim     old_dsa_priv_decode,
673280304Sjkim     old_dsa_priv_encode}
674280304Sjkim};
675