mirror of
https://github.com/clearml/dropbear
synced 2025-06-26 18:17:32 +00:00
split signkey_type and signature_type for RSA sha1 vs sha256
This commit is contained in:
parent
7dc2f36c3e
commit
972d723484
@ -33,7 +33,7 @@
|
|||||||
#include "agentfwd.h"
|
#include "agentfwd.h"
|
||||||
|
|
||||||
#if DROPBEAR_CLI_PUBKEY_AUTH
|
#if DROPBEAR_CLI_PUBKEY_AUTH
|
||||||
static void send_msg_userauth_pubkey(sign_key *key, enum signkey_type sigtype, int realsign);
|
static void send_msg_userauth_pubkey(sign_key *key, enum signature_type sigtype, int realsign);
|
||||||
|
|
||||||
/* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request.
|
/* Called when we receive a SSH_MSG_USERAUTH_FAILURE for a pubkey request.
|
||||||
* We use it to remove the key we tried from the list */
|
* We use it to remove the key we tried from the list */
|
||||||
@ -58,7 +58,8 @@ void recv_msg_userauth_pk_ok() {
|
|||||||
buffer* keybuf = NULL;
|
buffer* keybuf = NULL;
|
||||||
char* algotype = NULL;
|
char* algotype = NULL;
|
||||||
unsigned int algolen;
|
unsigned int algolen;
|
||||||
enum signkey_type sigtype, keytype;
|
enum signkey_type keytype;
|
||||||
|
enum signature_type sigtype;
|
||||||
unsigned int remotelen;
|
unsigned int remotelen;
|
||||||
|
|
||||||
TRACE(("enter recv_msg_userauth_pk_ok"))
|
TRACE(("enter recv_msg_userauth_pk_ok"))
|
||||||
@ -113,7 +114,7 @@ void recv_msg_userauth_pk_ok() {
|
|||||||
TRACE(("matching key"))
|
TRACE(("matching key"))
|
||||||
/* XXX TODO: if it's an encrypted key, here we ask for their
|
/* XXX TODO: if it's an encrypted key, here we ask for their
|
||||||
* password */
|
* password */
|
||||||
send_msg_userauth_pubkey((sign_key*)iter->item, keytype, 1);
|
send_msg_userauth_pubkey((sign_key*)iter->item, sigtype, 1);
|
||||||
} else {
|
} else {
|
||||||
TRACE(("That was whacky. We got told that a key was valid, but it didn't match our list. Sounds like dodgy code on Dropbear's part"))
|
TRACE(("That was whacky. We got told that a key was valid, but it didn't match our list. Sounds like dodgy code on Dropbear's part"))
|
||||||
}
|
}
|
||||||
@ -121,7 +122,7 @@ void recv_msg_userauth_pk_ok() {
|
|||||||
TRACE(("leave recv_msg_userauth_pk_ok"))
|
TRACE(("leave recv_msg_userauth_pk_ok"))
|
||||||
}
|
}
|
||||||
|
|
||||||
static void cli_buf_put_sign(buffer* buf, sign_key *key, enum signkey_type sigtype,
|
static void cli_buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,
|
||||||
const buffer *data_buf) {
|
const buffer *data_buf) {
|
||||||
#if DROPBEAR_CLI_AGENTFWD
|
#if DROPBEAR_CLI_AGENTFWD
|
||||||
// TODO: rsa-sha256 agent
|
// TODO: rsa-sha256 agent
|
||||||
@ -139,14 +140,14 @@ static void cli_buf_put_sign(buffer* buf, sign_key *key, enum signkey_type sigty
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void send_msg_userauth_pubkey(sign_key *key, enum signkey_type sigtype, int realsign) {
|
static void send_msg_userauth_pubkey(sign_key *key, enum signature_type sigtype, int realsign) {
|
||||||
|
|
||||||
const char *algoname = NULL;
|
const char *algoname = NULL;
|
||||||
unsigned int algolen;
|
unsigned int algolen;
|
||||||
buffer* sigbuf = NULL;
|
buffer* sigbuf = NULL;
|
||||||
enum signkey_type keytype = signkey_type_from_signature(sigtype);
|
enum signkey_type keytype = signkey_type_from_signature(sigtype);
|
||||||
|
|
||||||
TRACE(("enter send_msg_userauth_pubkey"))
|
TRACE(("enter send_msg_userauth_pubkey sigtype %d", sigtype))
|
||||||
CHECKCLEARTOWRITE();
|
CHECKCLEARTOWRITE();
|
||||||
|
|
||||||
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
|
buf_putbyte(ses.writepayload, SSH_MSG_USERAUTH_REQUEST);
|
||||||
@ -183,7 +184,6 @@ static void send_msg_userauth_pubkey(sign_key *key, enum signkey_type sigtype, i
|
|||||||
|
|
||||||
/* Returns 1 if a key was tried */
|
/* Returns 1 if a key was tried */
|
||||||
int cli_auth_pubkey() {
|
int cli_auth_pubkey() {
|
||||||
|
|
||||||
TRACE(("enter cli_auth_pubkey"))
|
TRACE(("enter cli_auth_pubkey"))
|
||||||
|
|
||||||
#if DROPBEAR_CLI_AGENTFWD
|
#if DROPBEAR_CLI_AGENTFWD
|
||||||
@ -194,16 +194,26 @@ int cli_auth_pubkey() {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* TODO iterate through privkeys to skip ones not in server-sig-algs */
|
||||||
|
|
||||||
|
/* TODO: testing */
|
||||||
|
#if DROPBEAR_RSA_SHA256
|
||||||
|
cli_ses.preferred_rsa_sigtype = DROPBEAR_SIGNATURE_RSA_SHA256;
|
||||||
|
#elif DROPBEAR_RSA_SHA1
|
||||||
|
cli_ses.preferred_rsa_sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (cli_opts.privkeys->first) {
|
if (cli_opts.privkeys->first) {
|
||||||
sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
|
sign_key * key = (sign_key*)cli_opts.privkeys->first->item;
|
||||||
enum signkey_type sigtype = key->type;
|
/* Determine the signature type to use */
|
||||||
/* Send a trial request */
|
enum signature_type sigtype = (enum signature_type)key->type;
|
||||||
#if DROPBEAR_RSA && DROPBEAR_RSA_SHA256
|
#if DROPBEAR_RSA
|
||||||
// TODO: use ext-info to choose rsa kind
|
if (key->type == DROPBEAR_SIGNKEY_RSA) {
|
||||||
if (sigtype == DROPBEAR_SIGNKEY_RSA) {
|
sigtype = cli_ses.preferred_rsa_sigtype;
|
||||||
sigtype = DROPBEAR_SIGNKEY_RSA_SHA256;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Send a trial request */
|
||||||
send_msg_userauth_pubkey(key, sigtype, 0);
|
send_msg_userauth_pubkey(key, sigtype, 0);
|
||||||
cli_ses.lastprivkey = key;
|
cli_ses.lastprivkey = key;
|
||||||
TRACE(("leave cli_auth_pubkey-success"))
|
TRACE(("leave cli_auth_pubkey-success"))
|
||||||
|
@ -223,29 +223,29 @@ algo_type ssh_nocompress[] = {
|
|||||||
|
|
||||||
algo_type sshhostkey[] = {
|
algo_type sshhostkey[] = {
|
||||||
#if DROPBEAR_ED25519
|
#if DROPBEAR_ED25519
|
||||||
{"ssh-ed25519", DROPBEAR_SIGNKEY_ED25519, NULL, 1, NULL},
|
{"ssh-ed25519", DROPBEAR_SIGNATURE_ED25519, NULL, 1, NULL},
|
||||||
#endif
|
#endif
|
||||||
#if DROPBEAR_ECDSA
|
#if DROPBEAR_ECDSA
|
||||||
#if DROPBEAR_ECC_256
|
#if DROPBEAR_ECC_256
|
||||||
{"ecdsa-sha2-nistp256", DROPBEAR_SIGNKEY_ECDSA_NISTP256, NULL, 1, NULL},
|
{"ecdsa-sha2-nistp256", DROPBEAR_SIGNATURE_ECDSA_NISTP256, NULL, 1, NULL},
|
||||||
#endif
|
#endif
|
||||||
#if DROPBEAR_ECC_384
|
#if DROPBEAR_ECC_384
|
||||||
{"ecdsa-sha2-nistp384", DROPBEAR_SIGNKEY_ECDSA_NISTP384, NULL, 1, NULL},
|
{"ecdsa-sha2-nistp384", DROPBEAR_SIGNATURE_ECDSA_NISTP384, NULL, 1, NULL},
|
||||||
#endif
|
#endif
|
||||||
#if DROPBEAR_ECC_521
|
#if DROPBEAR_ECC_521
|
||||||
{"ecdsa-sha2-nistp521", DROPBEAR_SIGNKEY_ECDSA_NISTP521, NULL, 1, NULL},
|
{"ecdsa-sha2-nistp521", DROPBEAR_SIGNATURE_ECDSA_NISTP521, NULL, 1, NULL},
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if DROPBEAR_RSA
|
#if DROPBEAR_RSA
|
||||||
#if DROPBEAR_RSA_SHA256
|
#if DROPBEAR_RSA_SHA256
|
||||||
{"rsa-sha2-256", DROPBEAR_SIGNKEY_RSA_SHA256, NULL, 1, NULL},
|
{"rsa-sha2-256", DROPBEAR_SIGNATURE_RSA_SHA256, NULL, 1, NULL},
|
||||||
#endif
|
#endif
|
||||||
#if DROPBEAR_RSA_SHA1
|
#if DROPBEAR_RSA_SHA1
|
||||||
{"ssh-rsa", DROPBEAR_SIGNKEY_RSA, NULL, 1, NULL},
|
{"ssh-rsa", DROPBEAR_SIGNATURE_RSA_SHA1, NULL, 1, NULL},
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#if DROPBEAR_DSS
|
#if DROPBEAR_DSS
|
||||||
{"ssh-dss", DROPBEAR_SIGNKEY_DSS, NULL, 1, NULL},
|
{"ssh-dss", DROPBEAR_SIGNATURE_DSS, NULL, 1, NULL},
|
||||||
#endif
|
#endif
|
||||||
{NULL, 0, NULL, 0, NULL}
|
{NULL, 0, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
@ -263,8 +263,6 @@ static const struct dropbear_kex kex_dh_group14_sha256 = {DROPBEAR_KEX_NORMAL_DH
|
|||||||
static const struct dropbear_kex kex_dh_group16_sha512 = {DROPBEAR_KEX_NORMAL_DH, dh_p_16, DH_P_16_LEN, NULL, &sha512_desc };
|
static const struct dropbear_kex kex_dh_group16_sha512 = {DROPBEAR_KEX_NORMAL_DH, dh_p_16, DH_P_16_LEN, NULL, &sha512_desc };
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* These can't be const since dropbear_ecc_fill_dp() fills out
|
|
||||||
ecc_curve at runtime */
|
|
||||||
#if DROPBEAR_ECDH
|
#if DROPBEAR_ECDH
|
||||||
#if DROPBEAR_ECC_256
|
#if DROPBEAR_ECC_256
|
||||||
static const struct dropbear_kex kex_ecdh_nistp256 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp256, &sha256_desc };
|
static const struct dropbear_kex kex_ecdh_nistp256 = {DROPBEAR_KEX_ECDH, NULL, 0, &ecc_curve_nistp256, &sha256_desc };
|
||||||
|
@ -27,15 +27,25 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
|
|||||||
|
|
||||||
if (setjmp(fuzz.jmp) == 0) {
|
if (setjmp(fuzz.jmp) == 0) {
|
||||||
sign_key *key = new_sign_key();
|
sign_key *key = new_sign_key();
|
||||||
enum signkey_type type = DROPBEAR_SIGNKEY_ANY;
|
enum signkey_type keytype = DROPBEAR_SIGNKEY_ANY;
|
||||||
if (buf_get_pub_key(fuzz.input, key, &type) == DROPBEAR_SUCCESS) {
|
if (buf_get_pub_key(fuzz.input, key, &keytype) == DROPBEAR_SUCCESS) {
|
||||||
if (buf_verify(fuzz.input, key, verifydata) == DROPBEAR_SUCCESS) {
|
enum signature_type sigtype = (enum signature_type)keytype;
|
||||||
|
if (keytype == DROPBEAR_SIGNKEY_RSA) {
|
||||||
|
/* Flip a coin to decide rsa signature type */
|
||||||
|
int flag = buf_getbyte(fuzz_input);
|
||||||
|
if (flag & 0x01) {
|
||||||
|
sigtype = DROPBEAR_SIGNATURE_RSA_SHA256;
|
||||||
|
} else {
|
||||||
|
sigtype = DROPBEAR_SIGNATURE_RSA_SHA1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (buf_verify(fuzz.input, key, sigtype, verifydata) == DROPBEAR_SUCCESS) {
|
||||||
/* The fuzzer is capable of generating keys with a signature to match.
|
/* The fuzzer is capable of generating keys with a signature to match.
|
||||||
We don't want false positives if the key is bogus, since a client/server
|
We don't want false positives if the key is bogus, since a client/server
|
||||||
wouldn't be trusting a bogus key anyway */
|
wouldn't be trusting a bogus key anyway */
|
||||||
int boguskey = 0;
|
int boguskey = 0;
|
||||||
|
|
||||||
if (type == DROPBEAR_SIGNKEY_DSS) {
|
if (keytype == DROPBEAR_SIGNKEY_DSS) {
|
||||||
/* So far have seen dss keys with bad p/q/g domain parameters */
|
/* So far have seen dss keys with bad p/q/g domain parameters */
|
||||||
int pprime, qprime, trials;
|
int pprime, qprime, trials;
|
||||||
trials = mp_prime_rabin_miller_trials(mp_count_bits(key->dsskey->p));
|
trials = mp_prime_rabin_miller_trials(mp_count_bits(key->dsskey->p));
|
||||||
|
12
rsa.c
12
rsa.c
@ -44,7 +44,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void rsa_pad_em(const dropbear_rsa_key * key,
|
static void rsa_pad_em(const dropbear_rsa_key * key,
|
||||||
const buffer *data_buf, mp_int * rsa_em, enum signkey_type sigtype);
|
const buffer *data_buf, mp_int * rsa_em, enum signature_type sigtype);
|
||||||
|
|
||||||
/* Load a public rsa key from a buffer, initialising the values.
|
/* Load a public rsa key from a buffer, initialising the values.
|
||||||
* The key will have the same format as buf_put_rsa_key.
|
* The key will have the same format as buf_put_rsa_key.
|
||||||
@ -197,7 +197,7 @@ void buf_put_rsa_priv_key(buffer* buf, const dropbear_rsa_key *key) {
|
|||||||
/* Verify a signature in buf, made on data by the key given.
|
/* Verify a signature in buf, made on data by the key given.
|
||||||
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
|
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
|
||||||
int buf_rsa_verify(buffer * buf, const dropbear_rsa_key *key,
|
int buf_rsa_verify(buffer * buf, const dropbear_rsa_key *key,
|
||||||
enum signkey_type sigtype, const buffer *data_buf) {
|
enum signature_type sigtype, const buffer *data_buf) {
|
||||||
unsigned int slen;
|
unsigned int slen;
|
||||||
DEF_MP_INT(rsa_s);
|
DEF_MP_INT(rsa_s);
|
||||||
DEF_MP_INT(rsa_mdash);
|
DEF_MP_INT(rsa_mdash);
|
||||||
@ -253,7 +253,7 @@ out:
|
|||||||
/* Sign the data presented with key, writing the signature contents
|
/* Sign the data presented with key, writing the signature contents
|
||||||
* to the buffer */
|
* to the buffer */
|
||||||
void buf_put_rsa_sign(buffer* buf, const dropbear_rsa_key *key,
|
void buf_put_rsa_sign(buffer* buf, const dropbear_rsa_key *key,
|
||||||
enum signkey_type sigtype, const buffer *data_buf) {
|
enum signature_type sigtype, const buffer *data_buf) {
|
||||||
const char *name = NULL;
|
const char *name = NULL;
|
||||||
unsigned int nsize, ssize, namelen = 0;
|
unsigned int nsize, ssize, namelen = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -352,7 +352,7 @@ void buf_put_rsa_sign(buffer* buf, const dropbear_rsa_key *key,
|
|||||||
/* Creates the message value as expected by PKCS,
|
/* Creates the message value as expected by PKCS,
|
||||||
see rfc8017 section 9.2 */
|
see rfc8017 section 9.2 */
|
||||||
static void rsa_pad_em(const dropbear_rsa_key * key,
|
static void rsa_pad_em(const dropbear_rsa_key * key,
|
||||||
const buffer *data_buf, mp_int * rsa_em, enum signkey_type sigtype) {
|
const buffer *data_buf, mp_int * rsa_em, enum signature_type sigtype) {
|
||||||
/* EM = 0x00 || 0x01 || PS || 0x00 || T
|
/* EM = 0x00 || 0x01 || PS || 0x00 || T
|
||||||
PS is padding of 0xff to make EM the size of key->n
|
PS is padding of 0xff to make EM the size of key->n
|
||||||
|
|
||||||
@ -380,14 +380,14 @@ static void rsa_pad_em(const dropbear_rsa_key * key,
|
|||||||
|
|
||||||
switch (sigtype) {
|
switch (sigtype) {
|
||||||
#if DROPBEAR_RSA_SHA1
|
#if DROPBEAR_RSA_SHA1
|
||||||
case DROPBEAR_SIGNKEY_RSA:
|
case DROPBEAR_SIGNATURE_RSA_SHA1:
|
||||||
Tlen = sizeof(T_sha1);
|
Tlen = sizeof(T_sha1);
|
||||||
T = T_sha1;
|
T = T_sha1;
|
||||||
hash_desc = &sha1_desc;
|
hash_desc = &sha1_desc;
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
#if DROPBEAR_RSA_SHA256
|
#if DROPBEAR_RSA_SHA256
|
||||||
case DROPBEAR_SIGNKEY_RSA_SHA256:
|
case DROPBEAR_SIGNATURE_RSA_SHA256:
|
||||||
Tlen = sizeof(T_sha256);
|
Tlen = sizeof(T_sha256);
|
||||||
T = T_sha256;
|
T = T_sha256;
|
||||||
hash_desc = &sha256_desc;
|
hash_desc = &sha256_desc;
|
||||||
|
4
rsa.h
4
rsa.h
@ -43,10 +43,10 @@ typedef struct dropbear_RSA_Key {
|
|||||||
} dropbear_rsa_key;
|
} dropbear_rsa_key;
|
||||||
|
|
||||||
void buf_put_rsa_sign(buffer* buf, const dropbear_rsa_key *key,
|
void buf_put_rsa_sign(buffer* buf, const dropbear_rsa_key *key,
|
||||||
enum signkey_type sigtype, const buffer *data_buf);
|
enum signature_type sigtype, const buffer *data_buf);
|
||||||
#if DROPBEAR_SIGNKEY_VERIFY
|
#if DROPBEAR_SIGNKEY_VERIFY
|
||||||
int buf_rsa_verify(buffer * buf, const dropbear_rsa_key *key,
|
int buf_rsa_verify(buffer * buf, const dropbear_rsa_key *key,
|
||||||
enum signkey_type sigtype, const buffer *data_buf);
|
enum signature_type sigtype, const buffer *data_buf);
|
||||||
#endif
|
#endif
|
||||||
int buf_get_rsa_pub_key(buffer* buf, dropbear_rsa_key *key);
|
int buf_get_rsa_pub_key(buffer* buf, dropbear_rsa_key *key);
|
||||||
int buf_get_rsa_priv_key(buffer* buf, dropbear_rsa_key *key);
|
int buf_get_rsa_priv_key(buffer* buf, dropbear_rsa_key *key);
|
||||||
|
12
session.h
12
session.h
@ -92,8 +92,8 @@ struct key_context {
|
|||||||
struct key_context_directional trans;
|
struct key_context_directional trans;
|
||||||
|
|
||||||
const struct dropbear_kex *algo_kex;
|
const struct dropbear_kex *algo_kex;
|
||||||
int algo_hostkey; /* server key type */
|
enum signkey_type algo_hostkey; /* server key type */
|
||||||
int algo_signature; /* server signature type */
|
enum signature_type algo_signature; /* server signature type */
|
||||||
|
|
||||||
int allow_compress; /* whether compression has started (useful in
|
int allow_compress; /* whether compression has started (useful in
|
||||||
zlib@openssh.com delayed compression case) */
|
zlib@openssh.com delayed compression case) */
|
||||||
@ -313,6 +313,14 @@ struct clientsession {
|
|||||||
#endif
|
#endif
|
||||||
sign_key *lastprivkey;
|
sign_key *lastprivkey;
|
||||||
|
|
||||||
|
enum signature_type server_sig_algs[DROPBEAR_SIGNKEY_NUM_NAMED+1];
|
||||||
|
int server_sig_algs_count;
|
||||||
|
#if DROPBEAR_RSA
|
||||||
|
/* Set to DROPBEAR_SIGNATURE_RSA_SHA256 or DROPBEAR_SIGNATURE_RSA_SHA1
|
||||||
|
if depending which the server accepts */
|
||||||
|
enum signature_type preferred_rsa_sigtype;
|
||||||
|
#endif
|
||||||
|
|
||||||
int retval; /* What the command exit status was - we emulate it */
|
int retval; /* What the command exit status was - we emulate it */
|
||||||
#if 0
|
#if 0
|
||||||
TODO
|
TODO
|
||||||
|
69
signkey.c
69
signkey.c
@ -111,34 +111,52 @@ enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen)
|
|||||||
|
|
||||||
/* Special case for rsa-sha2-256. This could be generalised if more
|
/* Special case for rsa-sha2-256. This could be generalised if more
|
||||||
signature names are added that aren't 1-1 with public key names */
|
signature names are added that aren't 1-1 with public key names */
|
||||||
const char* signature_name_from_type(enum signkey_type type, unsigned int *namelen) {
|
const char* signature_name_from_type(enum signature_type type, unsigned int *namelen) {
|
||||||
#if DROPBEAR_RSA_SHA256
|
#if DROPBEAR_RSA_SHA256
|
||||||
if (type == DROPBEAR_SIGNKEY_RSA_SHA256) {
|
if (type == DROPBEAR_SIGNATURE_RSA_SHA256) {
|
||||||
*namelen = strlen(SSH_SIGNKEY_RSA_SHA256);
|
*namelen = strlen(SSH_SIGNATURE_RSA_SHA256);
|
||||||
return SSH_SIGNKEY_RSA_SHA256;
|
return SSH_SIGNATURE_RSA_SHA256;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return signkey_name_from_type(type, namelen);
|
#if DROPBEAR_RSA_SHA1
|
||||||
}
|
if (type == DROPBEAR_SIGNATURE_RSA_SHA1) {
|
||||||
|
*namelen = strlen(SSH_SIGNKEY_RSA);
|
||||||
enum signkey_type signature_type_from_name(const char* name, unsigned int namelen) {
|
return SSH_SIGNKEY_RSA;
|
||||||
#if DROPBEAR_RSA_SHA256
|
|
||||||
if (namelen == strlen(SSH_SIGNKEY_RSA_SHA256)
|
|
||||||
&& memcmp(name, SSH_SIGNKEY_RSA_SHA256, namelen) == 0) {
|
|
||||||
return DROPBEAR_SIGNKEY_RSA_SHA256;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return signkey_type_from_name(name, namelen);
|
return signkey_name_from_type((enum signkey_type)type, namelen);
|
||||||
}
|
}
|
||||||
|
|
||||||
enum signkey_type signkey_type_from_signature(enum signkey_type sigtype) {
|
/* Returns DROPBEAR_SIGNATURE_NONE if none match */
|
||||||
|
enum signature_type signature_type_from_name(const char* name, unsigned int namelen) {
|
||||||
#if DROPBEAR_RSA_SHA256
|
#if DROPBEAR_RSA_SHA256
|
||||||
if (sigtype == DROPBEAR_SIGNKEY_RSA_SHA256) {
|
if (namelen == strlen(SSH_SIGNATURE_RSA_SHA256)
|
||||||
|
&& memcmp(name, SSH_SIGNATURE_RSA_SHA256, namelen) == 0) {
|
||||||
|
return DROPBEAR_SIGNATURE_RSA_SHA256;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if DROPBEAR_RSA_SHA256
|
||||||
|
if (namelen == strlen(SSH_SIGNKEY_RSA)
|
||||||
|
&& memcmp(name, SSH_SIGNKEY_RSA, namelen) == 0) {
|
||||||
|
return DROPBEAR_SIGNATURE_RSA_SHA1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return (enum signature_type)signkey_type_from_name(name, namelen);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum signkey_type signkey_type_from_signature(enum signature_type sigtype) {
|
||||||
|
#if DROPBEAR_RSA_SHA256
|
||||||
|
if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA256) {
|
||||||
|
return DROPBEAR_SIGNKEY_RSA;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if DROPBEAR_RSA_SHA1
|
||||||
|
if (sigtype == DROPBEAR_SIGNATURE_RSA_SHA1) {
|
||||||
return DROPBEAR_SIGNKEY_RSA;
|
return DROPBEAR_SIGNKEY_RSA;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
assert(sigtype < DROPBEAR_SIGNKEY_NUM_NAMED);
|
assert(sigtype < DROPBEAR_SIGNKEY_NUM_NAMED);
|
||||||
return sigtype;
|
return (enum signkey_type)sigtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns a pointer to the key part specific to "type".
|
/* Returns a pointer to the key part specific to "type".
|
||||||
@ -562,11 +580,20 @@ char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloble
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type sigtype,
|
void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,
|
||||||
const buffer *data_buf) {
|
const buffer *data_buf) {
|
||||||
buffer *sigblob = buf_new(MAX_PUBKEY_SIZE);
|
buffer *sigblob = buf_new(MAX_PUBKEY_SIZE);
|
||||||
enum signkey_type keytype = signkey_type_from_signature(sigtype);
|
enum signkey_type keytype = signkey_type_from_signature(sigtype);
|
||||||
|
|
||||||
|
#if DEBUG_TRACE
|
||||||
|
{
|
||||||
|
int namelen;
|
||||||
|
const char* signame = signature_name_from_type(sigtype, &namelen);
|
||||||
|
TRACE(("buf_put_sign type %d %s", sigtype, signame));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if DROPBEAR_DSS
|
#if DROPBEAR_DSS
|
||||||
if (keytype == DROPBEAR_SIGNKEY_DSS) {
|
if (keytype == DROPBEAR_SIGNKEY_DSS) {
|
||||||
buf_put_dss_sign(sigblob, key->dsskey, data_buf);
|
buf_put_dss_sign(sigblob, key->dsskey, data_buf);
|
||||||
@ -603,11 +630,12 @@ void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type sigtype,
|
|||||||
* If FAILURE is returned, the position of
|
* If FAILURE is returned, the position of
|
||||||
* buf is undefined. If SUCCESS is returned, buf will be positioned after the
|
* buf is undefined. If SUCCESS is returned, buf will be positioned after the
|
||||||
* signature blob */
|
* signature blob */
|
||||||
int buf_verify(buffer * buf, sign_key *key, enum signkey_type expect_sigtype, const buffer *data_buf) {
|
int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf) {
|
||||||
|
|
||||||
char *type_name = NULL;
|
char *type_name = NULL;
|
||||||
unsigned int type_name_len = 0;
|
unsigned int type_name_len = 0;
|
||||||
enum signkey_type sigtype, keytype;
|
enum signature_type sigtype;
|
||||||
|
enum signkey_type keytype;
|
||||||
|
|
||||||
TRACE(("enter buf_verify"))
|
TRACE(("enter buf_verify"))
|
||||||
|
|
||||||
@ -616,8 +644,7 @@ int buf_verify(buffer * buf, sign_key *key, enum signkey_type expect_sigtype, co
|
|||||||
sigtype = signature_type_from_name(type_name, type_name_len);
|
sigtype = signature_type_from_name(type_name, type_name_len);
|
||||||
m_free(type_name);
|
m_free(type_name);
|
||||||
|
|
||||||
if (expect_sigtype != DROPBEAR_SIGNKEY_ANY
|
if (expect_sigtype != sigtype) {
|
||||||
&& expect_sigtype != sigtype) {
|
|
||||||
dropbear_exit("Non-matching signing type");
|
dropbear_exit("Non-matching signing type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
36
signkey.h
36
signkey.h
@ -32,6 +32,7 @@ struct dropbear_DSS_Key;
|
|||||||
struct dropbear_RSA_Key;
|
struct dropbear_RSA_Key;
|
||||||
struct dropbear_ED25519_Key;
|
struct dropbear_ED25519_Key;
|
||||||
|
|
||||||
|
/* Must match with signature_type below */
|
||||||
enum signkey_type {
|
enum signkey_type {
|
||||||
#if DROPBEAR_RSA
|
#if DROPBEAR_RSA
|
||||||
DROPBEAR_SIGNKEY_RSA,
|
DROPBEAR_SIGNKEY_RSA,
|
||||||
@ -49,13 +50,32 @@ enum signkey_type {
|
|||||||
#endif
|
#endif
|
||||||
DROPBEAR_SIGNKEY_NUM_NAMED,
|
DROPBEAR_SIGNKEY_NUM_NAMED,
|
||||||
DROPBEAR_SIGNKEY_ECDSA_KEYGEN = 70, /* just "ecdsa" for keygen */
|
DROPBEAR_SIGNKEY_ECDSA_KEYGEN = 70, /* just "ecdsa" for keygen */
|
||||||
#if DROPBEAR_RSA_SHA256
|
|
||||||
DROPBEAR_SIGNKEY_RSA_SHA256, /* rsa-sha2-256 signature. has a ssh-rsa key */
|
|
||||||
#endif
|
|
||||||
DROPBEAR_SIGNKEY_ANY = 80,
|
DROPBEAR_SIGNKEY_ANY = 80,
|
||||||
DROPBEAR_SIGNKEY_NONE = 90,
|
DROPBEAR_SIGNKEY_NONE = 90,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Must match with signkey_type above, apart from rsa */
|
||||||
|
enum signature_type {
|
||||||
|
#if DROPBEAR_DSS
|
||||||
|
DROPBEAR_SIGNATURE_DSS = DROPBEAR_SIGNKEY_DSS,
|
||||||
|
#endif
|
||||||
|
#if DROPBEAR_ECDSA
|
||||||
|
DROPBEAR_SIGNATURE_ECDSA_NISTP256 = DROPBEAR_SIGNKEY_ECDSA_NISTP256,
|
||||||
|
DROPBEAR_SIGNATURE_ECDSA_NISTP384 = DROPBEAR_SIGNKEY_ECDSA_NISTP384,
|
||||||
|
DROPBEAR_SIGNATURE_ECDSA_NISTP521 = DROPBEAR_SIGNKEY_ECDSA_NISTP521,
|
||||||
|
#endif /* DROPBEAR_ECDSA */
|
||||||
|
#if DROPBEAR_ED25519
|
||||||
|
DROPBEAR_SIGNATURE_ED25519 = DROPBEAR_SIGNKEY_ED25519,
|
||||||
|
#endif
|
||||||
|
#if DROPBEAR_RSA_SHA1
|
||||||
|
DROPBEAR_SIGNATURE_RSA_SHA1 = 100, /* ssh-rsa signature (sha1) */
|
||||||
|
#endif
|
||||||
|
#if DROPBEAR_RSA_SHA256
|
||||||
|
DROPBEAR_SIGNATURE_RSA_SHA256 = 101, /* rsa-sha2-256 signature. has a ssh-rsa key */
|
||||||
|
#endif
|
||||||
|
DROPBEAR_SIGNATURE_NONE = DROPBEAR_SIGNKEY_NONE,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Sources for signing keys */
|
/* Sources for signing keys */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -97,17 +117,17 @@ typedef struct SIGN_key sign_key;
|
|||||||
sign_key * new_sign_key(void);
|
sign_key * new_sign_key(void);
|
||||||
const char* signkey_name_from_type(enum signkey_type type, unsigned int *namelen);
|
const char* signkey_name_from_type(enum signkey_type type, unsigned int *namelen);
|
||||||
enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen);
|
enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen);
|
||||||
const char* signature_name_from_type(enum signkey_type type, unsigned int *namelen);
|
const char* signature_name_from_type(enum signature_type type, unsigned int *namelen);
|
||||||
enum signkey_type signature_type_from_name(const char* name, unsigned int namelen);
|
enum signature_type signature_type_from_name(const char* name, unsigned int namelen);
|
||||||
enum signkey_type signkey_type_from_signature(enum signkey_type sigtype);
|
enum signkey_type signkey_type_from_signature(enum signature_type sigtype);
|
||||||
int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type);
|
int buf_get_pub_key(buffer *buf, sign_key *key, enum signkey_type *type);
|
||||||
int buf_get_priv_key(buffer* buf, sign_key *key, enum signkey_type *type);
|
int buf_get_priv_key(buffer* buf, sign_key *key, enum signkey_type *type);
|
||||||
void buf_put_pub_key(buffer* buf, sign_key *key, enum signkey_type type);
|
void buf_put_pub_key(buffer* buf, sign_key *key, enum signkey_type type);
|
||||||
void buf_put_priv_key(buffer* buf, sign_key *key, enum signkey_type type);
|
void buf_put_priv_key(buffer* buf, sign_key *key, enum signkey_type type);
|
||||||
void sign_key_free(sign_key *key);
|
void sign_key_free(sign_key *key);
|
||||||
void buf_put_sign(buffer* buf, sign_key *key, enum signkey_type sigtype, const buffer *data_buf);
|
void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype, const buffer *data_buf);
|
||||||
#if DROPBEAR_SIGNKEY_VERIFY
|
#if DROPBEAR_SIGNKEY_VERIFY
|
||||||
int buf_verify(buffer * buf, sign_key *key, enum signkey_type type, const buffer *data_buf);
|
int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf);
|
||||||
char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloblen);
|
char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloblen);
|
||||||
#endif
|
#endif
|
||||||
int cmp_base64_key(const unsigned char* keyblob, unsigned int keybloblen,
|
int cmp_base64_key(const unsigned char* keyblob, unsigned int keybloblen,
|
||||||
|
2
ssh.h
2
ssh.h
@ -108,7 +108,7 @@
|
|||||||
#define SSH_SIGNKEY_ED25519 "ssh-ed25519"
|
#define SSH_SIGNKEY_ED25519 "ssh-ed25519"
|
||||||
#define SSH_SIGNKEY_ED25519_LEN 11
|
#define SSH_SIGNKEY_ED25519_LEN 11
|
||||||
/* signature type */
|
/* signature type */
|
||||||
#define SSH_SIGNKEY_RSA_SHA256 "rsa-sha2-256"
|
#define SSH_SIGNATURE_RSA_SHA256 "rsa-sha2-256"
|
||||||
|
|
||||||
/* Agent commands. These aren't part of the spec, and are defined
|
/* Agent commands. These aren't part of the spec, and are defined
|
||||||
* only on the openssh implementation. */
|
* only on the openssh implementation. */
|
||||||
|
@ -92,7 +92,8 @@ void svr_auth_pubkey(int valid_user) {
|
|||||||
buffer * signbuf = NULL;
|
buffer * signbuf = NULL;
|
||||||
sign_key * key = NULL;
|
sign_key * key = NULL;
|
||||||
char* fp = NULL;
|
char* fp = NULL;
|
||||||
enum signkey_type sigtype, keytype;
|
enum signature_type sigtype;
|
||||||
|
enum signkey_type keytype;
|
||||||
int auth_failure = 1;
|
int auth_failure = 1;
|
||||||
|
|
||||||
TRACE(("enter pubkeyauth"))
|
TRACE(("enter pubkeyauth"))
|
||||||
@ -102,10 +103,6 @@ void svr_auth_pubkey(int valid_user) {
|
|||||||
testkey = (buf_getbool(ses.payload) == 0);
|
testkey = (buf_getbool(ses.payload) == 0);
|
||||||
|
|
||||||
sigalgo = buf_getstring(ses.payload, &sigalgolen);
|
sigalgo = buf_getstring(ses.payload, &sigalgolen);
|
||||||
sigtype = signature_type_from_name(sigalgo, sigalgolen);
|
|
||||||
keytype = signkey_type_from_signature(sigtype);
|
|
||||||
keyalgo = signkey_name_from_type(keytype, &keyalgolen);
|
|
||||||
|
|
||||||
keybloblen = buf_getint(ses.payload);
|
keybloblen = buf_getint(ses.payload);
|
||||||
keyblob = buf_getptr(ses.payload, keybloblen);
|
keyblob = buf_getptr(ses.payload, keybloblen);
|
||||||
|
|
||||||
@ -117,6 +114,16 @@ void svr_auth_pubkey(int valid_user) {
|
|||||||
send_msg_userauth_failure(0, 0);
|
send_msg_userauth_failure(0, 0);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sigtype = signature_type_from_name(sigalgo, sigalgolen);
|
||||||
|
if (sigtype == DROPBEAR_SIGNATURE_NONE) {
|
||||||
|
send_msg_userauth_failure(0, 0);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
keytype = signkey_type_from_signature(sigtype);
|
||||||
|
keyalgo = signkey_name_from_type(keytype, &keyalgolen);
|
||||||
|
|
||||||
#if DROPBEAR_PLUGIN
|
#if DROPBEAR_PLUGIN
|
||||||
if (svr_ses.plugin_instance != NULL) {
|
if (svr_ses.plugin_instance != NULL) {
|
||||||
char *options_buf;
|
char *options_buf;
|
||||||
|
Loading…
Reference in New Issue
Block a user