[openssl-users] Possible bug in DSA_verify() since CVE-2014-8275 patch (present in 1.0.1k and 1.0.1l)
arnaud.mouiche at invoxia.com
arnaud.mouiche at invoxia.com
Fri Jan 16 11:56:34 UTC 2015
Hi all.
I was just checking the latest 1.0.1l version (running previously the
1.0.1i).
some DSA signature check done with DSA_verify() are not working any
more, for at least one private/public key I'm using.
The public key was generated from the private key, long time ago, as
usual with command "openssl dsa -in key.priv -out key.pub -pubout"
So, it is not a forged key.
Here is the various things I tried / see.
I someone can tell me if this is an openssl issue, or simply the way I'm
using openssl lib, I will appreciate.
1) I imagine first that old generated keys are no more valid one to
enforce the CVE-2014-8275 warning, yet,
generating a new public key with the new openssl version lead to the
same issue.
2) I try the lastest openssl-1.0.1-stable-SNAP-20150116 sources, but the
issue is still here
3) trying a public key in DER format (openssl dsa -in key.priv -out
key.pub -pubout -outform DER), it doesn't change anything
4) if I revert CVE-2014-8275 patch
https://github.com/openssl/openssl/commit/684400ce192dac51df3d3e92b61830a6ef90be3e,
it fix my issue.
5) diging in the source code
diff --git a/crypto/dsa/dsa_asn1.c b/crypto/dsa/dsa_asn1.c
index 473af87..a018d52 100644
--- a/crypto/dsa/dsa_asn1.c
+++ b/crypto/dsa/dsa_asn1.c
@@ -184,17 +184,24 @@ int DSA_verify(int type, const unsigned char
*dgst, int dgst_len,
s = DSA_SIG_new();
if (s == NULL) return(ret);
if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto err;
/* Ensure signature uses DER and doesn't have trailing
garbage */
derlen = i2d_DSA_SIG(s, &der);
- if (derlen != siglen || memcmp(sigbuf, der, derlen))
+ if (derlen != siglen || memcmp(sigbuf, der, derlen)) {
+ printf(" derlen=%d siglen=%d\n", derlen, siglen);
goto err;
+ }
ret=DSA_do_verify(dgst,dgst_len,s,dsa);
err:
it shows: derlen=47 siglen=48. this is the reason why it failed.
5) here is the public key
-----BEGIN PUBLIC KEY-----
MIIBtjCCASsGByqGSM44BAEwggEeAoGBAKeSlIE9Q3ijwBOsB4ObfZW8cSsvIyDO
wioNBzZOEm8AoeOVc8xROEmWqvt7TBvM6OK46qNMJTLeHOiIXaRjqosQVWEb4D4l
IVjMtjpQFDAzxPsJZv6EaW/jM2ZXe6tVBanCJW/gi1NgnXpIkA5ohRqPJ+nqPR8p
OPbrBERrG1bzAhUAjDqhLrONrdvTe2HJJrB9V4An0BMCgYAF6vZzaZ4GEF8urI7b
ChkD0+aQZIAXBal/cBJMHI94HeYtBThT25+whfiWtEPbc99NhNAHnvGyIDVECAjZ
Rx1ZhV0Wn45UExCm7S7hHZY/I/jjoQRFvtMR0e4OqJXjIykx4r1SqXgZuO4M8Tv7
VzBLz6hhMqGZ7TqdqxqLH/cd9gOBhAACgYAlJlPWDNetO1TbO5OFfbl0rvTgIlZV
yWnRtIlks35f/iPkb2a7PsRUXcosvblX7Lg5oheC2m68MaEDx16XMvPmHWmvaR16
/BnX6DZHMtNDNMW6o7sce/AMhnT0PGiB1SCuugTxSt32RdDgRFcNBKUUCr47Nyor
dHdD2r/2/GQqpQ==
-----END PUBLIC KEY-----
6) ... and the way I'm using DSA_verify()
static enum dsa_verify_result dsa_verify_helper(const char *name, const
unsigned char *digest, int digest_size, const unsigned char *signature,
int signature_size) {
DSA * dsa = NULL;
char pubkey_path[128];
FILE *F = NULL;
/* try to read a PEM formatted key */
snprintf(pubkey_path, sizeof(pubkey_path), "/share/pubkey/%s.pub",
name );
F = fopen( pubkey_path, "rb" );
if (F) {
if (PEM_read_DSA_PUBKEY( F, &dsa, PEM_def_callback, (void *)"" )) {
dbg(" find a PEM pub key");
goto dsa_verify_helper_get_a_key;
}
fclose( F );
F = NULL;
}
/* try to read a DER formatted key */
snprintf(pubkey_path, sizeof(pubkey_path),
"/share/pubkey/%s.pub.der", name );
F = fopen( pubkey_path, "rb" );
if (F) {
if (d2i_DSA_PUBKEY_fp( F, &dsa )) {
dbg(" find a DER pub key");
goto dsa_verify_helper_get_a_key;
}
}
/* if we are here, we failed to read a pub key */
if (F) fclose( F );
return DSA_VERIFY_NO_PUBKEY;
dsa_verify_helper_get_a_key:
fclose( F );
int r = DSA_verify( 0, digest, digest_size, signature,
signature_size, dsa );
DSA_free( dsa );
if (r == 1) {
/* ok */
return DSA_VERIFY_OK;
} else {
return DSA_VERIFY_BAD;
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mta.openssl.org/pipermail/openssl-users/attachments/20150116/65abc5b5/attachment.html>
More information about the openssl-users
mailing list