upstream commit

unifdef WITH_SSH1 ok markus@

Upstream-ID: 9716e62a883ef8826c57f4d33b4a81a9cc7755c7
This commit is contained in:
djm@openbsd.org 2017-04-30 23:10:43 +00:00 committed by Damien Miller
parent d4084cd230
commit 56912dea6e
16 changed files with 15 additions and 972 deletions

123
authfd.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfd.c,v 1.100 2015/12/04 16:41:28 markus Exp $ */ /* $OpenBSD: authfd.c,v 1.101 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -199,43 +199,6 @@ ssh_lock_agent(int sock, int lock, const char *password)
return r; return r;
} }
#ifdef WITH_SSH1
static int
deserialise_identity1(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
{
struct sshkey *key;
int r, keybits;
u_int32_t bits;
char *comment = NULL;
if ((key = sshkey_new(KEY_RSA1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_u32(ids, &bits)) != 0 ||
(r = sshbuf_get_bignum1(ids, key->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(ids, key->rsa->n)) != 0 ||
(r = sshbuf_get_cstring(ids, &comment, NULL)) != 0)
goto out;
keybits = BN_num_bits(key->rsa->n);
/* XXX previously we just warned here. I think we should be strict */
if (keybits < 0 || bits != (u_int)keybits) {
r = SSH_ERR_KEY_BITS_MISMATCH;
goto out;
}
if (keyp != NULL) {
*keyp = key;
key = NULL;
}
if (commentp != NULL) {
*commentp = comment;
comment = NULL;
}
r = 0;
out:
sshkey_free(key);
free(comment);
return r;
}
#endif
static int static int
deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp) deserialise_identity2(struct sshbuf *ids, struct sshkey **keyp, char **commentp)
@ -331,11 +294,6 @@ ssh_fetch_identitylist(int sock, int version, struct ssh_identitylist **idlp)
for (i = 0; i < num;) { for (i = 0; i < num;) {
switch (version) { switch (version) {
case 1: case 1:
#ifdef WITH_SSH1
if ((r = deserialise_identity1(msg,
&(idl->keys[i]), &(idl->comments[i]))) != 0)
goto out;
#endif
break; break;
case 2: case 2:
if ((r = deserialise_identity2(msg, if ((r = deserialise_identity2(msg,
@ -385,46 +343,6 @@ ssh_free_identitylist(struct ssh_identitylist *idl)
* otherwise. * otherwise.
*/ */
#ifdef WITH_SSH1
int
ssh_decrypt_challenge(int sock, struct sshkey* key, BIGNUM *challenge,
u_char session_id[16], u_char response[16])
{
struct sshbuf *msg;
int r;
u_char type;
if (key->type != KEY_RSA1)
return SSH_ERR_INVALID_ARGUMENT;
if ((msg = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_put_u8(msg, SSH_AGENTC_RSA_CHALLENGE)) != 0 ||
(r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0 ||
(r = sshbuf_put_bignum1(msg, challenge)) != 0 ||
(r = sshbuf_put(msg, session_id, 16)) != 0 ||
(r = sshbuf_put_u32(msg, 1)) != 0) /* Response type for proto 1.1 */
goto out;
if ((r = ssh_request_reply(sock, msg, msg)) != 0)
goto out;
if ((r = sshbuf_get_u8(msg, &type)) != 0)
goto out;
if (agent_failed(type)) {
r = SSH_ERR_AGENT_FAILURE;
goto out;
} else if (type != SSH_AGENT_RSA_RESPONSE) {
r = SSH_ERR_INVALID_FORMAT;
goto out;
}
if ((r = sshbuf_get(msg, response, 16)) != 0)
goto out;
r = 0;
out:
sshbuf_free(msg);
return r;
}
#endif
/* encode signature algoritm in flag bits, so we can keep the msg format */ /* encode signature algoritm in flag bits, so we can keep the msg format */
static u_int static u_int
@ -494,25 +412,6 @@ ssh_agent_sign(int sock, struct sshkey *key,
/* Encode key for a message to the agent. */ /* Encode key for a message to the agent. */
#ifdef WITH_SSH1
static int
ssh_encode_identity_rsa1(struct sshbuf *b, RSA *key, const char *comment)
{
int r;
/* To keep within the protocol: p < q for ssh. in SSL p > q */
if ((r = sshbuf_put_u32(b, BN_num_bits(key->n))) != 0 ||
(r = sshbuf_put_bignum1(b, key->n)) != 0 ||
(r = sshbuf_put_bignum1(b, key->e)) != 0 ||
(r = sshbuf_put_bignum1(b, key->d)) != 0 ||
(r = sshbuf_put_bignum1(b, key->iqmp)) != 0 ||
(r = sshbuf_put_bignum1(b, key->q)) != 0 ||
(r = sshbuf_put_bignum1(b, key->p)) != 0 ||
(r = sshbuf_put_cstring(b, comment)) != 0)
return r;
return 0;
}
#endif
static int static int
ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key, ssh_encode_identity_ssh2(struct sshbuf *b, struct sshkey *key,
@ -561,16 +460,6 @@ ssh_add_identity_constrained(int sock, struct sshkey *key, const char *comment,
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
switch (key->type) { switch (key->type) {
#ifdef WITH_SSH1
case KEY_RSA1:
type = constrained ?
SSH_AGENTC_ADD_RSA_ID_CONSTRAINED :
SSH_AGENTC_ADD_RSA_IDENTITY;
if ((r = sshbuf_put_u8(msg, type)) != 0 ||
(r = ssh_encode_identity_rsa1(msg, key->rsa, comment)) != 0)
goto out;
break;
#endif
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
case KEY_RSA: case KEY_RSA:
case KEY_RSA_CERT: case KEY_RSA_CERT:
@ -620,16 +509,6 @@ ssh_remove_identity(int sock, struct sshkey *key)
if ((msg = sshbuf_new()) == NULL) if ((msg = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL; return SSH_ERR_ALLOC_FAIL;
#ifdef WITH_SSH1
if (key->type == KEY_RSA1) {
if ((r = sshbuf_put_u8(msg,
SSH_AGENTC_REMOVE_RSA_IDENTITY)) != 0 ||
(r = sshbuf_put_u32(msg, BN_num_bits(key->rsa->n))) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->e)) != 0 ||
(r = sshbuf_put_bignum1(msg, key->rsa->n)) != 0)
goto out;
} else
#endif
if (key->type != KEY_UNSPEC) { if (key->type != KEY_UNSPEC) {
if ((r = sshkey_to_blob(key, &blob, &blen)) != 0) if ((r = sshkey_to_blob(key, &blob, &blen)) != 0)
goto out; goto out;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: authfile.c,v 1.123 2017/03/26 00:18:52 deraadt Exp $ */ /* $OpenBSD: authfile.c,v 1.124 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Copyright (c) 2000, 2013 Markus Friedl. All rights reserved. * Copyright (c) 2000, 2013 Markus Friedl. All rights reserved.
* *
@ -147,35 +147,6 @@ sshkey_load_file(int fd, struct sshbuf *blob)
return r; return r;
} }
#ifdef WITH_SSH1
/*
* Loads the public part of the ssh v1 key file. Returns NULL if an error was
* encountered (the file does not exist or is not readable), and the key
* otherwise.
*/
static int
sshkey_load_public_rsa1(int fd, struct sshkey **keyp, char **commentp)
{
struct sshbuf *b = NULL;
int r;
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
if ((b = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshkey_load_file(fd, b)) != 0)
goto out;
if ((r = sshkey_parse_public_rsa1_fileblob(b, keyp, commentp)) != 0)
goto out;
r = 0;
out:
sshbuf_free(b);
return r;
}
#endif /* WITH_SSH1 */
/* XXX remove error() calls from here? */ /* XXX remove error() calls from here? */
int int
@ -362,21 +333,7 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
if ((fd = open(filename, O_RDONLY)) < 0) if ((fd = open(filename, O_RDONLY)) < 0)
goto skip; goto skip;
#ifdef WITH_SSH1
/* try rsa1 private key */
r = sshkey_load_public_rsa1(fd, keyp, commentp);
close(fd); close(fd);
switch (r) {
case SSH_ERR_INTERNAL_ERROR:
case SSH_ERR_ALLOC_FAIL:
case SSH_ERR_INVALID_ARGUMENT:
case SSH_ERR_SYSTEM_ERROR:
case 0:
return r;
}
#else /* WITH_SSH1 */
close(fd);
#endif /* WITH_SSH1 */
/* try ssh2 public key */ /* try ssh2 public key */
if ((pub = sshkey_new(KEY_UNSPEC)) == NULL) if ((pub = sshkey_new(KEY_UNSPEC)) == NULL)
@ -388,17 +345,6 @@ sshkey_load_public(const char *filename, struct sshkey **keyp, char **commentp)
} }
sshkey_free(pub); sshkey_free(pub);
#ifdef WITH_SSH1
/* try rsa1 public key */
if ((pub = sshkey_new(KEY_RSA1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshkey_try_load_public(pub, filename, commentp)) == 0) {
if (keyp != NULL)
*keyp = pub;
return 0;
}
sshkey_free(pub);
#endif /* WITH_SSH1 */
skip: skip:
/* try .pub suffix */ /* try .pub suffix */

View File

@ -1,4 +1,4 @@
/* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41:57 djm Exp $ */ /* $OpenBSD: cipher.c,v 1.103 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -51,11 +51,6 @@
#include "openbsd-compat/openssl-compat.h" #include "openbsd-compat/openssl-compat.h"
#ifdef WITH_SSH1
extern const EVP_CIPHER *evp_ssh1_bf(void);
extern const EVP_CIPHER *evp_ssh1_3des(void);
extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
#endif
struct sshcipher_ctx { struct sshcipher_ctx {
int plaintext; int plaintext;
@ -87,13 +82,6 @@ struct sshcipher {
}; };
static const struct sshcipher ciphers[] = { static const struct sshcipher ciphers[] = {
#ifdef WITH_SSH1
{ "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc },
{ "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des },
# ifndef OPENSSL_NO_BF
{ "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf },
# endif /* OPENSSL_NO_BF */
#endif /* WITH_SSH1 */
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
{ "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null },
{ "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc },
@ -627,10 +615,6 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len)
} else } else
memcpy(iv, cc->evp->iv, len); memcpy(iv, cc->evp->iv, len);
break; break;
#endif
#ifdef WITH_SSH1
case SSH_CIPHER_3DES:
return ssh1_3des_iv(cc->evp, 0, iv, 24);
#endif #endif
default: default:
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
@ -673,10 +657,6 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv)
} else } else
memcpy(cc->evp->iv, iv, evplen); memcpy(cc->evp->iv, iv, evplen);
break; break;
#endif
#ifdef WITH_SSH1
case SSH_CIPHER_3DES:
return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24);
#endif #endif
default: default:
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: compat.c,v 1.100 2017/02/03 23:01:19 djm Exp $ */ /* $OpenBSD: compat.c,v 1.101 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved.
* *
@ -233,11 +233,6 @@ proto_spec(const char *spec)
for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) { for ((p = strsep(&q, SEP)); p && *p != '\0'; (p = strsep(&q, SEP))) {
switch (atoi(p)) { switch (atoi(p)) {
case 1: case 1:
#ifdef WITH_SSH1
if (ret == SSH_PROTO_UNKNOWN)
ret |= SSH_PROTO_1_PREFERRED;
ret |= SSH_PROTO_1;
#endif
break; break;
case 2: case 2:
ret |= SSH_PROTO_2; ret |= SSH_PROTO_2;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: hostfile.c,v 1.68 2017/03/10 04:26:06 djm Exp $ */ /* $OpenBSD: hostfile.c,v 1.69 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -789,20 +789,7 @@ hostkeys_foreach(const char *path, hostkeys_foreach_fn *callback, void *ctx,
break; break;
} }
if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) { if (!hostfile_read_key(&cp, &kbits, lineinfo.key)) {
#ifdef WITH_SSH1
sshkey_free(lineinfo.key);
lineinfo.key = sshkey_new(KEY_RSA1);
if (lineinfo.key == NULL) {
error("%s: sshkey_new fail", __func__);
r = SSH_ERR_ALLOC_FAIL;
break;
}
if (!hostfile_read_key(&cp, &kbits,
lineinfo.key))
goto bad;
#else
goto bad; goto bad;
#endif
} }
lineinfo.keytype = lineinfo.key->type; lineinfo.keytype = lineinfo.key->type;
lineinfo.comment = cp; lineinfo.comment = cp;

43
kex.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: kex.c,v 1.131 2017/03/15 07:07:39 markus Exp $ */ /* $OpenBSD: kex.c,v 1.132 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* *
@ -980,47 +980,6 @@ kex_derive_keys_bn(struct ssh *ssh, u_char *hash, u_int hashlen,
} }
#endif #endif
#ifdef WITH_SSH1
int
derive_ssh1_session_id(BIGNUM *host_modulus, BIGNUM *server_modulus,
u_int8_t cookie[8], u_int8_t id[16])
{
u_int8_t hbuf[2048], sbuf[2048], obuf[SSH_DIGEST_MAX_LENGTH];
struct ssh_digest_ctx *hashctx = NULL;
size_t hlen, slen;
int r;
hlen = BN_num_bytes(host_modulus);
slen = BN_num_bytes(server_modulus);
if (hlen < (512 / 8) || (u_int)hlen > sizeof(hbuf) ||
slen < (512 / 8) || (u_int)slen > sizeof(sbuf))
return SSH_ERR_KEY_BITS_MISMATCH;
if (BN_bn2bin(host_modulus, hbuf) <= 0 ||
BN_bn2bin(server_modulus, sbuf) <= 0) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
if ((hashctx = ssh_digest_start(SSH_DIGEST_MD5)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if (ssh_digest_update(hashctx, hbuf, hlen) != 0 ||
ssh_digest_update(hashctx, sbuf, slen) != 0 ||
ssh_digest_update(hashctx, cookie, 8) != 0 ||
ssh_digest_final(hashctx, obuf, sizeof(obuf)) != 0) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
memcpy(id, obuf, ssh_digest_bytes(SSH_DIGEST_MD5));
r = 0;
out:
ssh_digest_free(hashctx);
explicit_bzero(hbuf, sizeof(hbuf));
explicit_bzero(sbuf, sizeof(sbuf));
explicit_bzero(obuf, sizeof(obuf));
return r;
}
#endif
#if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH)
void void

View File

@ -74,16 +74,6 @@ ssh_packet_put_raw(struct ssh *ssh, const void *buf, u_int len)
fatal("%s: %s", __func__, ssh_err(r)); fatal("%s: %s", __func__, ssh_err(r));
} }
#ifdef WITH_SSH1
void
ssh_packet_put_bignum(struct ssh *ssh, BIGNUM * value)
{
int r;
if ((r = sshpkt_put_bignum1(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
#endif
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
void void
@ -150,16 +140,6 @@ ssh_packet_get_int64(struct ssh *ssh)
return val; return val;
} }
#ifdef WITH_SSH1
void
ssh_packet_get_bignum(struct ssh *ssh, BIGNUM * value)
{
int r;
if ((r = sshpkt_get_bignum1(ssh, value)) != 0)
fatal("%s: %s", __func__, ssh_err(r));
}
#endif
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
void void

View File

@ -1,4 +1,4 @@
/* $OpenBSD: packet.c,v 1.247 2017/03/11 13:07:35 markus Exp $ */ /* $OpenBSD: packet.c,v 1.248 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -811,34 +811,7 @@ uncompress_buffer(struct ssh *ssh, struct sshbuf *in, struct sshbuf *out)
void void
ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number) ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, int number)
{ {
#ifndef WITH_SSH1
fatal("no SSH protocol 1 support"); fatal("no SSH protocol 1 support");
#else /* WITH_SSH1 */
struct session_state *state = ssh->state;
const struct sshcipher *cipher = cipher_by_number(number);
int r;
const char *wmsg;
if (cipher == NULL)
fatal("%s: unknown cipher number %d", __func__, number);
if (keylen < 20)
fatal("%s: keylen too small: %d", __func__, keylen);
if (keylen > SSH_SESSION_KEY_LENGTH)
fatal("%s: keylen too big: %d", __func__, keylen);
memcpy(state->ssh1_key, key, keylen);
state->ssh1_keylen = keylen;
if ((r = cipher_init(&state->send_context, cipher, key, keylen,
NULL, 0, CIPHER_ENCRYPT)) != 0 ||
(r = cipher_init(&state->receive_context, cipher, key, keylen,
NULL, 0, CIPHER_DECRYPT) != 0))
fatal("%s: cipher_init failed: %s", __func__, ssh_err(r));
if (!state->cipher_warning_done &&
((wmsg = cipher_warning_message(state->send_context)) != NULL ||
(wmsg = cipher_warning_message(state->send_context)) != NULL)) {
error("Warning: %s", wmsg);
state->cipher_warning_done = 1;
}
#endif /* WITH_SSH1 */
} }
/* /*
@ -2862,13 +2835,6 @@ sshpkt_put_ec(struct ssh *ssh, const EC_POINT *v, const EC_GROUP *g)
} }
#endif /* OPENSSL_HAS_ECC */ #endif /* OPENSSL_HAS_ECC */
#ifdef WITH_SSH1
int
sshpkt_put_bignum1(struct ssh *ssh, const BIGNUM *v)
{
return sshbuf_put_bignum1(ssh->state->outgoing_packet, v);
}
#endif /* WITH_SSH1 */
int int
sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v) sshpkt_put_bignum2(struct ssh *ssh, const BIGNUM *v)
@ -2930,13 +2896,6 @@ sshpkt_get_ec(struct ssh *ssh, EC_POINT *v, const EC_GROUP *g)
} }
#endif /* OPENSSL_HAS_ECC */ #endif /* OPENSSL_HAS_ECC */
#ifdef WITH_SSH1
int
sshpkt_get_bignum1(struct ssh *ssh, BIGNUM *v)
{
return sshbuf_get_bignum1(ssh->state->incoming_packet, v);
}
#endif /* WITH_SSH1 */
int int
sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v) sshpkt_get_bignum2(struct ssh *ssh, BIGNUM *v)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: readconf.c,v 1.271 2017/04/28 03:20:27 dtucker Exp $ */ /* $OpenBSD: readconf.c,v 1.272 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -208,15 +208,9 @@ static struct {
{ "smartcarddevice", oUnsupported }, { "smartcarddevice", oUnsupported },
{ "pkcs11provider", oUnsupported }, { "pkcs11provider", oUnsupported },
#endif #endif
#ifdef WITH_SSH1
{ "rsaauthentication", oRSAAuthentication },
{ "rhostsrsaauthentication", oRhostsRSAAuthentication },
{ "compressionlevel", oCompressionLevel },
# else
{ "rsaauthentication", oUnsupported }, { "rsaauthentication", oUnsupported },
{ "rhostsrsaauthentication", oUnsupported }, { "rhostsrsaauthentication", oUnsupported },
{ "compressionlevel", oUnsupported }, { "compressionlevel", oUnsupported },
#endif
{ "forwardagent", oForwardAgent }, { "forwardagent", oForwardAgent },
{ "forwardx11", oForwardX11 }, { "forwardx11", oForwardX11 },
@ -2575,9 +2569,6 @@ dump_client_config(Options *o, const char *host)
/* Integer options */ /* Integer options */
dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots); dump_cfg_int(oCanonicalizeMaxDots, o->canonicalize_max_dots);
#ifdef WITH_SSH1
dump_cfg_int(oCompressionLevel, o->compression_level);
#endif
dump_cfg_int(oConnectionAttempts, o->connection_attempts); dump_cfg_int(oConnectionAttempts, o->connection_attempts);
dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout); dump_cfg_int(oForwardX11Timeout, o->forward_x11_timeout);
dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts); dump_cfg_int(oNumberOfPasswordPrompts, o->number_of_password_prompts);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-add.c,v 1.128 2016/02/15 09:47:49 dtucker Exp $ */ /* $OpenBSD: ssh-add.c,v 1.129 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -79,9 +79,6 @@ static char *default_files[] = {
#endif #endif
#endif /* WITH_OPENSSL */ #endif /* WITH_OPENSSL */
_PATH_SSH_CLIENT_ID_ED25519, _PATH_SSH_CLIENT_ID_ED25519,
#ifdef WITH_SSH1
_PATH_SSH_CLIENT_IDENTITY,
#endif
NULL NULL
}; };
@ -363,11 +360,7 @@ list_identities(int agent_fd, int do_fp)
int r, had_identities = 0; int r, had_identities = 0;
struct ssh_identitylist *idlist; struct ssh_identitylist *idlist;
size_t i; size_t i;
#ifdef WITH_SSH1
int version = 1;
#else
int version = 2; int version = 2;
#endif
for (; version <= 2; version++) { for (; version <= 2; version++) {
if ((r = ssh_fetch_identitylist(agent_fd, version, if ((r = ssh_fetch_identitylist(agent_fd, version,

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-agent.c,v 1.218 2017/03/15 03:52:30 deraadt Exp $ */ /* $OpenBSD: ssh-agent.c,v 1.219 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -257,16 +257,6 @@ process_request_identities(SocketEntry *e, int version)
fatal("%s: buffer error: %s", __func__, ssh_err(r)); fatal("%s: buffer error: %s", __func__, ssh_err(r));
TAILQ_FOREACH(id, &tab->idlist, next) { TAILQ_FOREACH(id, &tab->idlist, next) {
if (id->key->type == KEY_RSA1) { if (id->key->type == KEY_RSA1) {
#ifdef WITH_SSH1
if ((r = sshbuf_put_u32(msg,
BN_num_bits(id->key->rsa->n))) != 0 ||
(r = sshbuf_put_bignum1(msg,
id->key->rsa->e)) != 0 ||
(r = sshbuf_put_bignum1(msg,
id->key->rsa->n)) != 0)
fatal("%s: buffer error: %s",
__func__, ssh_err(r));
#endif
} else { } else {
u_char *blob; u_char *blob;
size_t blen; size_t blen;
@ -289,87 +279,6 @@ process_request_identities(SocketEntry *e, int version)
sshbuf_free(msg); sshbuf_free(msg);
} }
#ifdef WITH_SSH1
/* ssh1 only */
static void
process_authentication_challenge1(SocketEntry *e)
{
u_char buf[32], mdbuf[16], session_id[16];
u_int response_type;
BIGNUM *challenge;
Identity *id;
int r, len;
struct sshbuf *msg;
struct ssh_digest_ctx *md;
struct sshkey *key;
if ((msg = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
if ((key = sshkey_new(KEY_RSA1)) == NULL)
fatal("%s: sshkey_new failed", __func__);
if ((challenge = BN_new()) == NULL)
fatal("%s: BN_new failed", __func__);
if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */
(r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 ||
(r = sshbuf_get_bignum1(e->request, challenge)))
fatal("%s: buffer error: %s", __func__, ssh_err(r));
/* Only protocol 1.1 is supported */
if (sshbuf_len(e->request) == 0)
goto failure;
if ((r = sshbuf_get(e->request, session_id, sizeof(session_id))) != 0 ||
(r = sshbuf_get_u32(e->request, &response_type)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (response_type != 1)
goto failure;
id = lookup_identity(key, 1);
if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
struct sshkey *private = id->key;
/* Decrypt the challenge using the private key. */
if ((r = rsa_private_decrypt(challenge, challenge,
private->rsa) != 0)) {
fatal("%s: rsa_public_encrypt: %s", __func__,
ssh_err(r));
goto failure; /* XXX ? */
}
/* The response is MD5 of decrypted challenge plus session id */
len = BN_num_bytes(challenge);
if (len <= 0 || len > 32) {
logit("%s: bad challenge length %d", __func__, len);
goto failure;
}
memset(buf, 0, 32);
BN_bn2bin(challenge, buf + 32 - len);
if ((md = ssh_digest_start(SSH_DIGEST_MD5)) == NULL ||
ssh_digest_update(md, buf, 32) < 0 ||
ssh_digest_update(md, session_id, 16) < 0 ||
ssh_digest_final(md, mdbuf, sizeof(mdbuf)) < 0)
fatal("%s: md5 failed", __func__);
ssh_digest_free(md);
/* Send the response. */
if ((r = sshbuf_put_u8(msg, SSH_AGENT_RSA_RESPONSE)) != 0 ||
(r = sshbuf_put(msg, mdbuf, sizeof(mdbuf))) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
goto send;
}
failure:
/* Unknown identity or protocol error. Send failure. */
if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
send:
if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
sshkey_free(key);
BN_clear_free(challenge);
sshbuf_free(msg);
}
#endif
static char * static char *
agent_decode_alg(struct sshkey *key, u_int flags) agent_decode_alg(struct sshkey *key, u_int flags)
@ -448,28 +357,8 @@ process_remove_identity(SocketEntry *e, int version)
int r, success = 0; int r, success = 0;
struct sshkey *key = NULL; struct sshkey *key = NULL;
u_char *blob; u_char *blob;
#ifdef WITH_SSH1
u_int bits;
#endif /* WITH_SSH1 */
switch (version) { switch (version) {
#ifdef WITH_SSH1
case 1:
if ((key = sshkey_new(KEY_RSA1)) == NULL) {
error("%s: sshkey_new failed", __func__);
return;
}
if ((r = sshbuf_get_u32(e->request, &bits)) != 0 ||
(r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r));
if (bits != sshkey_size(key))
logit("Warning: identity keysize mismatch: "
"actual %u, announced %u",
sshkey_size(key), bits);
break;
#endif /* WITH_SSH1 */
case 2: case 2:
if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0) if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0)
fatal("%s: buffer error: %s", __func__, ssh_err(r)); fatal("%s: buffer error: %s", __func__, ssh_err(r));
@ -559,45 +448,6 @@ reaper(void)
* XXX this and the corresponding serialisation function probably belongs * XXX this and the corresponding serialisation function probably belongs
* in key.c * in key.c
*/ */
#ifdef WITH_SSH1
static int
agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp)
{
struct sshkey *k = NULL;
int r = SSH_ERR_INTERNAL_ERROR;
*kp = NULL;
if ((k = sshkey_new_private(KEY_RSA1)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */
(r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 ||
(r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 ||
(r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 ||
/* SSH1 and SSL have p and q swapped */
(r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */
(r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */
goto out;
/* Generate additional parameters */
if ((r = rsa_generate_additional_parameters(k->rsa)) != 0)
goto out;
/* enable blinding */
if (RSA_blinding_on(k->rsa, NULL) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
r = 0; /* success */
out:
if (r == 0)
*kp = k;
else
sshkey_free(k);
return r;
}
#endif /* WITH_SSH1 */
static void static void
process_add_identity(SocketEntry *e, int version) process_add_identity(SocketEntry *e, int version)
@ -613,11 +463,6 @@ process_add_identity(SocketEntry *e, int version)
int r = SSH_ERR_INTERNAL_ERROR; int r = SSH_ERR_INTERNAL_ERROR;
switch (version) { switch (version) {
#ifdef WITH_SSH1
case 1:
r = agent_decode_rsa1(e->request, &k);
break;
#endif /* WITH_SSH1 */
case 2: case 2:
r = sshkey_private_deserialize(e->request, &k); r = sshkey_private_deserialize(e->request, &k);
break; break;
@ -912,22 +757,6 @@ process_message(SocketEntry *e)
case SSH_AGENTC_UNLOCK: case SSH_AGENTC_UNLOCK:
process_lock_agent(e, type == SSH_AGENTC_LOCK); process_lock_agent(e, type == SSH_AGENTC_LOCK);
break; break;
#ifdef WITH_SSH1
/* ssh1 */
case SSH_AGENTC_RSA_CHALLENGE:
process_authentication_challenge1(e);
break;
case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
process_request_identities(e, 1);
break;
case SSH_AGENTC_ADD_RSA_IDENTITY:
case SSH_AGENTC_ADD_RSA_ID_CONSTRAINED:
process_add_identity(e, 1);
break;
case SSH_AGENTC_REMOVE_RSA_IDENTITY:
process_remove_identity(e, 1);
break;
#endif
case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
process_remove_all_identities(e, 1); /* safe for !WITH_SSH1 */ process_remove_all_identities(e, 1); /* safe for !WITH_SSH1 */
break; break;

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keygen.c,v 1.300 2017/04/29 04:12:25 djm Exp $ */ /* $OpenBSD: ssh-keygen.c,v 1.301 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -987,9 +987,6 @@ do_gen_all_hostkeys(struct passwd *pw)
char *path; char *path;
} key_types[] = { } key_types[] = {
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
#ifdef WITH_SSH1
{ "rsa1", "RSA1", _PATH_HOST_KEY_FILE },
#endif /* WITH_SSH1 */
{ "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE }, { "rsa", "RSA" ,_PATH_HOST_RSA_KEY_FILE },
{ "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE }, { "dsa", "DSA", _PATH_HOST_DSA_KEY_FILE },
#ifdef OPENSSL_HAS_ECC #ifdef OPENSSL_HAS_ECC
@ -2244,11 +2241,7 @@ do_check_krl(struct passwd *pw, int argc, char **argv)
exit(ret); exit(ret);
} }
#ifdef WITH_SSH1
# define RSA1_USAGE " | rsa1"
#else
# define RSA1_USAGE "" # define RSA1_USAGE ""
#endif
static void static void
usage(void) usage(void)

View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh-keyscan.c,v 1.109 2017/03/10 04:26:06 djm Exp $ */ /* $OpenBSD: ssh-keyscan.c,v 1.110 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>. * Copyright 1995, 1996 by David Mazieres <dm@lcs.mit.edu>.
* *
@ -187,52 +187,6 @@ strnnsep(char **stringp, char *delim)
return (tok); return (tok);
} }
#ifdef WITH_SSH1
static struct sshkey *
keygrab_ssh1(con *c)
{
static struct sshkey *rsa;
static struct sshbuf *msg;
int r;
u_char type;
if (rsa == NULL) {
if ((rsa = sshkey_new(KEY_RSA1)) == NULL) {
error("%s: sshkey_new failed", __func__);
return NULL;
}
if ((msg = sshbuf_new()) == NULL)
fatal("%s: sshbuf_new failed", __func__);
}
if ((r = sshbuf_put(msg, c->c_data, c->c_plen)) != 0 ||
(r = sshbuf_consume(msg, 8 - (c->c_plen & 7))) != 0 || /* padding */
(r = sshbuf_get_u8(msg, &type)) != 0)
goto buf_err;
if (type != (int) SSH_SMSG_PUBLIC_KEY) {
error("%s: invalid packet type", c->c_name);
sshbuf_reset(msg);
return NULL;
}
if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */
/* server key */
(r = sshbuf_get_u32(msg, NULL)) != 0 ||
(r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
(r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
/* host key */
(r = sshbuf_get_u32(msg, NULL)) != 0 ||
(r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 ||
(r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) {
buf_err:
error("%s: buffer error: %s", __func__, ssh_err(r));
sshbuf_reset(msg);
return NULL;
}
sshbuf_reset(msg);
return (rsa);
}
#endif
static int static int
key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh) key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh)
@ -585,12 +539,6 @@ conread(int s)
c->c_data = xmalloc(c->c_len); c->c_data = xmalloc(c->c_len);
c->c_status = CS_KEYS; c->c_status = CS_KEYS;
break; break;
#ifdef WITH_SSH1
case CS_KEYS:
keyprint(c, keygrab_ssh1(c));
confree(s);
return;
#endif
default: default:
fatal("conread: invalid status %d", c->c_status); fatal("conread: invalid status %d", c->c_status);
break; break;
@ -756,11 +704,6 @@ main(int argc, char **argv)
int type = sshkey_type_from_name(tname); int type = sshkey_type_from_name(tname);
switch (type) { switch (type) {
#ifdef WITH_SSH1
case KEY_RSA1:
get_keytypes |= KT_RSA1;
break;
#endif
case KEY_DSA: case KEY_DSA:
get_keytypes |= KT_DSA; get_keytypes |= KT_DSA;
break; break;

10
ssh.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: ssh.c,v 1.452 2017/04/28 03:20:27 dtucker Exp $ */ /* $OpenBSD: ssh.c,v 1.453 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -690,11 +690,7 @@ main(int ac, char **av)
else if (strcmp(optarg, "key-plain") == 0) else if (strcmp(optarg, "key-plain") == 0)
cp = sshkey_alg_list(0, 1, 0, '\n'); cp = sshkey_alg_list(0, 1, 0, '\n');
else if (strcmp(optarg, "protocol-version") == 0) { else if (strcmp(optarg, "protocol-version") == 0) {
#ifdef WITH_SSH1
cp = xstrdup("1\n2");
#else
cp = xstrdup("2"); cp = xstrdup("2");
#endif
} }
if (cp == NULL) if (cp == NULL)
fatal("Unsupported query \"%s\"", optarg); fatal("Unsupported query \"%s\"", optarg);
@ -1304,10 +1300,6 @@ main(int ac, char **av)
sensitive_data.keys[i] = NULL; sensitive_data.keys[i] = NULL;
PRIV_START; PRIV_START;
#if WITH_SSH1
sensitive_data.keys[0] = key_load_private_type(KEY_RSA1,
_PATH_HOST_KEY_FILE, "", NULL, NULL);
#endif
#ifdef OPENSSL_HAS_ECC #ifdef OPENSSL_HAS_ECC
sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA, sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA,
_PATH_HOST_ECDSA_KEY_FILE, "", NULL); _PATH_HOST_ECDSA_KEY_FILE, "", NULL);

View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshconnect.c,v 1.273 2017/03/10 03:22:40 dtucker Exp $ */ /* $OpenBSD: sshconnect.c,v 1.274 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Author: Tatu Ylonen <ylo@cs.hut.fi> * Author: Tatu Ylonen <ylo@cs.hut.fi>
* Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@ -1382,12 +1382,7 @@ ssh_login(Sensitive *sensitive, const char *orighost,
ssh_kex2(host, hostaddr, port); ssh_kex2(host, hostaddr, port);
ssh_userauth2(local_user, server_user, host, sensitive); ssh_userauth2(local_user, server_user, host, sensitive);
} else { } else {
#ifdef WITH_SSH1
ssh_kex(host, hostaddr);
ssh_userauth1(local_user, server_user, host, sensitive);
#else
fatal("ssh1 is not supported"); fatal("ssh1 is not supported");
#endif
} }
free(local_user); free(local_user);
} }

380
sshkey.c
View File

@ -1,4 +1,4 @@
/* $OpenBSD: sshkey.c,v 1.45 2017/03/10 04:07:20 djm Exp $ */ /* $OpenBSD: sshkey.c,v 1.46 2017/04/30 23:10:43 djm Exp $ */
/* /*
* Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved.
* Copyright (c) 2008 Alexander von Gernler. All rights reserved. * Copyright (c) 2008 Alexander von Gernler. All rights reserved.
@ -89,9 +89,6 @@ static const struct keytype keytypes[] = {
{ "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT", { "ssh-ed25519-cert-v01@openssh.com", "ED25519-CERT",
KEY_ED25519_CERT, 0, 1, 0 }, KEY_ED25519_CERT, 0, 1, 0 },
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
# ifdef WITH_SSH1
{ NULL, "RSA1", KEY_RSA1, 0, 0, 0 },
# endif
{ "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 }, { "ssh-rsa", "RSA", KEY_RSA, 0, 0, 0 },
{ "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 }, { "rsa-sha2-256", "RSA", KEY_RSA, 0, 0, 1 },
{ "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 }, { "rsa-sha2-512", "RSA", KEY_RSA, 0, 0, 1 },
@ -1194,39 +1191,6 @@ sshkey_fingerprint(const struct sshkey *k, int dgst_alg,
return retval; return retval;
} }
#ifdef WITH_SSH1
/*
* Reads a multiple-precision integer in decimal from the buffer, and advances
* the pointer. The integer must already be initialized. This function is
* permitted to modify the buffer. This leaves *cpp to point just beyond the
* last processed character.
*/
static int
read_decimal_bignum(char **cpp, BIGNUM *v)
{
char *cp;
size_t e;
int skip = 1; /* skip white space */
cp = *cpp;
while (*cp == ' ' || *cp == '\t')
cp++;
e = strspn(cp, "0123456789");
if (e == 0)
return SSH_ERR_INVALID_FORMAT;
if (e > SSHBUF_MAX_BIGNUM * 3)
return SSH_ERR_BIGNUM_TOO_LARGE;
if (cp[e] == '\0')
skip = 0;
else if (strchr(" \t\r\n", cp[e]) == NULL)
return SSH_ERR_INVALID_FORMAT;
cp[e] = '\0';
if (BN_dec2bn(&v, cp) <= 0)
return SSH_ERR_INVALID_FORMAT;
*cpp = cp + e + skip;
return 0;
}
#endif /* WITH_SSH1 */
/* returns 0 ok, and < 0 error */ /* returns 0 ok, and < 0 error */
int int
@ -1237,9 +1201,6 @@ sshkey_read(struct sshkey *ret, char **cpp)
char *ep, *cp, *space; char *ep, *cp, *space;
int r, type, curve_nid = -1; int r, type, curve_nid = -1;
struct sshbuf *blob; struct sshbuf *blob;
#ifdef WITH_SSH1
u_long bits;
#endif /* WITH_SSH1 */
if (ret == NULL) if (ret == NULL)
return SSH_ERR_INVALID_ARGUMENT; return SSH_ERR_INVALID_ARGUMENT;
@ -1248,23 +1209,6 @@ sshkey_read(struct sshkey *ret, char **cpp)
switch (ret->type) { switch (ret->type) {
case KEY_RSA1: case KEY_RSA1:
#ifdef WITH_SSH1
/* Get number of bits. */
bits = strtoul(cp, &ep, 10);
if (*cp == '\0' || strchr(" \t\r\n", *ep) == NULL ||
bits == 0 || bits > SSHBUF_MAX_BIGNUM * 8)
return SSH_ERR_INVALID_FORMAT; /* Bad bit count... */
/* Get public exponent, public modulus. */
if ((r = read_decimal_bignum(&ep, ret->rsa->e)) < 0)
return r;
if ((r = read_decimal_bignum(&ep, ret->rsa->n)) < 0)
return r;
/* validate the claimed number of bits */
if (BN_num_bits(ret->rsa->n) != (int)bits)
return SSH_ERR_KEY_BITS_MISMATCH;
*cpp = ep;
retval = 0;
#endif /* WITH_SSH1 */
break; break;
case KEY_UNSPEC: case KEY_UNSPEC:
case KEY_RSA: case KEY_RSA:
@ -1422,36 +1366,6 @@ static int
sshkey_format_rsa1(const struct sshkey *key, struct sshbuf *b) sshkey_format_rsa1(const struct sshkey *key, struct sshbuf *b)
{ {
int r = SSH_ERR_INTERNAL_ERROR; int r = SSH_ERR_INTERNAL_ERROR;
#ifdef WITH_SSH1
u_int bits = 0;
char *dec_e = NULL, *dec_n = NULL;
if (key->rsa == NULL || key->rsa->e == NULL ||
key->rsa->n == NULL) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if ((dec_e = BN_bn2dec(key->rsa->e)) == NULL ||
(dec_n = BN_bn2dec(key->rsa->n)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* size of modulus 'n' */
if ((bits = BN_num_bits(key->rsa->n)) <= 0) {
r = SSH_ERR_INVALID_ARGUMENT;
goto out;
}
if ((r = sshbuf_putf(b, "%u %s %s", bits, dec_e, dec_n)) != 0)
goto out;
/* Success */
r = 0;
out:
if (dec_e != NULL)
OPENSSL_free(dec_e);
if (dec_n != NULL)
OPENSSL_free(dec_n);
#endif /* WITH_SSH1 */
return r; return r;
} }
@ -3404,105 +3318,6 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase,
return r; return r;
} }
#if WITH_SSH1
/*
* Serialises the authentication (private) key to a blob, encrypting it with
* passphrase. The identification of the blob (lowest 64 bits of n) will
* precede the key to provide identification of the key without needing a
* passphrase.
*/
static int
sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob,
const char *passphrase, const char *comment)
{
struct sshbuf *buffer = NULL, *encrypted = NULL;
u_char buf[8];
int r, cipher_num;
struct sshcipher_ctx *ciphercontext = NULL;
const struct sshcipher *cipher;
u_char *cp;
/*
* If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
* to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
*/
cipher_num = (strcmp(passphrase, "") == 0) ?
SSH_CIPHER_NONE : SSH_CIPHER_3DES;
if ((cipher = cipher_by_number(cipher_num)) == NULL)
return SSH_ERR_INTERNAL_ERROR;
/* This buffer is used to build the secret part of the private key. */
if ((buffer = sshbuf_new()) == NULL)
return SSH_ERR_ALLOC_FAIL;
/* Put checkbytes for checking passphrase validity. */
if ((r = sshbuf_reserve(buffer, 4, &cp)) != 0)
goto out;
arc4random_buf(cp, 2);
memcpy(cp + 2, cp, 2);
/*
* Store the private key (n and e will not be stored because they
* will be stored in plain text, and storing them also in encrypted
* format would just give known plaintext).
* Note: q and p are stored in reverse order to SSL.
*/
if ((r = sshbuf_put_bignum1(buffer, key->rsa->d)) != 0 ||
(r = sshbuf_put_bignum1(buffer, key->rsa->iqmp)) != 0 ||
(r = sshbuf_put_bignum1(buffer, key->rsa->q)) != 0 ||
(r = sshbuf_put_bignum1(buffer, key->rsa->p)) != 0)
goto out;
/* Pad the part to be encrypted to a size that is a multiple of 8. */
explicit_bzero(buf, 8);
if ((r = sshbuf_put(buffer, buf, 8 - (sshbuf_len(buffer) % 8))) != 0)
goto out;
/* This buffer will be used to contain the data in the file. */
if ((encrypted = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
/* First store keyfile id string. */
if ((r = sshbuf_put(encrypted, LEGACY_BEGIN,
sizeof(LEGACY_BEGIN))) != 0)
goto out;
/* Store cipher type and "reserved" field. */
if ((r = sshbuf_put_u8(encrypted, cipher_num)) != 0 ||
(r = sshbuf_put_u32(encrypted, 0)) != 0)
goto out;
/* Store public key. This will be in plain text. */
if ((r = sshbuf_put_u32(encrypted, BN_num_bits(key->rsa->n))) != 0 ||
(r = sshbuf_put_bignum1(encrypted, key->rsa->n)) != 0 ||
(r = sshbuf_put_bignum1(encrypted, key->rsa->e)) != 0 ||
(r = sshbuf_put_cstring(encrypted, comment)) != 0)
goto out;
/* Allocate space for the private part of the key in the buffer. */
if ((r = sshbuf_reserve(encrypted, sshbuf_len(buffer), &cp)) != 0)
goto out;
if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,
CIPHER_ENCRYPT)) != 0)
goto out;
if ((r = cipher_crypt(ciphercontext, 0, cp,
sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0)
goto out;
r = sshbuf_putb(blob, encrypted);
out:
cipher_free(ciphercontext);
explicit_bzero(buf, sizeof(buf));
sshbuf_free(buffer);
sshbuf_free(encrypted);
return r;
}
#endif /* WITH_SSH1 */
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
/* convert SSH v2 key in OpenSSL PEM format */ /* convert SSH v2 key in OpenSSL PEM format */
@ -3565,11 +3380,6 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
int force_new_format, const char *new_format_cipher, int new_format_rounds) int force_new_format, const char *new_format_cipher, int new_format_rounds)
{ {
switch (key->type) { switch (key->type) {
#ifdef WITH_SSH1
case KEY_RSA1:
return sshkey_private_rsa1_to_blob(key, blob,
passphrase, comment);
#endif /* WITH_SSH1 */
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
case KEY_DSA: case KEY_DSA:
case KEY_ECDSA: case KEY_ECDSA:
@ -3589,182 +3399,6 @@ sshkey_private_to_fileblob(struct sshkey *key, struct sshbuf *blob,
} }
} }
#ifdef WITH_SSH1
/*
* Parse the public, unencrypted portion of a RSA1 key.
*/
int
sshkey_parse_public_rsa1_fileblob(struct sshbuf *blob,
struct sshkey **keyp, char **commentp)
{
int r;
struct sshkey *pub = NULL;
struct sshbuf *copy = NULL;
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
/* Check that it is at least big enough to contain the ID string. */
if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))
return SSH_ERR_INVALID_FORMAT;
/*
* Make sure it begins with the id string. Consume the id string
* from the buffer.
*/
if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0)
return SSH_ERR_INVALID_FORMAT;
/* Make a working copy of the keyblob and skip past the magic */
if ((copy = sshbuf_fromb(blob)) == NULL)
return SSH_ERR_ALLOC_FAIL;
if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)
goto out;
/* Skip cipher type, reserved data and key bits. */
if ((r = sshbuf_get_u8(copy, NULL)) != 0 || /* cipher type */
(r = sshbuf_get_u32(copy, NULL)) != 0 || /* reserved */
(r = sshbuf_get_u32(copy, NULL)) != 0) /* key bits */
goto out;
/* Read the public key from the buffer. */
if ((pub = sshkey_new(KEY_RSA1)) == NULL ||
(r = sshbuf_get_bignum1(copy, pub->rsa->n)) != 0 ||
(r = sshbuf_get_bignum1(copy, pub->rsa->e)) != 0)
goto out;
/* Finally, the comment */
if ((r = sshbuf_get_string(copy, (u_char**)commentp, NULL)) != 0)
goto out;
/* The encrypted private part is not parsed by this function. */
r = 0;
if (keyp != NULL) {
*keyp = pub;
pub = NULL;
}
out:
sshbuf_free(copy);
sshkey_free(pub);
return r;
}
static int
sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase,
struct sshkey **keyp, char **commentp)
{
int r;
u_int16_t check1, check2;
u_int8_t cipher_type;
struct sshbuf *decrypted = NULL, *copy = NULL;
u_char *cp;
char *comment = NULL;
struct sshcipher_ctx *ciphercontext = NULL;
const struct sshcipher *cipher;
struct sshkey *prv = NULL;
if (keyp != NULL)
*keyp = NULL;
if (commentp != NULL)
*commentp = NULL;
/* Check that it is at least big enough to contain the ID string. */
if (sshbuf_len(blob) < sizeof(LEGACY_BEGIN))
return SSH_ERR_INVALID_FORMAT;
/*
* Make sure it begins with the id string. Consume the id string
* from the buffer.
*/
if (memcmp(sshbuf_ptr(blob), LEGACY_BEGIN, sizeof(LEGACY_BEGIN)) != 0)
return SSH_ERR_INVALID_FORMAT;
if ((prv = sshkey_new_private(KEY_RSA1)) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((copy = sshbuf_fromb(blob)) == NULL ||
(decrypted = sshbuf_new()) == NULL) {
r = SSH_ERR_ALLOC_FAIL;
goto out;
}
if ((r = sshbuf_consume(copy, sizeof(LEGACY_BEGIN))) != 0)
goto out;
/* Read cipher type. */
if ((r = sshbuf_get_u8(copy, &cipher_type)) != 0 ||
(r = sshbuf_get_u32(copy, NULL)) != 0) /* reserved */
goto out;
/* Read the public key and comment from the buffer. */
if ((r = sshbuf_get_u32(copy, NULL)) != 0 || /* key bits */
(r = sshbuf_get_bignum1(copy, prv->rsa->n)) != 0 ||
(r = sshbuf_get_bignum1(copy, prv->rsa->e)) != 0 ||
(r = sshbuf_get_cstring(copy, &comment, NULL)) != 0)
goto out;
/* Check that it is a supported cipher. */
cipher = cipher_by_number(cipher_type);
if (cipher == NULL) {
r = SSH_ERR_KEY_UNKNOWN_CIPHER;
goto out;
}
/* Initialize space for decrypted data. */
if ((r = sshbuf_reserve(decrypted, sshbuf_len(copy), &cp)) != 0)
goto out;
/* Rest of the buffer is encrypted. Decrypt it using the passphrase. */
if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase,
CIPHER_DECRYPT)) != 0)
goto out;
if ((r = cipher_crypt(ciphercontext, 0, cp,
sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0)
goto out;
if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 ||
(r = sshbuf_get_u16(decrypted, &check2)) != 0)
goto out;
if (check1 != check2) {
r = SSH_ERR_KEY_WRONG_PASSPHRASE;
goto out;
}
/* Read the rest of the private key. */
if ((r = sshbuf_get_bignum1(decrypted, prv->rsa->d)) != 0 ||
(r = sshbuf_get_bignum1(decrypted, prv->rsa->iqmp)) != 0 ||
(r = sshbuf_get_bignum1(decrypted, prv->rsa->q)) != 0 ||
(r = sshbuf_get_bignum1(decrypted, prv->rsa->p)) != 0)
goto out;
/* calculate p-1 and q-1 */
if ((r = rsa_generate_additional_parameters(prv->rsa)) != 0)
goto out;
/* enable blinding */
if (RSA_blinding_on(prv->rsa, NULL) != 1) {
r = SSH_ERR_LIBCRYPTO_ERROR;
goto out;
}
r = 0;
if (keyp != NULL) {
*keyp = prv;
prv = NULL;
}
if (commentp != NULL) {
*commentp = comment;
comment = NULL;
}
out:
cipher_free(ciphercontext);
free(comment);
sshkey_free(prv);
sshbuf_free(copy);
sshbuf_free(decrypted);
return r;
}
#endif /* WITH_SSH1 */
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
static int static int
@ -3910,11 +3544,6 @@ sshkey_parse_private_fileblob_type(struct sshbuf *blob, int type,
*commentp = NULL; *commentp = NULL;
switch (type) { switch (type) {
#ifdef WITH_SSH1
case KEY_RSA1:
return sshkey_parse_private_rsa1(blob, passphrase,
keyp, commentp);
#endif /* WITH_SSH1 */
#ifdef WITH_OPENSSL #ifdef WITH_OPENSSL
case KEY_DSA: case KEY_DSA:
case KEY_ECDSA: case KEY_ECDSA:
@ -3951,13 +3580,6 @@ sshkey_parse_private_fileblob(struct sshbuf *buffer, const char *passphrase,
if (commentp != NULL) if (commentp != NULL)
*commentp = NULL; *commentp = NULL;
#ifdef WITH_SSH1
/* it's a SSH v1 key if the public key part is readable */
if (sshkey_parse_public_rsa1_fileblob(buffer, NULL, NULL) == 0) {
return sshkey_parse_private_fileblob_type(buffer, KEY_RSA1,
passphrase, keyp, commentp);
}
#endif /* WITH_SSH1 */
return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC, return sshkey_parse_private_fileblob_type(buffer, KEY_UNSPEC,
passphrase, keyp, commentp); passphrase, keyp, commentp);
} }