1 Star 0 Fork 11

liufshu / oh-dropbear

forked from xfan1024 / oh-dropbear 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
signkey.c 19.44 KB
一键复制 编辑 原始数据 按行查看 历史
xfan1024 提交于 2021-08-13 14:40 . Init commit: dropbear-2020.81
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774
/*
* Dropbear - a SSH2 server
*
* Copyright (c) 2002,2003 Matt Johnston
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE. */
#include "includes.h"
#include "dbutil.h"
#include "signkey.h"
#include "buffer.h"
#include "ssh.h"
#include "ecdsa.h"
#include "rsa.h"
#include "dss.h"
#include "ed25519.h"
static const char * const signkey_names[DROPBEAR_SIGNKEY_NUM_NAMED] = {
#if DROPBEAR_RSA
"ssh-rsa",
#endif
#if DROPBEAR_DSS
"ssh-dss",
#endif
#if DROPBEAR_ECDSA
"ecdsa-sha2-nistp256",
"ecdsa-sha2-nistp384",
"ecdsa-sha2-nistp521",
#endif /* DROPBEAR_ECDSA */
#if DROPBEAR_ED25519
"ssh-ed25519",
#endif /* DROPBEAR_ED25519 */
/* "rsa-sha2-256" is special-cased below since it is only a signature name, not key type */
};
/* malloc a new sign_key and set the dss and rsa keys to NULL */
sign_key * new_sign_key() {
sign_key * ret;
ret = (sign_key*)m_malloc(sizeof(sign_key));
ret->type = DROPBEAR_SIGNKEY_NONE;
ret->source = SIGNKEY_SOURCE_INVALID;
return ret;
}
/* Returns key name corresponding to the type. Exits fatally
* if the type is invalid */
const char* signkey_name_from_type(enum signkey_type type, unsigned int *namelen) {
if (type >= DROPBEAR_SIGNKEY_NUM_NAMED) {
dropbear_exit("Bad key type %d", type);
}
if (namelen) {
*namelen = strlen(signkey_names[type]);
}
return signkey_names[type];
}
/* Returns DROPBEAR_SIGNKEY_NONE if none match */
enum signkey_type signkey_type_from_name(const char* name, unsigned int namelen) {
int i;
for (i = 0; i < DROPBEAR_SIGNKEY_NUM_NAMED; i++) {
const char *fixed_name = signkey_names[i];
if (namelen == strlen(fixed_name)
&& memcmp(fixed_name, name, namelen) == 0) {
#if DROPBEAR_ECDSA
/* Some of the ECDSA key sizes are defined even if they're not compiled in */
if (0
#if !DROPBEAR_ECC_256
|| i == DROPBEAR_SIGNKEY_ECDSA_NISTP256
#endif
#if !DROPBEAR_ECC_384
|| i == DROPBEAR_SIGNKEY_ECDSA_NISTP384
#endif
#if !DROPBEAR_ECC_521
|| i == DROPBEAR_SIGNKEY_ECDSA_NISTP521
#endif
) {
TRACE(("attempt to use ecdsa type %d not compiled in", i))
return DROPBEAR_SIGNKEY_NONE;
}
#endif
return (enum signkey_type)i;
}
}
TRACE(("signkey_type_from_name unexpected key type."))
return DROPBEAR_SIGNKEY_NONE;
}
/* 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 */
const char* signature_name_from_type(enum signature_type type, unsigned int *namelen) {
#if DROPBEAR_RSA_SHA256
if (type == DROPBEAR_SIGNATURE_RSA_SHA256) {
if (namelen) {
*namelen = strlen(SSH_SIGNATURE_RSA_SHA256);
}
return SSH_SIGNATURE_RSA_SHA256;
}
#endif
#if DROPBEAR_RSA_SHA1
if (type == DROPBEAR_SIGNATURE_RSA_SHA1) {
if (namelen) {
*namelen = strlen(SSH_SIGNKEY_RSA);
}
return SSH_SIGNKEY_RSA;
}
#endif
return signkey_name_from_type((enum signkey_type)type, namelen);
}
/* 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 (namelen == strlen(SSH_SIGNATURE_RSA_SHA256)
&& memcmp(name, SSH_SIGNATURE_RSA_SHA256, namelen) == 0) {
return DROPBEAR_SIGNATURE_RSA_SHA256;
}
#endif
#if DROPBEAR_RSA_SHA1
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);
}
/* Returns the signature type from a key type. Must not be called
with RSA keytype */
enum signature_type signature_type_from_signkey(enum signkey_type keytype) {
#if DROPBEAR_RSA
assert(keytype != DROPBEAR_SIGNKEY_RSA);
#endif
assert(keytype < DROPBEAR_SIGNKEY_NUM_NAMED);
return (enum signature_type)keytype;
}
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;
}
#endif
assert((int)sigtype < (int)DROPBEAR_SIGNKEY_NUM_NAMED);
return (enum signkey_type)sigtype;
}
/* Returns a pointer to the key part specific to "type".
Be sure to check both (ret != NULL) and (*ret != NULL) */
void **
signkey_key_ptr(sign_key *key, enum signkey_type type) {
switch (type) {
#if DROPBEAR_ED25519
case DROPBEAR_SIGNKEY_ED25519:
return (void**)&key->ed25519key;
#endif
#if DROPBEAR_ECDSA
#if DROPBEAR_ECC_256
case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
return (void**)&key->ecckey256;
#endif
#if DROPBEAR_ECC_384
case DROPBEAR_SIGNKEY_ECDSA_NISTP384:
return (void**)&key->ecckey384;
#endif
#if DROPBEAR_ECC_521
case DROPBEAR_SIGNKEY_ECDSA_NISTP521:
return (void**)&key->ecckey521;
#endif
#endif /* DROPBEAR_ECDSA */
#if DROPBEAR_RSA
case DROPBEAR_SIGNKEY_RSA:
return (void**)&key->rsakey;
#endif
#if DROPBEAR_DSS
case DROPBEAR_SIGNKEY_DSS:
return (void**)&key->dsskey;
#endif
default:
return NULL;
}
}
/* 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_pub_key(buffer *buf, sign_key *key, enum signkey_type *type) {
char *ident;
unsigned int len;
enum signkey_type keytype;
int ret = DROPBEAR_FAILURE;
TRACE2(("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) {
TRACE(("buf_get_pub_key bad type - got %d, expected %d", keytype, *type))
return DROPBEAR_FAILURE;
}
TRACE2(("buf_get_pub_key keytype is %d", keytype))
*type = keytype;
/* Rewind the buffer back before "ssh-rsa" etc */
buf_decrpos(buf, len + 4);
#if DROPBEAR_DSS
if (keytype == DROPBEAR_SIGNKEY_DSS) {
dss_key_free(key->dsskey);
key->dsskey = m_malloc(sizeof(*key->dsskey));
ret = buf_get_dss_pub_key(buf, key->dsskey);
if (ret == DROPBEAR_FAILURE) {
dss_key_free(key->dsskey);
key->dsskey = NULL;
}
}
#endif
#if DROPBEAR_RSA
if (keytype == DROPBEAR_SIGNKEY_RSA) {
rsa_key_free(key->rsakey);
key->rsakey = m_malloc(sizeof(*key->rsakey));
ret = buf_get_rsa_pub_key(buf, key->rsakey);
if (ret == DROPBEAR_FAILURE) {
rsa_key_free(key->rsakey);
key->rsakey = NULL;
}
}
#endif
#if DROPBEAR_ECDSA
if (signkey_is_ecdsa(keytype)) {
ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
if (eck) {
if (*eck) {
ecc_free(*eck);
m_free(*eck);
*eck = NULL;
}
*eck = buf_get_ecdsa_pub_key(buf);
if (*eck) {
ret = DROPBEAR_SUCCESS;
}
}
}
#endif
#if DROPBEAR_ED25519
if (keytype == DROPBEAR_SIGNKEY_ED25519) {
ed25519_key_free(key->ed25519key);
key->ed25519key = m_malloc(sizeof(*key->ed25519key));
ret = buf_get_ed25519_pub_key(buf, key->ed25519key);
if (ret == DROPBEAR_FAILURE) {
m_free(key->ed25519key);
key->ed25519key = NULL;
}
}
#endif
TRACE2(("leave buf_get_pub_key"))
return ret;
}
/* 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, enum signkey_type *type) {
char *ident;
unsigned int len;
enum signkey_type keytype;
int ret = DROPBEAR_FAILURE;
TRACE2(("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) {
TRACE(("wrong key type: %d %d", *type, keytype))
return DROPBEAR_FAILURE;
}
*type = keytype;
/* Rewind the buffer back before "ssh-rsa" etc */
buf_decrpos(buf, len + 4);
#if DROPBEAR_DSS
if (keytype == DROPBEAR_SIGNKEY_DSS) {
dss_key_free(key->dsskey);
key->dsskey = m_malloc(sizeof(*key->dsskey));
ret = buf_get_dss_priv_key(buf, key->dsskey);
if (ret == DROPBEAR_FAILURE) {
dss_key_free(key->dsskey);
key->dsskey = NULL;
}
}
#endif
#if DROPBEAR_RSA
if (keytype == DROPBEAR_SIGNKEY_RSA) {
rsa_key_free(key->rsakey);
key->rsakey = m_malloc(sizeof(*key->rsakey));
ret = buf_get_rsa_priv_key(buf, key->rsakey);
if (ret == DROPBEAR_FAILURE) {
rsa_key_free(key->rsakey);
key->rsakey = NULL;
}
}
#endif
#if DROPBEAR_ECDSA
if (signkey_is_ecdsa(keytype)) {
ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
if (eck) {
if (*eck) {
ecc_free(*eck);
m_free(*eck);
*eck = NULL;
}
*eck = buf_get_ecdsa_priv_key(buf);
if (*eck) {
ret = DROPBEAR_SUCCESS;
}
}
}
#endif
#if DROPBEAR_ED25519
if (keytype == DROPBEAR_SIGNKEY_ED25519) {
ed25519_key_free(key->ed25519key);
key->ed25519key = m_malloc(sizeof(*key->ed25519key));
ret = buf_get_ed25519_priv_key(buf, key->ed25519key);
if (ret == DROPBEAR_FAILURE) {
m_free(key->ed25519key);
key->ed25519key = NULL;
}
}
#endif
TRACE2(("leave buf_get_priv_key"))
return ret;
}
/* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
void buf_put_pub_key(buffer* buf, sign_key *key, enum signkey_type type) {
buffer *pubkeys;
TRACE2(("enter buf_put_pub_key"))
pubkeys = buf_new(MAX_PUBKEY_SIZE);
#if DROPBEAR_DSS
if (type == DROPBEAR_SIGNKEY_DSS) {
buf_put_dss_pub_key(pubkeys, key->dsskey);
}
#endif
#if DROPBEAR_RSA
if (type == DROPBEAR_SIGNKEY_RSA) {
buf_put_rsa_pub_key(pubkeys, key->rsakey);
}
#endif
#if DROPBEAR_ECDSA
if (signkey_is_ecdsa(type)) {
ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
if (eck && *eck) {
buf_put_ecdsa_pub_key(pubkeys, *eck);
}
}
#endif
#if DROPBEAR_ED25519
if (type == DROPBEAR_SIGNKEY_ED25519) {
buf_put_ed25519_pub_key(pubkeys, key->ed25519key);
}
#endif
if (pubkeys->len == 0) {
dropbear_exit("Bad key types in buf_put_pub_key");
}
buf_putbufstring(buf, pubkeys);
buf_free(pubkeys);
TRACE2(("leave buf_put_pub_key"))
}
/* type is either DROPBEAR_SIGNKEY_DSS or DROPBEAR_SIGNKEY_RSA */
void buf_put_priv_key(buffer* buf, sign_key *key, enum signkey_type type) {
TRACE(("enter buf_put_priv_key"))
TRACE(("type is %d", type))
#if DROPBEAR_DSS
if (type == DROPBEAR_SIGNKEY_DSS) {
buf_put_dss_priv_key(buf, key->dsskey);
TRACE(("leave buf_put_priv_key: dss done"))
return;
}
#endif
#if DROPBEAR_RSA
if (type == DROPBEAR_SIGNKEY_RSA) {
buf_put_rsa_priv_key(buf, key->rsakey);
TRACE(("leave buf_put_priv_key: rsa done"))
return;
}
#endif
#if DROPBEAR_ECDSA
if (signkey_is_ecdsa(type)) {
ecc_key **eck = (ecc_key**)signkey_key_ptr(key, type);
if (eck && *eck) {
buf_put_ecdsa_priv_key(buf, *eck);
TRACE(("leave buf_put_priv_key: ecdsa done"))
return;
}
}
#endif
#if DROPBEAR_ED25519
if (type == DROPBEAR_SIGNKEY_ED25519) {
buf_put_ed25519_priv_key(buf, key->ed25519key);
TRACE(("leave buf_put_priv_key: ed25519 done"))
return;
}
#endif
dropbear_exit("Bad key types in put pub key");
}
void sign_key_free(sign_key *key) {
TRACE2(("enter sign_key_free"))
#if DROPBEAR_DSS
dss_key_free(key->dsskey);
key->dsskey = NULL;
#endif
#if DROPBEAR_RSA
rsa_key_free(key->rsakey);
key->rsakey = NULL;
#endif
#if DROPBEAR_ECDSA
#if DROPBEAR_ECC_256
if (key->ecckey256) {
ecc_free(key->ecckey256);
m_free(key->ecckey256);
key->ecckey256 = NULL;
}
#endif
#if DROPBEAR_ECC_384
if (key->ecckey384) {
ecc_free(key->ecckey384);
m_free(key->ecckey384);
key->ecckey384 = NULL;
}
#endif
#if DROPBEAR_ECC_521
if (key->ecckey521) {
ecc_free(key->ecckey521);
m_free(key->ecckey521);
key->ecckey521 = NULL;
}
#endif
#endif
#if DROPBEAR_ED25519
ed25519_key_free(key->ed25519key);
key->ed25519key = NULL;
#endif
m_free(key->filename);
m_free(key);
TRACE2(("leave sign_key_free"))
}
static char hexdig(unsigned char x) {
if (x > 0xf)
return 'X';
if (x < 10)
return '0' + x;
else
return 'a' + x - 10;
}
/* Since we're not sure if we'll have md5 or sha1, we present both.
* MD5 is used in preference, but sha1 could still be useful */
#if DROPBEAR_MD5_HMAC
static char * sign_key_md5_fingerprint(const unsigned char* keyblob,
unsigned int keybloblen) {
char * ret;
hash_state hs;
unsigned char hash[MD5_HASH_SIZE];
unsigned int i;
unsigned int buflen;
md5_init(&hs);
/* skip the size int of the string - this is a bit messy */
md5_process(&hs, keyblob, keybloblen);
md5_done(&hs, hash);
/* "md5 hexfingerprinthere\0", each hex digit is "AB:" etc */
buflen = 4 + 3*MD5_HASH_SIZE;
ret = (char*)m_malloc(buflen);
memset(ret, 'Z', buflen);
strcpy(ret, "md5 ");
for (i = 0; i < MD5_HASH_SIZE; i++) {
unsigned int pos = 4 + i*3;
ret[pos] = hexdig(hash[i] >> 4);
ret[pos+1] = hexdig(hash[i] & 0x0f);
ret[pos+2] = ':';
}
ret[buflen-1] = 0x0;
return ret;
}
#else /* use SHA1 rather than MD5 for fingerprint */
static char * sign_key_sha1_fingerprint(const unsigned char* keyblob,
unsigned int keybloblen) {
char * ret;
hash_state hs;
unsigned char hash[SHA1_HASH_SIZE];
unsigned int i;
unsigned int buflen;
sha1_init(&hs);
/* skip the size int of the string - this is a bit messy */
sha1_process(&hs, keyblob, keybloblen);
sha1_done(&hs, hash);
/* "sha1!! hexfingerprinthere\0", each hex digit is "AB:" etc */
buflen = 7 + 3*SHA1_HASH_SIZE;
ret = (char*)m_malloc(buflen);
strcpy(ret, "sha1!! ");
for (i = 0; i < SHA1_HASH_SIZE; i++) {
unsigned int pos = 7 + 3*i;
ret[pos] = hexdig(hash[i] >> 4);
ret[pos+1] = hexdig(hash[i] & 0x0f);
ret[pos+2] = ':';
}
ret[buflen-1] = 0x0;
return ret;
}
#endif /* MD5/SHA1 switch */
/* This will return a freshly malloced string, containing a fingerprint
* in either sha1 or md5 */
char * sign_key_fingerprint(const unsigned char* keyblob, unsigned int keybloblen) {
#if DROPBEAR_MD5_HMAC
return sign_key_md5_fingerprint(keyblob, keybloblen);
#else
return sign_key_sha1_fingerprint(keyblob, keybloblen);
#endif
}
void buf_put_sign(buffer* buf, sign_key *key, enum signature_type sigtype,
const buffer *data_buf) {
buffer *sigblob = buf_new(MAX_PUBKEY_SIZE);
enum signkey_type keytype = signkey_type_from_signature(sigtype);
#if DEBUG_TRACE
{
const char* signame = signature_name_from_type(sigtype, NULL);
TRACE(("buf_put_sign type %d %s", sigtype, signame));
}
#endif
#if DROPBEAR_DSS
if (keytype == DROPBEAR_SIGNKEY_DSS) {
buf_put_dss_sign(sigblob, key->dsskey, data_buf);
}
#endif
#if DROPBEAR_RSA
if (keytype == DROPBEAR_SIGNKEY_RSA) {
buf_put_rsa_sign(sigblob, key->rsakey, sigtype, data_buf);
}
#endif
#if DROPBEAR_ECDSA
if (signkey_is_ecdsa(keytype)) {
ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
if (eck && *eck) {
buf_put_ecdsa_sign(sigblob, *eck, data_buf);
}
}
#endif
#if DROPBEAR_ED25519
if (keytype == DROPBEAR_SIGNKEY_ED25519) {
buf_put_ed25519_sign(sigblob, key->ed25519key, data_buf);
}
#endif
if (sigblob->len == 0) {
dropbear_exit("Non-matching signing type");
}
buf_putbufstring(buf, sigblob);
buf_free(sigblob);
}
#if DROPBEAR_SIGNKEY_VERIFY
/* Return DROPBEAR_SUCCESS or DROPBEAR_FAILURE.
* If FAILURE is returned, the position of
* buf is undefined. If SUCCESS is returned, buf will be positioned after the
* signature blob */
int buf_verify(buffer * buf, sign_key *key, enum signature_type expect_sigtype, const buffer *data_buf) {
char *type_name = NULL;
unsigned int type_name_len = 0;
enum signature_type sigtype;
enum signkey_type keytype;
TRACE(("enter buf_verify"))
buf_getint(buf); /* blob length */
type_name = buf_getstring(buf, &type_name_len);
sigtype = signature_type_from_name(type_name, type_name_len);
m_free(type_name);
if (expect_sigtype != sigtype) {
dropbear_exit("Non-matching signing type");
}
keytype = signkey_type_from_signature(sigtype);
#if DROPBEAR_DSS
if (keytype == DROPBEAR_SIGNKEY_DSS) {
if (key->dsskey == NULL) {
dropbear_exit("No DSS key to verify signature");
}
return buf_dss_verify(buf, key->dsskey, data_buf);
}
#endif
#if DROPBEAR_RSA
if (keytype == DROPBEAR_SIGNKEY_RSA) {
if (key->rsakey == NULL) {
dropbear_exit("No RSA key to verify signature");
}
return buf_rsa_verify(buf, key->rsakey, sigtype, data_buf);
}
#endif
#if DROPBEAR_ECDSA
if (signkey_is_ecdsa(keytype)) {
ecc_key **eck = (ecc_key**)signkey_key_ptr(key, keytype);
if (eck && *eck) {
return buf_ecdsa_verify(buf, *eck, data_buf);
}
}
#endif
#if DROPBEAR_ED25519
if (keytype == DROPBEAR_SIGNKEY_ED25519) {
if (key->ed25519key == NULL) {
dropbear_exit("No Ed25519 key to verify signature");
}
return buf_ed25519_verify(buf, key->ed25519key, data_buf);
}
#endif
dropbear_exit("Non-matching signing type");
return DROPBEAR_FAILURE;
}
#endif /* DROPBEAR_SIGNKEY_VERIFY */
#if DROPBEAR_KEY_LINES /* ie we're using authorized_keys or known_hosts */
/* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE when given a buffer containing
* a key, a key, and a type. The buffer is positioned at the start of the
* base64 data, and contains no trailing data */
/* If fingerprint is non-NULL, it will be set to a malloc()ed fingerprint
of the key if it is successfully decoded */
int cmp_base64_key(const unsigned char* keyblob, unsigned int keybloblen,
const unsigned char* algoname, unsigned int algolen,
const buffer * line, char ** fingerprint) {
buffer * decodekey = NULL;
int ret = DROPBEAR_FAILURE;
unsigned int len, filealgolen;
unsigned long decodekeylen;
unsigned char* filealgo = NULL;
/* now we have the actual data */
len = line->len - line->pos;
if (len == 0) {
/* base64_decode doesn't like NULL argument */
return DROPBEAR_FAILURE;
}
decodekeylen = len * 2; /* big to be safe */
decodekey = buf_new(decodekeylen);
if (base64_decode(buf_getptr(line, len), len,
buf_getwriteptr(decodekey, decodekey->size),
&decodekeylen) != CRYPT_OK) {
TRACE(("checkpubkey: base64 decode failed"))
goto out;
}
TRACE(("checkpubkey: base64_decode success"))
buf_incrlen(decodekey, decodekeylen);
if (fingerprint) {
*fingerprint = sign_key_fingerprint(buf_getptr(decodekey, decodekeylen),
decodekeylen);
}
/* compare the keys */
if ( ( decodekeylen != keybloblen )
|| memcmp( buf_getptr(decodekey, decodekey->len),
keyblob, decodekey->len) != 0) {
TRACE(("checkpubkey: compare failed"))
goto out;
}
/* ... and also check that the algo specified and the algo in the key
* itself match */
filealgolen = buf_getint(decodekey);
filealgo = buf_getptr(decodekey, filealgolen);
if (filealgolen != algolen || memcmp(filealgo, algoname, algolen) != 0) {
TRACE(("checkpubkey: algo match failed"))
goto out;
}
/* All checks passed */
ret = DROPBEAR_SUCCESS;
out:
buf_free(decodekey);
decodekey = NULL;
return ret;
}
#endif
#if DROPBEAR_FUZZ
const char * const * fuzz_signkey_names = signkey_names;
#endif
1
https://gitee.com/liufshu/oh-dropbear.git
git@gitee.com:liufshu/oh-dropbear.git
liufshu
oh-dropbear
oh-dropbear
master

搜索帮助