[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] pki_crypto: pad RSA signature blobs
[Thread Prev] | [Thread Next]
- Subject: [PATCH] pki_crypto: pad RSA signature blobs
- From: Jon Simons <jon@xxxxxxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Sun, 19 Jan 2014 19:08:14 -0800
- To: libssh@xxxxxxxxxx
Hi, Attached is a patch, based of off v0-6, that seems to fix a sporadic bug I've hit when testing with PuTTY clients. I would sometimes (but not always) hit a problem during key signature validation before the patch, and am unable to hit the issue again after. More details are in the commit message. Thanks, -Jon
From 4377a8545e41ee5c336a5f0ca351a7846eb88da7 Mon Sep 17 00:00:00 2001 From: Jon Simons <jon@xxxxxxxxxxxxx> Date: Sun, 19 Jan 2014 16:37:57 -0800 Subject: [PATCH] pki_crypto: pad RSA signature blobs Pad RSA signature blobs to the expected RSA signature length when processing via 'pki_signature_to_blob'. Some clients, notably PuTTY, may send unpadded RSA signatures during the public key exchange: before this change, one can sometimes observe failure in signature validation when using PuTTY's 'plink' client, along these lines: ssh_packet_process: ssh_packet_process: Dispatching handler for packet type 50 ssh_packet_userauth_request: ssh_packet_userauth_request: Auth request for service ssh-connection, method publickey for user 'foo' ssh_pki_signature_verify_blob: ssh_pki_signature_verify_blob: Going to verify a ssh-rsa type signature pki_signature_verify: pki_signature_verify: RSA error: error:04091077:rsa routines:INT_RSA_VERIFY:wrong signature length ssh_packet_userauth_request: ssh_packet_userauth_request: Received an invalid signature from peer For cross-reference this issue once also existed between PuTTY and OpenSSH: http://www.chiark.greenend.org.uk/~sgtatham/putty/wishlist/rsa-verify-failed.html http://www.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/ssh-rsa.c?rev=1.19;content-type=text%2Fx-cvsweb-markup With the fix I am unable to reproduce the above failure mode when testing with 'plink'. --- src/pki_crypto.c | 89 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 65 insertions(+), 24 deletions(-) diff --git a/src/pki_crypto.c b/src/pki_crypto.c index 1080a80..4605946 100644 --- a/src/pki_crypto.c +++ b/src/pki_crypto.c @@ -1188,6 +1188,70 @@ ssh_string pki_signature_to_blob(const ssh_signature sig) return sig_blob; } +static ssh_signature pki_signature_from_rsa_blob(const ssh_key pubkey, + const ssh_string sig_blob, + ssh_signature sig) +{ + uint32_t pad_len = 0; + char *blob_orig; + char *blob_padded_data; + ssh_string sig_blob_padded; + + size_t len = ssh_string_len(sig_blob); + size_t rsalen= RSA_size(pubkey->rsa); + + if (len > rsalen) { + ssh_pki_log("Signature is too big: %lu > %lu", + (unsigned long)len, (unsigned long)rsalen); + goto errout; + } + +#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 (len == rsalen) { + sig->rsa_sig = ssh_string_copy(sig_blob); + } else { + /* pad the blob to the expected rsalen size */ + ssh_pki_log("RSA signature len %lu < %lu", + (unsigned long)len, (unsigned long)rsalen); + + pad_len = rsalen - len; + + sig_blob_padded = ssh_string_new(rsalen); + if (sig_blob_padded == NULL) { + goto errout; + } + + blob_padded_data = (char *) ssh_string_data(sig_blob_padded); + if (blob_padded_data == NULL) { + goto paderrout; + } + + blob_orig = (char *) ssh_string_data(sig_blob); + if (blob_orig == NULL) { + goto paderrout; + } + + /* front-pad the buffer with zeroes */ + memset(blob_padded_data, 0x0, pad_len); + /* fill the rest with the actual signature blob */ + memcpy(blob_padded_data + pad_len, blob_orig, len); + + sig->rsa_sig = sig_blob_padded; + } + + return sig; + +paderrout: + ssh_string_free(sig_blob_padded); +errout: + ssh_signature_free(sig); + return NULL; +} + ssh_signature pki_signature_from_blob(const ssh_key pubkey, const ssh_string sig_blob, enum ssh_keytypes_e type) @@ -1196,7 +1260,6 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, ssh_string r; ssh_string s; size_t len; - size_t rsalen; sig = ssh_signature_new(); if (sig == NULL) { @@ -1260,29 +1323,7 @@ ssh_signature pki_signature_from_blob(const ssh_key pubkey, 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 = ssh_string_copy(sig_blob); - if (sig->rsa_sig == NULL) { - ssh_signature_free(sig); - return NULL; - } + sig = pki_signature_from_rsa_blob(pubkey, sig_blob, sig); break; case SSH_KEYTYPE_ECDSA: #ifdef HAVE_OPENSSL_ECC -- 1.8.4.21.g992c386
Re: [PATCH] pki_crypto: pad RSA signature blobs | Aris Adamantiadis <aris@xxxxxxxxxxxx> |