зеркало из https://github.com/github/putty.git
Uppity: option to use a pregenerated key for RSA kex.
As and when I make this SSH server into a test suite, I'm not going to want to wait for a gratuitous RSA key generation in every test run. So now you can provide one in advance. It has to be in SSH-1 format, because that's the format for which I happen to already have internal API routines that return an RSAKey instead of an opaque ssh_key. But since you also have to store it without a passphrase, that doesn't really matter anyway.
This commit is contained in:
Родитель
7a49ff9ac1
Коммит
6d7a6d47e6
|
@ -552,6 +552,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted)
|
||||||
*aborted = true;
|
*aborted = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
s->rsa_kex_key_needs_freeing = true;
|
||||||
|
|
||||||
put_stringpl(s->exhash, rsakeydata);
|
put_stringpl(s->exhash, rsakeydata);
|
||||||
|
|
||||||
|
@ -611,6 +612,7 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted)
|
||||||
|
|
||||||
ssh_rsakex_freekey(s->rsa_kex_key);
|
ssh_rsakex_freekey(s->rsa_kex_key);
|
||||||
s->rsa_kex_key = NULL;
|
s->rsa_kex_key = NULL;
|
||||||
|
s->rsa_kex_key_needs_freeing = false;
|
||||||
|
|
||||||
crMaybeWaitUntilV((pktin = ssh2_transport_pop(s)) != NULL);
|
crMaybeWaitUntilV((pktin = ssh2_transport_pop(s)) != NULL);
|
||||||
if (pktin->type != SSH2_MSG_KEXRSA_DONE) {
|
if (pktin->type != SSH2_MSG_KEXRSA_DONE) {
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "sshbpp.h"
|
#include "sshbpp.h"
|
||||||
#include "sshppl.h"
|
#include "sshppl.h"
|
||||||
#include "sshcr.h"
|
#include "sshcr.h"
|
||||||
|
#include "sshserver.h"
|
||||||
#include "storage.h"
|
#include "storage.h"
|
||||||
#include "ssh2transport.h"
|
#include "ssh2transport.h"
|
||||||
#include "mpint.h"
|
#include "mpint.h"
|
||||||
|
@ -243,13 +244,27 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted)
|
||||||
ssh_hash_alg(s->exhash)->text_name);
|
ssh_hash_alg(s->exhash)->text_name);
|
||||||
s->ppl.bpp->pls->kctx = SSH2_PKTCTX_RSAKEX;
|
s->ppl.bpp->pls->kctx = SSH2_PKTCTX_RSAKEX;
|
||||||
|
|
||||||
{
|
const struct ssh_rsa_kex_extra *extra =
|
||||||
const struct ssh_rsa_kex_extra *extra =
|
(const struct ssh_rsa_kex_extra *)s->kex_alg->extra;
|
||||||
(const struct ssh_rsa_kex_extra *)s->kex_alg->extra;
|
|
||||||
|
if (s->ssc && s->ssc->rsa_kex_key) {
|
||||||
|
int klen = ssh_rsakex_klen(s->ssc->rsa_kex_key);
|
||||||
|
if (klen >= extra->minklen) {
|
||||||
|
ppl_logevent("Using configured %d-bit RSA key", klen);
|
||||||
|
s->rsa_kex_key = s->ssc->rsa_kex_key;
|
||||||
|
} else {
|
||||||
|
ppl_logevent("Configured %d-bit RSA key is too short (min %d)",
|
||||||
|
klen, extra->minklen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!s->rsa_kex_key) {
|
||||||
|
ppl_logevent("Generating a %d-bit RSA key", extra->minklen);
|
||||||
|
|
||||||
s->rsa_kex_key = snew(RSAKey);
|
s->rsa_kex_key = snew(RSAKey);
|
||||||
rsa_generate(s->rsa_kex_key, extra->minklen, no_progress, NULL);
|
rsa_generate(s->rsa_kex_key, extra->minklen, no_progress, NULL);
|
||||||
s->rsa_kex_key->comment = NULL;
|
s->rsa_kex_key->comment = NULL;
|
||||||
|
s->rsa_kex_key_needs_freeing = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_KEXRSA_PUBKEY);
|
pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_KEXRSA_PUBKEY);
|
||||||
|
@ -288,8 +303,12 @@ void ssh2kex_coroutine(struct ssh2_transport_state *s, bool *aborted)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssh_rsakex_freekey(s->rsa_kex_key);
|
if (s->rsa_kex_key_needs_freeing) {
|
||||||
|
ssh_rsakex_freekey(s->rsa_kex_key);
|
||||||
|
sfree(s->rsa_kex_key);
|
||||||
|
}
|
||||||
s->rsa_kex_key = NULL;
|
s->rsa_kex_key = NULL;
|
||||||
|
s->rsa_kex_key_needs_freeing = false;
|
||||||
|
|
||||||
pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_KEXRSA_DONE);
|
pktout = ssh_bpp_new_pktout(s->ppl.bpp, SSH2_MSG_KEXRSA_DONE);
|
||||||
put_stringsb(pktout, finalise_and_sign_exhash(s));
|
put_stringsb(pktout, finalise_and_sign_exhash(s));
|
||||||
|
|
|
@ -220,8 +220,10 @@ static void ssh2_transport_free(PacketProtocolLayer *ppl)
|
||||||
if (s->K) mp_free(s->K);
|
if (s->K) mp_free(s->K);
|
||||||
if (s->dh_ctx)
|
if (s->dh_ctx)
|
||||||
dh_cleanup(s->dh_ctx);
|
dh_cleanup(s->dh_ctx);
|
||||||
if (s->rsa_kex_key)
|
if (s->rsa_kex_key_needs_freeing) {
|
||||||
ssh_rsakex_freekey(s->rsa_kex_key);
|
ssh_rsakex_freekey(s->rsa_kex_key);
|
||||||
|
sfree(s->rsa_kex_key);
|
||||||
|
}
|
||||||
if (s->ecdh_key)
|
if (s->ecdh_key)
|
||||||
ssh_ecdhkex_freekey(s->ecdh_key);
|
ssh_ecdhkex_freekey(s->ecdh_key);
|
||||||
if (s->exhash)
|
if (s->exhash)
|
||||||
|
|
|
@ -173,6 +173,7 @@ struct ssh2_transport_state {
|
||||||
char *keystr, *fingerprint;
|
char *keystr, *fingerprint;
|
||||||
ssh_key *hkey; /* actual host key */
|
ssh_key *hkey; /* actual host key */
|
||||||
RSAKey *rsa_kex_key; /* for RSA kex */
|
RSAKey *rsa_kex_key; /* for RSA kex */
|
||||||
|
bool rsa_kex_key_needs_freeing;
|
||||||
ecdh_key *ecdh_key; /* for ECDH kex */
|
ecdh_key *ecdh_key; /* for ECDH kex */
|
||||||
unsigned char exchange_hash[MAX_HASH_LEN];
|
unsigned char exchange_hash[MAX_HASH_LEN];
|
||||||
bool can_gssapi_keyex;
|
bool can_gssapi_keyex;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
typedef struct AuthPolicy AuthPolicy;
|
typedef struct AuthPolicy AuthPolicy;
|
||||||
|
|
||||||
struct SshServerConfig {
|
struct SshServerConfig {
|
||||||
|
RSAKey *rsa_kex_key;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In all of these ptrlens, setting the 'ptr' member to NULL means
|
* In all of these ptrlens, setting the 'ptr' member to NULL means
|
||||||
* that we're not overriding the default configuration.
|
* that we're not overriding the default configuration.
|
||||||
|
|
|
@ -579,6 +579,35 @@ int main(int argc, char **argv)
|
||||||
key_type_to_str(keytype));
|
key_type_to_str(keytype));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
} else if (longoptarg(arg, "--rsakexkey", &val, &argc, &argv)) {
|
||||||
|
Filename *keyfile;
|
||||||
|
int keytype;
|
||||||
|
const char *error;
|
||||||
|
|
||||||
|
keyfile = filename_from_str(val);
|
||||||
|
keytype = key_type(keyfile);
|
||||||
|
|
||||||
|
if (keytype != SSH_KEYTYPE_SSH1) {
|
||||||
|
fprintf(stderr, "%s: '%s' is not loadable as an SSH-1 format "
|
||||||
|
"private key (%s)", appname, val,
|
||||||
|
key_type_to_str(keytype));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ssc.rsa_kex_key) {
|
||||||
|
freersakey(ssc.rsa_kex_key);
|
||||||
|
} else {
|
||||||
|
ssc.rsa_kex_key = snew(RSAKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!rsa_ssh1_loadkey(keyfile, ssc.rsa_kex_key,
|
||||||
|
NULL, &error)) {
|
||||||
|
fprintf(stderr, "%s: unable to load RSA kex key '%s': "
|
||||||
|
"%s\n", appname, val, error);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssc.rsa_kex_key->sshk.vt = &ssh_rsa;
|
||||||
} else if (longoptarg(arg, "--userkey", &val, &argc, &argv)) {
|
} else if (longoptarg(arg, "--userkey", &val, &argc, &argv)) {
|
||||||
Filename *keyfile;
|
Filename *keyfile;
|
||||||
int keytype;
|
int keytype;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче