diff options
author | Andreas Schneider <asn@cryptomilk.org> | 2011-08-21 11:03:53 +0200 |
---|---|---|
committer | Andreas Schneider <asn@cryptomilk.org> | 2011-08-21 11:03:53 +0200 |
commit | a4b2518761c6b68b8a28ea250d58e7257bce6554 (patch) | |
tree | 2f81d30583ae47854779e9d914e6104c09ef8e8c /src/pki_gcrypt.c | |
parent | 4f19a304d182ada3e67290c61bad47a0a6c16f5b (diff) | |
download | libssh-a4b2518761c6b68b8a28ea250d58e7257bce6554.tar.gz libssh-a4b2518761c6b68b8a28ea250d58e7257bce6554.tar.xz libssh-a4b2518761c6b68b8a28ea250d58e7257bce6554.zip |
pki: Add ssh_pki_import_signature_blob().
Diffstat (limited to 'src/pki_gcrypt.c')
-rw-r--r-- | src/pki_gcrypt.c | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/pki_gcrypt.c b/src/pki_gcrypt.c index 2a6a120c..33175142 100644 --- a/src/pki_gcrypt.c +++ b/src/pki_gcrypt.c @@ -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; |