1/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project 2 * 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#include <openssl/evp.h> 57 58#include <openssl/asn1.h> 59#include <openssl/asn1t.h> 60#include <openssl/digest.h> 61#include <openssl/dsa.h> 62#include <openssl/err.h> 63#include <openssl/mem.h> 64#include <openssl/obj.h> 65#include <openssl/x509.h> 66 67#include "../dsa/internal.h" 68#include "internal.h" 69 70 71static int dsa_pub_decode(EVP_PKEY *pkey, X509_PUBKEY *pubkey) { 72 const uint8_t *p, *pm; 73 int pklen, pmlen; 74 int ptype; 75 void *pval; 76 ASN1_STRING *pstr; 77 X509_ALGOR *palg; 78 ASN1_INTEGER *public_key = NULL; 79 80 DSA *dsa = NULL; 81 82 if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) { 83 return 0; 84 } 85 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 86 87 if (ptype == V_ASN1_SEQUENCE) { 88 pstr = pval; 89 pm = pstr->data; 90 pmlen = pstr->length; 91 92 dsa = d2i_DSAparams(NULL, &pm, pmlen); 93 if (dsa == NULL) { 94 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 95 goto err; 96 } 97 } else if (ptype == V_ASN1_NULL || ptype == V_ASN1_UNDEF) { 98 dsa = DSA_new(); 99 if (dsa == NULL) { 100 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 101 goto err; 102 } 103 } else { 104 OPENSSL_PUT_ERROR(EVP, EVP_R_PARAMETER_ENCODING_ERROR); 105 goto err; 106 } 107 108 public_key = d2i_ASN1_INTEGER(NULL, &p, pklen); 109 if (public_key == NULL) { 110 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 111 goto err; 112 } 113 114 dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL); 115 if (dsa->pub_key == NULL) { 116 OPENSSL_PUT_ERROR(EVP, EVP_R_BN_DECODE_ERROR); 117 goto err; 118 } 119 120 ASN1_INTEGER_free(public_key); 121 EVP_PKEY_assign_DSA(pkey, dsa); 122 return 1; 123 124err: 125 ASN1_INTEGER_free(public_key); 126 DSA_free(dsa); 127 return 0; 128} 129 130static int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) { 131 DSA *dsa; 132 ASN1_STRING *pval = NULL; 133 uint8_t *penc = NULL; 134 int penclen; 135 136 dsa = pkey->pkey.dsa; 137 dsa->write_params = 0; 138 139 int ptype; 140 if (dsa->p && dsa->q && dsa->g) { 141 pval = ASN1_STRING_new(); 142 if (!pval) { 143 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 144 goto err; 145 } 146 pval->length = i2d_DSAparams(dsa, &pval->data); 147 if (pval->length <= 0) { 148 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 149 goto err; 150 } 151 ptype = V_ASN1_SEQUENCE; 152 } else { 153 ptype = V_ASN1_UNDEF; 154 } 155 156 penclen = i2d_DSAPublicKey(dsa, &penc); 157 if (penclen <= 0) { 158 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 159 goto err; 160 } 161 162 if (X509_PUBKEY_set0_param(pk, OBJ_nid2obj(EVP_PKEY_DSA), ptype, pval, 163 penc, penclen)) { 164 return 1; 165 } 166 167err: 168 OPENSSL_free(penc); 169 ASN1_STRING_free(pval); 170 171 return 0; 172} 173 174static int dsa_priv_decode(EVP_PKEY *pkey, PKCS8_PRIV_KEY_INFO *p8) { 175 const uint8_t *p, *pm; 176 int pklen, pmlen; 177 int ptype; 178 void *pval; 179 ASN1_STRING *pstr; 180 X509_ALGOR *palg; 181 ASN1_INTEGER *privkey = NULL; 182 BN_CTX *ctx = NULL; 183 184 /* In PKCS#8 DSA: you just get a private key integer and parameters in the 185 * AlgorithmIdentifier the pubkey must be recalculated. */ 186 187 DSA *dsa = NULL; 188 189 if (!PKCS8_pkey_get0(NULL, &p, &pklen, &palg, p8)) { 190 return 0; 191 } 192 privkey = d2i_ASN1_INTEGER(NULL, &p, pklen); 193 if (privkey == NULL || privkey->type == V_ASN1_NEG_INTEGER) { 194 goto decerr; 195 } 196 197 X509_ALGOR_get0(NULL, &ptype, &pval, palg); 198 if (ptype != V_ASN1_SEQUENCE) { 199 goto decerr; 200 } 201 pstr = pval; 202 pm = pstr->data; 203 pmlen = pstr->length; 204 dsa = d2i_DSAparams(NULL, &pm, pmlen); 205 if (dsa == NULL) { 206 goto decerr; 207 } 208 /* We have parameters. Now set private key */ 209 dsa->priv_key = ASN1_INTEGER_to_BN(privkey, NULL); 210 if (dsa->priv_key == NULL) { 211 OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN); 212 goto dsaerr; 213 } 214 /* Calculate public key. */ 215 dsa->pub_key = BN_new(); 216 if (dsa->pub_key == NULL) { 217 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 218 goto dsaerr; 219 } 220 ctx = BN_CTX_new(); 221 if (ctx == NULL) { 222 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 223 goto dsaerr; 224 } 225 226 if (!BN_mod_exp(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, ctx)) { 227 OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN); 228 goto dsaerr; 229 } 230 231 EVP_PKEY_assign_DSA(pkey, dsa); 232 BN_CTX_free(ctx); 233 ASN1_INTEGER_free(privkey); 234 235 return 1; 236 237decerr: 238 OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); 239 240dsaerr: 241 BN_CTX_free(ctx); 242 ASN1_INTEGER_free(privkey); 243 DSA_free(dsa); 244 return 0; 245} 246 247static int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) { 248 ASN1_STRING *params = NULL; 249 ASN1_INTEGER *prkey = NULL; 250 uint8_t *dp = NULL; 251 int dplen; 252 253 if (!pkey->pkey.dsa || !pkey->pkey.dsa->priv_key) { 254 OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); 255 goto err; 256 } 257 258 params = ASN1_STRING_new(); 259 if (!params) { 260 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 261 goto err; 262 } 263 264 params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); 265 if (params->length <= 0) { 266 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 267 goto err; 268 } 269 params->type = V_ASN1_SEQUENCE; 270 271 /* Get private key into integer. */ 272 prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); 273 274 if (!prkey) { 275 OPENSSL_PUT_ERROR(EVP, ERR_LIB_BN); 276 goto err; 277 } 278 279 dplen = i2d_ASN1_INTEGER(prkey, &dp); 280 281 ASN1_INTEGER_free(prkey); 282 prkey = NULL; 283 284 if (!PKCS8_pkey_set0(p8, (ASN1_OBJECT *)OBJ_nid2obj(NID_dsa), 0, 285 V_ASN1_SEQUENCE, params, dp, dplen)) { 286 goto err; 287 } 288 289 return 1; 290 291err: 292 OPENSSL_free(dp); 293 ASN1_STRING_free(params); 294 ASN1_INTEGER_free(prkey); 295 return 0; 296} 297 298static int int_dsa_size(const EVP_PKEY *pkey) { 299 return DSA_size(pkey->pkey.dsa); 300} 301 302static int dsa_bits(const EVP_PKEY *pkey) { 303 return BN_num_bits(pkey->pkey.dsa->p); 304} 305 306static int dsa_missing_parameters(const EVP_PKEY *pkey) { 307 DSA *dsa; 308 dsa = pkey->pkey.dsa; 309 if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { 310 return 1; 311 } 312 return 0; 313} 314 315static int dup_bn_into(BIGNUM **out, BIGNUM *src) { 316 BIGNUM *a; 317 318 a = BN_dup(src); 319 if (a == NULL) { 320 return 0; 321 } 322 BN_free(*out); 323 *out = a; 324 325 return 1; 326} 327 328static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { 329 if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) || 330 !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) || 331 !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) { 332 return 0; 333 } 334 335 return 1; 336} 337 338static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { 339 return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 && 340 BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 && 341 BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0; 342} 343 344static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { 345 return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0; 346} 347 348static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); } 349 350static void update_buflen(const BIGNUM *b, size_t *pbuflen) { 351 size_t i; 352 353 if (!b) { 354 return; 355 } 356 i = BN_num_bytes(b); 357 if (*pbuflen < i) { 358 *pbuflen = i; 359 } 360} 361 362static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { 363 uint8_t *m = NULL; 364 int ret = 0; 365 size_t buf_len = 0; 366 const char *ktype = NULL; 367 368 const BIGNUM *priv_key, *pub_key; 369 370 priv_key = NULL; 371 if (ptype == 2) { 372 priv_key = x->priv_key; 373 } 374 375 pub_key = NULL; 376 if (ptype > 0) { 377 pub_key = x->pub_key; 378 } 379 380 ktype = "DSA-Parameters"; 381 if (ptype == 2) { 382 ktype = "Private-Key"; 383 } else if (ptype == 1) { 384 ktype = "Public-Key"; 385 } 386 387 update_buflen(x->p, &buf_len); 388 update_buflen(x->q, &buf_len); 389 update_buflen(x->g, &buf_len); 390 update_buflen(priv_key, &buf_len); 391 update_buflen(pub_key, &buf_len); 392 393 m = (uint8_t *)OPENSSL_malloc(buf_len + 10); 394 if (m == NULL) { 395 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 396 goto err; 397 } 398 399 if (priv_key) { 400 if (!BIO_indent(bp, off, 128) || 401 BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) { 402 goto err; 403 } 404 } 405 406 if (!ASN1_bn_print(bp, "priv:", priv_key, m, off) || 407 !ASN1_bn_print(bp, "pub: ", pub_key, m, off) || 408 !ASN1_bn_print(bp, "P: ", x->p, m, off) || 409 !ASN1_bn_print(bp, "Q: ", x->q, m, off) || 410 !ASN1_bn_print(bp, "G: ", x->g, m, off)) { 411 goto err; 412 } 413 ret = 1; 414 415err: 416 OPENSSL_free(m); 417 return ret; 418} 419 420static int dsa_param_decode(EVP_PKEY *pkey, const uint8_t **pder, int derlen) { 421 DSA *dsa; 422 dsa = d2i_DSAparams(NULL, pder, derlen); 423 if (dsa == NULL) { 424 OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB); 425 return 0; 426 } 427 EVP_PKEY_assign_DSA(pkey, dsa); 428 return 1; 429} 430 431static int dsa_param_encode(const EVP_PKEY *pkey, uint8_t **pder) { 432 return i2d_DSAparams(pkey->pkey.dsa, pder); 433} 434 435static int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, 436 ASN1_PCTX *ctx) { 437 return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); 438} 439 440static int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 441 ASN1_PCTX *ctx) { 442 return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); 443} 444 445static int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 446 ASN1_PCTX *ctx) { 447 return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); 448} 449 450static int old_dsa_priv_decode(EVP_PKEY *pkey, const uint8_t **pder, 451 int derlen) { 452 DSA *dsa; 453 dsa = d2i_DSAPrivateKey(NULL, pder, derlen); 454 if (dsa == NULL) { 455 OPENSSL_PUT_ERROR(EVP, ERR_R_DSA_LIB); 456 return 0; 457 } 458 EVP_PKEY_assign_DSA(pkey, dsa); 459 return 1; 460} 461 462static int old_dsa_priv_encode(const EVP_PKEY *pkey, uint8_t **pder) { 463 return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); 464} 465 466static int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, 467 const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) { 468 DSA_SIG *dsa_sig; 469 const uint8_t *p; 470 471 if (!sig) { 472 return BIO_puts(bp, "\n") > 0; 473 } 474 475 p = sig->data; 476 dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); 477 if (dsa_sig == NULL) { 478 return X509_signature_dump(bp, sig, indent); 479 } 480 481 int rv = 0; 482 size_t buf_len = 0; 483 uint8_t *m = NULL; 484 485 update_buflen(dsa_sig->r, &buf_len); 486 update_buflen(dsa_sig->s, &buf_len); 487 m = OPENSSL_malloc(buf_len + 10); 488 if (m == NULL) { 489 OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); 490 goto err; 491 } 492 493 if (BIO_write(bp, "\n", 1) != 1 || 494 !ASN1_bn_print(bp, "r: ", dsa_sig->r, m, indent) || 495 !ASN1_bn_print(bp, "s: ", dsa_sig->s, m, indent)) { 496 goto err; 497 } 498 rv = 1; 499 500err: 501 OPENSSL_free(m); 502 DSA_SIG_free(dsa_sig); 503 return rv; 504} 505 506const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { 507 EVP_PKEY_DSA, 508 EVP_PKEY_DSA, 509 0, 510 511 "DSA", 512 513 dsa_pub_decode, 514 dsa_pub_encode, 515 dsa_pub_cmp, 516 dsa_pub_print, 517 518 dsa_priv_decode, 519 dsa_priv_encode, 520 dsa_priv_print, 521 522 NULL /* pkey_opaque */, 523 NULL /* pkey_supports_digest */, 524 525 int_dsa_size, 526 dsa_bits, 527 528 dsa_param_decode, 529 dsa_param_encode, 530 dsa_missing_parameters, 531 dsa_copy_parameters, 532 dsa_cmp_parameters, 533 dsa_param_print, 534 dsa_sig_print, 535 536 int_dsa_free, 537 old_dsa_priv_decode, 538 old_dsa_priv_encode, 539 540 NULL /* digest_verify_init_from_algorithm */, 541 NULL /* digest_sign_algorithm */, 542}; 543