Improved signkey code

--HG--
extra : convert_revision : fcf64cb4d2e273f80bf8c5f1d2dd00a0f4dc1acf
This commit is contained in:
Matt Johnston 2004-08-03 15:51:55 +00:00
parent 9c91ea1caf
commit 7a854cb1f8
4 changed files with 90 additions and 47 deletions

View File

@ -227,6 +227,7 @@
#define DROPBEAR_SIGNKEY_ANY 0
#define DROPBEAR_SIGNKEY_RSA 1
#define DROPBEAR_SIGNKEY_DSS 2
#define DROPBEAR_SIGNKEY_NONE 3
#define DROPBEAR_COMP_NONE 0
#define DROPBEAR_COMP_ZLIB 1

124
signkey.c
View File

@ -44,6 +44,46 @@ sign_key * new_sign_key() {
}
/* Returns "ssh-dss" or "ssh-rsa" corresponding to the type. Exits fatally
* if the type is invalid */
const char* signkey_name_from_type(int type, int *namelen) {
#ifdef DROPBEAR_RSA
if (type == DROPBEAR_SIGNKEY_RSA) {
*namelen = SSH_SIGNKEY_RSA_LEN;
return SSH_SIGNKEY_RSA;
}
#endif
#ifdef DROPBEAR_DSS
if (type == DROPBEAR_SIGNKEY_DSS) {
*namelen = SSH_SIGNKEY_DSS_LEN;
return SSH_SIGNKEY_DSS;
}
#endif
dropbear_exit("bad key type %d", type);
return NULL; /* notreached */
}
/* Returns DROPBEAR_SIGNKEY_RSA, DROPBEAR_SIGNKEY_DSS,
* or DROPBEAR_SIGNKEY_NONE */
int signkey_type_from_name(const char* name, int namelen) {
#ifdef DROPBEAR_RSA
if (namelen == SSH_SIGNKEY_RSA_LEN
&& memcmp(name, SSH_SIGNKEY_RSA, SSH_SIGNKEY_RSA_LEN) == 0) {
return DROPBEAR_SIGNKEY_RSA;
}
#endif
#ifdef DROPBEAR_DSS
if (namelen == SSH_SIGNKEY_DSS_LEN
&& memcmp(name, SSH_SIGNKEY_DSS, SSH_SIGNKEY_DSS_LEN) == 0) {
return DROPBEAR_SIGNKEY_DSS;
}
#endif
return DROPBEAR_SIGNKEY_NONE;
}
/* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail.
* type should be set by the caller to specify the type to read, and
* on return is set to the type read (useful when type = _ANY) */
@ -51,94 +91,100 @@ int buf_get_pub_key(buffer *buf, sign_key *key, int *type) {
unsigned char* ident;
unsigned int len;
int keytype;
int ret = DROPBEAR_FAILURE;
TRACE(("enter buf_get_pub_key"));
ident = buf_getstring(buf, &len);
keytype = signkey_type_from_name(ident, len);
m_free(ident);
if (*type != DROPBEAR_SIGNKEY_ANY && *type != keytype) {
return DROPBEAR_FAILURE;
}
*type = keytype;
/* Rewind the buffer back before "ssh-rsa" etc */
buf_incrpos(buf, -len - 4);
#ifdef DROPBEAR_DSS
if (memcmp(ident, SSH_SIGNKEY_DSS, len) == 0
&& (*type == DROPBEAR_SIGNKEY_ANY
|| *type == DROPBEAR_SIGNKEY_DSS)) {
m_free(ident);
buf_setpos(buf, buf->pos - len - 4);
if (keytype == DROPBEAR_SIGNKEY_DSS) {
dss_key_free(key->dsskey);
key->dsskey = (dss_key*)m_malloc(sizeof(dss_key));
*type = DROPBEAR_SIGNKEY_DSS;
return buf_get_dss_pub_key(buf, key->dsskey);
ret = buf_get_dss_pub_key(buf, key->dsskey);
if (ret == DROPBEAR_FAILURE) {
m_free(key->dsskey);
}
}
#endif
#ifdef DROPBEAR_RSA
if (memcmp(ident, SSH_SIGNKEY_RSA, len) == 0
&& (*type == DROPBEAR_SIGNKEY_ANY
|| *type == DROPBEAR_SIGNKEY_RSA)) {
m_free(ident);
buf_setpos(buf, buf->pos - len - 4);
if (keytype == DROPBEAR_SIGNKEY_RSA) {
rsa_key_free(key->rsakey);
key->rsakey = (rsa_key*)m_malloc(sizeof(rsa_key));
*type = DROPBEAR_SIGNKEY_RSA;
return buf_get_rsa_pub_key(buf, key->rsakey);
ret = buf_get_rsa_pub_key(buf, key->rsakey);
if (ret == DROPBEAR_FAILURE) {
m_free(key->rsakey);
}
}
#endif
TRACE(("leave buf_get_pub_key: didn't match the type we want (%d versus '%s'len %d)", *type, ident, len));
m_free(ident);
TRACE(("leave buf_get_pub_key"));
return DROPBEAR_FAILURE;
return ret;
}
/* returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
/* type is set to hold the type returned */
/* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail.
* type should be set by the caller to specify the type to read, and
* on return is set to the type read (useful when type = _ANY) */
int buf_get_priv_key(buffer *buf, sign_key *key, int *type) {
unsigned char* ident;
unsigned int len;
int ret;
int keytype;
int ret = DROPBEAR_FAILURE;
TRACE(("enter buf_get_priv_key"));
ident = buf_getstring(buf, &len);
keytype = signkey_type_from_name(ident, len);
m_free(ident);
if (*type != DROPBEAR_SIGNKEY_ANY && *type != keytype) {
return DROPBEAR_FAILURE;
}
*type = keytype;
/* Rewind the buffer back before "ssh-rsa" etc */
buf_incrpos(buf, -len - 4);
#ifdef DROPBEAR_DSS
if (memcmp(ident, SSH_SIGNKEY_DSS, len) == 0
&& (*type == DROPBEAR_SIGNKEY_ANY
|| *type == DROPBEAR_SIGNKEY_DSS)) {
m_free(ident);
buf_setpos(buf, buf->pos - len - 4);
if (keytype == DROPBEAR_SIGNKEY_DSS) {
dss_key_free(key->dsskey);
key->dsskey = (dss_key*)m_malloc(sizeof(dss_key));
ret = buf_get_dss_priv_key(buf, key->dsskey);
*type = DROPBEAR_SIGNKEY_DSS;
if (ret == DROPBEAR_FAILURE) {
m_free(key->dsskey);
}
TRACE(("leave buf_get_priv_key: done get dss"));
return ret;
}
#endif
#ifdef DROPBEAR_RSA
if (memcmp(ident, SSH_SIGNKEY_RSA, len) == 0
&& (*type == DROPBEAR_SIGNKEY_ANY
|| *type == DROPBEAR_SIGNKEY_RSA)) {
m_free(ident);
buf_setpos(buf, buf->pos - len - 4);
if (keytype == DROPBEAR_SIGNKEY_RSA) {
rsa_key_free(key->rsakey);
key->rsakey = (rsa_key*)m_malloc(sizeof(rsa_key));
ret = buf_get_rsa_priv_key(buf, key->rsakey);
*type = DROPBEAR_SIGNKEY_RSA;
if (ret == DROPBEAR_FAILURE) {
m_free(key->rsakey);
}
TRACE(("leave buf_get_priv_key: done get rsa"));
return ret;
}
#endif
m_free(ident);
TRACE(("leave buf_get_priv_key"));
return DROPBEAR_FAILURE;
return ret;
}

View File

@ -42,6 +42,8 @@ struct SIGN_key {
typedef struct SIGN_key sign_key;
sign_key * new_sign_key();
const char* signkey_name_from_type(int type, int *namelen);
int signkey_type_from_name(const char* name, int namelen);
int buf_get_pub_key(buffer *buf, sign_key *key, int *type);
int buf_get_priv_key(buffer* buf, sign_key *key, int *type);
void buf_put_pub_key(buffer* buf, sign_key *key, int type);

View File

@ -58,7 +58,6 @@ void svr_auth_pubkey() {
unsigned char* keyblob;
unsigned int keybloblen;
buffer * signbuf = NULL;
unsigned int sigoffset;
sign_key * key = NULL;
char* fp = NULL;
int type = -1;
@ -99,14 +98,9 @@ void svr_auth_pubkey() {
* session_id, concatenated with the payload packet up to the signature */
signbuf = buf_new(ses.payload->pos + 4 + SHA1_HASH_SIZE);
buf_putstring(signbuf, ses.session_id, SHA1_HASH_SIZE);
sigoffset = ses.payload->pos;
buf_setpos(ses.payload, 0);
memcpy(buf_getwriteptr(signbuf, sigoffset),
buf_getptr(ses.payload, sigoffset), sigoffset);
buf_incrwritepos(signbuf, sigoffset);
buf_setpos(ses.payload, sigoffset);
buf_putbytes(signbuf, ses.payload->data, ses.payload->pos);
buf_setpos(signbuf, 0);
/* ... and finally verify the signature */
fp = sign_key_fingerprint(key, type);
if (buf_verify(ses.payload, key, buf_getptr(signbuf, signbuf->len),