Repository: pyca/cryptography

Issue:
Suport for signature algorithm 1.3.14.3.2.29 (sha1RSA)
Hi,

I encountered an issue while attempting to verify the signature of a certificate.
My code looks like this:

``` python
verifier = public_key.verifier(signature, padding.PKCS1v15(), cert_signed.signature_hash_algorithm)
```

Works fine with most certificates but for some it raises:

```
File "/usr/lib/python2.7/site-packages/cryptography/hazmat/backends/openssl/x509.py", line 120, in signature_hash_algorithm
    "Signature algorithm OID:{0} not recognized".format(oid)
cryptography.exceptions.UnsupportedAlgorithm: Signature algorithm OID:1.3.14.3.2.29 not recognized
```

It seems the OID "1.3.14.3.2.29" is not in the list of supported `SignatureAlgorithmOID`.
https://github.com/pyca/cryptography/blob/master/src/cryptography/x509/oid.py#L123

I found a reference to this OID on MSDN website:
https://msdn.microsoft.com/en-gb/library/ff635603.aspx

They identify it as `sha1RSA`, i.e. the same as OID "1.2.840.113549.1.1.5".

Should `cryptography` add support for this signature algorithm OID?

Possibly related links:
https://bugzilla.mozilla.org/show_bug.cgi?id=405966
https://lists.gnupg.org/pipermail/gnutls-help/2013-October/003252.html



Discussion:
@anthrotype yeah looks like we need to add this as an alternate OID for sha1WithRSA, thanks for the report.

Thanks!

I'd like to work on this if possible. Is there a preference on how alternate OIDs are added to oid.py?

I think my preference would be to add it to the mapping, but not put it in the enum. Haven't thought too hard about this though.


Resolving patch:
diff --git a/src/cryptography/x509/oid.py b/src/cryptography/x509/oid.py
--- a/src/cryptography/x509/oid.py
+++ b/src/cryptography/x509/oid.py
@@ -121,6 +121,8 @@ class NameOID(object):
 class SignatureAlgorithmOID(object):
     RSA_WITH_MD5 = ObjectIdentifier("1.2.840.113549.1.1.4")
     RSA_WITH_SHA1 = ObjectIdentifier("1.2.840.113549.1.1.5")
+    # This is an alternate OID for RSA with SHA1 that is occasionally seen
+    _RSA_WITH_SHA1 = ObjectIdentifier("1.3.14.3.2.29")
     RSA_WITH_SHA224 = ObjectIdentifier("1.2.840.113549.1.1.14")
     RSA_WITH_SHA256 = ObjectIdentifier("1.2.840.113549.1.1.11")
     RSA_WITH_SHA384 = ObjectIdentifier("1.2.840.113549.1.1.12")
@@ -137,6 +139,7 @@ class SignatureAlgorithmOID(object):
 _SIG_OIDS_TO_HASH = {
     SignatureAlgorithmOID.RSA_WITH_MD5: hashes.MD5(),
     SignatureAlgorithmOID.RSA_WITH_SHA1: hashes.SHA1(),
+    SignatureAlgorithmOID._RSA_WITH_SHA1: hashes.SHA1(),
     SignatureAlgorithmOID.RSA_WITH_SHA224: hashes.SHA224(),
     SignatureAlgorithmOID.RSA_WITH_SHA256: hashes.SHA256(),
     SignatureAlgorithmOID.RSA_WITH_SHA384: hashes.SHA384(),


Test patch:
diff --git a/tests/test_x509.py b/tests/test_x509.py
--- a/tests/test_x509.py
+++ b/tests/test_x509.py
@@ -502,6 +502,18 @@ def test_load_pem_cert(self, backend):
             cert.signature_algorithm_oid == SignatureAlgorithmOID.RSA_WITH_SHA1
         )
 
+    def test_alternate_rsa_with_sha1_oid(self, backend):
+        cert = _load_cert(
+            os.path.join("x509", "alternate-rsa-sha1-oid.pem"),
+            x509.load_pem_x509_certificate,
+            backend
+        )
+        assert isinstance(cert.signature_hash_algorithm, hashes.SHA1)
+        assert (
+            cert.signature_algorithm_oid ==
+            SignatureAlgorithmOID._RSA_WITH_SHA1
+        )
+
     def test_cert_serial_number(self, backend):
         cert = _load_cert(
             os.path.join("x509", "PKITS_data", "certs", "GoodCACert.crt"),