pki: Add ssh_pki_import_signature_blob().
Этот коммит содержится в:
родитель
4f19a304d1
Коммит
a4b2518761
@ -93,6 +93,9 @@ ssh_string ssh_pki_export_pubkey_blob(const ssh_key key);
|
||||
|
||||
int ssh_pki_export_signature_blob(const ssh_signature sign,
|
||||
ssh_string *sign_blob);
|
||||
int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
const ssh_key pubkey,
|
||||
ssh_signature *psig);
|
||||
ssh_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
|
||||
ssh_key privatekey);
|
||||
|
||||
@ -107,6 +110,9 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
||||
void *auth_data);
|
||||
|
||||
ssh_string pki_signature_to_blob(const ssh_signature sign);
|
||||
ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
const ssh_string sig_blob,
|
||||
enum ssh_keytypes_e type);
|
||||
struct signature_struct *pki_do_sign(const ssh_key privatekey,
|
||||
const unsigned char *hash);
|
||||
|
||||
|
60
src/pki.c
60
src/pki.c
@ -913,6 +913,66 @@ int ssh_pki_export_signature_blob(const ssh_signature sig,
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
int ssh_pki_import_signature_blob(const ssh_string sig_blob,
|
||||
const ssh_key pubkey,
|
||||
ssh_signature *psig)
|
||||
{
|
||||
ssh_signature sig;
|
||||
enum ssh_keytypes_e type;
|
||||
ssh_string str;
|
||||
ssh_buffer buf;
|
||||
char *type_c;
|
||||
int rc;
|
||||
|
||||
if (sig_blob == NULL || psig == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
buf = ssh_buffer_new();
|
||||
if (buf == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
rc = buffer_add_data(buf,
|
||||
ssh_string_data(sig_blob),
|
||||
ssh_string_len(sig_blob));
|
||||
if (rc < 0) {
|
||||
ssh_buffer_free(buf);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
str = buffer_get_ssh_string(buf);
|
||||
if (str == NULL) {
|
||||
ssh_buffer_free(buf);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
type_c = ssh_string_to_char(str);
|
||||
ssh_string_free(str);
|
||||
if (type_c == NULL) {
|
||||
ssh_buffer_free(buf);
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
type = ssh_key_type_from_name(type_c);
|
||||
SAFE_FREE(type_c);
|
||||
|
||||
str = buffer_get_ssh_string(buf);
|
||||
ssh_buffer_free(buf);
|
||||
if (str == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
sig = pki_signature_from_blob(pubkey, str, type);
|
||||
ssh_string_free(str);
|
||||
if (sig == NULL) {
|
||||
return SSH_ERROR;
|
||||
}
|
||||
|
||||
*psig = sig;
|
||||
return SSH_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function signs the session id (known as H) as a string then
|
||||
* the content of sigbuf */
|
||||
|
104
src/pki_crypto.c
104
src/pki_crypto.c
@ -561,6 +561,110 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
return sig_blob;
|
||||
}
|
||||
|
||||
ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
const ssh_string sig_blob,
|
||||
enum ssh_keytypes_e type)
|
||||
{
|
||||
ssh_signature sig;
|
||||
ssh_string r;
|
||||
ssh_string s;
|
||||
size_t len;
|
||||
size_t rsalen;
|
||||
|
||||
sig = ssh_signature_new();
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig->type = type;
|
||||
|
||||
len = ssh_string_len(sig_blob);
|
||||
|
||||
switch(type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
/* 40 is the dual signature blob len. */
|
||||
if (len != 40) {
|
||||
ssh_pki_log("Signature has wrong size: %lu",
|
||||
(unsigned long)len);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("r", ssh_string_data(str), 20);
|
||||
ssh_print_hexa("s", (unsigned char *)ssh_string_data(rs) + 20, 20);
|
||||
#endif
|
||||
|
||||
sig->dsa_sig = DSA_SIG_new();
|
||||
if (sig->dsa_sig == NULL) {
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
r = ssh_string_new(20);
|
||||
if (r == NULL) {
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_fill(r, ssh_string_data(sig_blob), 20);
|
||||
|
||||
sig->dsa_sig->r = make_string_bn(r);
|
||||
ssh_string_free(r);
|
||||
if (sig->dsa_sig->r == NULL) {
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
s = ssh_string_new(20);
|
||||
if (s == NULL) {
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
ssh_string_fill(s, (char *)ssh_string_data(sig_blob) + 20, 20);
|
||||
|
||||
sig->dsa_sig->s = make_string_bn(s);
|
||||
ssh_string_free(s);
|
||||
if (sig->dsa_sig->s == NULL) {
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
rsalen = RSA_size(pubkey->rsa);
|
||||
|
||||
if (len > rsalen) {
|
||||
ssh_pki_log("Signature is to big size: %lu",
|
||||
(unsigned long)len);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len < rsalen) {
|
||||
ssh_pki_log("RSA signature len %lu < %lu",
|
||||
(unsigned long)len, (unsigned long)rsalen);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_pki_log("RSA signature len: %lu", (unsigned long)len);
|
||||
ssh_print_hexa("RSA signature", ssh_string_data(sig_blob), len);
|
||||
#endif
|
||||
sig->rsa_sig = string_copy(sig_blob);
|
||||
if (sig->rsa_sig == NULL) {
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
ssh_pki_log("Unknown signature type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
struct signature_struct *pki_do_sign(ssh_key privatekey,
|
||||
const unsigned char *hash) {
|
||||
struct signature_struct *sign;
|
||||
|
@ -1224,6 +1224,86 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
|
||||
return sig_blob;
|
||||
}
|
||||
|
||||
ssh_signature pki_signature_from_blob(const ssh_key pubkey,
|
||||
const ssh_string sig_blob,
|
||||
enum ssh_keytypes_e type)
|
||||
{
|
||||
ssh_signature sig;
|
||||
gcry_error_t err;
|
||||
size_t len;
|
||||
size_t rsalen;
|
||||
|
||||
sig = ssh_signature_new();
|
||||
if (sig == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
sig->type = type;
|
||||
|
||||
len = ssh_string_len(sig_blob);
|
||||
|
||||
switch(type) {
|
||||
case SSH_KEYTYPE_DSS:
|
||||
/* 40 is the dual signature blob len. */
|
||||
if (len != 40) {
|
||||
ssh_pki_log("Signature has wrong size: %lu",
|
||||
(unsigned long)len);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_print_hexa("r", ssh_string_data(str), 20);
|
||||
ssh_print_hexa("s", (unsigned char *)ssh_string_data(rs) + 20, 20);
|
||||
#endif
|
||||
|
||||
err = gcry_sexp_build(&sig->dsa_sig,
|
||||
NULL,
|
||||
"(sig-val(dsa(r %b)(s %b)))",
|
||||
20,
|
||||
ssh_string_data(sig_blob),
|
||||
20,
|
||||
(unsigned char *)ssh_string_data(sig_blob) + 20);
|
||||
if (err) {
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case SSH_KEYTYPE_RSA:
|
||||
case SSH_KEYTYPE_RSA1:
|
||||
rsalen = (gcry_pk_get_nbits(pubkey->rsa) + 7) / 8;
|
||||
|
||||
if (len > rsalen) {
|
||||
ssh_pki_log("Signature is to big size: %lu",
|
||||
(unsigned long)len);
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (len < rsalen) {
|
||||
ssh_pki_log("RSA signature len %lu < %lu",
|
||||
(unsigned long)len, (unsigned long)rsalen);
|
||||
}
|
||||
|
||||
#ifdef DEBUG_CRYPTO
|
||||
ssh_pki_log("RSA signature len: %lu", (unsigned long)len);
|
||||
ssh_print_hexa("RSA signature", ssh_string_data(sig_blob), len);
|
||||
#endif
|
||||
|
||||
if (gcry_sexp_build(&sig->rsa_sig, NULL, "(sig-val(rsa(s %b)))",
|
||||
ssh_string_len(sig_blob), ssh_string_data(sig_blob))) {
|
||||
ssh_signature_free(sig);
|
||||
return NULL;
|
||||
}
|
||||
case SSH_KEYTYPE_ECDSA:
|
||||
case SSH_KEYTYPE_UNKNOWN:
|
||||
ssh_pki_log("Unknown signature type");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return sig;
|
||||
}
|
||||
|
||||
struct signature_struct *pki_do_sign(ssh_key privatekey,
|
||||
const unsigned char *hash) {
|
||||
struct signature_struct *sign;
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user