]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - crypto/openssh/dsa.c
Vendor import of OpenSSH-portable 3.5p1.
[FreeBSD/FreeBSD.git] / crypto / openssh / dsa.c
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  *
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.
23  */
24
25 #include "includes.h"
26 RCSID("$OpenBSD: dsa.c,v 1.11 2000/09/07 20:27:51 deraadt Exp $");
27
28 #include "ssh.h"
29 #include "xmalloc.h"
30 #include "buffer.h"
31 #include "bufaux.h"
32 #include "compat.h"
33
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>
41
42 #include <openssl/hmac.h>
43 #include "kex.h"
44 #include "key.h"
45 #include "uuencode.h"
46
47 #define INTBLOB_LEN     20
48 #define SIGBLOB_LEN     (2*INTBLOB_LEN)
49
50 Key *
51 dsa_key_from_blob(char *blob, int blen)
52 {
53         Buffer b;
54         char *ktype;
55         int rlen;
56         DSA *dsa;
57         Key *key;
58
59 #ifdef DEBUG_DSS
60         dump_base64(stderr, blob, blen);
61 #endif
62         /* fetch & parse DSA/DSS pubkey */
63         buffer_init(&b);
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);
68                 buffer_free(&b);
69                 xfree(ktype);
70                 return NULL;
71         }
72         key = key_new(KEY_DSA);
73         dsa = 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);
79         if(rlen != 0)
80                 error("dsa_key_from_blob: remaining bytes in key blob %d", rlen);
81         buffer_free(&b);
82         xfree(ktype);
83
84 #ifdef DEBUG_DSS
85         DSA_print_fp(stderr, dsa, 8);
86 #endif
87         return key;
88 }
89 int
90 dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
91 {
92         Buffer b;
93         int len;
94         unsigned char *buf;
95
96         if (key == NULL || key->type != KEY_DSA)
97                 return 0;
98         buffer_init(&b);
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);
105         buf = xmalloc(len);
106         memcpy(buf, buffer_ptr(&b), len);
107         memset(buffer_ptr(&b), 0, len);
108         buffer_free(&b);
109         if (lenp != NULL)
110                 *lenp = len;
111         if (blobp != NULL)
112                 *blobp = buf;
113         return len;
114 }
115 int
116 dsa_sign(
117     Key *key,
118     unsigned char **sigp, int *lenp,
119     unsigned char *data, int datalen)
120 {
121         unsigned char *digest;
122         unsigned char *ret;
123         DSA_SIG *sig;
124         EVP_MD *evp_md = EVP_sha1();
125         EVP_MD_CTX md;
126         unsigned int rlen;
127         unsigned int slen;
128         unsigned int len;
129         unsigned char sigblob[SIGBLOB_LEN];
130         Buffer b;
131
132         if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
133                 error("dsa_sign: no DSA key");
134                 return -1;
135         }
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);
140
141         sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
142         if (sig == NULL) {
143                 fatal("dsa_sign: cannot sign");
144         }
145
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);
150                 DSA_SIG_free(sig);
151                 return -1;
152         }
153         debug("sig size %d %d", rlen, slen);
154
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);
158         DSA_SIG_free(sig);
159
160         if (datafellows & SSH_BUG_SIGBLOB) {
161                 debug("datafellows");
162                 ret = xmalloc(SIGBLOB_LEN);
163                 memcpy(ret, sigblob, SIGBLOB_LEN);
164                 if (lenp != NULL)
165                         *lenp = SIGBLOB_LEN;
166                 if (sigp != NULL)
167                         *sigp = ret;
168         } else {
169                 /* ietf-drafts */
170                 buffer_init(&b);
171                 buffer_put_cstring(&b, KEX_DSS);
172                 buffer_put_string(&b, sigblob, SIGBLOB_LEN);
173                 len = buffer_len(&b);
174                 ret = xmalloc(len);
175                 memcpy(ret, buffer_ptr(&b), len);
176                 buffer_free(&b);
177                 if (lenp != NULL)
178                         *lenp = len;
179                 if (sigp != NULL)
180                         *sigp = ret;
181         }
182         return 0;
183 }
184 int
185 dsa_verify(
186     Key *key,
187     unsigned char *signature, int signaturelen,
188     unsigned char *data, int datalen)
189 {
190         Buffer b;
191         unsigned char *digest;
192         DSA_SIG *sig;
193         EVP_MD *evp_md = EVP_sha1();
194         EVP_MD_CTX md;
195         unsigned char *sigblob;
196         char *txt;
197         unsigned int len;
198         int rlen;
199         int ret;
200
201         if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
202                 error("dsa_verify: no DSA key");
203                 return -1;
204         }
205
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;
214         }
215
216         debug("len %d datafellows %d", signaturelen, datafellows);
217
218         /* fetch signature */
219         if (datafellows & SSH_BUG_SIGBLOB) {
220                 sigblob = signature;
221                 len = signaturelen;
222         } else {
223                 /* ietf-drafts */
224                 char *ktype;
225                 buffer_init(&b);
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);
230                         buffer_free(&b);
231                         return -1;
232                 }
233                 sigblob = (unsigned char *)buffer_get_string(&b, &len);
234                 rlen = buffer_len(&b);
235                 if(rlen != 0) {
236                         error("remaining bytes in signature %d", rlen);
237                         buffer_free(&b);
238                         return -1;
239                 }
240                 buffer_free(&b);
241                 xfree(ktype);
242         }
243
244         if (len != SIGBLOB_LEN) {
245                 fatal("bad sigbloblen %d != SIGBLOB_LEN", len);
246         }
247
248         /* parse signature */
249         sig = DSA_SIG_new();
250         sig->r = BN_new();
251         sig->s = BN_new();
252         BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
253         BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
254
255         if (!(datafellows & SSH_BUG_SIGBLOB)) {
256                 memset(sigblob, 0, len);
257                 xfree(sigblob);
258         }
259         
260         /* sha1 the data */
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);
265
266         ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa);
267
268         memset(digest, 0, evp_md->md_size);
269         xfree(digest);
270         DSA_SIG_free(sig);
271
272         switch (ret) {
273         case 1:
274                 txt = "correct";
275                 break;
276         case 0:
277                 txt = "incorrect";
278                 break;
279         case -1:
280         default:
281                 txt = "error";
282                 break;
283         }
284         debug("dsa_verify: signature %s", txt);
285         return ret;
286 }
287
288 Key *
289 dsa_generate_key(unsigned int bits)
290 {
291         DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
292         Key *k;
293         if (dsa == NULL) {
294                 fatal("DSA_generate_parameters failed");
295         }
296         if (!DSA_generate_key(dsa)) {
297                 fatal("DSA_generate_keys failed");
298         }
299
300         k = key_new(KEY_EMPTY);
301         k->type = KEY_DSA;
302         k->dsa = dsa;
303         return k;
304 }