dsa_ameth.c revision 296341
1151497Sru/*
279543Sru * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
375584Sru * 2006.
475584Sru */
575584Sru/* ====================================================================
675584Sru * Copyright (c) 2006 The OpenSSL Project.  All rights reserved.
775584Sru *
875584Sru * Redistribution and use in source and binary forms, with or without
975584Sru * modification, are permitted provided that the following conditions
1075584Sru * are met:
1175584Sru *
1275584Sru * 1. Redistributions of source code must retain the above copyright
1375584Sru *    notice, this list of conditions and the following disclaimer.
1475584Sru *
1575584Sru * 2. Redistributions in binary form must reproduce the above copyright
1675584Sru *    notice, this list of conditions and the following disclaimer in
1775584Sru *    the documentation and/or other materials provided with the
1875584Sru *    distribution.
19151497Sru *
2075584Sru * 3. All advertising materials mentioning features or use of this
21104862Sru *    software must display the following acknowledgment:
22104862Sru *    "This product includes software developed by the OpenSSL Project
23104862Sru *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
2475584Sru *
2575584Sru * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
2675584Sru *    endorse or promote products derived from this software without
2775584Sru *    prior written permission. For written permission, please contact
2875584Sru *    licensing@OpenSSL.org.
2975584Sru *
3075584Sru * 5. Products derived from this software may not be called "OpenSSL"
3175584Sru *    nor may "OpenSSL" appear in their names without prior written
3275584Sru *    permission of the OpenSSL Project.
3379543Sru *
3479543Sru * 6. Redistributions of any form whatsoever must retain the following
3579543Sru *    acknowledgment:
3675584Sru *    "This product includes software developed by the OpenSSL Project
3779543Sru *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
3875584Sru *
3975584Sru * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
4075584Sru * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4175584Sru * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
4275584Sru * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
4375584Sru * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
4475584Sru * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
4575584Sru * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
4675584Sru * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4775584Sru * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
4875584Sru * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
4975584Sru * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
5075584Sru * OF THE POSSIBILITY OF SUCH DAMAGE.
5175584Sru * ====================================================================
5275584Sru *
5375584Sru * This product includes cryptographic software written by Eric Young
5475584Sru * (eay@cryptsoft.com).  This product includes software written by Tim
5575584Sru * Hudson (tjh@cryptsoft.com).
5675584Sru *
5775584Sru */
5875584Sru
5975584Sru#include <stdio.h>
6075584Sru#include "cryptlib.h"
6175584Sru#include <openssl/x509.h>
6275584Sru#include <openssl/asn1.h>
6375584Sru#include <openssl/dsa.h>
6475584Sru#include <openssl/bn.h>
6575584Sru#ifndef OPENSSL_NO_CMS
6675584Sru# include <openssl/cms.h>
6775584Sru#endif
6875584Sru#include "asn1_locl.h"
6975584Sru
7075584Srustatic int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey)
7175584Sru{
7275584Sru    const unsigned char *p, *pm;
7375584Sru    int pklen, pmlen;
7475584Sru    int ptype;
7575584Sru    void *pval;
7675584Sru    ASN1_STRING *pstr;
7775584Sru    X509_ALGOR *palg;
7875584Sru    ASN1_INTEGER *public_key = NULL;
7975584Sru
80151497Sru    DSA *dsa = NULL;
81151497Sru
82151497Sru    if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey))
83151497Sru        return 0;
8475584Sru    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
85151497Sru
86151497Sru    if (ptype == V_ASN1_SEQUENCE) {
87151497Sru        pstr = pval;
88151497Sru        pm = pstr->data;
89151497Sru        pmlen = pstr->length;
90151497Sru
91151497Sru        if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen))) {
92114402Sru            DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
9375584Sru            goto err;
94151497Sru        }
95151497Sru
9675584Sru    } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) {
9775584Sru        if (!(dsa = DSA_new())) {
9879543Sru            DSAerr(DSA_F_DSA_PUB_DECODE, ERR_R_MALLOC_FAILURE);
99104862Sru            goto err;
100104862Sru        }
10175584Sru    } else {
10275584Sru        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_PARAMETER_ENCODING_ERROR);
10375584Sru        goto err;
10475584Sru    }
105151497Sru
10675584Sru    if (!(public_key = d2i_ASN1_INTEGER(NULL, &p, pklen))) {
10775584Sru        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_DECODE_ERROR);
10875584Sru        goto err;
109151497Sru    }
110151497Sru
111151497Sru    if (!(dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL))) {
11275584Sru        DSAerr(DSA_F_DSA_PUB_DECODE, DSA_R_BN_DECODE_ERROR);
113151497Sru        goto err;
114151497Sru    }
115151497Sru
11675584Sru    ASN1_INTEGER_free(public_key);
117151497Sru    EVP_PKEY_assign_DSA(pkey, dsa);
118151497Sru    return 1;
119151497Sru
120151497Sru err:
121151497Sru    if (public_key)
122151497Sru        ASN1_INTEGER_free(public_key);
123151497Sru    if (dsa)
124151497Sru        DSA_free(dsa);
125151497Sru    return 0;
126151497Sru
127151497Sru}
128151497Sru
129151497Srustatic int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey)
130151497Sru{
131151497Sru    DSA *dsa;
132151497Sru    int ptype;
133151497Sru    unsigned char *penc = NULL;
134151497Sru    int penclen;
135151497Sru    ASN1_STRING *str = NULL;
136151497Sru
13775584Sru    dsa = pkey->pkey.dsa;
13875584Sru    if (pkey->save_parameters && dsa->p && dsa->q && dsa->g) {
139151497Sru        str = ASN1_STRING_new();
140151497Sru        if (!str) {
14175584Sru            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
142151497Sru            goto err;
14375584Sru        }
144151497Sru        str->length = i2d_DSAparams(dsa, &str->data);
145151497Sru        if (str->length <= 0) {
146151497Sru            DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
147151497Sru            goto err;
148151497Sru        }
14975584Sru        ptype = V_ASN1_SEQUENCE;
150151497Sru    } else
151151497Sru        ptype = V_ASN1_UNDEF;
152151497Sru
153151497Sru    dsa->write_params = 0;
154151497Sru
155151497Sru    penclen = i2d_DSAPublicKey(dsa, &penc);
156151497Sru
157151497Sru    if (penclen <= 0) {
158151497Sru        DSAerr(DSA_F_DSA_PUB_ENCODE, ERR_R_MALLOC_FAILURE);
159151497Sru        goto err;
160151497Sru    }
161151497Sru
16275584Sru    if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA),
16375584Sru                               ptype, str, penc, penclen))
164151497Sru        return 1;
16575584Sru
166151497Sru err:
167151497Sru    if (penc)
168151497Sru        OPENSSL_free(penc);
169151497Sru    if (str)
170151497Sru        ASN1_STRING_free(str);
171151497Sru
172151497Sru    return 0;
173151497Sru}
17475584Sru
175151497Sru/*
176151497Sru * In PKCS#8 DSA: you just get a private key integer and parameters in the
177151497Sru * AlgorithmIdentifier the pubkey must be recalculated.
178151497Sru */
17975584Sru
18075584Srustatic int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8)
181151497Sru{
18275584Sru    const unsigned char *p, *pm;
183151497Sru    int pklen, pmlen;
184151497Sru    int ptype;
18575584Sru    void *pval;
186151497Sru    ASN1_STRING *pstr;
18775584Sru    X509_ALGOR *palg;
18875584Sru    ASN1_INTEGER *privkey = NULL;
189151497Sru    BN_CTX *ctx = NULL;
190151497Sru
19175584Sru    STACK_OF(ASN1_TYPE) *ndsa = NULL;
192151497Sru    DSA *dsa = NULL;
193151497Sru
194151497Sru    int ret = 0;
195151497Sru
196151497Sru    if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8))
197151497Sru        return 0;
19875584Sru    X509_ALGOR_get0(NULL, &ptype, &pval, palg);
19975584Sru
200114402Sru    /* Check for broken DSA PKCS#8, UGH! */
20175584Sru    if (*p == (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
202151497Sru        ASN1_TYPE *t1, *t2;
203151497Sru        if (!(ndsa = d2i_ASN1_SEQUENCE_ANY(NULL, &p, pklen)))
204151497Sru            goto decerr;
205151497Sru        if (sk_ASN1_TYPE_num(ndsa) != 2)
206151497Sru            goto decerr;
207151497Sru        /*-
208151497Sru         * Handle Two broken types:
209151497Sru         * SEQUENCE {parameters, priv_key}
210151497Sru         * SEQUENCE {pub_key, priv_key}
211114402Sru         */
212151497Sru
21375584Sru        t1 = sk_ASN1_TYPE_value(ndsa, 0);
214114402Sru        t2 = sk_ASN1_TYPE_value(ndsa, 1);
215151497Sru        if (t1->type == V_ASN1_SEQUENCE) {
216151497Sru            p8->broken = PKCS8_EMBEDDED_PARAM;
217151497Sru            pval = t1->value.ptr;
218114402Sru        } else if (ptype == V_ASN1_SEQUENCE)
219114402Sru            p8->broken = PKCS8_NS_DB;
220114402Sru        else
221114402Sru            goto decerr;
222114402Sru
223114402Sru        if (t2->type != V_ASN1_INTEGER)
224114402Sru            goto decerr;
225114402Sru
226114402Sru        privkey = t2->value.integer;
227114402Sru    } else {
228114402Sru        const unsigned char *q = p;
229114402Sru        if (!(privkey = d2i_ASN1_INTEGER(NULL, &p, pklen)))
230114402Sru            goto decerr;
231151497Sru        if (privkey->type == V_ASN1_NEG_INTEGER) {
232151497Sru            p8->broken = PKCS8_NEG_PRIVKEY;
233151497Sru            ASN1_STRING_clear_free(privkey);
234151497Sru            if (!(privkey = d2i_ASN1_UINTEGER(NULL, &q, pklen)))
235114402Sru                goto decerr;
236114402Sru        }
237114402Sru        if (ptype != V_ASN1_SEQUENCE)
238151497Sru            goto decerr;
239151497Sru    }
240151497Sru
241114402Sru    pstr = pval;
242151497Sru    pm = pstr->data;
243114402Sru    pmlen = pstr->length;
244151497Sru    if (!(dsa = d2i_DSAparams(NULL, &pm, pmlen)))
245114402Sru        goto decerr;
246151497Sru    /* We have parameters now set private key */
247114402Sru    if (!(dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL))) {
248114402Sru        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
249114402Sru        goto dsaerr;
250114402Sru    }
251114402Sru    /* Calculate public key */
252114402Sru    if (!(dsa->pub_key = BN_new())) {
253114402Sru        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
254151497Sru        goto dsaerr;
255151497Sru    }
256151497Sru    if (!(ctx = BN_CTX_new())) {
257151497Sru        DSAerr(DSA_F_DSA_PRIV_DECODE, ERR_R_MALLOC_FAILURE);
258151497Sru        goto dsaerr;
259114402Sru    }
260114402Sru
261114402Sru    if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) {
262114402Sru        DSAerr(DSA_F_DSA_PRIV_DECODE, DSA_R_BN_ERROR);
263114402Sru        goto dsaerr;
264151497Sru    }
265114402Sru
266151497Sru    EVP_PKEY_assign_DSA(pkey, dsa);
267114402Sru
268151497Sru    ret = 1;
269151497Sru    goto done;
270151497Sru
271151497Sru decerr:
272114402Sru    DSAerr(DSA_F_DSA_PRIV_DECODE, EVP_R_DECODE_ERROR);
273151497Sru dsaerr:
274114402Sru    DSA_free(dsa);
275151497Sru done:
276114402Sru    BN_CTX_free(ctx);
277114402Sru    if (ndsa)
278114402Sru        sk_ASN1_TYPE_pop_free(ndsa, ASN1_TYPE_free);
279114402Sru    else
280114402Sru        ASN1_STRING_clear_free(privkey);
281114402Sru    return ret;
282114402Sru}
283114402Sru
284114402Srustatic int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey)
285114402Sru{
286151497Sru    ASN1_STRING *params = NULL;
287114402Sru    ASN1_INTEGER *prkey = NULL;
288151497Sru    unsigned char *dp = NULL;
289114402Sru    int dplen;
290114402Sru
291151497Sru    if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) {
292114402Sru        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_MISSING_PARAMETERS);
293114402Sru        goto err;
294114402Sru    }
295151497Sru
296151497Sru    params = ASN1_STRING_new();
297114402Sru
298114402Sru    if (!params) {
299151497Sru        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
300151497Sru        goto err;
301151497Sru    }
302151497Sru
303151497Sru    params->length = i2d_DSAparams(pkey->pkey.dsa, &params->data);
304114402Sru    if (params->length <= 0) {
305114402Sru        DSAerr(DSA_F_DSA_PRIV_ENCODE, ERR_R_MALLOC_FAILURE);
306151497Sru        goto err;
307114402Sru    }
308114402Sru    params->type = V_ASN1_SEQUENCE;
309114402Sru
310114402Sru    /* Get private key into integer */
311114402Sru    prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL);
312114402Sru
313114402Sru    if (!prkey) {
314151497Sru        DSAerr(DSA_F_DSA_PRIV_ENCODE, DSA_R_BN_ERROR);
315151497Sru        goto err;
316151497Sru    }
317151497Sru
318151497Sru    dplen = i2d_ASN1_INTEGER(prkey, &dp);
319151497Sru
320151497Sru    ASN1_STRING_clear_free(prkey);
321151497Sru
322151497Sru    if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0,
323151497Sru                         V_ASN1_SEQUENCE, params, dp, dplen))
324151497Sru        goto err;
325151497Sru
326151497Sru    return 1;
327151497Sru
328114402Sru err:
329114402Sru    if (dp != NULL)
330151497Sru        OPENSSL_free(dp);
331114402Sru    if (params != NULL)
332114402Sru        ASN1_STRING_free(params);
333151497Sru    if (prkey != NULL)
334151497Sru        ASN1_STRING_clear_free(prkey);
335151497Sru    return 0;
336114402Sru}
337151497Sru
338151497Srustatic int int_dsa_size(const EVP_PKEY *pkey)
339114402Sru{
340114402Sru    return (DSA_size(pkey->pkey.dsa));
341114402Sru}
342114402Sru
343151497Srustatic int dsa_bits(const EVP_PKEY *pkey)
344114402Sru{
345114402Sru    return BN_num_bits(pkey->pkey.dsa->p);
346151497Sru}
347114402Sru
348114402Srustatic int dsa_missing_parameters(const EVP_PKEY *pkey)
349114402Sru{
350151497Sru    DSA *dsa;
351151497Sru    dsa = pkey->pkey.dsa;
352151497Sru    if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
353151497Sru        return 1;
354151497Sru    return 0;
355114402Sru}
356151497Sru
357151497Srustatic int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from)
358151497Sru{
359151497Sru    BIGNUM *a;
360151497Sru
36175584Sru    if ((a = BN_dup(from->pkey.dsa->p)) == NULL)
36275584Sru        return 0;
36375584Sru    if (to->pkey.dsa->p != NULL)
36475584Sru        BN_free(to->pkey.dsa->p);
36575584Sru    to->pkey.dsa->p = a;
36675584Sru
36775584Sru    if ((a = BN_dup(from->pkey.dsa->q)) == NULL)
368151497Sru        return 0;
369151497Sru    if (to->pkey.dsa->q != NULL)
370151497Sru        BN_free(to->pkey.dsa->q);
371151497Sru    to->pkey.dsa->q = a;
372151497Sru
373151497Sru    if ((a = BN_dup(from->pkey.dsa->g)) == NULL)
374151497Sru        return 0;
375151497Sru    if (to->pkey.dsa->g != NULL)
376151497Sru        BN_free(to->pkey.dsa->g);
37775584Sru    to->pkey.dsa->g = a;
378151497Sru    return 1;
379151497Sru}
380151497Sru
381151497Srustatic int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b)
382151497Sru{
383151497Sru    if (BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) ||
384114402Sru        BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) ||
385114402Sru        BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g))
386114402Sru        return 0;
38775584Sru    else
388151497Sru        return 1;
389114402Sru}
390114402Sru
391114402Srustatic int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b)
392114402Sru{
393114402Sru    if (BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) != 0)
394114402Sru        return 0;
395114402Sru    else
396114402Sru        return 1;
397114402Sru}
398114402Sru
399114402Srustatic void int_dsa_free(EVP_PKEY *pkey)
400114402Sru{
401114402Sru    DSA_free(pkey->pkey.dsa);
402114402Sru}
403114402Sru
404114402Srustatic void update_buflen(const BIGNUM *b, size_t *pbuflen)
405114402Sru{
406114402Sru    size_t i;
407114402Sru    if (!b)
408114402Sru        return;
409114402Sru    if (*pbuflen < (i = (size_t)BN_num_bytes(b)))
41075584Sru        *pbuflen = i;
411114402Sru}
412114402Sru
413114402Srustatic int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype)
414114402Sru{
415114402Sru    unsigned char *m = NULL;
416114402Sru    int ret = 0;
417114402Sru    size_t buf_len = 0;
418114402Sru    const char *ktype = NULL;
41975584Sru
420114402Sru    const BIGNUM *priv_key, *pub_key;
421114402Sru
422114402Sru    if (ptype == 2)
423114402Sru        priv_key = x->priv_key;
424114402Sru    else
425114402Sru        priv_key = NULL;
426114402Sru
427114402Sru    if (ptype > 0)
428114402Sru        pub_key = x->pub_key;
429114402Sru    else
430114402Sru        pub_key = NULL;
431114402Sru
432114402Sru    if (ptype == 2)
433114402Sru        ktype = "Private-Key";
434114402Sru    else if (ptype == 1)
435114402Sru        ktype = "Public-Key";
43675584Sru    else
43775584Sru        ktype = "DSA-Parameters";
43875584Sru
43975584Sru    update_buflen(x->p, &buf_len);
44075584Sru    update_buflen(x->q, &buf_len);
44175584Sru    update_buflen(x->g, &buf_len);
44275584Sru    update_buflen(priv_key, &buf_len);
443151497Sru    update_buflen(pub_key, &buf_len);
44475584Sru
445114402Sru    m = (unsigned char *)OPENSSL_malloc(buf_len + 10);
446114402Sru    if (m == NULL) {
447151497Sru        DSAerr(DSA_F_DO_DSA_PRINT, ERR_R_MALLOC_FAILURE);
44875584Sru        goto err;
44975584Sru    }
45075584Sru
45175584Sru    if (priv_key) {
45275584Sru        if (!BIO_indent(bp, off, 128))
45375584Sru            goto err;
45475584Sru        if (BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p))
45575584Sru            <= 0)
456114402Sru            goto err;
457114402Sru    }
458114402Sru
459114402Sru    if (!ASN1_bn_print(bp, "priv:", priv_key, m, off))
460114402Sru        goto err;
461114402Sru    if (!ASN1_bn_print(bp, "pub: ", pub_key, m, off))
462114402Sru        goto err;
463114402Sru    if (!ASN1_bn_print(bp, "P:   ", x->p, m, off))
464114402Sru        goto err;
465114402Sru    if (!ASN1_bn_print(bp, "Q:   ", x->q, m, off))
466114402Sru        goto err;
467114402Sru    if (!ASN1_bn_print(bp, "G:   ", x->g, m, off))
46875584Sru        goto err;
469114402Sru    ret = 1;
470114402Sru err:
471114402Sru    if (m != NULL)
472114402Sru        OPENSSL_free(m);
47375584Sru    return (ret);
47475584Sru}
47575584Sru
47675584Srustatic int dsa_param_decode(EVP_PKEY *pkey,
477114402Sru                            const unsigned char **pder, int derlen)
478114402Sru{
479114402Sru    DSA *dsa;
480114402Sru    if (!(dsa = d2i_DSAparams(NULL, pder, derlen))) {
48175584Sru        DSAerr(DSA_F_DSA_PARAM_DECODE, ERR_R_DSA_LIB);
48275584Sru        return 0;
483114402Sru    }
484114402Sru    EVP_PKEY_assign_DSA(pkey, dsa);
48575584Sru    return 1;
486114402Sru}
487114402Sru
488114402Srustatic int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder)
489114402Sru{
490114402Sru    return i2d_DSAparams(pkey->pkey.dsa, pder);
49175584Sru}
492114402Sru
493114402Srustatic int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent,
494114402Sru                           ASN1_PCTX *ctx)
495114402Sru{
496114402Sru    return do_dsa_print(bp, pkey->pkey.dsa, indent, 0);
497114402Sru}
498114402Sru
499114402Srustatic int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent,
500114402Sru                         ASN1_PCTX *ctx)
501114402Sru{
502114402Sru    return do_dsa_print(bp, pkey->pkey.dsa, indent, 1);
503114402Sru}
50475584Sru
50575584Srustatic int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent,
50675584Sru                          ASN1_PCTX *ctx)
507114402Sru{
50875584Sru    return do_dsa_print(bp, pkey->pkey.dsa, indent, 2);
50975584Sru}
51075584Sru
51175584Srustatic int old_dsa_priv_decode(EVP_PKEY *pkey,
51275584Sru                               const unsigned char **pder, int derlen)
51375584Sru{
51475584Sru    DSA *dsa;
51575584Sru    if (!(dsa = d2i_DSAPrivateKey(NULL, pder, derlen))) {
51675584Sru        DSAerr(DSA_F_OLD_DSA_PRIV_DECODE, ERR_R_DSA_LIB);
51775584Sru        return 0;
51875584Sru    }
51975584Sru    EVP_PKEY_assign_DSA(pkey, dsa);
52075584Sru    return 1;
52175584Sru}
52275584Sru
52375584Srustatic int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder)
52475584Sru{
52575584Sru    return i2d_DSAPrivateKey(pkey->pkey.dsa, pder);
52675584Sru}
52775584Sru
528114402Srustatic int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg,
52975584Sru                         const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx)
53075584Sru{
53175584Sru    DSA_SIG *dsa_sig;
53275584Sru    const unsigned char *p;
53375584Sru    if (!sig) {
53475584Sru        if (BIO_puts(bp, "\n") <= 0)
53575584Sru            return 0;
53675584Sru        else
53775584Sru            return 1;
53875584Sru    }
53975584Sru    p = sig->data;
54075584Sru    dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length);
54175584Sru    if (dsa_sig) {
54275584Sru        int rv = 0;
54375584Sru        size_t buf_len = 0;
54475584Sru        unsigned char *m = NULL;
54575584Sru        update_buflen(dsa_sig->r, &buf_len);
546114402Sru        update_buflen(dsa_sig->s, &buf_len);
54775584Sru        m = OPENSSL_malloc(buf_len + 10);
54875584Sru        if (m == NULL) {
54975584Sru            DSAerr(DSA_F_DSA_SIG_PRINT, ERR_R_MALLOC_FAILURE);
55075584Sru            goto err;
55175584Sru        }
55275584Sru
553114402Sru        if (BIO_write(bp, "\n", 1) != 1)
55475584Sru            goto err;
55575584Sru
55675584Sru        if (!ASN1_bn_print(bp, "r:   ", dsa_sig->r, m, indent))
55775584Sru            goto err;
55875584Sru        if (!ASN1_bn_print(bp, "s:   ", dsa_sig->s, m, indent))
55975584Sru            goto err;
56075584Sru        rv = 1;
56175584Sru err:
562151497Sru        if (m)
56375584Sru            OPENSSL_free(m);
56475584Sru        DSA_SIG_free(dsa_sig);
56575584Sru        return rv;
56675584Sru    }
567151497Sru    return X509_signature_dump(bp, sig, indent);
56875584Sru}
569114402Sru
570114402Srustatic int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2)
57175584Sru{
572151497Sru    switch (op) {
57375584Sru    case ASN1_PKEY_CTRL_PKCS7_SIGN:
57475584Sru        if (arg1 == 0) {
575151497Sru            int snid, hnid;
57675584Sru            X509_ALGOR *alg1, *alg2;
57775584Sru            PKCS7_SIGNER_INFO_get0_algs(arg2, NULL, &alg1, &alg2);
57875584Sru            if (alg1 == NULL || alg1->algorithm == NULL)
57975584Sru                return -1;
580            hnid = OBJ_obj2nid(alg1->algorithm);
581            if (hnid == NID_undef)
582                return -1;
583            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
584                return -1;
585            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
586        }
587        return 1;
588#ifndef OPENSSL_NO_CMS
589    case ASN1_PKEY_CTRL_CMS_SIGN:
590        if (arg1 == 0) {
591            int snid, hnid;
592            X509_ALGOR *alg1, *alg2;
593            CMS_SignerInfo_get0_algs(arg2, NULL, NULL, &alg1, &alg2);
594            if (alg1 == NULL || alg1->algorithm == NULL)
595                return -1;
596            hnid = OBJ_obj2nid(alg1->algorithm);
597            if (hnid == NID_undef)
598                return -1;
599            if (!OBJ_find_sigid_by_algs(&snid, hnid, EVP_PKEY_id(pkey)))
600                return -1;
601            X509_ALGOR_set0(alg2, OBJ_nid2obj(snid), V_ASN1_UNDEF, 0);
602        }
603        return 1;
604#endif
605
606    case ASN1_PKEY_CTRL_DEFAULT_MD_NID:
607        *(int *)arg2 = NID_sha1;
608        return 2;
609
610    default:
611        return -2;
612
613    }
614
615}
616
617/* NB these are sorted in pkey_id order, lowest first */
618
619const EVP_PKEY_ASN1_METHOD dsa_asn1_meths[] = {
620
621    {
622     EVP_PKEY_DSA2,
623     EVP_PKEY_DSA,
624     ASN1_PKEY_ALIAS},
625
626    {
627     EVP_PKEY_DSA1,
628     EVP_PKEY_DSA,
629     ASN1_PKEY_ALIAS},
630
631    {
632     EVP_PKEY_DSA4,
633     EVP_PKEY_DSA,
634     ASN1_PKEY_ALIAS},
635
636    {
637     EVP_PKEY_DSA3,
638     EVP_PKEY_DSA,
639     ASN1_PKEY_ALIAS},
640
641    {
642     EVP_PKEY_DSA,
643     EVP_PKEY_DSA,
644     0,
645
646     "DSA",
647     "OpenSSL DSA method",
648
649     dsa_pub_decode,
650     dsa_pub_encode,
651     dsa_pub_cmp,
652     dsa_pub_print,
653
654     dsa_priv_decode,
655     dsa_priv_encode,
656     dsa_priv_print,
657
658     int_dsa_size,
659     dsa_bits,
660
661     dsa_param_decode,
662     dsa_param_encode,
663     dsa_missing_parameters,
664     dsa_copy_parameters,
665     dsa_cmp_parameters,
666     dsa_param_print,
667     dsa_sig_print,
668
669     int_dsa_free,
670     dsa_pkey_ctrl,
671     old_dsa_priv_decode,
672     old_dsa_priv_encode}
673};
674