Annotation of src/usr.bin/ssh/dsa.c, Revision 1.6
1.1 markus 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"
1.6 ! markus 31: RCSID("$Id: dsa.c,v 1.5 2000/04/26 20:56:29 markus Exp $");
1.1 markus 32:
33: #include "ssh.h"
34: #include "xmalloc.h"
35: #include "buffer.h"
36: #include "bufaux.h"
37: #include "compat.h"
38:
1.3 markus 39: #include <openssl/bn.h>
40: #include <openssl/dh.h>
41: #include <openssl/rsa.h>
42: #include <openssl/dsa.h>
43: #include <openssl/evp.h>
44: #include <openssl/bio.h>
45: #include <openssl/pem.h>
1.1 markus 46:
1.3 markus 47: #include <openssl/hmac.h>
1.1 markus 48: #include "kex.h"
49: #include "key.h"
1.5 markus 50: #include "uuencode.h"
1.1 markus 51:
52: #define INTBLOB_LEN 20
53: #define SIGBLOB_LEN (2*INTBLOB_LEN)
54:
55: Key *
1.5 markus 56: dsa_key_from_blob(
57: char *blob, int blen)
1.1 markus 58: {
59: Buffer b;
60: char *ktype;
61: int rlen;
62: DSA *dsa;
63: Key *key;
64:
1.5 markus 65: #ifdef DEBUG_DSS
1.6 ! markus 66: dump_base64(stderr, blob, blen);
1.5 markus 67: #endif
1.1 markus 68: /* fetch & parse DSA/DSS pubkey */
69: key = key_new(KEY_DSA);
70: dsa = key->dsa;
71: buffer_init(&b);
1.5 markus 72: buffer_append(&b, blob, blen);
1.1 markus 73: ktype = buffer_get_string(&b, NULL);
74: if (strcmp(KEX_DSS, ktype) != 0) {
1.5 markus 75: error("dsa_key_from_blob: cannot handle type %s", ktype);
1.1 markus 76: key_free(key);
77: return NULL;
78: }
79: buffer_get_bignum2(&b, dsa->p);
80: buffer_get_bignum2(&b, dsa->q);
81: buffer_get_bignum2(&b, dsa->g);
82: buffer_get_bignum2(&b, dsa->pub_key);
83: rlen = buffer_len(&b);
84: if(rlen != 0)
1.5 markus 85: error("dsa_key_from_blob: remaining bytes in key blob %d", rlen);
1.1 markus 86: buffer_free(&b);
87:
1.2 markus 88: debug("keytype %s", ktype);
1.1 markus 89: #ifdef DEBUG_DSS
90: DSA_print_fp(stderr, dsa, 8);
91: #endif
92: return key;
93: }
94: int
1.5 markus 95: dsa_make_key_blob(Key *key, unsigned char **blobp, unsigned int *lenp)
1.1 markus 96: {
97: Buffer b;
98: int len;
99: unsigned char *buf;
100:
101: if (key == NULL || key->type != KEY_DSA)
102: return 0;
103: buffer_init(&b);
104: buffer_put_cstring(&b, KEX_DSS);
105: buffer_put_bignum2(&b, key->dsa->p);
106: buffer_put_bignum2(&b, key->dsa->q);
107: buffer_put_bignum2(&b, key->dsa->g);
108: buffer_put_bignum2(&b, key->dsa->pub_key);
109: len = buffer_len(&b);
110: buf = xmalloc(len);
111: memcpy(buf, buffer_ptr(&b), len);
112: memset(buffer_ptr(&b), 0, len);
113: buffer_free(&b);
114: if (lenp != NULL)
115: *lenp = len;
116: if (blobp != NULL)
117: *blobp = buf;
118: return len;
119: }
120: int
121: dsa_sign(
122: Key *key,
123: unsigned char **sigp, int *lenp,
1.5 markus 124: unsigned char *data, int datalen)
1.1 markus 125: {
126: unsigned char *digest;
127: unsigned char *ret;
128: DSA_SIG *sig;
129: EVP_MD *evp_md = EVP_sha1();
130: EVP_MD_CTX md;
131: unsigned int rlen;
132: unsigned int slen;
133: unsigned int len;
134: unsigned char sigblob[SIGBLOB_LEN];
135: Buffer b;
136:
137: if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
1.2 markus 138: error("dsa_sign: no DSA key");
1.1 markus 139: return -1;
140: }
141: digest = xmalloc(evp_md->md_size);
142: EVP_DigestInit(&md, evp_md);
1.5 markus 143: EVP_DigestUpdate(&md, data, datalen);
1.1 markus 144: EVP_DigestFinal(&md, digest, NULL);
145:
146: sig = DSA_do_sign(digest, evp_md->md_size, key->dsa);
1.5 markus 147: if (sig == NULL) {
148: fatal("dsa_sign: cannot sign");
149: }
1.1 markus 150:
1.4 markus 151: rlen = BN_num_bytes(sig->r);
152: slen = BN_num_bytes(sig->s);
153: if (rlen > INTBLOB_LEN || slen > INTBLOB_LEN) {
1.2 markus 154: error("bad sig size %d %d", rlen, slen);
1.1 markus 155: DSA_SIG_free(sig);
156: return -1;
157: }
1.2 markus 158: debug("sig size %d %d", rlen, slen);
1.1 markus 159:
160: memset(sigblob, 0, SIGBLOB_LEN);
161: BN_bn2bin(sig->r, sigblob+ SIGBLOB_LEN - INTBLOB_LEN - rlen);
162: BN_bn2bin(sig->s, sigblob+ SIGBLOB_LEN - slen);
163: DSA_SIG_free(sig);
164:
165: if (datafellows) {
1.2 markus 166: debug("datafellows");
1.1 markus 167: ret = xmalloc(SIGBLOB_LEN);
168: memcpy(ret, sigblob, SIGBLOB_LEN);
169: if (lenp != NULL)
170: *lenp = SIGBLOB_LEN;
171: if (sigp != NULL)
172: *sigp = ret;
173: } else {
174: /* ietf-drafts */
175: buffer_init(&b);
176: buffer_put_cstring(&b, KEX_DSS);
177: buffer_put_string(&b, sigblob, SIGBLOB_LEN);
178: len = buffer_len(&b);
179: ret = xmalloc(len);
180: memcpy(ret, buffer_ptr(&b), len);
181: buffer_free(&b);
182: if (lenp != NULL)
183: *lenp = len;
184: if (sigp != NULL)
185: *sigp = ret;
186: }
187: return 0;
188: }
189: int
190: dsa_verify(
191: Key *key,
192: unsigned char *signature, int signaturelen,
1.5 markus 193: unsigned char *data, int datalen)
1.1 markus 194: {
195: Buffer b;
196: unsigned char *digest;
197: DSA_SIG *sig;
198: EVP_MD *evp_md = EVP_sha1();
199: EVP_MD_CTX md;
200: char *ktype;
201: unsigned char *sigblob;
202: char *txt;
203: unsigned int len;
204: int rlen;
205: int ret;
206:
207: if (key == NULL || key->type != KEY_DSA || key->dsa == NULL) {
1.2 markus 208: error("dsa_verify: no DSA key");
1.1 markus 209: return -1;
210: }
211:
212: if (datafellows && signaturelen != SIGBLOB_LEN) {
213: log("heh? datafellows ssh2 complies with ietf-drafts????");
214: datafellows = 0;
215: }
216:
1.2 markus 217: debug("len %d datafellows %d", signaturelen, datafellows);
1.1 markus 218:
219: /* fetch signature */
220: if (datafellows) {
221: sigblob = signature;
222: len = signaturelen;
223: } else {
224: /* ietf-drafts */
225: buffer_init(&b);
226: buffer_append(&b, (char *) signature, signaturelen);
227: ktype = buffer_get_string(&b, NULL);
228: sigblob = (unsigned char *)buffer_get_string(&b, &len);
229: rlen = buffer_len(&b);
230: if(rlen != 0)
1.2 markus 231: error("remaining bytes in signature %d", rlen);
1.1 markus 232: buffer_free(&b);
233: }
234:
235: if (len != SIGBLOB_LEN) {
236: fatal("bad sigbloblen %d != SIGBLOB_LEN", len);
237: }
238:
239: /* parse signature */
240: sig = DSA_SIG_new();
241: sig->r = BN_new();
242: sig->s = BN_new();
243: BN_bin2bn(sigblob, INTBLOB_LEN, sig->r);
244: BN_bin2bn(sigblob+ INTBLOB_LEN, INTBLOB_LEN, sig->s);
245: if (!datafellows) {
246: memset(sigblob, 0, len);
247: xfree(sigblob);
248: }
249:
1.5 markus 250: /* sha1 the data */
1.1 markus 251: digest = xmalloc(evp_md->md_size);
252: EVP_DigestInit(&md, evp_md);
1.5 markus 253: EVP_DigestUpdate(&md, data, datalen);
1.1 markus 254: EVP_DigestFinal(&md, digest, NULL);
255:
256: ret = DSA_do_verify(digest, evp_md->md_size, sig, key->dsa);
257:
258: memset(digest, 0, evp_md->md_size);
259: xfree(digest);
260: DSA_SIG_free(sig);
261:
262: switch (ret) {
263: case 1:
264: txt = "correct";
265: break;
266: case 0:
267: txt = "incorrect";
268: break;
269: case -1:
270: default:
271: txt = "error";
272: break;
273: }
1.2 markus 274: debug("dsa_verify: signature %s", txt);
1.1 markus 275: return ret;
1.5 markus 276: }
277:
278: Key *
279: dsa_generate_key(unsigned int bits)
280: {
281: DSA *dsa = DSA_generate_parameters(bits, NULL, 0, NULL, NULL, NULL, NULL);
282: Key *k;
283: if (dsa == NULL) {
284: fatal("DSA_generate_parameters failed");
285: }
286: if (!DSA_generate_key(dsa)) {
287: fatal("DSA_generate_keys failed");
288: }
289:
290: k = key_new(KEY_EMPTY);
291: k->type = KEY_DSA;
292: k->dsa = dsa;
293: return k;
1.1 markus 294: }