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_crypto.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_crypto.c')
-rw-r--r-- | src/pki_crypto.c | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/pki_crypto.c b/src/pki_crypto.c index 0dafd227..f71c22bb 100644 --- a/src/pki_crypto.c +++ b/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; |