aboutsummaryrefslogtreecommitdiff
path: root/src/pki_crypto.c
diff options
context:
space:
mode:
authorAndreas Schneider <asn@cryptomilk.org>2011-08-21 11:03:53 +0200
committerAndreas Schneider <asn@cryptomilk.org>2011-08-21 11:03:53 +0200
commita4b2518761c6b68b8a28ea250d58e7257bce6554 (patch)
tree2f81d30583ae47854779e9d914e6104c09ef8e8c /src/pki_crypto.c
parent4f19a304d182ada3e67290c61bad47a0a6c16f5b (diff)
downloadlibssh-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.c104
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;