Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-5]: src/crypto/dist/ssh Pullup 1.2 [itojun]:
details: https://anonhg.NetBSD.org/src/rev/c1331e418a1e
branches: netbsd-1-5
changeset: 489764:c1331e418a1e
user: tv <tv%NetBSD.org@localhost>
date: Tue Oct 17 01:21:01 2000 +0000
description:
Pullup 1.2 [itojun]:
improve error message on rnd(4) failure. the old text made reference
to ssl(4), which is openssl specific (talks about plugin RSA library).
diffstat:
crypto/dist/ssh/kex.c | 478 +++++++++++++++++++
crypto/dist/ssh/ssh-add.c | 314 ++++++++++++
crypto/dist/ssh/ssh-agent.c | 829 +++++++++++++++++++++++++++++++++
crypto/dist/ssh/ssh-keygen.c | 755 ++++++++++++++++++++++++++++++
crypto/dist/ssh/ssh.c | 1029 ++++++++++++++++++++++++++++++++++++++++++
5 files changed, 3405 insertions(+), 0 deletions(-)
diffs (truncated from 3425 to 300 lines):
diff -r a37b62106d7d -r c1331e418a1e crypto/dist/ssh/kex.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/dist/ssh/kex.c Tue Oct 17 01:21:01 2000 +0000
@@ -0,0 +1,478 @@
+/* $NetBSD: kex.c,v 1.1.1.1.2.2 2000/10/17 01:21:01 tv Exp $ */
+
+/*
+ * Copyright (c) 2000 Markus Friedl. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* from OpenBSD: kex.c,v 1.10 2000/09/07 20:27:51 deraadt Exp */
+
+#include <sys/cdefs.h>
+#ifndef lint
+__RCSID("$NetBSD: kex.c,v 1.1.1.1.2.2 2000/10/17 01:21:01 tv Exp $");
+#endif
+
+#include "includes.h"
+
+#include "ssh.h"
+#include "ssh2.h"
+#include "xmalloc.h"
+#include "buffer.h"
+#include "bufaux.h"
+#include "packet.h"
+#include "cipher.h"
+#include "compat.h"
+
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+
+#include <openssl/crypto.h>
+#include <openssl/bio.h>
+#include <openssl/bn.h>
+#include <openssl/dh.h>
+#include <openssl/pem.h>
+#include <openssl/rand.h>
+
+#include "kex.h"
+
+#define KEX_COOKIE_LEN 16
+
+Buffer *
+kex_init(char *myproposal[PROPOSAL_MAX])
+{
+ int first_kex_packet_follows = 0;
+ unsigned char cookie[KEX_COOKIE_LEN];
+ u_int32_t rand = 0;
+ int i;
+ Buffer *ki = xmalloc(sizeof(*ki));
+ for (i = 0; i < KEX_COOKIE_LEN; i++) {
+ if (i % 4 == 0) {
+ /* XXXthorpej */
+ RAND_pseudo_bytes((u_char *)&rand, sizeof(rand));
+ }
+ cookie[i] = rand & 0xff;
+ rand >>= 8;
+ }
+ buffer_init(ki);
+ buffer_append(ki, (char *)cookie, sizeof cookie);
+ for (i = 0; i < PROPOSAL_MAX; i++)
+ buffer_put_cstring(ki, myproposal[i]);
+ buffer_put_char(ki, first_kex_packet_follows);
+ buffer_put_int(ki, 0); /* uint32 reserved */
+ return ki;
+}
+
+/* send kexinit, parse and save reply */
+void
+kex_exchange_kexinit(
+ Buffer *my_kexinit, Buffer *peer_kexint,
+ char *peer_proposal[PROPOSAL_MAX])
+{
+ int i;
+ char *ptr;
+ int plen;
+
+ debug("send KEXINIT");
+ packet_start(SSH2_MSG_KEXINIT);
+ packet_put_raw(buffer_ptr(my_kexinit), buffer_len(my_kexinit));
+ packet_send();
+ packet_write_wait();
+ debug("done");
+
+ /*
+ * read and save raw KEXINIT payload in buffer. this is used during
+ * computation of the session_id and the session keys.
+ */
+ debug("wait KEXINIT");
+ packet_read_expect(&plen, SSH2_MSG_KEXINIT);
+ ptr = packet_get_raw(&plen);
+ buffer_append(peer_kexint, ptr, plen);
+
+ /* parse packet and save algorithm proposal */
+ /* skip cookie */
+ for (i = 0; i < KEX_COOKIE_LEN; i++)
+ packet_get_char();
+ /* extract kex init proposal strings */
+ for (i = 0; i < PROPOSAL_MAX; i++) {
+ peer_proposal[i] = packet_get_string(NULL);
+ debug("got kexinit: %s", peer_proposal[i]);
+ }
+ /* first kex follow / reserved */
+ i = packet_get_char();
+ debug("first kex follow: %d ", i);
+ i = packet_get_int();
+ debug("reserved: %d ", i);
+ packet_done();
+ debug("done");
+}
+
+/* diffie-hellman-group1-sha1 */
+
+int
+dh_pub_is_valid(DH *dh, BIGNUM *dh_pub)
+{
+ int i;
+ int n = BN_num_bits(dh_pub);
+ int bits_set = 0;
+
+ /* we only accept g==2 */
+ if (!BN_is_word(dh->g, 2)) {
+ log("invalid DH base != 2");
+ return 0;
+ }
+ if (dh_pub->neg) {
+ log("invalid public DH value: negativ");
+ return 0;
+ }
+ for (i = 0; i <= n; i++)
+ if (BN_is_bit_set(dh_pub, i))
+ bits_set++;
+ debug("bits set: %d/%d", bits_set, BN_num_bits(dh->p));
+
+ /* if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial */
+ if (bits_set > 1 && (BN_cmp(dh_pub, dh->p) == -1))
+ return 1;
+ log("invalid public DH value (%d/%d)", bits_set, BN_num_bits(dh->p));
+ return 0;
+}
+
+DH *
+dh_new_group1()
+{
+ static char *group1 =
+ "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" "C4C6628B" "80DC1CD1"
+ "29024E08" "8A67CC74" "020BBEA6" "3B139B22" "514A0879" "8E3404DD"
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" "4FE1356D" "6D51C245"
+ "E485B576" "625E7EC6" "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED"
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" "49286651" "ECE65381"
+ "FFFFFFFF" "FFFFFFFF";
+ DH *dh;
+ int ret, tries = 0;
+ dh = DH_new();
+ if(dh == NULL)
+ fatal("DH_new");
+ ret = BN_hex2bn(&dh->p, group1);
+ if(ret<0)
+ fatal("BN_hex2bn");
+ dh->g = BN_new();
+ if(dh->g == NULL)
+ fatal("DH_new g");
+ BN_set_word(dh->g, 2);
+ do {
+ if (DH_generate_key(dh) == 0)
+ fatal("failed to generate DH key: rnd(4) is mandatory.");
+ if (tries++ > 10)
+ fatal("dh_new_group1: too many bad keys: giving up");
+ } while (!dh_pub_is_valid(dh, dh->pub_key));
+ return dh;
+}
+
+#ifdef DEBUG_KEX
+static void
+dump_digest(unsigned char *digest, int len)
+{
+ int i;
+ for (i = 0; i< len; i++){
+ fprintf(stderr, "%02x", digest[i]);
+ if(i%2!=0)
+ fprintf(stderr, " ");
+ }
+ fprintf(stderr, "\n");
+}
+#endif
+
+unsigned char *
+kex_hash(
+ char *client_version_string,
+ char *server_version_string,
+ char *ckexinit, int ckexinitlen,
+ char *skexinit, int skexinitlen,
+ char *serverhostkeyblob, int sbloblen,
+ BIGNUM *client_dh_pub,
+ BIGNUM *server_dh_pub,
+ BIGNUM *shared_secret)
+{
+ Buffer b;
+ static unsigned char digest[EVP_MAX_MD_SIZE];
+ EVP_MD *evp_md = EVP_sha1();
+ EVP_MD_CTX md;
+
+ buffer_init(&b);
+ buffer_put_string(&b, client_version_string, strlen(client_version_string));
+ buffer_put_string(&b, server_version_string, strlen(server_version_string));
+
+ /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
+ buffer_put_int(&b, ckexinitlen+1);
+ buffer_put_char(&b, SSH2_MSG_KEXINIT);
+ buffer_append(&b, ckexinit, ckexinitlen);
+ buffer_put_int(&b, skexinitlen+1);
+ buffer_put_char(&b, SSH2_MSG_KEXINIT);
+ buffer_append(&b, skexinit, skexinitlen);
+
+ buffer_put_string(&b, serverhostkeyblob, sbloblen);
+ buffer_put_bignum2(&b, client_dh_pub);
+ buffer_put_bignum2(&b, server_dh_pub);
+ buffer_put_bignum2(&b, shared_secret);
+
+#ifdef DEBUG_KEX
+ buffer_dump(&b);
+#endif
+
+ EVP_DigestInit(&md, evp_md);
+ EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
+ EVP_DigestFinal(&md, digest, NULL);
+
+ buffer_free(&b);
+
+#ifdef DEBUG_KEX
+ dump_digest(digest, evp_md->md_size);
+#endif
+ return digest;
+}
+
+static unsigned char *
+derive_key(int id, int need, char unsigned *hash, BIGNUM *shared_secret)
+{
+ Buffer b;
+ EVP_MD *evp_md = EVP_sha1();
+ EVP_MD_CTX md;
+ char c = id;
+ int have;
+ int mdsz = evp_md->md_size;
+ unsigned char *digest = xmalloc(((need+mdsz-1)/mdsz)*mdsz);
+
+ buffer_init(&b);
+ buffer_put_bignum2(&b, shared_secret);
+
+ EVP_DigestInit(&md, evp_md);
+ EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b)); /* shared_secret K */
+ EVP_DigestUpdate(&md, hash, mdsz); /* transport-06 */
+ EVP_DigestUpdate(&md, &c, 1); /* key id */
+ EVP_DigestUpdate(&md, hash, mdsz); /* session id */
+ EVP_DigestFinal(&md, digest, NULL);
+
+ /* expand */
+ for (have = mdsz; need > have; have += mdsz) {
+ EVP_DigestInit(&md, evp_md);
+ EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
+ EVP_DigestUpdate(&md, hash, mdsz);
+ EVP_DigestUpdate(&md, digest, have);
+ EVP_DigestFinal(&md, digest + have, NULL);
+ }
+ buffer_free(&b);
+#ifdef DEBUG_KEX
+ fprintf(stderr, "Digest '%c'== ", c);
+ dump_digest(digest, need);
+#endif
+ return digest;
+}
+
+#define NKEYS 6
+
+#define MAX_PROP 20
+#define SEP ","
+
+static char *
+get_match(char *client, char *server)
+{
Home |
Main Index |
Thread Index |
Old Index