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.
12 * 3. All advertising materials mentioning features or use of this software
13 * must display the following acknowledgement:
14 * This product includes software developed by Markus Friedl.
15 * 4. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 # include <openssl/bn.h>
41 # include <openssl/dh.h>
42 # include <openssl/rsa.h>
43 # include <openssl/dsa.h>
44 # include <openssl/evp.h>
45 # include <openssl/bio.h>
46 # include <openssl/pem.h>
47 #endif /* HAVE_OPENSSL */
62 #define INTBLOB_LEN 20
63 #define SIGBLOB_LEN (2*INTBLOB_LEN)
66 dsa_serverkey_from_blob(
67 char *serverhostkey, int serverhostkeylen)
75 /* fetch & parse DSA/DSS pubkey */
76 key = key_new(KEY_DSA);
79 buffer_append(&b, serverhostkey, serverhostkeylen);
80 ktype = buffer_get_string(&b, NULL);
81 if (strcmp(KEX_DSS, ktype) != 0) {
82 log("dsa_serverkey_from_blob: cannot handle type %s", ktype);
86 buffer_get_bignum2(&b, dsa->p);
87 buffer_get_bignum2(&b, dsa->q);
88 buffer_get_bignum2(&b, dsa->g);
89 buffer_get_bignum2(&b, dsa->pub_key);
90 rlen = buffer_len(&b);
92 log("dsa_serverkey_from_blob: remaining bytes in serverhostkey %d", rlen);
95 log("keytype %s", ktype);
97 DSA_print_fp(stderr, dsa, 8);
102 dsa_load_private(char *filename)
107 in = BIO_new(BIO_s_file());
109 fatal("BIO_new failed");
110 if (BIO_read_filename(in, filename) <= 0)
111 fatal("BIO_read failed %s: %s", filename, strerror(errno));
112 fprintf(stderr, "read DSA private key\n");
113 dsa = PEM_read_bio_DSAPrivateKey(in,NULL,NULL,NULL);
115 fatal("PEM_read_bio_DSAPrivateKey failed %s", filename);
120 dsa_get_serverkey(char *filename)
122 Key *k = key_new(KEY_EMPTY);
124 k->dsa = dsa_load_private(filename);
126 DSA_print_fp(stderr, dsa, 8);
131 dsa_make_serverkey_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
137 if (key == NULL || key->type != KEY_DSA)
140 buffer_put_cstring(&b, KEX_DSS);
141 buffer_put_bignum2(&b, key->dsa->p);
142 buffer_put_bignum2(&b, key->dsa->q);
143 buffer_put_bignum2(&b, key->dsa->g);
144 buffer_put_bignum2(&b, key->dsa->pub_key);
145 len = buffer_len(&b);
147 memcpy(buf, buffer_ptr(&b), len);
148 memset(buffer_ptr(&b), 0, len);
159 unsigned char **sigp, int *lenp,
160 unsigned char *hash, int hlen)
162 unsigned char *digest;
165 EVP_MD *evp_md = EVP_sha1();
170 unsigned char sigblob[SIGBLOB_LEN];
173 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
174 log("dsa_sign: no DSA key");
177 digest = xmalloc(evp_md->md_size);
178 EVP_DigestInit(&md, evp_md);
179 EVP_DigestUpdate(&md, hash, hlen);
180 EVP_DigestFinal(&md, digest, NULL);
182 sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
184 rlen = BN_num_bytes(sig->r);
185 slen = BN_num_bytes(sig->s);
186 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
187 log("bad sig size %d %d", rlen, slen);
191 log("sig size %d %d", rlen, slen);
193 memset(sigblob, 0, SIGBLOB_LEN);
194 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
195 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
200 ret = xmalloc(SIGBLOB_LEN);
201 memcpy(ret, sigblob, SIGBLOB_LEN);
209 buffer_put_cstring(&b, KEX_DSS);
210 buffer_put_string(&b, sigblob, SIGBLOB_LEN);
211 len = buffer_len(&b);
213 memcpy(ret, buffer_ptr(&b), len);
225 unsigned char *signature, int signaturelen,
226 unsigned char *hash, int hlen)
229 unsigned char *digest;
231 EVP_MD *evp_md = EVP_sha1();
234 unsigned char *sigblob;
240 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
241 log("dsa_verify: no DSA key");
245 if (datafellows && signaturelen != SIGBLOB_LEN) {
246 log("heh? datafellows ssh2 complies with ietf-drafts????");
250 log("len %d datafellows %d", signaturelen, datafellows);
252 /* fetch signature */
259 buffer_append(&b, (char *) signature, signaturelen);
260 ktype = buffer_get_string(&b, NULL);
261 sigblob = (unsigned char *)buffer_get_string(&b, &len);
262 rlen = buffer_len(&b);
264 log("remaining bytes in signature %d", rlen);
268 if (len != SIGBLOB_LEN) {
269 fatal("bad sigbloblen %d != SIGBLOB_LEN", len);
272 /* parse signature */
276 BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
277 BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
279 memset(sigblob, 0, len);
283 /* sha1 the signed data (== session_id == hash) */
284 digest = xmalloc(evp_md->md_size);
285 EVP_DigestInit(&md, evp_md);
286 EVP_DigestUpdate(&md, hash, hlen);
287 EVP_DigestFinal(&md, digest, NULL);
289 ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa);
291 memset(digest, 0, evp_md->md_size);
307 log("dsa_verify: signature %s", txt);