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, ¶ms->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