]>
Commit | Line | Data |
---|---|---|
d2e9e320 | 1 | /* |
33388b44 | 2 | * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved. |
d02b48c6 | 3 | * |
3cdbea65 | 4 | * Licensed under the Apache License 2.0 (the "License"). You may not use |
d2e9e320 RS |
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 | |
d02b48c6 RE |
8 | */ |
9 | ||
f41ac0ee P |
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 | ||
e683582b | 16 | #include <openssl/bn.h> |
b39fc560 | 17 | #include "internal/cryptlib.h" |
706457b7 | 18 | #include "dsa_local.h" |
e683582b SL |
19 | #include "crypto/asn1_dsa.h" |
20 | #include "crypto/dsa.h" | |
d02b48c6 | 21 | |
0f113f3e MC |
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 | } | |
d02b48c6 | 26 | |
936c2b9e | 27 | #ifndef OPENSSL_NO_DEPRECATED_3_0 |
f7a2afa6 | 28 | int DSA_sign_setup(DSA *dsa, BN_CTX *ctx_in, BIGNUM **kinvp, BIGNUM **rp) |
0f113f3e MC |
29 | { |
30 | return dsa->meth->dsa_sign_setup(dsa, ctx_in, kinvp, rp); | |
31 | } | |
4f1b96f9 | 32 | #endif |
e683582b SL |
33 | |
34 | DSA_SIG *DSA_SIG_new(void) | |
35 | { | |
36 | DSA_SIG *sig = OPENSSL_zalloc(sizeof(*sig)); | |
37 | if (sig == NULL) | |
38 | DSAerr(DSA_F_DSA_SIG_NEW, ERR_R_MALLOC_FAILURE); | |
39 | return sig; | |
40 | } | |
41 | ||
42 | void DSA_SIG_free(DSA_SIG *sig) | |
43 | { | |
44 | if (sig == NULL) | |
45 | return; | |
46 | BN_clear_free(sig->r); | |
47 | BN_clear_free(sig->s); | |
48 | OPENSSL_free(sig); | |
49 | } | |
50 | ||
51 | DSA_SIG *d2i_DSA_SIG(DSA_SIG **psig, const unsigned char **ppin, long len) | |
52 | { | |
53 | DSA_SIG *sig; | |
54 | ||
55 | if (len < 0) | |
56 | return NULL; | |
57 | if (psig != NULL && *psig != NULL) { | |
58 | sig = *psig; | |
59 | } else { | |
60 | sig = DSA_SIG_new(); | |
61 | if (sig == NULL) | |
62 | return NULL; | |
63 | } | |
64 | if (sig->r == NULL) | |
65 | sig->r = BN_new(); | |
66 | if (sig->s == NULL) | |
67 | sig->s = BN_new(); | |
a55b00bd | 68 | if (ossl_decode_der_dsa_sig(sig->r, sig->s, ppin, (size_t)len) == 0) { |
e683582b SL |
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 (!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; | |
122 | DSA_SIG sig; | |
123 | ||
dc8de3e6 | 124 | sig.r = sig.s = dsa->params.q; |
e683582b SL |
125 | ret = i2d_DSA_SIG(&sig, NULL); |
126 | ||
127 | if (ret < 0) | |
128 | ret = 0; | |
129 | return ret; | |
130 | } | |
131 | ||
132 | void DSA_SIG_get0(const DSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) | |
133 | { | |
134 | if (pr != NULL) | |
135 | *pr = sig->r; | |
136 | if (ps != NULL) | |
137 | *ps = sig->s; | |
138 | } | |
139 | ||
140 | int DSA_SIG_set0(DSA_SIG *sig, BIGNUM *r, BIGNUM *s) | |
141 | { | |
142 | if (r == NULL || s == NULL) | |
143 | return 0; | |
144 | BN_clear_free(sig->r); | |
145 | BN_clear_free(sig->s); | |
146 | sig->r = r; | |
147 | sig->s = s; | |
148 | return 1; | |
149 | } | |
150 | ||
8083fd3a | 151 | int dsa_sign_int(int type, const unsigned char *dgst, |
e683582b SL |
152 | int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa) |
153 | { | |
154 | DSA_SIG *s; | |
155 | ||
156 | /* legacy case uses the method table */ | |
8083fd3a | 157 | if (dsa->libctx == NULL || dsa->meth != DSA_get_default_method()) |
e683582b SL |
158 | s = DSA_do_sign(dgst, dlen, dsa); |
159 | else | |
8083fd3a | 160 | s = dsa_do_sign_int(dgst, dlen, dsa); |
e683582b SL |
161 | if (s == NULL) { |
162 | *siglen = 0; | |
163 | return 0; | |
164 | } | |
165 | *siglen = i2d_DSA_SIG(s, &sig); | |
166 | DSA_SIG_free(s); | |
167 | return 1; | |
168 | } | |
169 | ||
170 | int DSA_sign(int type, const unsigned char *dgst, int dlen, | |
171 | unsigned char *sig, unsigned int *siglen, DSA *dsa) | |
172 | { | |
8083fd3a | 173 | return dsa_sign_int(type, dgst, dlen, sig, siglen, dsa); |
e683582b SL |
174 | } |
175 | ||
176 | /* data has already been hashed (probably with SHA or SHA-1). */ | |
177 | /*- | |
178 | * returns | |
179 | * 1: correct signature | |
180 | * 0: incorrect signature | |
181 | * -1: error | |
182 | */ | |
183 | int DSA_verify(int type, const unsigned char *dgst, int dgst_len, | |
184 | const unsigned char *sigbuf, int siglen, DSA *dsa) | |
185 | { | |
186 | DSA_SIG *s; | |
187 | const unsigned char *p = sigbuf; | |
188 | unsigned char *der = NULL; | |
189 | int derlen = -1; | |
190 | int ret = -1; | |
191 | ||
192 | s = DSA_SIG_new(); | |
193 | if (s == NULL) | |
194 | return ret; | |
195 | if (d2i_DSA_SIG(&s, &p, siglen) == NULL) | |
196 | goto err; | |
197 | /* Ensure signature uses DER and doesn't have trailing garbage */ | |
198 | derlen = i2d_DSA_SIG(s, &der); | |
199 | if (derlen != siglen || memcmp(sigbuf, der, derlen)) | |
200 | goto err; | |
201 | ret = DSA_do_verify(dgst, dgst_len, s, dsa); | |
202 | err: | |
203 | OPENSSL_clear_free(der, derlen); | |
204 | DSA_SIG_free(s); | |
205 | return ret; | |
206 | } | |
207 |