Branch data Line data Source code
1 : : /* crypto/dsa/dsa_lib.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
7 : : * The implementation was written so as to conform with Netscapes SSL.
8 : : *
9 : : * This library is free for commercial and non-commercial use as long as
10 : : * the following conditions are aheared to. The following conditions
11 : : * apply to all code found in this distribution, be it the RC4, RSA,
12 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : : * included with this distribution is covered by the same copyright terms
14 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : : *
16 : : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : : * the code are not to be removed.
18 : : * If this package is used in a product, Eric Young should be given attribution
19 : : * as the author of the parts of the library used.
20 : : * This can be in the form of a textual message at program startup or
21 : : * in documentation (online or textual) provided with the package.
22 : : *
23 : : * Redistribution and use in source and binary forms, with or without
24 : : * modification, are permitted provided that the following conditions
25 : : * are met:
26 : : * 1. Redistributions of source code must retain the copyright
27 : : * notice, this list of conditions and the following disclaimer.
28 : : * 2. Redistributions in binary form must reproduce the above copyright
29 : : * notice, this list of conditions and the following disclaimer in the
30 : : * documentation and/or other materials provided with the distribution.
31 : : * 3. All advertising materials mentioning features or use of this software
32 : : * must display the following acknowledgement:
33 : : * "This product includes cryptographic software written by
34 : : * Eric Young (eay@cryptsoft.com)"
35 : : * The word 'cryptographic' can be left out if the rouines from the library
36 : : * being used are not cryptographic related :-).
37 : : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : : * the apps directory (application code) you must include an acknowledgement:
39 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : : *
41 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : : * SUCH DAMAGE.
52 : : *
53 : : * The licence and distribution terms for any publically available version or
54 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : : * copied and put under another distribution licence
56 : : * [including the GNU Public Licence.]
57 : : */
58 : :
59 : : /* Original version from Steven Schoch <schoch@sheba.arc.nasa.gov> */
60 : :
61 : : #include <stdio.h>
62 : : #include "cryptlib.h"
63 : : #include <openssl/bn.h>
64 : : #include <openssl/dsa.h>
65 : : #include <openssl/asn1.h>
66 : : #ifndef OPENSSL_NO_ENGINE
67 : : #include <openssl/engine.h>
68 : : #endif
69 : : #ifndef OPENSSL_NO_DH
70 : : #include <openssl/dh.h>
71 : : #endif
72 : :
73 : : const char DSA_version[]="DSA" OPENSSL_VERSION_PTEXT;
74 : :
75 : : static const DSA_METHOD *default_DSA_method = NULL;
76 : :
77 : 0 : void DSA_set_default_method(const DSA_METHOD *meth)
78 : : {
79 : 0 : default_DSA_method = meth;
80 : 0 : }
81 : :
82 : 846 : const DSA_METHOD *DSA_get_default_method(void)
83 : : {
84 [ + + ]: 846 : if(!default_DSA_method)
85 : 730 : default_DSA_method = DSA_OpenSSL();
86 : 846 : return default_DSA_method;
87 : : }
88 : :
89 : 118 : DSA *DSA_new(void)
90 : : {
91 : 118 : return DSA_new_method(NULL);
92 : : }
93 : :
94 : 0 : int DSA_set_method(DSA *dsa, const DSA_METHOD *meth)
95 : : {
96 : : /* NB: The caller is specifically setting a method, so it's not up to us
97 : : * to deal with which ENGINE it comes from. */
98 : : const DSA_METHOD *mtmp;
99 : 0 : mtmp = dsa->meth;
100 [ # # ]: 0 : if (mtmp->finish) mtmp->finish(dsa);
101 : : #ifndef OPENSSL_NO_ENGINE
102 [ # # ]: 0 : if (dsa->engine)
103 : : {
104 : 0 : ENGINE_finish(dsa->engine);
105 : 0 : dsa->engine = NULL;
106 : : }
107 : : #endif
108 : 0 : dsa->meth = meth;
109 [ # # ]: 0 : if (meth->init) meth->init(dsa);
110 : 0 : return 1;
111 : : }
112 : :
113 : 118 : DSA *DSA_new_method(ENGINE *engine)
114 : : {
115 : : DSA *ret;
116 : :
117 : 118 : ret=(DSA *)OPENSSL_malloc(sizeof(DSA));
118 [ - + ]: 118 : if (ret == NULL)
119 : : {
120 : 0 : DSAerr(DSA_F_DSA_NEW_METHOD,ERR_R_MALLOC_FAILURE);
121 : 0 : return(NULL);
122 : : }
123 : 118 : ret->meth = DSA_get_default_method();
124 : : #ifndef OPENSSL_NO_ENGINE
125 [ - + ]: 118 : if (engine)
126 : : {
127 [ # # ]: 0 : if (!ENGINE_init(engine))
128 : : {
129 : 0 : DSAerr(DSA_F_DSA_NEW_METHOD, ERR_R_ENGINE_LIB);
130 : 0 : OPENSSL_free(ret);
131 : 0 : return NULL;
132 : : }
133 : 0 : ret->engine = engine;
134 : : }
135 : : else
136 : 118 : ret->engine = ENGINE_get_default_DSA();
137 [ - + ]: 118 : if(ret->engine)
138 : : {
139 : 0 : ret->meth = ENGINE_get_DSA(ret->engine);
140 [ # # ]: 0 : if(!ret->meth)
141 : : {
142 : 0 : DSAerr(DSA_F_DSA_NEW_METHOD,
143 : : ERR_R_ENGINE_LIB);
144 : 0 : ENGINE_finish(ret->engine);
145 : 0 : OPENSSL_free(ret);
146 : 0 : return NULL;
147 : : }
148 : : }
149 : : #endif
150 : :
151 : 118 : ret->pad=0;
152 : 118 : ret->version=0;
153 : 118 : ret->write_params=1;
154 : 118 : ret->p=NULL;
155 : 118 : ret->q=NULL;
156 : 118 : ret->g=NULL;
157 : :
158 : 118 : ret->pub_key=NULL;
159 : 118 : ret->priv_key=NULL;
160 : :
161 : 118 : ret->kinv=NULL;
162 : 118 : ret->r=NULL;
163 : 118 : ret->method_mont_p=NULL;
164 : :
165 : 118 : ret->references=1;
166 : 118 : ret->flags=ret->meth->flags & ~DSA_FLAG_NON_FIPS_ALLOW;
167 : 118 : CRYPTO_new_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
168 [ + - ][ - + ]: 118 : if ((ret->meth->init != NULL) && !ret->meth->init(ret))
169 : : {
170 : : #ifndef OPENSSL_NO_ENGINE
171 [ # # ]: 0 : if (ret->engine)
172 : 0 : ENGINE_finish(ret->engine);
173 : : #endif
174 : 0 : CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, ret, &ret->ex_data);
175 : 0 : OPENSSL_free(ret);
176 : 0 : ret=NULL;
177 : : }
178 : :
179 : 118 : return(ret);
180 : : }
181 : :
182 : 120 : void DSA_free(DSA *r)
183 : : {
184 : : int i;
185 : :
186 [ + - ]: 120 : if (r == NULL) return;
187 : :
188 : 120 : i=CRYPTO_add(&r->references,-1,CRYPTO_LOCK_DSA);
189 : : #ifdef REF_PRINT
190 : : REF_PRINT("DSA",r);
191 : : #endif
192 [ + + ]: 120 : if (i > 0) return;
193 : : #ifdef REF_CHECK
194 : : if (i < 0)
195 : : {
196 : : fprintf(stderr,"DSA_free, bad reference count\n");
197 : : abort();
198 : : }
199 : : #endif
200 : :
201 [ + - ]: 118 : if(r->meth->finish)
202 : 118 : r->meth->finish(r);
203 : : #ifndef OPENSSL_NO_ENGINE
204 [ - + ]: 118 : if(r->engine)
205 : 0 : ENGINE_finish(r->engine);
206 : : #endif
207 : :
208 : 118 : CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DSA, r, &r->ex_data);
209 : :
210 [ + - ]: 118 : if (r->p != NULL) BN_clear_free(r->p);
211 [ + - ]: 118 : if (r->q != NULL) BN_clear_free(r->q);
212 [ + - ]: 118 : if (r->g != NULL) BN_clear_free(r->g);
213 [ + - ]: 118 : if (r->pub_key != NULL) BN_clear_free(r->pub_key);
214 [ + + ]: 118 : if (r->priv_key != NULL) BN_clear_free(r->priv_key);
215 [ - + ]: 118 : if (r->kinv != NULL) BN_clear_free(r->kinv);
216 [ - + ]: 118 : if (r->r != NULL) BN_clear_free(r->r);
217 : 118 : OPENSSL_free(r);
218 : : }
219 : :
220 : 2 : int DSA_up_ref(DSA *r)
221 : : {
222 : 2 : int i = CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DSA);
223 : : #ifdef REF_PRINT
224 : : REF_PRINT("DSA",r);
225 : : #endif
226 : : #ifdef REF_CHECK
227 : : if (i < 2)
228 : : {
229 : : fprintf(stderr, "DSA_up_ref, bad reference count\n");
230 : : abort();
231 : : }
232 : : #endif
233 : 2 : return ((i > 1) ? 1 : 0);
234 : : }
235 : :
236 : 80 : int DSA_size(const DSA *r)
237 : : {
238 : : int ret,i;
239 : : ASN1_INTEGER bs;
240 : : unsigned char buf[4]; /* 4 bytes looks really small.
241 : : However, i2d_ASN1_INTEGER() will not look
242 : : beyond the first byte, as long as the second
243 : : parameter is NULL. */
244 : :
245 : 80 : i=BN_num_bits(r->q);
246 : 80 : bs.length=(i+7)/8;
247 : 80 : bs.data=buf;
248 : 80 : bs.type=V_ASN1_INTEGER;
249 : : /* If the top bit is set the asn1 encoding is 1 larger. */
250 : 80 : buf[0]=0xff;
251 : :
252 : 80 : i=i2d_ASN1_INTEGER(&bs,NULL);
253 : 80 : i+=i; /* r and s */
254 : 80 : ret=ASN1_object_size(1,i,V_ASN1_SEQUENCE);
255 : 80 : return(ret);
256 : : }
257 : :
258 : 0 : int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
259 : : CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
260 : : {
261 : 0 : return CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_DSA, argl, argp,
262 : : new_func, dup_func, free_func);
263 : : }
264 : :
265 : 0 : int DSA_set_ex_data(DSA *d, int idx, void *arg)
266 : : {
267 : 0 : return(CRYPTO_set_ex_data(&d->ex_data,idx,arg));
268 : : }
269 : :
270 : 0 : void *DSA_get_ex_data(DSA *d, int idx)
271 : : {
272 : 0 : return(CRYPTO_get_ex_data(&d->ex_data,idx));
273 : : }
274 : :
275 : 0 : int DSA_security_bits(const DSA *d)
276 : : {
277 : 0 : return BN_security_bits(BN_num_bits(d->p), BN_num_bits(d->q));
278 : : }
279 : :
280 : : #ifndef OPENSSL_NO_DH
281 : 0 : DH *DSA_dup_DH(const DSA *r)
282 : : {
283 : : /* DSA has p, q, g, optional pub_key, optional priv_key.
284 : : * DH has p, optional length, g, optional pub_key, optional priv_key,
285 : : * optional q.
286 : : */
287 : :
288 : 0 : DH *ret = NULL;
289 : :
290 [ # # ]: 0 : if (r == NULL)
291 : : goto err;
292 : 0 : ret = DH_new();
293 [ # # ]: 0 : if (ret == NULL)
294 : : goto err;
295 [ # # ]: 0 : if (r->p != NULL)
296 [ # # ]: 0 : if ((ret->p = BN_dup(r->p)) == NULL)
297 : : goto err;
298 [ # # ]: 0 : if (r->q != NULL)
299 : : {
300 : 0 : ret->length = BN_num_bits(r->q);
301 [ # # ]: 0 : if ((ret->q = BN_dup(r->q)) == NULL)
302 : : goto err;
303 : : }
304 [ # # ]: 0 : if (r->g != NULL)
305 [ # # ]: 0 : if ((ret->g = BN_dup(r->g)) == NULL)
306 : : goto err;
307 [ # # ]: 0 : if (r->pub_key != NULL)
308 [ # # ]: 0 : if ((ret->pub_key = BN_dup(r->pub_key)) == NULL)
309 : : goto err;
310 [ # # ]: 0 : if (r->priv_key != NULL)
311 [ # # ]: 0 : if ((ret->priv_key = BN_dup(r->priv_key)) == NULL)
312 : : goto err;
313 : :
314 : 0 : return ret;
315 : :
316 : : err:
317 [ # # ]: 0 : if (ret != NULL)
318 : 0 : DH_free(ret);
319 : : return NULL;
320 : : }
321 : : #endif
|