|
Chris Weyl |
8d25ddb |
commit 1aba38cd7d2658146675ce1737e5090f879f3068
|
|
Chris Weyl |
8d25ddb |
Author: Peter Stuge <peter@stuge.se>
|
|
Chris Weyl |
8d25ddb |
Date: Sun Dec 6 07:20:58 2009 +0100
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
Fix padding in ssh-dss signature blob encoding
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
DSA signatures consist of two 160-bit integers called r and s. In ssh-dss
|
|
Chris Weyl |
8d25ddb |
signature blobs r and s are stored directly after each other in binary
|
|
Chris Weyl |
8d25ddb |
representation, making up a 320-bit (40 byte) string. (See RFC4253 p14.)
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
The crypto wrappers in libssh2 would either pack r and s incorrectly, or
|
|
Chris Weyl |
8d25ddb |
fail, when at least one integer was small enough to be stored in 19 bytes
|
|
Chris Weyl |
8d25ddb |
or less.
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
The patch ensures that r and s are always stored as two 160 bit numbers.
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
|
|
Chris Weyl |
8d25ddb |
index ba00284..b06be42 100644
|
|
Chris Weyl |
8d25ddb |
--- a/src/libgcrypt.c
|
|
Chris Weyl |
8d25ddb |
+++ b/src/libgcrypt.c
|
|
Chris Weyl |
8d25ddb |
@@ -424,6 +424,8 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
|
Chris Weyl |
8d25ddb |
return -1;
|
|
Chris Weyl |
8d25ddb |
}
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
+ memset(sig, 0, 40);
|
|
Chris Weyl |
8d25ddb |
+
|
|
Chris Weyl |
8d25ddb |
/* Extract R. */
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
data = gcry_sexp_find_token(sig_sexp, "r", 0);
|
|
Chris Weyl |
8d25ddb |
@@ -433,22 +435,12 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
|
Chris Weyl |
8d25ddb |
}
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
tmp = gcry_sexp_nth_data(data, 1, &size);
|
|
Chris Weyl |
8d25ddb |
- if (!tmp) {
|
|
Chris Weyl |
8d25ddb |
- ret = -1;
|
|
Chris Weyl |
8d25ddb |
- goto out;
|
|
Chris Weyl |
8d25ddb |
- }
|
|
Chris Weyl |
8d25ddb |
-
|
|
Chris Weyl |
8d25ddb |
- if (tmp[0] == '\0') {
|
|
Chris Weyl |
8d25ddb |
- tmp++;
|
|
Chris Weyl |
8d25ddb |
- size--;
|
|
Chris Weyl |
8d25ddb |
- }
|
|
Chris Weyl |
8d25ddb |
-
|
|
Chris Weyl |
8d25ddb |
- if (size != 20) {
|
|
Chris Weyl |
8d25ddb |
+ if (!tmp || size < 1 || size > 20) {
|
|
Chris Weyl |
8d25ddb |
ret = -1;
|
|
Chris Weyl |
8d25ddb |
goto out;
|
|
Chris Weyl |
8d25ddb |
}
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
- memcpy(sig, tmp, 20);
|
|
Chris Weyl |
8d25ddb |
+ memcpy(sig + (20 - size), tmp, size);
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
gcry_sexp_release(data);
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
@@ -461,22 +453,12 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
|
Chris Weyl |
8d25ddb |
}
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
tmp = gcry_sexp_nth_data(data, 1, &size);
|
|
Chris Weyl |
8d25ddb |
- if (!tmp) {
|
|
Chris Weyl |
8d25ddb |
- ret = -1;
|
|
Chris Weyl |
8d25ddb |
- goto out;
|
|
Chris Weyl |
8d25ddb |
- }
|
|
Chris Weyl |
8d25ddb |
-
|
|
Chris Weyl |
8d25ddb |
- if (tmp[0] == '\0') {
|
|
Chris Weyl |
8d25ddb |
- tmp++;
|
|
Chris Weyl |
8d25ddb |
- size--;
|
|
Chris Weyl |
8d25ddb |
- }
|
|
Chris Weyl |
8d25ddb |
-
|
|
Chris Weyl |
8d25ddb |
- if (size != 20) {
|
|
Chris Weyl |
8d25ddb |
+ if (!tmp || size < 1 || size > 20) {
|
|
Chris Weyl |
8d25ddb |
ret = -1;
|
|
Chris Weyl |
8d25ddb |
goto out;
|
|
Chris Weyl |
8d25ddb |
}
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
- memcpy(sig + 20, tmp, 20);
|
|
Chris Weyl |
8d25ddb |
+ memcpy(sig + 20 + (20 - size), tmp, size);
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
ret = 0;
|
|
Chris Weyl |
8d25ddb |
out:
|
|
Chris Weyl |
8d25ddb |
diff --git a/src/openssl.c b/src/openssl.c
|
|
Chris Weyl |
8d25ddb |
index 250ea63..000c9ec 100644
|
|
Chris Weyl |
8d25ddb |
--- a/src/openssl.c
|
|
Chris Weyl |
8d25ddb |
+++ b/src/openssl.c
|
|
Chris Weyl |
8d25ddb |
@@ -420,7 +420,7 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
|
Chris Weyl |
8d25ddb |
unsigned long hash_len, unsigned char *signature)
|
|
Chris Weyl |
8d25ddb |
{
|
|
Chris Weyl |
8d25ddb |
DSA_SIG *sig;
|
|
Chris Weyl |
8d25ddb |
- int r_len, s_len, rs_pad;
|
|
Chris Weyl |
8d25ddb |
+ int r_len, s_len;
|
|
Chris Weyl |
8d25ddb |
(void) hash_len;
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
sig = DSA_do_sign(hash, SHA_DIGEST_LENGTH, dsactx);
|
|
Chris Weyl |
8d25ddb |
@@ -429,15 +429,20 @@ _libssh2_dsa_sha1_sign(libssh2_dsa_ctx * dsactx,
|
|
Chris Weyl |
8d25ddb |
}
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
r_len = BN_num_bytes(sig->r);
|
|
Chris Weyl |
8d25ddb |
+ if (r_len < 1 || r_len > 20) {
|
|
Chris Weyl |
8d25ddb |
+ DSA_SIG_free(sig);
|
|
Chris Weyl |
8d25ddb |
+ return -1;
|
|
Chris Weyl |
8d25ddb |
+ }
|
|
Chris Weyl |
8d25ddb |
s_len = BN_num_bytes(sig->s);
|
|
Chris Weyl |
8d25ddb |
- rs_pad = (2 * SHA_DIGEST_LENGTH) - (r_len + s_len);
|
|
Chris Weyl |
8d25ddb |
- if (rs_pad < 0) {
|
|
Chris Weyl |
8d25ddb |
+ if (s_len < 1 || s_len > 20) {
|
|
Chris Weyl |
8d25ddb |
DSA_SIG_free(sig);
|
|
Chris Weyl |
8d25ddb |
return -1;
|
|
Chris Weyl |
8d25ddb |
}
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
- BN_bn2bin(sig->r, signature + rs_pad);
|
|
Chris Weyl |
8d25ddb |
- BN_bn2bin(sig->s, signature + rs_pad + r_len);
|
|
Chris Weyl |
8d25ddb |
+ memset(signature, 0, 40);
|
|
Chris Weyl |
8d25ddb |
+
|
|
Chris Weyl |
8d25ddb |
+ BN_bn2bin(sig->r, signature + (20 - r_len));
|
|
Chris Weyl |
8d25ddb |
+ BN_bn2bin(sig->s, signature + 20 + (20 - s_len));
|
|
Chris Weyl |
8d25ddb |
|
|
Chris Weyl |
8d25ddb |
DSA_SIG_free(sig);
|
|
Chris Weyl |
8d25ddb |
|