]>
Commit | Line | Data |
---|---|---|
1 | /* | |
2 | * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved. | |
3 | * | |
4 | * Licensed under the Apache License 2.0 (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 | /* | |
11 | * DSA low level APIs are deprecated for public use, but still ok for | |
12 | * internal use. | |
13 | */ | |
14 | #include "internal/deprecated.h" | |
15 | ||
16 | #include <openssl/bn.h> | |
17 | #include "internal/cryptlib.h" | |
18 | #include "dsa_local.h" | |
19 | #include "crypto/asn1_dsa.h" | |
20 | #include "crypto/dsa.h" | |
21 | ||
22 | DSA_SIG *DSA_do_sign(const unsigned char *dgst, int dlen, DSA *dsa) | |
23 | { | |
24 | return dsa->meth->dsa_do_sign(dgst, dlen, dsa); | |
25 | } | |
26 | ||
27 | #ifndef OPENSSL_NO_DEPRECATED_3_0 | |
28 | int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) | |
29 | { | |
30 | return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); | |
31 | } | |
32 | #endif | |
33 | ||
34 | DSA_SIG *DSA_SIG_new(void) | |
35 | { | |
36 | DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); | |
37 | ||
38 | return sig; | |
39 | } | |
40 | ||
41 | void DSA_SIG_free(DSA_SIG *sig) | |
42 | { | |
43 | if (sig == NULL) | |
44 | return; | |
45 | BN_clear_free(sig->r); | |
46 | BN_clear_free(sig->s); | |
47 | OPENSSL_free(sig); | |
48 | } | |
49 | ||
50 | DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len) | |
51 | { | |
52 | DSA_SIG *sig; | |
53 | ||
54 | if (len < 0) | |
55 | return NULL; | |
56 | if (psig != NULL && *psig != NULL) { | |
57 | sig = *psig; | |
58 | } else { | |
59 | sig = DSA_SIG_new(); | |
60 | if (sig == NULL) | |
61 | return NULL; | |
62 | } | |
63 | if (sig->r == NULL) | |
64 | sig->r = BN_new(); | |
65 | if (sig->s == NULL) | |
66 | sig->s = BN_new(); | |
67 | if (sig->r == NULL || sig->s == NULL | |
68 | || ossl_decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { | |
69 | if (psig == NULL || *psig == NULL) | |
70 | DSA_SIG_free(sig); | |
71 | return NULL; | |
72 | } | |
73 | if (psig != NULL && *psig == NULL) | |
74 | *psig = sig; | |
75 | return sig; | |
76 | } | |
77 | ||
78 | int i2d_DSA_SIG(const DSA_SIG *sig, unsigned char **ppout) | |
79 | { | |
80 | BUF_MEM *buf = NULL; | |
81 | size_t encoded_len; | |
82 | WPACKET pkt; | |
83 | ||
84 | if (ppout == NULL) { | |
85 | if (!WPACKET_init_null(&pkt, 0)) | |
86 | return -1; | |
87 | } else if (*ppout == NULL) { | |
88 | if ((buf = BUF_MEM_new()) == NULL | |
89 | || !WPACKET_init_len(&pkt, buf, 0)) { | |
90 | BUF_MEM_free(buf); | |
91 | return -1; | |
92 | } | |
93 | } else { | |
94 | if (!WPACKET_init_static_len(&pkt, *ppout, SIZE_MAX, 0)) | |
95 | return -1; | |
96 | } | |
97 | ||
98 | if (!ossl_encode_der_dsa_sig(&pkt, sig->r, sig->s) | |
99 | || !WPACKET_get_total_written(&pkt, &encoded_len) | |
100 | || !WPACKET_finish(&pkt)) { | |
101 | BUF_MEM_free(buf); | |
102 | WPACKET_cleanup(&pkt); | |
103 | return -1; | |
104 | } | |
105 | ||
106 | if (ppout != NULL) { | |
107 | if (*ppout == NULL) { | |
108 | *ppout = (unsigned char *)buf->data; | |
109 | buf->data = NULL; | |
110 | BUF_MEM_free(buf); | |
111 | } else { | |
112 | *ppout += encoded_len; | |
113 | } | |
114 | } | |
115 | ||
116 | return (int)encoded_len; | |
117 | } | |
118 | ||
119 | int DSA_size(const DSA *dsa) | |
120 | { | |
121 | int ret = -1; | |
122 | DSA_SIG sig; | |
123 | ||
124 | if (dsa->params.q != NULL) { | |
125 | sig.r = sig.s = dsa->params.q; | |
126 | ret = i2d_DSA_SIG(&sig, NULL); | |
127 | ||
128 | if (ret < 0) | |
129 | ret = 0; | |
130 | } | |
131 | return ret; | |
132 | } | |
133 | ||
134 | void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) | |
135 | { | |
136 | if (pr != NULL) | |
137 | *pr = sig->r; | |
138 | if (ps != NULL) | |
139 | *ps = sig->s; | |
140 | } | |
141 | ||
142 | int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) | |
143 | { | |
144 | if (r == NULL || s == NULL) | |
145 | return 0; | |
146 | BN_clear_free(sig->r); | |
147 | BN_clear_free(sig->s); | |
148 | sig->r = r; | |
149 | sig->s = s; | |
150 | return 1; | |
151 | } | |
152 | ||
153 | int ossl_dsa_sign_int(int type, const unsigned char *dgst, int dlen, | |
154 | unsigned char *sig, unsigned int *siglen, DSA *dsa, | |
155 | unsigned int nonce_type, const char *digestname, | |
156 | OSSL_LIB_CTX *libctx, const char *propq) | |
157 | { | |
158 | DSA_SIG *s; | |
159 | ||
160 | /* legacy case uses the method table */ | |
161 | if (dsa->libctx == NULL || dsa->meth != DSA_get_default_method()) | |
162 | s = DSA_do_sign(dgst, dlen, dsa); | |
163 | else | |
164 | s = ossl_dsa_do_sign_int(dgst, dlen, dsa, | |
165 | nonce_type, digestname, libctx, propq); | |
166 | if (s == NULL) { | |
167 | *siglen = 0; | |
168 | return 0; | |
169 | } | |
170 | *siglen = i2d_DSA_SIG(s, &sig); | |
171 | DSA_SIG_free(s); | |
172 | return 1; | |
173 | } | |
174 | ||
175 | int DSA_sign(int type, const unsigned char *dgst, int dlen, | |
176 | unsigned char *sig, unsigned int *siglen, DSA *dsa) | |
177 | { | |
178 | return ossl_dsa_sign_int(type, dgst, dlen, sig, siglen, dsa, | |
179 | 0, NULL, NULL, NULL); | |
180 | } | |
181 | ||
182 | /* data has already been hashed (probably with SHA or SHA-1). */ | |
183 | /*- | |
184 | * returns | |
185 | * 1: correct signature | |
186 | * 0: incorrect signature | |
187 | * -1: error | |
188 | */ | |
189 | int DSA_verify(int type, const unsigned char *dgst, int dgst_len, | |
190 | const unsigned char *sigbuf, int siglen, DSA *dsa) | |
191 | { | |
192 | DSA_SIG *s; | |
193 | const unsigned char *p = sigbuf; | |
194 | unsigned char *der = NULL; | |
195 | int derlen = -1; | |
196 | int ret = -1; | |
197 | ||
198 | s = DSA_SIG_new(); | |
199 | if (s == NULL) | |
200 | return ret; | |
201 | if (d2i_DSA_SIG(&s, &p, siglen) == NULL) | |
202 | goto err; | |
203 | /* Ensure signature uses DER and doesn't have trailing garbage */ | |
204 | derlen = i2d_DSA_SIG(s, &der); | |
205 | if (derlen != siglen || memcmp(sigbuf, der, derlen)) | |
206 | goto err; | |
207 | ret = DSA_do_verify(dgst, dgst_len, s, dsa); | |
208 | err: | |
209 | OPENSSL_clear_free(der, derlen); | |
210 | DSA_SIG_free(s); | |
211 | return ret; | |
212 | } |