<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
Hi all.<br>
<br>
I was just checking the latest 1.0.1l version (running previously
the 1.0.1i).<br>
some DSA signature check done with DSA_verify() are not working any
more, for at least one private/public key I'm using.<br>
<br>
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"<br>
So, it is not a forged key.<br>
<br>
Here is the various things I tried / see. <br>
I someone can tell me if this is an openssl issue, or simply the way
I'm using openssl lib, I will appreciate.<br>
<br>
1) I imagine first that old generated keys are no more valid one to
enforce the CVE-2014-8275 warning, yet,<br>
generating a new public key with the new openssl version lead to the
same issue.<br>
<br>
2) I try the lastest openssl-1.0.1-stable-SNAP-20150116 sources, but
the issue is still here<br>
<br>
3) trying a public key in DER format (openssl dsa -in key.priv -out
key.pub -pubout -outform DER), it doesn't change anything<br>
<br>
4) if I revert CVE-2014-8275 patch
<a class="moz-txt-link-freetext" href="https://github.com/openssl/openssl/commit/684400ce192dac51df3d3e92b61830a6ef90be3e">https://github.com/openssl/openssl/commit/684400ce192dac51df3d3e92b61830a6ef90be3e</a>,<br>
it fix my issue.<br>
<br>
5) diging in the source code<br>
<br>
<blockquote><tt>diff --git a/crypto/dsa/dsa_asn1.c
b/crypto/dsa/dsa_asn1.c</tt><br>
<tt>index 473af87..a018d52 100644</tt><br>
<tt>--- a/crypto/dsa/dsa_asn1.c</tt><br>
<tt>+++ b/crypto/dsa/dsa_asn1.c</tt><br>
<tt>@@ -184,17 +184,24 @@ int DSA_verify(int type, const unsigned
char *dgst, int dgst_len,</tt><br>
<tt> s = DSA_SIG_new();</tt><br>
<tt> if (s == NULL) return(ret);</tt><br>
<tt> if (d2i_DSA_SIG(&s,&p,siglen) == NULL) goto
err;</tt><br>
<tt> /* Ensure signature uses DER and doesn't have trailing
garbage */</tt><br>
<tt> derlen = i2d_DSA_SIG(s, &der);</tt><br>
<tt>- if (derlen != siglen || memcmp(sigbuf, der, derlen))</tt><br>
<tt>+ if (derlen != siglen || memcmp(sigbuf, der, derlen)) {</tt><br>
<tt>+ printf(" derlen=%d siglen=%d\n", derlen, siglen);</tt><br>
<tt> goto err;</tt><br>
<tt>+ }</tt><br>
<tt> ret=DSA_do_verify(dgst,dgst_len,s,dsa);</tt><br>
<tt> err:</tt><br>
</blockquote>
<br>
<br>
it shows: derlen=47 siglen=48. this is the reason why it failed.<br>
<br>
5) here is the public key<br>
<br>
-----BEGIN PUBLIC KEY-----<br>
MIIBtjCCASsGByqGSM44BAEwggEeAoGBAKeSlIE9Q3ijwBOsB4ObfZW8cSsvIyDO<br>
wioNBzZOEm8AoeOVc8xROEmWqvt7TBvM6OK46qNMJTLeHOiIXaRjqosQVWEb4D4l<br>
IVjMtjpQFDAzxPsJZv6EaW/jM2ZXe6tVBanCJW/gi1NgnXpIkA5ohRqPJ+nqPR8p<br>
OPbrBERrG1bzAhUAjDqhLrONrdvTe2HJJrB9V4An0BMCgYAF6vZzaZ4GEF8urI7b<br>
ChkD0+aQZIAXBal/cBJMHI94HeYtBThT25+whfiWtEPbc99NhNAHnvGyIDVECAjZ<br>
Rx1ZhV0Wn45UExCm7S7hHZY/I/jjoQRFvtMR0e4OqJXjIykx4r1SqXgZuO4M8Tv7<br>
VzBLz6hhMqGZ7TqdqxqLH/cd9gOBhAACgYAlJlPWDNetO1TbO5OFfbl0rvTgIlZV<br>
yWnRtIlks35f/iPkb2a7PsRUXcosvblX7Lg5oheC2m68MaEDx16XMvPmHWmvaR16<br>
/BnX6DZHMtNDNMW6o7sce/AMhnT0PGiB1SCuugTxSt32RdDgRFcNBKUUCr47Nyor<br>
dHdD2r/2/GQqpQ==<br>
-----END PUBLIC KEY-----<br>
<br>
6) ... and the way I'm using DSA_verify()<br>
<br>
<tt>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) {</tt><tt><br>
</tt><tt> DSA * dsa = NULL;</tt><tt><br>
</tt><tt> char pubkey_path[128];</tt><tt><br>
</tt><tt> FILE *F = NULL;</tt><tt><br>
</tt><tt><br>
</tt><tt> /* try to read a PEM formatted key */</tt><tt><br>
</tt><tt> snprintf(pubkey_path, sizeof(pubkey_path),
"/share/pubkey/%s.pub", name );</tt><tt><br>
</tt><tt> F = fopen( pubkey_path, "rb" );</tt><tt><br>
</tt><tt> if (F) {</tt><tt><br>
</tt><tt> if (PEM_read_DSA_PUBKEY( F, &dsa,
PEM_def_callback, (void *)"" )) {</tt><tt><br>
</tt><tt> dbg(" find a PEM pub key");</tt><tt><br>
</tt><tt> goto dsa_verify_helper_get_a_key;</tt><tt><br>
</tt><tt> }</tt><tt><br>
</tt><tt> fclose( F );</tt><tt><br>
</tt><tt> F = NULL;</tt><tt><br>
</tt><tt> }</tt><tt><br>
</tt><tt><br>
</tt><tt> /* try to read a DER formatted key */</tt><tt><br>
</tt><tt> snprintf(pubkey_path, sizeof(pubkey_path),
"/share/pubkey/%s.pub.der", name );</tt><tt><br>
</tt><tt> F = fopen( pubkey_path, "rb" );</tt><tt><br>
</tt><tt> if (F) {</tt><tt><br>
</tt><tt> if (d2i_DSA_PUBKEY_fp( F, &dsa )) {</tt><tt><br>
</tt><tt> dbg(" find a DER pub key");</tt><tt><br>
</tt><tt> goto dsa_verify_helper_get_a_key;</tt><tt><br>
</tt><tt> }</tt><tt><br>
</tt><tt> }</tt><tt><br>
</tt><tt> /* if we are here, we failed to read a pub key */</tt><tt><br>
</tt><tt> if (F) fclose( F );</tt><tt><br>
</tt><tt> return DSA_VERIFY_NO_PUBKEY;</tt><tt><br>
</tt><tt><br>
</tt><tt><br>
</tt><tt>dsa_verify_helper_get_a_key:</tt><tt><br>
</tt><tt> fclose( F );</tt><tt><br>
</tt><tt><br>
</tt><tt> int r = DSA_verify( 0, digest, digest_size, signature,
signature_size, dsa );</tt><tt><br>
</tt><tt></tt><tt><br>
</tt><tt> DSA_free( dsa );</tt><tt><br>
</tt><tt><br>
</tt><tt> if (r == 1) {</tt><tt><br>
</tt><tt> /* ok */</tt><tt><br>
</tt><tt> return DSA_VERIFY_OK;</tt><tt><br>
</tt><tt> } else {</tt><tt><br>
</tt><tt> return DSA_VERIFY_BAD;</tt><tt><br>
</tt><tt> }</tt><tt><br>
</tt><tt>}</tt><tt><br>
</tt><br>
</body>
</html>