2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 RCSID("$OpenBSD: dsa.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $");
34 #include <openssl/bn.h>
35 #include <openssl/dh.h>
36 #include <openssl/rsa.h>
37 #include <openssl/dsa.h>
38 #include <openssl/evp.h>
39 #include <openssl/bio.h>
40 #include <openssl/pem.h>
42 #include <openssl/hmac.h>
47 #define INTBLOB_LEN 20
48 #define SIGBLOB_LEN (2*INTBLOB_LEN)
51 dsa_key_from_blob(char *blob, int blen)
60 dump_base64(stderr, blob, blen);
62 /* fetch & parse DSA/DSS pubkey */
64 buffer_append(&b, blob, blen);
65 ktype = buffer_get_string(&b, NULL);
66 if (strcmp(KEX_DSS, ktype) != 0) {
67 error("dsa_key_from_blob: cannot handle type %s", ktype);
72 key = key_new(KEY_DSA);
74 buffer_get_bignum2(&b, dsa->p);
75 buffer_get_bignum2(&b, dsa->q);
76 buffer_get_bignum2(&b, dsa->g);
77 buffer_get_bignum2(&b, dsa->pub_key);
78 rlen = buffer_len(&b);
80 error("dsa_key_from_blob: remaining bytes in key blob %d", rlen);
85 DSA_print_fp(stderr, dsa, 8);
90 dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
96 if (key == NULL || key->type != KEY_DSA)
99 buffer_put_cstring(&b, KEX_DSS);
100 buffer_put_bignum2(&b, key->dsa->p);
101 buffer_put_bignum2(&b, key->dsa->q);
102 buffer_put_bignum2(&b, key->dsa->g);
103 buffer_put_bignum2(&b, key->dsa->pub_key);
104 len = buffer_len(&b);
106 memcpy(buf, buffer_ptr(&b), len);
107 memset(buffer_ptr(&b), 0, len);
118 unsigned char **sigp, int *lenp,
119 unsigned char *data, int datalen)
121 unsigned char *digest;
124 EVP_MD *evp_md = EVP_sha1();
129 unsigned char sigblob[SIGBLOB_LEN];
132 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
133 error("dsa_sign: no DSA key");
136 digest = xmalloc(evp_md->md_size);
137 EVP_DigestInit(&md, evp_md);
138 EVP_DigestUpdate(&md, data, datalen);
139 EVP_DigestFinal(&md, digest, NULL);
141 sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
143 fatal("dsa_sign: cannot sign");
146 rlen = BN_num_bytes(sig->r);
147 slen = BN_num_bytes(sig->s);
148 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
149 error("bad sig size %d %d", rlen, slen);
153 debug("sig size %d %d", rlen, slen);
155 memset(sigblob, 0, SIGBLOB_LEN);
156 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
157 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
160 if (datafellows & SSH_BUG_SIGBLOB) {
161 debug("datafellows");
162 ret = xmalloc(SIGBLOB_LEN);
163 memcpy(ret, sigblob, SIGBLOB_LEN);
171 buffer_put_cstring(&b, KEX_DSS);
172 buffer_put_string(&b, sigblob, SIGBLOB_LEN);
173 len = buffer_len(&b);
175 memcpy(ret, buffer_ptr(&b), len);
187 unsigned char *signature, int signaturelen,
188 unsigned char *data, int datalen)
191 unsigned char *digest;
193 EVP_MD *evp_md = EVP_sha1();
195 unsigned char *sigblob;
201 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
202 error("dsa_verify: no DSA key");
206 if (!(datafellows & SSH_BUG_SIGBLOB) &&
207 signaturelen == SIGBLOB_LEN) {
208 datafellows |= ~SSH_BUG_SIGBLOB;
209 log("autodetect SSH_BUG_SIGBLOB");
210 } else if ((datafellows & SSH_BUG_SIGBLOB) &&
211 signaturelen != SIGBLOB_LEN) {
212 log("autoremove SSH_BUG_SIGBLOB");
213 datafellows &= ~SSH_BUG_SIGBLOB;
216 debug("len %d datafellows %d", signaturelen, datafellows);
218 /* fetch signature */
219 if (datafellows & SSH_BUG_SIGBLOB) {
226 buffer_append(&b, (char *) signature, signaturelen);
227 ktype = buffer_get_string(&b, NULL);
228 if (strcmp(KEX_DSS, ktype) != 0) {
229 error("dsa_verify: cannot handle type %s", ktype);
233 sigblob = (unsigned char *)buffer_get_string(&b, &len);
234 rlen = buffer_len(&b);
236 error("remaining bytes in signature %d", rlen);
244 if (len != SIGBLOB_LEN) {
245 fatal("bad sigbloblen %d != SIGBLOB_LEN", len);
248 /* parse signature */
252 BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
253 BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
255 if (!(datafellows & SSH_BUG_SIGBLOB)) {
256 memset(sigblob, 0, len);
261 digest = xmalloc(evp_md->md_size);
262 EVP_DigestInit(&md, evp_md);
263 EVP_DigestUpdate(&md, data, datalen);
264 EVP_DigestFinal(&md, digest, NULL);
266 ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa);
268 memset(digest, 0, evp_md->md_size);
284 debug("dsa_verify: signature %s", txt);
289 dsa_generate_key(unsigned int bits)
291 DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
294 fatal("DSA_generate_parameters failed");
296 if (!DSA_generate_key(dsa)) {
297 fatal("DSA_generate_keys failed");
300 k = key_new(KEY_EMPTY);