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_ANY 0
#define DROPBEAR_SIGNKEY_RSA 1 #define DROPBEAR_SIGNKEY_RSA 1
#define DROPBEAR_SIGNKEY_DSS 2 #define DROPBEAR_SIGNKEY_DSS 2
#define DROPBEAR_SIGNKEY_NONE 3
#define DROPBEAR_COMP_NONE 0 #define DROPBEAR_COMP_NONE 0
#define DROPBEAR_COMP_ZLIB 1 #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. /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail.
* type should be set by the caller to specify the type to read, and * 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) */ * 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 char* ident;
unsigned int len; unsigned int len;
int keytype;
int ret = DROPBEAR_FAILURE;
TRACE(("enter buf_get_pub_key")); TRACE(("enter buf_get_pub_key"));
ident = buf_getstring(buf, &len); 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 #ifdef DROPBEAR_DSS
if (memcmp(ident, SSH_SIGNKEY_DSS, len) == 0 if (keytype == DROPBEAR_SIGNKEY_DSS) {
&& (*type == DROPBEAR_SIGNKEY_ANY
|| *type == DROPBEAR_SIGNKEY_DSS)) {
m_free(ident);
buf_setpos(buf, buf->pos - len - 4);
dss_key_free(key->dsskey); dss_key_free(key->dsskey);
key->dsskey = (dss_key*)m_malloc(sizeof(dss_key)); key->dsskey = (dss_key*)m_malloc(sizeof(dss_key));
*type = DROPBEAR_SIGNKEY_DSS; ret = buf_get_dss_pub_key(buf, key->dsskey);
return buf_get_dss_pub_key(buf, key->dsskey); if (ret == DROPBEAR_FAILURE) {
m_free(key->dsskey);
}
} }
#endif #endif
#ifdef DROPBEAR_RSA #ifdef DROPBEAR_RSA
if (memcmp(ident, SSH_SIGNKEY_RSA, len) == 0 if (keytype == DROPBEAR_SIGNKEY_RSA) {
&& (*type == DROPBEAR_SIGNKEY_ANY
|| *type == DROPBEAR_SIGNKEY_RSA)) {
m_free(ident);
buf_setpos(buf, buf->pos - len - 4);
rsa_key_free(key->rsakey); rsa_key_free(key->rsakey);
key->rsakey = (rsa_key*)m_malloc(sizeof(rsa_key)); key->rsakey = (rsa_key*)m_malloc(sizeof(rsa_key));
*type = DROPBEAR_SIGNKEY_RSA; ret = buf_get_rsa_pub_key(buf, key->rsakey);
return buf_get_rsa_pub_key(buf, key->rsakey); if (ret == DROPBEAR_FAILURE) {
m_free(key->rsakey);
}
} }
#endif #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 */ /* returns DROPBEAR_SUCCESS on success, DROPBEAR_FAILURE on fail.
/* type is set to hold the type returned */ * 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) { int buf_get_priv_key(buffer *buf, sign_key *key, int *type) {
unsigned char* ident; unsigned char* ident;
unsigned int len; unsigned int len;
int ret; int keytype;
int ret = DROPBEAR_FAILURE;
TRACE(("enter buf_get_priv_key")); TRACE(("enter buf_get_priv_key"));
ident = buf_getstring(buf, &len); 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 #ifdef DROPBEAR_DSS
if (memcmp(ident, SSH_SIGNKEY_DSS, len) == 0 if (keytype == DROPBEAR_SIGNKEY_DSS) {
&& (*type == DROPBEAR_SIGNKEY_ANY
|| *type == DROPBEAR_SIGNKEY_DSS)) {
m_free(ident);
buf_setpos(buf, buf->pos - len - 4);
dss_key_free(key->dsskey); dss_key_free(key->dsskey);
key->dsskey = (dss_key*)m_malloc(sizeof(dss_key)); key->dsskey = (dss_key*)m_malloc(sizeof(dss_key));
ret = buf_get_dss_priv_key(buf, key->dsskey); ret = buf_get_dss_priv_key(buf, key->dsskey);
*type = DROPBEAR_SIGNKEY_DSS;
if (ret == DROPBEAR_FAILURE) { if (ret == DROPBEAR_FAILURE) {
m_free(key->dsskey); m_free(key->dsskey);
} }
TRACE(("leave buf_get_priv_key: done get dss"));
return ret;
} }
#endif #endif
#ifdef DROPBEAR_RSA #ifdef DROPBEAR_RSA
if (memcmp(ident, SSH_SIGNKEY_RSA, len) == 0 if (keytype == DROPBEAR_SIGNKEY_RSA) {
&& (*type == DROPBEAR_SIGNKEY_ANY
|| *type == DROPBEAR_SIGNKEY_RSA)) {
m_free(ident);
buf_setpos(buf, buf->pos - len - 4);
rsa_key_free(key->rsakey); rsa_key_free(key->rsakey);
key->rsakey = (rsa_key*)m_malloc(sizeof(rsa_key)); key->rsakey = (rsa_key*)m_malloc(sizeof(rsa_key));
ret = buf_get_rsa_priv_key(buf, key->rsakey); ret = buf_get_rsa_priv_key(buf, key->rsakey);
*type = DROPBEAR_SIGNKEY_RSA;
if (ret == DROPBEAR_FAILURE) { if (ret == DROPBEAR_FAILURE) {
m_free(key->rsakey); m_free(key->rsakey);
} }
TRACE(("leave buf_get_priv_key: done get rsa"));
return ret;
} }
#endif #endif
m_free(ident);
TRACE(("leave buf_get_priv_key")); 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; typedef struct SIGN_key sign_key;
sign_key * new_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_pub_key(buffer *buf, sign_key *key, int *type);
int buf_get_priv_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); 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 char* keyblob;
unsigned int keybloblen; unsigned int keybloblen;
buffer * signbuf = NULL; buffer * signbuf = NULL;
unsigned int sigoffset;
sign_key * key = NULL; sign_key * key = NULL;
char* fp = NULL; char* fp = NULL;
int type = -1; int type = -1;
@ -99,14 +98,9 @@ void svr_auth_pubkey() {
* session_id, concatenated with the payload packet up to the signature */ * session_id, concatenated with the payload packet up to the signature */
signbuf = buf_new(ses.payload->pos + 4 + SHA1_HASH_SIZE); signbuf = buf_new(ses.payload->pos + 4 + SHA1_HASH_SIZE);
buf_putstring(signbuf, ses.session_id, SHA1_HASH_SIZE); buf_putstring(signbuf, ses.session_id, SHA1_HASH_SIZE);
sigoffset = ses.payload->pos; buf_putbytes(signbuf, ses.payload->data, 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_setpos(signbuf, 0); buf_setpos(signbuf, 0);
/* ... and finally verify the signature */ /* ... and finally verify the signature */
fp = sign_key_fingerprint(key, type); fp = sign_key_fingerprint(key, type);
if (buf_verify(ses.payload, key, buf_getptr(signbuf, signbuf->len), if (buf_verify(ses.payload, key, buf_getptr(signbuf, signbuf->len),