1 /* 2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. 3 * 4 * Licensed under the OpenSSL license (the "License"). You may not use 5 * this file except in compliance with the License. You can obtain a copy 6 * in the file LICENSE in the source distribution or at 7 * https://www.openssl.org/source/license.html 8 */ 9 10 #include <stdio.h> 11 #include "internal/cryptlib.h" 12 #include "internal/refcount.h" 13 #include <openssl/bn.h> 14 #include "dsa_local.h" 15 #include <openssl/asn1.h> 16 #include <openssl/engine.h> 17 #include <openssl/dh.h> 18 19 DSA *DSA_new(void) 20 { 21 return DSA_new_method(NULL); 22 } 23 24 int DSA_set_method(DSA *dsa, const DSA_METHOD *meth) 25 { 26 /* 27 * NB: The caller is specifically setting a method, so it's not up to us 28 * to deal with which ENGINE it comes from. 29 */ 30 const DSA_METHOD *mtmp; 31 mtmp = dsa->meth; 32 if (mtmp->finish) 33 mtmp->finish(dsa); 34 #ifndef OPENSSL_NO_ENGINE 35 ENGINE_finish(dsa->engine); 36 dsa->engine = NULL; 37 #endif 38 dsa->meth = meth; 39 if (meth->init) 40 meth->init(dsa); 41 return 1; 42 } 43 44 const DSA_METHOD *DSA_get_method(DSA *d) 45 { 46 return d->meth; 47 } 48 49 DSA *DSA_new_method(ENGINE *engine) 50 { 51 DSA *ret = OPENSSL_zalloc(sizeof(*ret)); 52 53 if (ret == NULL) { 54 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); 55 return NULL; 56 } 57 58 ret->references = 1; 59 ret->lock = CRYPTO_THREAD_lock_new(); 60 if (ret->lock == NULL) { 61 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_MALLOC_FAILURE); 62 OPENSSL_free(ret); 63 return NULL; 64 } 65 66 ret->meth = DSA_get_default_method(); 67 #ifndef OPENSSL_NO_ENGINE 68 ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; /* early default init */ 69 if (engine) { 70 if (!ENGINE_init(engine)) { 71 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); 72 goto err; 73 } 74 ret->engine = engine; 75 } else 76 ret->engine = ENGINE_get_default_DSA(); 77 if (ret->engine) { 78 ret->meth = ENGINE_get_DSA(ret->engine); 79 if (ret->meth == NULL) { 80 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB); 81 goto err; 82 } 83 } 84 #endif 85 86 ret->flags = ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW; 87 88 if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data)) 89 goto err; 90 91 if ((ret->meth->init != NULL) && !ret->meth->init(ret)) { 92 DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_INIT_FAIL); 93 goto err; 94 } 95 96 return ret; 97 98 err: 99 DSA_free(ret); 100 return NULL; 101 } 102 103 void DSA_free(DSA *r) 104 { 105 int i; 106 107 if (r == NULL) 108 return; 109 110 CRYPTO_DOWN_REF(&r->references, &i, r->lock); 111 REF_PRINT_COUNT("DSA", r); 112 if (i > 0) 113 return; 114 REF_ASSERT_ISNT(i < 0); 115 116 if (r->meth != NULL && r->meth->finish != NULL) 117 r->meth->finish(r); 118 #ifndef OPENSSL_NO_ENGINE 119 ENGINE_finish(r->engine); 120 #endif 121 122 CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data); 123 124 CRYPTO_THREAD_lock_free(r->lock); 125 126 BN_clear_free(r->p); 127 BN_clear_free(r->q); 128 BN_clear_free(r->g); 129 BN_clear_free(r->pub_key); 130 BN_clear_free(r->priv_key); 131 OPENSSL_free(r); 132 } 133 134 int DSA_up_ref(DSA *r) 135 { 136 int i; 137 138 if (CRYPTO_UP_REF(&r->references, &i, r->lock) <= 0) 139 return 0; 140 141 REF_PRINT_COUNT("DSA", r); 142 REF_ASSERT_ISNT(i < 2); 143 return ((i > 1) ? 1 : 0); 144 } 145 146 int DSA_size(const DSA *r) 147 { 148 int ret, i; 149 ASN1_INTEGER bs; 150 unsigned char buf[4]; /* 4 bytes looks really small. However, 151 * i2d_ASN1_INTEGER() will not look beyond 152 * the first byte, as long as the second 153 * parameter is NULL. */ 154 155 i = BN_num_bits(r->q); 156 bs.length = (i + 7) / 8; 157 bs.data = buf; 158 bs.type = V_ASN1_INTEGER; 159 /* If the top bit is set the asn1 encoding is 1 larger. */ 160 buf[0] = 0xff; 161 162 i = i2d_ASN1_INTEGER(&bs, NULL); 163 i += i; /* r and s */ 164 ret = ASN1_object_size(1, i, V_ASN1_SEQUENCE); 165 return ret; 166 } 167 168 int DSA_set_ex_data(DSA *d, int idx, void *arg) 169 { 170 return CRYPTO_set_ex_data(&d->ex_data, idx, arg); 171 } 172 173 void *DSA_get_ex_data(DSA *d, int idx) 174 { 175 return CRYPTO_get_ex_data(&d->ex_data, idx); 176 } 177 178 int DSA_security_bits(const DSA *d) 179 { 180 if (d->p && d->q) 181 return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q)); 182 return -1; 183 } 184 185 #ifndef OPENSSL_NO_DH 186 DH *DSA_dup_DH(const DSA *r) 187 { 188 /* 189 * DSA has p, q, g, optional pub_key, optional priv_key. DH has p, 190 * optional length, g, optional pub_key, optional priv_key, optional q. 191 */ 192 193 DH *ret = NULL; 194 BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub_key = NULL, *priv_key = NULL; 195 196 if (r == NULL) 197 goto err; 198 ret = DH_new(); 199 if (ret == NULL) 200 goto err; 201 if (r->p != NULL || r->g != NULL || r->q != NULL) { 202 if (r->p == NULL || r->g == NULL || r->q == NULL) { 203 /* Shouldn't happen */ 204 goto err; 205 } 206 p = BN_dup(r->p); 207 g = BN_dup(r->g); 208 q = BN_dup(r->q); 209 if (p == NULL || g == NULL || q == NULL || !DH_set0_pqg(ret, p, q, g)) 210 goto err; 211 p = g = q = NULL; 212 } 213 214 if (r->pub_key != NULL) { 215 pub_key = BN_dup(r->pub_key); 216 if (pub_key == NULL) 217 goto err; 218 if (r->priv_key != NULL) { 219 priv_key = BN_dup(r->priv_key); 220 if (priv_key == NULL) 221 goto err; 222 } 223 if (!DH_set0_key(ret, pub_key, priv_key)) 224 goto err; 225 } else if (r->priv_key != NULL) { 226 /* Shouldn't happen */ 227 goto err; 228 } 229 230 return ret; 231 232 err: 233 BN_free(p); 234 BN_free(g); 235 BN_free(q); 236 BN_free(pub_key); 237 BN_free(priv_key); 238 DH_free(ret); 239 return NULL; 240 } 241 #endif 242 243 void DSA_get0_pqg(const DSA *d, 244 const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) 245 { 246 if (p != NULL) 247 *p = d->p; 248 if (q != NULL) 249 *q = d->q; 250 if (g != NULL) 251 *g = d->g; 252 } 253 254 int DSA_set0_pqg(DSA *d, BIGNUM *p, BIGNUM *q, BIGNUM *g) 255 { 256 /* If the fields p, q and g in d are NULL, the corresponding input 257 * parameters MUST be non-NULL. 258 */ 259 if ((d->p == NULL && p == NULL) 260 || (d->q == NULL && q == NULL) 261 || (d->g == NULL && g == NULL)) 262 return 0; 263 264 if (p != NULL) { 265 BN_free(d->p); 266 d->p = p; 267 } 268 if (q != NULL) { 269 BN_free(d->q); 270 d->q = q; 271 } 272 if (g != NULL) { 273 BN_free(d->g); 274 d->g = g; 275 } 276 277 return 1; 278 } 279 280 void DSA_get0_key(const DSA *d, 281 const BIGNUM **pub_key, const BIGNUM **priv_key) 282 { 283 if (pub_key != NULL) 284 *pub_key = d->pub_key; 285 if (priv_key != NULL) 286 *priv_key = d->priv_key; 287 } 288 289 int DSA_set0_key(DSA *d, BIGNUM *pub_key, BIGNUM *priv_key) 290 { 291 /* If the field pub_key in d is NULL, the corresponding input 292 * parameters MUST be non-NULL. The priv_key field may 293 * be left NULL. 294 */ 295 if (d->pub_key == NULL && pub_key == NULL) 296 return 0; 297 298 if (pub_key != NULL) { 299 BN_free(d->pub_key); 300 d->pub_key = pub_key; 301 } 302 if (priv_key != NULL) { 303 BN_free(d->priv_key); 304 d->priv_key = priv_key; 305 } 306 307 return 1; 308 } 309 310 const BIGNUM *DSA_get0_p(const DSA *d) 311 { 312 return d->p; 313 } 314 315 const BIGNUM *DSA_get0_q(const DSA *d) 316 { 317 return d->q; 318 } 319 320 const BIGNUM *DSA_get0_g(const DSA *d) 321 { 322 return d->g; 323 } 324 325 const BIGNUM *DSA_get0_pub_key(const DSA *d) 326 { 327 return d->pub_key; 328 } 329 330 const BIGNUM *DSA_get0_priv_key(const DSA *d) 331 { 332 return d->priv_key; 333 } 334 335 void DSA_clear_flags(DSA *d, int flags) 336 { 337 d->flags &= ~flags; 338 } 339 340 int DSA_test_flags(const DSA *d, int flags) 341 { 342 return d->flags & flags; 343 } 344 345 void DSA_set_flags(DSA *d, int flags) 346 { 347 d->flags |= flags; 348 } 349 350 ENGINE *DSA_get0_engine(DSA *d) 351 { 352 return d->engine; 353 } 354 355 int DSA_bits(const DSA *dsa) 356 { 357 return BN_num_bits(dsa->p); 358 } 359