1e1051a39Sopenharmony_ci/* 2e1051a39Sopenharmony_ci * Copyright 2006-2022 The OpenSSL Project Authors. All Rights Reserved. 3e1051a39Sopenharmony_ci * 4e1051a39Sopenharmony_ci * Licensed under the Apache License 2.0 (the "License"). You may not use 5e1051a39Sopenharmony_ci * this file except in compliance with the License. You can obtain a copy 6e1051a39Sopenharmony_ci * in the file LICENSE in the source distribution or at 7e1051a39Sopenharmony_ci * https://www.openssl.org/source/license.html 8e1051a39Sopenharmony_ci */ 9e1051a39Sopenharmony_ci 10e1051a39Sopenharmony_ci/* 11e1051a39Sopenharmony_ci * DSA low level APIs are deprecated for public use, but still ok for 12e1051a39Sopenharmony_ci * internal use. 13e1051a39Sopenharmony_ci */ 14e1051a39Sopenharmony_ci#include "internal/deprecated.h" 15e1051a39Sopenharmony_ci 16e1051a39Sopenharmony_ci#include <stdio.h> 17e1051a39Sopenharmony_ci#include <openssl/x509.h> 18e1051a39Sopenharmony_ci#include <openssl/asn1.h> 19e1051a39Sopenharmony_ci#include <openssl/bn.h> 20e1051a39Sopenharmony_ci#include <openssl/core_names.h> 21e1051a39Sopenharmony_ci#include <openssl/param_build.h> 22e1051a39Sopenharmony_ci#include "internal/cryptlib.h" 23e1051a39Sopenharmony_ci#include "crypto/asn1.h" 24e1051a39Sopenharmony_ci#include "crypto/dsa.h" 25e1051a39Sopenharmony_ci#include "crypto/evp.h" 26e1051a39Sopenharmony_ci#include "internal/ffc.h" 27e1051a39Sopenharmony_ci#include "dsa_local.h" 28e1051a39Sopenharmony_ci 29e1051a39Sopenharmony_cistatic int dsa_pub_decode(EVP_PKEY *pkey, const X509_PUBKEY *pubkey) 30e1051a39Sopenharmony_ci{ 31e1051a39Sopenharmony_ci const unsigned char *p, *pm; 32e1051a39Sopenharmony_ci int pklen, pmlen; 33e1051a39Sopenharmony_ci int ptype; 34e1051a39Sopenharmony_ci const void *pval; 35e1051a39Sopenharmony_ci const ASN1_STRING *pstr; 36e1051a39Sopenharmony_ci X509_ALGOR *palg; 37e1051a39Sopenharmony_ci ASN1_INTEGER *public_key = NULL; 38e1051a39Sopenharmony_ci 39e1051a39Sopenharmony_ci DSA *dsa = NULL; 40e1051a39Sopenharmony_ci 41e1051a39Sopenharmony_ci if (!X509_PUBKEY_get0_param(NULL, &p, &pklen, &palg, pubkey)) 42e1051a39Sopenharmony_ci return 0; 43e1051a39Sopenharmony_ci X509_ALGOR_get0(NULL, &ptype, &pval, palg); 44e1051a39Sopenharmony_ci 45e1051a39Sopenharmony_ci if (ptype == V_ASN1_SEQUENCE) { 46e1051a39Sopenharmony_ci pstr = pval; 47e1051a39Sopenharmony_ci pm = pstr->data; 48e1051a39Sopenharmony_ci pmlen = pstr->length; 49e1051a39Sopenharmony_ci 50e1051a39Sopenharmony_ci if ((dsa = d2i_DSAparams(NULL, &pm, pmlen)) == NULL) { 51e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR); 52e1051a39Sopenharmony_ci goto err; 53e1051a39Sopenharmony_ci } 54e1051a39Sopenharmony_ci 55e1051a39Sopenharmony_ci } else if ((ptype == V_ASN1_NULL) || (ptype == V_ASN1_UNDEF)) { 56e1051a39Sopenharmony_ci if ((dsa = DSA_new()) == NULL) { 57e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 58e1051a39Sopenharmony_ci goto err; 59e1051a39Sopenharmony_ci } 60e1051a39Sopenharmony_ci } else { 61e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, DSA_R_PARAMETER_ENCODING_ERROR); 62e1051a39Sopenharmony_ci goto err; 63e1051a39Sopenharmony_ci } 64e1051a39Sopenharmony_ci 65e1051a39Sopenharmony_ci if ((public_key = d2i_ASN1_INTEGER(NULL, &p, pklen)) == NULL) { 66e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, DSA_R_DECODE_ERROR); 67e1051a39Sopenharmony_ci goto err; 68e1051a39Sopenharmony_ci } 69e1051a39Sopenharmony_ci 70e1051a39Sopenharmony_ci if ((dsa->pub_key = ASN1_INTEGER_to_BN(public_key, NULL)) == NULL) { 71e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, DSA_R_BN_DECODE_ERROR); 72e1051a39Sopenharmony_ci goto err; 73e1051a39Sopenharmony_ci } 74e1051a39Sopenharmony_ci 75e1051a39Sopenharmony_ci dsa->dirty_cnt++; 76e1051a39Sopenharmony_ci ASN1_INTEGER_free(public_key); 77e1051a39Sopenharmony_ci EVP_PKEY_assign_DSA(pkey, dsa); 78e1051a39Sopenharmony_ci return 1; 79e1051a39Sopenharmony_ci 80e1051a39Sopenharmony_ci err: 81e1051a39Sopenharmony_ci ASN1_INTEGER_free(public_key); 82e1051a39Sopenharmony_ci DSA_free(dsa); 83e1051a39Sopenharmony_ci return 0; 84e1051a39Sopenharmony_ci 85e1051a39Sopenharmony_ci} 86e1051a39Sopenharmony_ci 87e1051a39Sopenharmony_cistatic int dsa_pub_encode(X509_PUBKEY *pk, const EVP_PKEY *pkey) 88e1051a39Sopenharmony_ci{ 89e1051a39Sopenharmony_ci DSA *dsa; 90e1051a39Sopenharmony_ci int ptype; 91e1051a39Sopenharmony_ci unsigned char *penc = NULL; 92e1051a39Sopenharmony_ci int penclen; 93e1051a39Sopenharmony_ci ASN1_STRING *str = NULL; 94e1051a39Sopenharmony_ci ASN1_INTEGER *pubint = NULL; 95e1051a39Sopenharmony_ci ASN1_OBJECT *aobj; 96e1051a39Sopenharmony_ci 97e1051a39Sopenharmony_ci dsa = pkey->pkey.dsa; 98e1051a39Sopenharmony_ci if (pkey->save_parameters 99e1051a39Sopenharmony_ci && dsa->params.p != NULL 100e1051a39Sopenharmony_ci && dsa->params.q != NULL 101e1051a39Sopenharmony_ci && dsa->params.g != NULL) { 102e1051a39Sopenharmony_ci str = ASN1_STRING_new(); 103e1051a39Sopenharmony_ci if (str == NULL) { 104e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 105e1051a39Sopenharmony_ci goto err; 106e1051a39Sopenharmony_ci } 107e1051a39Sopenharmony_ci str->length = i2d_DSAparams(dsa, &str->data); 108e1051a39Sopenharmony_ci if (str->length <= 0) { 109e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 110e1051a39Sopenharmony_ci goto err; 111e1051a39Sopenharmony_ci } 112e1051a39Sopenharmony_ci ptype = V_ASN1_SEQUENCE; 113e1051a39Sopenharmony_ci } else 114e1051a39Sopenharmony_ci ptype = V_ASN1_UNDEF; 115e1051a39Sopenharmony_ci 116e1051a39Sopenharmony_ci pubint = BN_to_ASN1_INTEGER(dsa->pub_key, NULL); 117e1051a39Sopenharmony_ci 118e1051a39Sopenharmony_ci if (pubint == NULL) { 119e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 120e1051a39Sopenharmony_ci goto err; 121e1051a39Sopenharmony_ci } 122e1051a39Sopenharmony_ci 123e1051a39Sopenharmony_ci penclen = i2d_ASN1_INTEGER(pubint, &penc); 124e1051a39Sopenharmony_ci ASN1_INTEGER_free(pubint); 125e1051a39Sopenharmony_ci 126e1051a39Sopenharmony_ci if (penclen <= 0) { 127e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 128e1051a39Sopenharmony_ci goto err; 129e1051a39Sopenharmony_ci } 130e1051a39Sopenharmony_ci 131e1051a39Sopenharmony_ci aobj = OBJ_nid2obj(EVP_PKEY_DSA); 132e1051a39Sopenharmony_ci if (aobj == NULL) 133e1051a39Sopenharmony_ci goto err; 134e1051a39Sopenharmony_ci 135e1051a39Sopenharmony_ci if (X509_PUBKEY_set0_param(pk, aobj, ptype, str, penc, penclen)) 136e1051a39Sopenharmony_ci return 1; 137e1051a39Sopenharmony_ci 138e1051a39Sopenharmony_ci err: 139e1051a39Sopenharmony_ci OPENSSL_free(penc); 140e1051a39Sopenharmony_ci ASN1_STRING_free(str); 141e1051a39Sopenharmony_ci 142e1051a39Sopenharmony_ci return 0; 143e1051a39Sopenharmony_ci} 144e1051a39Sopenharmony_ci 145e1051a39Sopenharmony_ci/* 146e1051a39Sopenharmony_ci * In PKCS#8 DSA: you just get a private key integer and parameters in the 147e1051a39Sopenharmony_ci * AlgorithmIdentifier the pubkey must be recalculated. 148e1051a39Sopenharmony_ci */ 149e1051a39Sopenharmony_ci 150e1051a39Sopenharmony_cistatic int dsa_priv_decode(EVP_PKEY *pkey, const PKCS8_PRIV_KEY_INFO *p8) 151e1051a39Sopenharmony_ci{ 152e1051a39Sopenharmony_ci int ret = 0; 153e1051a39Sopenharmony_ci DSA *dsa = ossl_dsa_key_from_pkcs8(p8, NULL, NULL); 154e1051a39Sopenharmony_ci 155e1051a39Sopenharmony_ci if (dsa != NULL) { 156e1051a39Sopenharmony_ci ret = 1; 157e1051a39Sopenharmony_ci EVP_PKEY_assign_DSA(pkey, dsa); 158e1051a39Sopenharmony_ci } 159e1051a39Sopenharmony_ci 160e1051a39Sopenharmony_ci return ret; 161e1051a39Sopenharmony_ci} 162e1051a39Sopenharmony_ci 163e1051a39Sopenharmony_cistatic int dsa_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) 164e1051a39Sopenharmony_ci{ 165e1051a39Sopenharmony_ci ASN1_STRING *params = NULL; 166e1051a39Sopenharmony_ci ASN1_INTEGER *prkey = NULL; 167e1051a39Sopenharmony_ci unsigned char *dp = NULL; 168e1051a39Sopenharmony_ci int dplen; 169e1051a39Sopenharmony_ci 170e1051a39Sopenharmony_ci if (pkey->pkey.dsa == NULL|| pkey->pkey.dsa->priv_key == NULL) { 171e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, DSA_R_MISSING_PARAMETERS); 172e1051a39Sopenharmony_ci goto err; 173e1051a39Sopenharmony_ci } 174e1051a39Sopenharmony_ci 175e1051a39Sopenharmony_ci params = ASN1_STRING_new(); 176e1051a39Sopenharmony_ci 177e1051a39Sopenharmony_ci if (params == NULL) { 178e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 179e1051a39Sopenharmony_ci goto err; 180e1051a39Sopenharmony_ci } 181e1051a39Sopenharmony_ci 182e1051a39Sopenharmony_ci params->length = i2d_DSAparams(pkey->pkey.dsa, ¶ms->data); 183e1051a39Sopenharmony_ci if (params->length <= 0) { 184e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 185e1051a39Sopenharmony_ci goto err; 186e1051a39Sopenharmony_ci } 187e1051a39Sopenharmony_ci params->type = V_ASN1_SEQUENCE; 188e1051a39Sopenharmony_ci 189e1051a39Sopenharmony_ci /* Get private key into integer */ 190e1051a39Sopenharmony_ci prkey = BN_to_ASN1_INTEGER(pkey->pkey.dsa->priv_key, NULL); 191e1051a39Sopenharmony_ci 192e1051a39Sopenharmony_ci if (prkey == NULL) { 193e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); 194e1051a39Sopenharmony_ci goto err; 195e1051a39Sopenharmony_ci } 196e1051a39Sopenharmony_ci 197e1051a39Sopenharmony_ci dplen = i2d_ASN1_INTEGER(prkey, &dp); 198e1051a39Sopenharmony_ci 199e1051a39Sopenharmony_ci ASN1_STRING_clear_free(prkey); 200e1051a39Sopenharmony_ci 201e1051a39Sopenharmony_ci if (dplen <= 0) { 202e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, DSA_R_BN_ERROR); 203e1051a39Sopenharmony_ci goto err; 204e1051a39Sopenharmony_ci } 205e1051a39Sopenharmony_ci 206e1051a39Sopenharmony_ci if (!PKCS8_pkey_set0(p8, OBJ_nid2obj(NID_dsa), 0, 207e1051a39Sopenharmony_ci V_ASN1_SEQUENCE, params, dp, dplen)) { 208e1051a39Sopenharmony_ci OPENSSL_clear_free(dp, dplen); 209e1051a39Sopenharmony_ci goto err; 210e1051a39Sopenharmony_ci } 211e1051a39Sopenharmony_ci return 1; 212e1051a39Sopenharmony_ci 213e1051a39Sopenharmony_ci err: 214e1051a39Sopenharmony_ci ASN1_STRING_free(params); 215e1051a39Sopenharmony_ci return 0; 216e1051a39Sopenharmony_ci} 217e1051a39Sopenharmony_ci 218e1051a39Sopenharmony_cistatic int int_dsa_size(const EVP_PKEY *pkey) 219e1051a39Sopenharmony_ci{ 220e1051a39Sopenharmony_ci return DSA_size(pkey->pkey.dsa); 221e1051a39Sopenharmony_ci} 222e1051a39Sopenharmony_ci 223e1051a39Sopenharmony_cistatic int dsa_bits(const EVP_PKEY *pkey) 224e1051a39Sopenharmony_ci{ 225e1051a39Sopenharmony_ci return DSA_bits(pkey->pkey.dsa); 226e1051a39Sopenharmony_ci} 227e1051a39Sopenharmony_ci 228e1051a39Sopenharmony_cistatic int dsa_security_bits(const EVP_PKEY *pkey) 229e1051a39Sopenharmony_ci{ 230e1051a39Sopenharmony_ci return DSA_security_bits(pkey->pkey.dsa); 231e1051a39Sopenharmony_ci} 232e1051a39Sopenharmony_ci 233e1051a39Sopenharmony_cistatic int dsa_missing_parameters(const EVP_PKEY *pkey) 234e1051a39Sopenharmony_ci{ 235e1051a39Sopenharmony_ci DSA *dsa; 236e1051a39Sopenharmony_ci dsa = pkey->pkey.dsa; 237e1051a39Sopenharmony_ci return dsa == NULL 238e1051a39Sopenharmony_ci || dsa->params.p == NULL 239e1051a39Sopenharmony_ci || dsa->params.q == NULL 240e1051a39Sopenharmony_ci || dsa->params.g == NULL; 241e1051a39Sopenharmony_ci} 242e1051a39Sopenharmony_ci 243e1051a39Sopenharmony_cistatic int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) 244e1051a39Sopenharmony_ci{ 245e1051a39Sopenharmony_ci if (to->pkey.dsa == NULL) { 246e1051a39Sopenharmony_ci to->pkey.dsa = DSA_new(); 247e1051a39Sopenharmony_ci if (to->pkey.dsa == NULL) 248e1051a39Sopenharmony_ci return 0; 249e1051a39Sopenharmony_ci } 250e1051a39Sopenharmony_ci if (!ossl_ffc_params_copy(&to->pkey.dsa->params, &from->pkey.dsa->params)) 251e1051a39Sopenharmony_ci return 0; 252e1051a39Sopenharmony_ci 253e1051a39Sopenharmony_ci to->pkey.dsa->dirty_cnt++; 254e1051a39Sopenharmony_ci return 1; 255e1051a39Sopenharmony_ci} 256e1051a39Sopenharmony_ci 257e1051a39Sopenharmony_cistatic int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) 258e1051a39Sopenharmony_ci{ 259e1051a39Sopenharmony_ci return ossl_ffc_params_cmp(&a->pkey.dsa->params, &b->pkey.dsa->params, 1); 260e1051a39Sopenharmony_ci} 261e1051a39Sopenharmony_ci 262e1051a39Sopenharmony_cistatic int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) 263e1051a39Sopenharmony_ci{ 264e1051a39Sopenharmony_ci return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0; 265e1051a39Sopenharmony_ci} 266e1051a39Sopenharmony_ci 267e1051a39Sopenharmony_cistatic void int_dsa_free(EVP_PKEY *pkey) 268e1051a39Sopenharmony_ci{ 269e1051a39Sopenharmony_ci DSA_free(pkey->pkey.dsa); 270e1051a39Sopenharmony_ci} 271e1051a39Sopenharmony_ci 272e1051a39Sopenharmony_cistatic int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) 273e1051a39Sopenharmony_ci{ 274e1051a39Sopenharmony_ci int ret = 0; 275e1051a39Sopenharmony_ci const char *ktype = NULL; 276e1051a39Sopenharmony_ci const BIGNUM *priv_key, *pub_key; 277e1051a39Sopenharmony_ci int mod_len = 0; 278e1051a39Sopenharmony_ci 279e1051a39Sopenharmony_ci if (x->params.p != NULL) 280e1051a39Sopenharmony_ci mod_len = DSA_bits(x); 281e1051a39Sopenharmony_ci 282e1051a39Sopenharmony_ci if (ptype == 2) 283e1051a39Sopenharmony_ci priv_key = x->priv_key; 284e1051a39Sopenharmony_ci else 285e1051a39Sopenharmony_ci priv_key = NULL; 286e1051a39Sopenharmony_ci 287e1051a39Sopenharmony_ci if (ptype > 0) 288e1051a39Sopenharmony_ci pub_key = x->pub_key; 289e1051a39Sopenharmony_ci else 290e1051a39Sopenharmony_ci pub_key = NULL; 291e1051a39Sopenharmony_ci 292e1051a39Sopenharmony_ci if (ptype == 2) 293e1051a39Sopenharmony_ci ktype = "Private-Key"; 294e1051a39Sopenharmony_ci else if (ptype == 1) 295e1051a39Sopenharmony_ci ktype = "Public-Key"; 296e1051a39Sopenharmony_ci else 297e1051a39Sopenharmony_ci ktype = "DSA-Parameters"; 298e1051a39Sopenharmony_ci 299e1051a39Sopenharmony_ci if (priv_key != NULL) { 300e1051a39Sopenharmony_ci if (!BIO_indent(bp, off, 128)) 301e1051a39Sopenharmony_ci goto err; 302e1051a39Sopenharmony_ci if (BIO_printf(bp, "%s: (%d bit)\n", ktype, mod_len) <= 0) 303e1051a39Sopenharmony_ci goto err; 304e1051a39Sopenharmony_ci } else { 305e1051a39Sopenharmony_ci if (BIO_printf(bp, "Public-Key: (%d bit)\n", mod_len) <= 0) 306e1051a39Sopenharmony_ci goto err; 307e1051a39Sopenharmony_ci } 308e1051a39Sopenharmony_ci 309e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "priv:", priv_key, NULL, off)) 310e1051a39Sopenharmony_ci goto err; 311e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "pub: ", pub_key, NULL, off)) 312e1051a39Sopenharmony_ci goto err; 313e1051a39Sopenharmony_ci if (!ossl_ffc_params_print(bp, &x->params, off)) 314e1051a39Sopenharmony_ci goto err; 315e1051a39Sopenharmony_ci ret = 1; 316e1051a39Sopenharmony_ci err: 317e1051a39Sopenharmony_ci return ret; 318e1051a39Sopenharmony_ci} 319e1051a39Sopenharmony_ci 320e1051a39Sopenharmony_cistatic int dsa_param_decode(EVP_PKEY *pkey, 321e1051a39Sopenharmony_ci const unsigned char **pder, int derlen) 322e1051a39Sopenharmony_ci{ 323e1051a39Sopenharmony_ci DSA *dsa; 324e1051a39Sopenharmony_ci 325e1051a39Sopenharmony_ci if ((dsa = d2i_DSAparams(NULL, pder, derlen)) == NULL) 326e1051a39Sopenharmony_ci return 0; 327e1051a39Sopenharmony_ci 328e1051a39Sopenharmony_ci dsa->dirty_cnt++; 329e1051a39Sopenharmony_ci EVP_PKEY_assign_DSA(pkey, dsa); 330e1051a39Sopenharmony_ci return 1; 331e1051a39Sopenharmony_ci} 332e1051a39Sopenharmony_ci 333e1051a39Sopenharmony_cistatic int dsa_param_encode(const EVP_PKEY *pkey, unsigned char **pder) 334e1051a39Sopenharmony_ci{ 335e1051a39Sopenharmony_ci return i2d_DSAparams(pkey->pkey.dsa, pder); 336e1051a39Sopenharmony_ci} 337e1051a39Sopenharmony_ci 338e1051a39Sopenharmony_cistatic int dsa_param_print(BIO *bp, const EVP_PKEY *pkey, int indent, 339e1051a39Sopenharmony_ci ASN1_PCTX *ctx) 340e1051a39Sopenharmony_ci{ 341e1051a39Sopenharmony_ci return do_dsa_print(bp, pkey->pkey.dsa, indent, 0); 342e1051a39Sopenharmony_ci} 343e1051a39Sopenharmony_ci 344e1051a39Sopenharmony_cistatic int dsa_pub_print(BIO *bp, const EVP_PKEY *pkey, int indent, 345e1051a39Sopenharmony_ci ASN1_PCTX *ctx) 346e1051a39Sopenharmony_ci{ 347e1051a39Sopenharmony_ci return do_dsa_print(bp, pkey->pkey.dsa, indent, 1); 348e1051a39Sopenharmony_ci} 349e1051a39Sopenharmony_ci 350e1051a39Sopenharmony_cistatic int dsa_priv_print(BIO *bp, const EVP_PKEY *pkey, int indent, 351e1051a39Sopenharmony_ci ASN1_PCTX *ctx) 352e1051a39Sopenharmony_ci{ 353e1051a39Sopenharmony_ci return do_dsa_print(bp, pkey->pkey.dsa, indent, 2); 354e1051a39Sopenharmony_ci} 355e1051a39Sopenharmony_ci 356e1051a39Sopenharmony_cistatic int old_dsa_priv_decode(EVP_PKEY *pkey, 357e1051a39Sopenharmony_ci const unsigned char **pder, int derlen) 358e1051a39Sopenharmony_ci{ 359e1051a39Sopenharmony_ci DSA *dsa; 360e1051a39Sopenharmony_ci 361e1051a39Sopenharmony_ci if ((dsa = d2i_DSAPrivateKey(NULL, pder, derlen)) == NULL) { 362e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_DSA_LIB); 363e1051a39Sopenharmony_ci return 0; 364e1051a39Sopenharmony_ci } 365e1051a39Sopenharmony_ci dsa->dirty_cnt++; 366e1051a39Sopenharmony_ci EVP_PKEY_assign_DSA(pkey, dsa); 367e1051a39Sopenharmony_ci return 1; 368e1051a39Sopenharmony_ci} 369e1051a39Sopenharmony_ci 370e1051a39Sopenharmony_cistatic int old_dsa_priv_encode(const EVP_PKEY *pkey, unsigned char **pder) 371e1051a39Sopenharmony_ci{ 372e1051a39Sopenharmony_ci return i2d_DSAPrivateKey(pkey->pkey.dsa, pder); 373e1051a39Sopenharmony_ci} 374e1051a39Sopenharmony_ci 375e1051a39Sopenharmony_cistatic int dsa_sig_print(BIO *bp, const X509_ALGOR *sigalg, 376e1051a39Sopenharmony_ci const ASN1_STRING *sig, int indent, ASN1_PCTX *pctx) 377e1051a39Sopenharmony_ci{ 378e1051a39Sopenharmony_ci DSA_SIG *dsa_sig; 379e1051a39Sopenharmony_ci const unsigned char *p; 380e1051a39Sopenharmony_ci 381e1051a39Sopenharmony_ci if (sig == NULL) { 382e1051a39Sopenharmony_ci if (BIO_puts(bp, "\n") <= 0) 383e1051a39Sopenharmony_ci return 0; 384e1051a39Sopenharmony_ci else 385e1051a39Sopenharmony_ci return 1; 386e1051a39Sopenharmony_ci } 387e1051a39Sopenharmony_ci p = sig->data; 388e1051a39Sopenharmony_ci dsa_sig = d2i_DSA_SIG(NULL, &p, sig->length); 389e1051a39Sopenharmony_ci if (dsa_sig != NULL) { 390e1051a39Sopenharmony_ci int rv = 0; 391e1051a39Sopenharmony_ci const BIGNUM *r, *s; 392e1051a39Sopenharmony_ci 393e1051a39Sopenharmony_ci DSA_SIG_get0(dsa_sig, &r, &s); 394e1051a39Sopenharmony_ci 395e1051a39Sopenharmony_ci if (BIO_write(bp, "\n", 1) != 1) 396e1051a39Sopenharmony_ci goto err; 397e1051a39Sopenharmony_ci 398e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "r: ", r, NULL, indent)) 399e1051a39Sopenharmony_ci goto err; 400e1051a39Sopenharmony_ci if (!ASN1_bn_print(bp, "s: ", s, NULL, indent)) 401e1051a39Sopenharmony_ci goto err; 402e1051a39Sopenharmony_ci rv = 1; 403e1051a39Sopenharmony_ci err: 404e1051a39Sopenharmony_ci DSA_SIG_free(dsa_sig); 405e1051a39Sopenharmony_ci return rv; 406e1051a39Sopenharmony_ci } 407e1051a39Sopenharmony_ci if (BIO_puts(bp, "\n") <= 0) 408e1051a39Sopenharmony_ci return 0; 409e1051a39Sopenharmony_ci return X509_signature_dump(bp, sig, indent); 410e1051a39Sopenharmony_ci} 411e1051a39Sopenharmony_ci 412e1051a39Sopenharmony_cistatic int dsa_pkey_ctrl(EVP_PKEY *pkey, int op, long arg1, void *arg2) 413e1051a39Sopenharmony_ci{ 414e1051a39Sopenharmony_ci switch (op) { 415e1051a39Sopenharmony_ci case ASN1_PKEY_CTRL_DEFAULT_MD_NID: 416e1051a39Sopenharmony_ci *(int *)arg2 = NID_sha256; 417e1051a39Sopenharmony_ci return 1; 418e1051a39Sopenharmony_ci 419e1051a39Sopenharmony_ci default: 420e1051a39Sopenharmony_ci return -2; 421e1051a39Sopenharmony_ci } 422e1051a39Sopenharmony_ci} 423e1051a39Sopenharmony_ci 424e1051a39Sopenharmony_cistatic size_t dsa_pkey_dirty_cnt(const EVP_PKEY *pkey) 425e1051a39Sopenharmony_ci{ 426e1051a39Sopenharmony_ci return pkey->pkey.dsa->dirty_cnt; 427e1051a39Sopenharmony_ci} 428e1051a39Sopenharmony_ci 429e1051a39Sopenharmony_cistatic int dsa_pkey_export_to(const EVP_PKEY *from, void *to_keydata, 430e1051a39Sopenharmony_ci OSSL_FUNC_keymgmt_import_fn *importer, 431e1051a39Sopenharmony_ci OSSL_LIB_CTX *libctx, const char *propq) 432e1051a39Sopenharmony_ci{ 433e1051a39Sopenharmony_ci DSA *dsa = from->pkey.dsa; 434e1051a39Sopenharmony_ci OSSL_PARAM_BLD *tmpl; 435e1051a39Sopenharmony_ci const BIGNUM *p = DSA_get0_p(dsa), *g = DSA_get0_g(dsa); 436e1051a39Sopenharmony_ci const BIGNUM *q = DSA_get0_q(dsa), *pub_key = DSA_get0_pub_key(dsa); 437e1051a39Sopenharmony_ci const BIGNUM *priv_key = DSA_get0_priv_key(dsa); 438e1051a39Sopenharmony_ci OSSL_PARAM *params; 439e1051a39Sopenharmony_ci int selection = 0; 440e1051a39Sopenharmony_ci int rv = 0; 441e1051a39Sopenharmony_ci 442e1051a39Sopenharmony_ci if (p == NULL || q == NULL || g == NULL) 443e1051a39Sopenharmony_ci return 0; 444e1051a39Sopenharmony_ci 445e1051a39Sopenharmony_ci tmpl = OSSL_PARAM_BLD_new(); 446e1051a39Sopenharmony_ci if (tmpl == NULL) 447e1051a39Sopenharmony_ci return 0; 448e1051a39Sopenharmony_ci 449e1051a39Sopenharmony_ci if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p) 450e1051a39Sopenharmony_ci || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_Q, q) 451e1051a39Sopenharmony_ci || !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_G, g)) 452e1051a39Sopenharmony_ci goto err; 453e1051a39Sopenharmony_ci selection |= OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS; 454e1051a39Sopenharmony_ci if (pub_key != NULL) { 455e1051a39Sopenharmony_ci if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PUB_KEY, 456e1051a39Sopenharmony_ci pub_key)) 457e1051a39Sopenharmony_ci goto err; 458e1051a39Sopenharmony_ci selection |= OSSL_KEYMGMT_SELECT_PUBLIC_KEY; 459e1051a39Sopenharmony_ci } 460e1051a39Sopenharmony_ci if (priv_key != NULL) { 461e1051a39Sopenharmony_ci if (!OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_PRIV_KEY, 462e1051a39Sopenharmony_ci priv_key)) 463e1051a39Sopenharmony_ci goto err; 464e1051a39Sopenharmony_ci selection |= OSSL_KEYMGMT_SELECT_PRIVATE_KEY; 465e1051a39Sopenharmony_ci } 466e1051a39Sopenharmony_ci 467e1051a39Sopenharmony_ci if ((params = OSSL_PARAM_BLD_to_param(tmpl)) == NULL) 468e1051a39Sopenharmony_ci goto err; 469e1051a39Sopenharmony_ci 470e1051a39Sopenharmony_ci /* We export, the provider imports */ 471e1051a39Sopenharmony_ci rv = importer(to_keydata, selection, params); 472e1051a39Sopenharmony_ci 473e1051a39Sopenharmony_ci OSSL_PARAM_free(params); 474e1051a39Sopenharmony_ci err: 475e1051a39Sopenharmony_ci OSSL_PARAM_BLD_free(tmpl); 476e1051a39Sopenharmony_ci return rv; 477e1051a39Sopenharmony_ci} 478e1051a39Sopenharmony_ci 479e1051a39Sopenharmony_cistatic int dsa_pkey_import_from(const OSSL_PARAM params[], void *vpctx) 480e1051a39Sopenharmony_ci{ 481e1051a39Sopenharmony_ci EVP_PKEY_CTX *pctx = vpctx; 482e1051a39Sopenharmony_ci EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(pctx); 483e1051a39Sopenharmony_ci DSA *dsa = ossl_dsa_new(pctx->libctx); 484e1051a39Sopenharmony_ci 485e1051a39Sopenharmony_ci if (dsa == NULL) { 486e1051a39Sopenharmony_ci ERR_raise(ERR_LIB_DSA, ERR_R_MALLOC_FAILURE); 487e1051a39Sopenharmony_ci return 0; 488e1051a39Sopenharmony_ci } 489e1051a39Sopenharmony_ci 490e1051a39Sopenharmony_ci if (!ossl_dsa_ffc_params_fromdata(dsa, params) 491e1051a39Sopenharmony_ci || !ossl_dsa_key_fromdata(dsa, params, 1) 492e1051a39Sopenharmony_ci || !EVP_PKEY_assign_DSA(pkey, dsa)) { 493e1051a39Sopenharmony_ci DSA_free(dsa); 494e1051a39Sopenharmony_ci return 0; 495e1051a39Sopenharmony_ci } 496e1051a39Sopenharmony_ci return 1; 497e1051a39Sopenharmony_ci} 498e1051a39Sopenharmony_ci 499e1051a39Sopenharmony_cistatic int dsa_pkey_copy(EVP_PKEY *to, EVP_PKEY *from) 500e1051a39Sopenharmony_ci{ 501e1051a39Sopenharmony_ci DSA *dsa = from->pkey.dsa; 502e1051a39Sopenharmony_ci DSA *dupkey = NULL; 503e1051a39Sopenharmony_ci int ret; 504e1051a39Sopenharmony_ci 505e1051a39Sopenharmony_ci if (dsa != NULL) { 506e1051a39Sopenharmony_ci dupkey = ossl_dsa_dup(dsa, OSSL_KEYMGMT_SELECT_ALL); 507e1051a39Sopenharmony_ci if (dupkey == NULL) 508e1051a39Sopenharmony_ci return 0; 509e1051a39Sopenharmony_ci } 510e1051a39Sopenharmony_ci 511e1051a39Sopenharmony_ci ret = EVP_PKEY_assign_DSA(to, dupkey); 512e1051a39Sopenharmony_ci if (!ret) 513e1051a39Sopenharmony_ci DSA_free(dupkey); 514e1051a39Sopenharmony_ci return ret; 515e1051a39Sopenharmony_ci} 516e1051a39Sopenharmony_ci 517e1051a39Sopenharmony_ci/* NB these are sorted in pkey_id order, lowest first */ 518e1051a39Sopenharmony_ci 519e1051a39Sopenharmony_ciconst EVP_PKEY_ASN1_METHOD ossl_dsa_asn1_meths[5] = { 520e1051a39Sopenharmony_ci 521e1051a39Sopenharmony_ci { 522e1051a39Sopenharmony_ci EVP_PKEY_DSA2, 523e1051a39Sopenharmony_ci EVP_PKEY_DSA, 524e1051a39Sopenharmony_ci ASN1_PKEY_ALIAS}, 525e1051a39Sopenharmony_ci 526e1051a39Sopenharmony_ci { 527e1051a39Sopenharmony_ci EVP_PKEY_DSA1, 528e1051a39Sopenharmony_ci EVP_PKEY_DSA, 529e1051a39Sopenharmony_ci ASN1_PKEY_ALIAS}, 530e1051a39Sopenharmony_ci 531e1051a39Sopenharmony_ci { 532e1051a39Sopenharmony_ci EVP_PKEY_DSA4, 533e1051a39Sopenharmony_ci EVP_PKEY_DSA, 534e1051a39Sopenharmony_ci ASN1_PKEY_ALIAS}, 535e1051a39Sopenharmony_ci 536e1051a39Sopenharmony_ci { 537e1051a39Sopenharmony_ci EVP_PKEY_DSA3, 538e1051a39Sopenharmony_ci EVP_PKEY_DSA, 539e1051a39Sopenharmony_ci ASN1_PKEY_ALIAS}, 540e1051a39Sopenharmony_ci 541e1051a39Sopenharmony_ci { 542e1051a39Sopenharmony_ci EVP_PKEY_DSA, 543e1051a39Sopenharmony_ci EVP_PKEY_DSA, 544e1051a39Sopenharmony_ci 0, 545e1051a39Sopenharmony_ci 546e1051a39Sopenharmony_ci "DSA", 547e1051a39Sopenharmony_ci "OpenSSL DSA method", 548e1051a39Sopenharmony_ci 549e1051a39Sopenharmony_ci dsa_pub_decode, 550e1051a39Sopenharmony_ci dsa_pub_encode, 551e1051a39Sopenharmony_ci dsa_pub_cmp, 552e1051a39Sopenharmony_ci dsa_pub_print, 553e1051a39Sopenharmony_ci 554e1051a39Sopenharmony_ci dsa_priv_decode, 555e1051a39Sopenharmony_ci dsa_priv_encode, 556e1051a39Sopenharmony_ci dsa_priv_print, 557e1051a39Sopenharmony_ci 558e1051a39Sopenharmony_ci int_dsa_size, 559e1051a39Sopenharmony_ci dsa_bits, 560e1051a39Sopenharmony_ci dsa_security_bits, 561e1051a39Sopenharmony_ci 562e1051a39Sopenharmony_ci dsa_param_decode, 563e1051a39Sopenharmony_ci dsa_param_encode, 564e1051a39Sopenharmony_ci dsa_missing_parameters, 565e1051a39Sopenharmony_ci dsa_copy_parameters, 566e1051a39Sopenharmony_ci dsa_cmp_parameters, 567e1051a39Sopenharmony_ci dsa_param_print, 568e1051a39Sopenharmony_ci dsa_sig_print, 569e1051a39Sopenharmony_ci 570e1051a39Sopenharmony_ci int_dsa_free, 571e1051a39Sopenharmony_ci dsa_pkey_ctrl, 572e1051a39Sopenharmony_ci old_dsa_priv_decode, 573e1051a39Sopenharmony_ci old_dsa_priv_encode, 574e1051a39Sopenharmony_ci 575e1051a39Sopenharmony_ci NULL, NULL, NULL, 576e1051a39Sopenharmony_ci NULL, NULL, NULL, 577e1051a39Sopenharmony_ci NULL, NULL, NULL, NULL, 578e1051a39Sopenharmony_ci 579e1051a39Sopenharmony_ci dsa_pkey_dirty_cnt, 580e1051a39Sopenharmony_ci dsa_pkey_export_to, 581e1051a39Sopenharmony_ci dsa_pkey_import_from, 582e1051a39Sopenharmony_ci dsa_pkey_copy 583e1051a39Sopenharmony_ci } 584e1051a39Sopenharmony_ci}; 585