Add X509.get_signature_algorithm
diff --git a/ChangeLog b/ChangeLog
index d16f254..5f60a16 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2011-05-19 Jean-Paul Calderone <exarkun@twistedmatrix.com>
+
+ * OpenSSL/crypto/x509.c, OpenSSL/test/test_crypto.py: Add a new
+ method to the X509 type, get_signature_algorithm, for inspecting
+ the signature algorithm field of the certificate. Based on a
+ patch from <lp:~okuda>.
+
2011-05-10 Jean-Paul Calderone <exarkun@twistedmatrix.com>
* OpenSSL/crypto/crypto.h: Work around a Windows/OpenSSL 1.0 issue
diff --git a/OpenSSL/crypto/x509.c b/OpenSSL/crypto/x509.c
index a12220b..0754dec 100644
--- a/OpenSSL/crypto/x509.c
+++ b/OpenSSL/crypto/x509.c
@@ -519,6 +519,34 @@
return Py_None;
}
+
+static char crypto_X509_get_signature_algorithm_doc[] = "\n\
+Retrieve the signature algorithm used in the certificate\n\
+\n\
+@return: A byte string giving the name of the signature algorithm used in\n\
+ the certificate.\n\
+@raise ValueError: If the signature algorithm is undefined.\n\
+";
+
+static PyObject *
+crypto_X509_get_signature_algorithm(crypto_X509Obj *self, PyObject *args) {
+ ASN1_OBJECT *alg;
+ int nid;
+
+ if (!PyArg_ParseTuple(args, ":get_signature_algorithm")) {
+ return NULL;
+ }
+
+ alg = self->x509->cert_info->signature->algorithm;
+ nid = OBJ_obj2nid(alg);
+ if (nid == NID_undef) {
+ PyErr_SetString(PyExc_ValueError, "Undefined signature algorithm");
+ return NULL;
+ }
+ return PyBytes_FromString(OBJ_nid2ln(nid));
+}
+
+
static char crypto_X509_sign_doc[] = "\n\
Sign the certificate using the supplied key and digest\n\
\n\
@@ -757,6 +785,7 @@
ADD_METHOD(set_notAfter),
ADD_METHOD(gmtime_adj_notBefore),
ADD_METHOD(gmtime_adj_notAfter),
+ ADD_METHOD(get_signature_algorithm),
ADD_METHOD(sign),
ADD_METHOD(has_expired),
ADD_METHOD(subject_name_hash),
diff --git a/OpenSSL/test/test_crypto.py b/OpenSSL/test/test_crypto.py
index 496dc59..b109b54 100644
--- a/OpenSSL/test/test_crypto.py
+++ b/OpenSSL/test/test_crypto.py
@@ -1474,12 +1474,54 @@
"""
cert = load_certificate(FILETYPE_PEM, self.pemData)
self.assertIn(
- cert.subject_name_hash(),
+ cert.subject_name_hash(),
[3350047874, # OpenSSL 0.9.8, MD5
3278919224, # OpenSSL 1.0.0, SHA1
])
+ def test_get_signature_algorithm(self):
+ """
+ L{X509Type.get_signature_algorithm} returns a string which means
+ the algorithm used to sign the certificate.
+ """
+ cert = load_certificate(FILETYPE_PEM, self.pemData)
+ self.assertEqual(
+ b("sha1WithRSAEncryption"), cert.get_signature_algorithm())
+
+
+ def test_get_undefined_signature_algorithm(self):
+ """
+ L{X509Type.get_signature_algorithm} raises L{ValueError} if the
+ signature algorithm is undefined or unknown.
+ """
+ # This certificate has been modified to indicate a bogus OID in the
+ # signature algorithm field so that OpenSSL does not recognize it.
+ certPEM = """\
+-----BEGIN CERTIFICATE-----
+MIIC/zCCAmigAwIBAgIBATAGBgJ8BQUAMHsxCzAJBgNVBAYTAlNHMREwDwYDVQQK
+EwhNMkNyeXB0bzEUMBIGA1UECxMLTTJDcnlwdG8gQ0ExJDAiBgNVBAMTG00yQ3J5
+cHRvIENlcnRpZmljYXRlIE1hc3RlcjEdMBsGCSqGSIb3DQEJARYObmdwc0Bwb3N0
+MS5jb20wHhcNMDAwOTEwMDk1MTMwWhcNMDIwOTEwMDk1MTMwWjBTMQswCQYDVQQG
+EwJTRzERMA8GA1UEChMITTJDcnlwdG8xEjAQBgNVBAMTCWxvY2FsaG9zdDEdMBsG
+CSqGSIb3DQEJARYObmdwc0Bwb3N0MS5jb20wXDANBgkqhkiG9w0BAQEFAANLADBI
+AkEArL57d26W9fNXvOhNlZzlPOACmvwOZ5AdNgLzJ1/MfsQQJ7hHVeHmTAjM664V
++fXvwUGJLziCeBo1ysWLRnl8CQIDAQABo4IBBDCCAQAwCQYDVR0TBAIwADAsBglg
+hkgBhvhCAQ0EHxYdT3BlblNTTCBHZW5lcmF0ZWQgQ2VydGlmaWNhdGUwHQYDVR0O
+BBYEFM+EgpK+eyZiwFU1aOPSbczbPSpVMIGlBgNVHSMEgZ0wgZqAFPuHI2nrnDqT
+FeXFvylRT/7tKDgBoX+kfTB7MQswCQYDVQQGEwJTRzERMA8GA1UEChMITTJDcnlw
+dG8xFDASBgNVBAsTC00yQ3J5cHRvIENBMSQwIgYDVQQDExtNMkNyeXB0byBDZXJ0
+aWZpY2F0ZSBNYXN0ZXIxHTAbBgkqhkiG9w0BCQEWDm5ncHNAcG9zdDEuY29tggEA
+MA0GCSqGSIb3DQEBBAUAA4GBADv8KpPo+gfJxN2ERK1Y1l17sz/ZhzoGgm5XCdbx
+jEY7xKfpQngV599k1xhl11IMqizDwu0855agrckg2MCTmOI9DZzDD77tAYb+Dk0O
+PEVk0Mk/V0aIsDE9bolfCi/i/QWZ3N8s5nTWMNyBBBmoSliWCm4jkkRZRD0ejgTN
+tgI5
+-----END CERTIFICATE-----
+"""
+ cert = load_certificate(FILETYPE_PEM, certPEM)
+ self.assertRaises(ValueError, cert.get_signature_algorithm)
+
+
class PKCS12Tests(TestCase):
"""
diff --git a/doc/pyOpenSSL.tex b/doc/pyOpenSSL.tex
index 239133f..fa7638d 100644
--- a/doc/pyOpenSSL.tex
+++ b/doc/pyOpenSSL.tex
@@ -321,6 +321,11 @@
Return the certificate serial number.
\end{methoddesc}
+\begin{methoddesc}[X509]{get_signature_algorithm}{}
+Return the signature algorithm used in the certificate. If the algorithm is
+undefined, raise \code{ValueError}.
+\end{methoddesc}
+
\begin{methoddesc}[X509]{get_subject}{}
Return an X509Name object representing the subject of the certificate.
\end{methoddesc}