1
1

pki: Add ssh_pki_import_signature_blob().

Этот коммит содержится в:
Andreas Schneider 2011-08-21 11:03:53 +02:00
родитель 4f19a304d1
Коммит a4b2518761
4 изменённых файлов: 250 добавлений и 0 удалений

Просмотреть файл

@ -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);

Просмотреть файл

@ -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 */

Просмотреть файл

@ -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;