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,
|
int ssh_pki_export_signature_blob(const ssh_signature sign,
|
||||||
ssh_string *sign_blob);
|
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_string ssh_pki_do_sign(ssh_session session, ssh_buffer sigbuf,
|
||||||
ssh_key privatekey);
|
ssh_key privatekey);
|
||||||
|
|
||||||
@ -107,6 +110,9 @@ ssh_key pki_private_key_from_base64(const char *b64_key,
|
|||||||
void *auth_data);
|
void *auth_data);
|
||||||
|
|
||||||
ssh_string pki_signature_to_blob(const ssh_signature sign);
|
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,
|
struct signature_struct *pki_do_sign(const ssh_key privatekey,
|
||||||
const unsigned char *hash);
|
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;
|
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
|
* This function signs the session id (known as H) as a string then
|
||||||
* the content of sigbuf */
|
* 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;
|
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,
|
struct signature_struct *pki_do_sign(ssh_key privatekey,
|
||||||
const unsigned char *hash) {
|
const unsigned char *hash) {
|
||||||
struct signature_struct *sign;
|
struct signature_struct *sign;
|
||||||
|
@ -1224,6 +1224,86 @@ ssh_string pki_signature_to_blob(const ssh_signature sig)
|
|||||||
return sig_blob;
|
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,
|
struct signature_struct *pki_do_sign(ssh_key privatekey,
|
||||||
const unsigned char *hash) {
|
const unsigned char *hash) {
|
||||||
struct signature_struct *sign;
|
struct signature_struct *sign;
|
||||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user