summaryrefslogtreecommitdiff
path: root/dsa.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2000-04-16 11:49:14 +1000
committerDamien Miller <djm@mindrot.org>2000-04-16 11:49:14 +1000
commitd8495e7d61c72093d81e9b2dba2a5acc440c3787 (patch)
treea6a4778dadf85a334c13efa2deaed5242d1563cd /dsa.c
parent4af51306d9a51459a5bef922df1037f876ae51fe (diff)
forgot -kb
Diffstat (limited to 'dsa.c')
-rw-r--r--dsa.c310
1 files changed, 0 insertions, 310 deletions
diff --git a/dsa.c b/dsa.c
deleted file mode 100644
index 778d43d59..000000000
--- a/dsa.c
+++ /dev/null
@@ -1,310 +0,0 @@
1/*
2 * Copyright (c) 2000 Markus Friedl. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
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.
17 *
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.
28 */
29
30#include "includes.h"
31RCSID("$Id: dsa.c,v 1.4 2000/04/14 10:30:31 markus Exp $");
32
33#include "ssh.h"
34#include "xmalloc.h"
35#include "buffer.h"
36#include "bufaux.h"
37#include "compat.h"
38
39#if HAVE_OPENSSL
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# include <openssl/hmac.h>
48#endif /* HAVE_OPENSSL */
49#if HAVE_SSL
50# include <ssl/bn.h>
51# include <ssl/dh.h>
52# include <ssl/rsa.h>
53# include <ssl/dsa.h>
54# include <ssl/evp.h>
55# include <ssl/bio.h>
56# include <ssl/pem.h>
57# include <ssl/hmac.h>
58#endif /* HAVE_SSL */
59
60#include "kex.h"
61#include "key.h"
62
63#define INTBLOB_LEN 20
64#define SIGBLOB_LEN (2*INTBLOB_LEN)
65
66Key *
67dsa_serverkey_from_blob(
68 char *serverhostkey, int serverhostkeylen)
69{
70 Buffer b;
71 char *ktype;
72 int rlen;
73 DSA *dsa;
74 Key *key;
75
76 /* fetch & parse DSA/DSS pubkey */
77 key = key_new(KEY_DSA);
78 dsa = key->dsa;
79 buffer_init(&b);
80 buffer_append(&b, serverhostkey, serverhostkeylen);
81 ktype = buffer_get_string(&b, NULL);
82 if (strcmp(KEX_DSS, ktype) != 0) {
83 error("dsa_serverkey_from_blob: cannot handle type %s", ktype);
84 key_free(key);
85 return NULL;
86 }
87 buffer_get_bignum2(&b, dsa->p);
88 buffer_get_bignum2(&b, dsa->q);
89 buffer_get_bignum2(&b, dsa->g);
90 buffer_get_bignum2(&b, dsa->pub_key);
91 rlen = buffer_len(&b);
92 if(rlen != 0)
93 error("dsa_serverkey_from_blob: remaining bytes in serverhostkey %d", rlen);
94 buffer_free(&b);
95
96 debug("keytype %s", ktype);
97#ifdef DEBUG_DSS
98 DSA_print_fp(stderr, dsa, 8);
99#endif
100 return key;
101}
102DSA *
103dsa_load_private(char *filename)
104{
105 DSA *dsa;
106 BIO *in;
107
108 in = BIO_new(BIO_s_file());
109 if (in == NULL)
110 fatal("BIO_new failed");
111 if (BIO_read_filename(in, filename) <= 0)
112 fatal("BIO_read failed %s: %s", filename, strerror(errno));
113 fprintf(stderr, "read DSA private key\n");
114 dsa = PEM_read_bio_DSAPrivateKey(in,NULL,NULL,NULL);
115 if (dsa == NULL)
116 fatal("PEM_read_bio_DSAPrivateKey failed %s", filename);
117 BIO_free(in);
118 return dsa;
119}
120Key *
121dsa_get_serverkey(char *filename)
122{
123 Key *k = key_new(KEY_EMPTY);
124 k->type = KEY_DSA;
125 k->dsa = dsa_load_private(filename);
126#ifdef DEBUG_DSS
127 DSA_print_fp(stderr, dsa, 8);
128#endif
129 return k;
130}
131int
132dsa_make_serverkey_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
133{
134 Buffer b;
135 int len;
136 unsigned char *buf;
137
138 if (key == NULL || key->type != KEY_DSA)
139 return 0;
140 buffer_init(&b);
141 buffer_put_cstring(&b, KEX_DSS);
142 buffer_put_bignum2(&b, key->dsa->p);
143 buffer_put_bignum2(&b, key->dsa->q);
144 buffer_put_bignum2(&b, key->dsa->g);
145 buffer_put_bignum2(&b, key->dsa->pub_key);
146 len = buffer_len(&b);
147 buf = xmalloc(len);
148 memcpy(buf, buffer_ptr(&b), len);
149 memset(buffer_ptr(&b), 0, len);
150 buffer_free(&b);
151 if (lenp != NULL)
152 *lenp = len;
153 if (blobp != NULL)
154 *blobp = buf;
155 return len;
156}
157int
158dsa_sign(
159 Key *key,
160 unsigned char **sigp, int *lenp,
161 unsigned char *hash, int hlen)
162{
163 unsigned char *digest;
164 unsigned char *ret;
165 DSA_SIG *sig;
166 EVP_MD *evp_md = EVP_sha1();
167 EVP_MD_CTX md;
168 unsigned int rlen;
169 unsigned int slen;
170 unsigned int len;
171 unsigned char sigblob[SIGBLOB_LEN];
172 Buffer b;
173
174 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
175 error("dsa_sign: no DSA key");
176 return -1;
177 }
178 digest = xmalloc(evp_md->md_size);
179 EVP_DigestInit(&md, evp_md);
180 EVP_DigestUpdate(&md, hash, hlen);
181 EVP_DigestFinal(&md, digest, NULL);
182
183 sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
184
185 rlen = BN_num_bytes(sig->r);
186 slen = BN_num_bytes(sig->s);
187 if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
188 error("bad sig size %d %d", rlen, slen);
189 DSA_SIG_free(sig);
190 return -1;
191 }
192 debug("sig size %d %d", rlen, slen);
193
194 memset(sigblob, 0, SIGBLOB_LEN);
195 BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
196 BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
197 DSA_SIG_free(sig);
198
199 if (datafellows) {
200 debug("datafellows");
201 ret = xmalloc(SIGBLOB_LEN);
202 memcpy(ret, sigblob, SIGBLOB_LEN);
203 if (lenp != NULL)
204 *lenp = SIGBLOB_LEN;
205 if (sigp != NULL)
206 *sigp = ret;
207 } else {
208 /* ietf-drafts */
209 buffer_init(&b);
210 buffer_put_cstring(&b, KEX_DSS);
211 buffer_put_string(&b, sigblob, SIGBLOB_LEN);
212 len = buffer_len(&b);
213 ret = xmalloc(len);
214 memcpy(ret, buffer_ptr(&b), len);
215 buffer_free(&b);
216 if (lenp != NULL)
217 *lenp = len;
218 if (sigp != NULL)
219 *sigp = ret;
220 }
221 return 0;
222}
223int
224dsa_verify(
225 Key *key,
226 unsigned char *signature, int signaturelen,
227 unsigned char *hash, int hlen)
228{
229 Buffer b;
230 unsigned char *digest;
231 DSA_SIG *sig;
232 EVP_MD *evp_md = EVP_sha1();
233 EVP_MD_CTX md;
234 char *ktype;
235 unsigned char *sigblob;
236 char *txt;
237 unsigned int len;
238 int rlen;
239 int ret;
240
241 if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
242 error("dsa_verify: no DSA key");
243 return -1;
244 }
245
246 if (datafellows && signaturelen != SIGBLOB_LEN) {
247 log("heh? datafellows ssh2 complies with ietf-drafts????");
248 datafellows = 0;
249 }
250
251 debug("len %d datafellows %d", signaturelen, datafellows);
252
253 /* fetch signature */
254 if (datafellows) {
255 sigblob = signature;
256 len = signaturelen;
257 } else {
258 /* ietf-drafts */
259 buffer_init(&b);
260 buffer_append(&b, (char *) signature, signaturelen);
261 ktype = buffer_get_string(&b, NULL);
262 sigblob = (unsigned char *)buffer_get_string(&b, &len);
263 rlen = buffer_len(&b);
264 if(rlen != 0)
265 error("remaining bytes in signature %d", rlen);
266 buffer_free(&b);
267 }
268
269 if (len != SIGBLOB_LEN) {
270 fatal("bad sigbloblen %d != SIGBLOB_LEN", len);
271 }
272
273 /* parse signature */
274 sig = DSA_SIG_new();
275 sig->r = BN_new();
276 sig->s = BN_new();
277 BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
278 BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
279 if (!datafellows) {
280 memset(sigblob, 0, len);
281 xfree(sigblob);
282 }
283
284 /* sha1 the signed data (== session_id == hash) */
285 digest = xmalloc(evp_md->md_size);
286 EVP_DigestInit(&md, evp_md);
287 EVP_DigestUpdate(&md, hash, hlen);
288 EVP_DigestFinal(&md, digest, NULL);
289
290 ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa);
291
292 memset(digest, 0, evp_md->md_size);
293 xfree(digest);
294 DSA_SIG_free(sig);
295
296 switch (ret) {
297 case 1:
298 txt = "correct";
299 break;
300 case 0:
301 txt = "incorrect";
302 break;
303 case -1:
304 default:
305 txt = "error";
306 break;
307 }
308 debug("dsa_verify: signature %s", txt);
309 return ret;
310}