title: Failed to verify a dsawithSha1 signed message against a DSA public key in m2crypto
body: <p>I'm trying to verify a signed message using a x509 certificate holding a dsa public key.
  The x509 certificate was provided by an SAP System in PKCS7 encoding and after converting in PEM with openssl I'm able to read the contents (openssl x509 -in sapcert.pem -inform pem -text)
  It holds a public key in dsaEncryption, showing me the DSA parameters y(pub), p, q and g.</p>
  <p>Because I did not found a DSA implementation in M2Crypto x509 class, I tried to build the DSA public key by myself. Therefor I patched MyCrypto, (see: <a href="https://stackoverflow.com/questions/3027196/how-do-i-create-a-m2crypto-dsa-object-given-parameters-and-key-values">How do I create a M2Crypto DSA object given parameters and key values?</a>), compilied it and got a new function DSA.pub_key_from_params(p,q,g,y) to build my DSA public-key using the parameters found in the certificate.
  Until this point everything works fine. (The unittest although ran without errors).</p>
  <p>In the second step I recieve the signedMessage (named seckey) as an URL parameter and after decoding it (base64) I got an proper DER string I'm able to read with openssl (openssl ans1parse -in seckey -inform der).
  In the output from openssl I can see the signed messageDigest, which is exactly the SHA1 encoded messagedigest I try to verify (so I can be sure the signedMessage was provided properly). Although I can see a dsaWithSHA1 signature string which seems to hold the r and s values needing for verify an dsa signed message (see: <a href="https://stackoverflow.com/questions/3454523/m2crypto-verifying-dsa-signatures">M2Crypto: verifying DSA signatures</a>)</p>
  <p>At this point I stuck in my attempts to verify the signedMessage for a couple of days now and I hope there is a crytographic-expert out there who can help me. I tried and googled a lot, tried the pyCrypto lib instead, all without success.</p>
  <p>I tried to pass the SHA1 MessageDigest and the r and s values to the M2Crypto.DSA.verify function but due it fails I think I either had to pass the signedMessage or parts of it.
  (in a Java forum I found some posts about verifying signedMessages provided by SAP and theres somewhat about calculating the signature over &quot;the DER encoding
  of the signed attributes.&quot; ?)</p>
  <p>Here's my sample code:</p>
  <pre><code># -*- coding: iso-8859-1 -*-
  
  import M2Crypto
  import urllib
  import base64
  from Crypto.Util import asn1
  from M2Crypto import m2
  import sha
  
  # the certificate
  cert = &quot;&quot;&quot;subject=/C=DE/O=SAP Trust Community/OU=SAP Web AS/OU=I0020154766/CN=RE2
  issuer=/C=DE/O=SAP Trust Community/OU=SAP Web AS/OU=I0020154766/CN=RE2
  -----BEGIN CERTIFICATE-----
  MIICMDCCAe8CAQAwCQYHKoZIzjgEAzBkMQswCQYDVQQGEwJERTEcMBoGA1UEChMT
  U0FQIFRydXN0IENvbW11bml0eTETMBEGA1UECxMKU0FQIFdlYiBBUzEUMBIGA1UE
  CxMLSTAwMjAxNTQ3NjYxDDAKBgNVBAMTA1JFMjAeFw05NzEwMDEwMDAwMDBaFw0z
  ODAxMDEwMDAwMDBaMGQxCzAJBgNVBAYTAkRFMRwwGgYDVQQKExNTQVAgVHJ1c3Qg
  Q29tbXVuaXR5MRMwEQYDVQQLEwpTQVAgV2ViIEFTMRQwEgYDVQQLEwtJMDAyMDE1
  NDc2NjEMMAoGA1UEAxMDUkUyMIHyMIGpBgcqhkjOOAQBMIGdAkEA//8x1Bqn4a00
  FKr9CTwPPskxy0yrx7iU6T4vza4wW93Mo2d/IYTZNAxFqhrm+fIUrEp5fxIpYRmJ
  rKL2qRCUmQIVANrcsXlFvrXH455gM69vKZebhQZfAkEAmYzXTzHYwvqKEM46FvQX
  yC5O+JInwgk7Dac7gqGAkkhCS1aII4Vkc9kIEx3GFLD2mx4+yJuMQ8pQ4wz4FkfB
  JANEAAJBAI1em/0owxMTEP+akz56BovQ7Q6LiqUmVLLxJcjDozjI+5z6IrAPtub2
  veLXPdghDHcHB5jHKoqT4JHpqRc+uhIwCQYHKoZIzjgEAwMwADAtAhRm2jqiMWL+
  26mA7HdKfZdkawMuYQIVAMekXdAT4wbyrb5/yFtuIPjCBfpr
  -----END CERTIFICATE-----
  
  &quot;&quot;&quot;
  f = open('sapcert.pem', 'w')
  f.write(cert)
  f.close()
  
  # now you can see it content with openssl
  # openssl x509 -in sapcert.pem -inform pem -text
  
  
  # this is the signedMessage
  secKey = &quot;MIIBSwYJKoZIhvcNAQcCoIIBPDCCATgCAQExCzAJBgUrDgMCGgUAMAsGCSqGSIb3DQEHATGCARcwggETAgEBMGkwZDELMAkGA1UEBhMCREUxHDAaBgNVBAoTE1NBUCBUcnVzdCBDb21tdW5pdHkxEzARBgNVBAsTClNBUCBXZWIgQVMxFDASBgNVBAsTC0kwMDIwMTU0NzY2MQwwCgYDVQQDEwNSRTICAQAwCQYFKw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTExMDUyNjE1MzAyNVowIwYJKoZIhvcNAQkEMRYEFPelg4iVtaKORpuFxUvgo23Du7%2BtMAkGByqGSM44BAMELjAsAhQ46oCNmzZArb5yOFSYGY0hWu8dZwIUT35hPccJ6B9HIsOE0u8LwYZaFNk%3D&quot;
  secKey = urllib.unquote(secKey)
  secKey64 = base64.b64decode(secKey)
  # now you can save it as a DER encoded file
  f = open('seckey.der', 'wb')
  f.write(secKey64)
  f.close()
  # you can pass it to openssl to see the the content
  # openssl asn1parse -in seckey.der -inform der
  
  
  # here is the sha1 encoded messagedigest I had to verify
  hashstr = &quot;ZS4DDB9616BA031C40E1008003AC100097dCN%3DRE2,OU%3DI0020154766,OU%3DSAPWebAS,O%3DSAPTrustCommunity,C%3DDE20110526173025&quot;
  osha1=M2Crypto.EVP.MessageDigest('sha1')
  osha1.update(hashstr)
  sha1_md = osha1.digest()
  print sha1_md.encode('hex')
  
  # now i build a DSA key with the params found in the certificate
  
  pub=&quot;8d5e9bfd28c3131310ff9a933e7a068bd0ed0e8b8aa52654b2f125c8c3a338c8fb9cfa22b00fb6e6f6bde2d73dd8210c77070798c72a8a93e091e9a9173eba12&quot;
  p=&quot;ffff31d41aa7e1ad3414aafd093c0f3ec931cb4cabc7b894e93e2fcdae305bddcca3677f2184d9340c45aa1ae6f9f214ac4a797f1229611989aca2f6a9109499&quot;
  q=&quot;dadcb17945beb5c7e39e6033af6f29979b85065f&quot;
  g=&quot;998cd74f31d8c2fa8a10ce3a16f417c82e4ef89227c2093b0da73b82a1809248424b568823856473d908131dc614b0f69b1e3ec89b8c43ca50e30cf81647c124&quot;
  
  
  pub1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(pub))
  p1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(p))
  q1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(q))
  g1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(g))
  
  # this function is available after patching und compiling M2Crypto
  # https://bugzilla.osafoundation.org/attachment.cgi?id=5700
  dsa1 = M2Crypto.DSA.pub_key_from_params(p1, q1, g1, pub1)
  print dsa1.check_key()
  
  # this seems to be the signature-values r and s in seckey.der
  asn_hex = &quot;302C021438EA808D9B3640ADBE72385498198D215AEF1D6702144F7E613DC709E81F4722C384D2EF0BC1865A14D9&quot;
  
  r = asn_hex[8:48]
  s = asn_hex[52:]
  r1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(r))
  s1 = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.hex_to_bn(s))
  
  # but this fails
  v = dsa1.verify(sha1_md, r1, s1)
  print v
  
  # this too
  sk = M2Crypto.m2.bn_to_mpi(M2Crypto.m2.bin_to_bn(secKey64))
  v = dsa1.verify(sk, r1, s1)
  print v
  </code></pre>
  <p>Is there anybody who knows how to do a proper dsawithsha1 signature verification? Please help!
  best Regards,
  Falko</p>