You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@labs.apache.org by dr...@apache.org on 2007/12/07 11:14:30 UTC

svn commit: r602056 - in /labs/badca: BaDCA/Certificates.py openssl/certmodule.c tests/03CertTestCase.py

Author: dreid
Date: Fri Dec  7 02:14:29 2007
New Revision: 602056

URL: http://svn.apache.org/viewvc?rev=602056&view=rev
Log:
We new extract fingerprint and purpose information from the
certificate
We now check for purpose and fingerprint


Modified:
    labs/badca/BaDCA/Certificates.py
    labs/badca/openssl/certmodule.c
    labs/badca/tests/03CertTestCase.py

Modified: labs/badca/BaDCA/Certificates.py
URL: http://svn.apache.org/viewvc/labs/badca/BaDCA/Certificates.py?rev=602056&r1=602055&r2=602056&view=diff
==============================================================================
--- labs/badca/BaDCA/Certificates.py (original)
+++ labs/badca/BaDCA/Certificates.py Fri Dec  7 02:14:29 2007
@@ -29,6 +29,29 @@
             return None
         return cert.getPublicKey(self.cert)
 
+    # convenience function
+    def getFingerprint(self):
+        return self.getInformation('fingerprint', 'value')
+
+    # which is the purpose to check, ca whether it is a CA purpose
+    def checkPurpose(self, which, ca = 0):
+        v = None
+        if ca == 0:
+            try:
+                v = self.info['purpose']['NonCA'][which]
+            except:
+                print "unable to find '%s'" % which
+                return 0
+        else:
+            try:
+                v = self.info['purpose']['CA'][which]
+            except:
+                print "unable to find '%s'" % which
+                return 0
+        if v == 'Yes':
+            return 1
+        return 0
+
     def getInformation(self, section, part = None):
         if self.cert is None or len(self.info) == 0:
             return None

Modified: labs/badca/openssl/certmodule.c
URL: http://svn.apache.org/viewvc/labs/badca/openssl/certmodule.c?rev=602056&r1=602055&r2=602056&view=diff
==============================================================================
--- labs/badca/openssl/certmodule.c (original)
+++ labs/badca/openssl/certmodule.c Fri Dec  7 02:14:29 2007
@@ -5,6 +5,8 @@
 #include <openssl/err.h>
 #include <openssl/ssl.h>
 #include <openssl/pem.h>
+#include <openssl/x509.h>
+#include <openssl/x509v3.h>
 
 static void delcert(void *ptr)
 {
@@ -83,6 +85,58 @@
 }
 
 static PyObject *
+makePyObjectFromPrintf(const char *fmt, ...)
+{
+    PyObject *rv = NULL;
+    char msg[2048];
+    int slen = 0;
+    va_list args;
+
+    memset(msg, 0, sizeof(msg));
+    va_start(args, fmt);
+    slen = vsnprintf(msg, sizeof(msg), fmt, args);
+    va_end(args);
+
+    if (slen > 0)
+        rv = PyString_FromStringAndSize(msg, slen);
+
+    return rv;
+}
+
+static void
+addX509PurposeToPyDict(X509 *cert, X509_PURPOSE *p, PyObject *dict, 
+                       PyObject *cadict)
+{
+    int i;
+    int id = X509_PURPOSE_get_id(p);
+    char *pname = X509_PURPOSE_get0_name(p);
+    PyObject *key = makePyObjectFromPrintf("%s", pname);
+
+    for (i = 0; i < 2; i++) {
+        int idret = X509_check_purpose(cert, id, i);
+        PyObject *val = NULL;
+
+        if (idret == 1)
+            val = makePyObjectFromPrintf("%s", "Yes");
+        else if (idret == 0)
+            val = makePyObjectFromPrintf("%s", "No");
+        else
+            val = makePyObjectFromPrintf("Yes (Warning code %d)", idret);
+
+        if (!val)
+            continue;
+
+        if (i == 0)
+           PyDict_SetItem(dict, key, val);
+        else
+           PyDict_SetItem(cadict, key, val);
+
+        Py_DECREF(val);
+    }
+    Py_DECREF(key);
+}
+
+static PyObject *
 readCert(PyObject *self, PyObject *args)
 {
     X509 *cert = NULL;
@@ -152,6 +206,7 @@
     PyObject *dict = NULL;
     X509 *cert = NULL;
     X509_NAME *subject = NULL, *issuer = NULL;
+    const EVP_MD *digest = EVP_sha1();
 
     if (! PyArg_ParseTuple(args, "O", &tmp))
         return NULL;
@@ -188,6 +243,34 @@
             Py_DECREF(serStr);
         }
     }
+    /* certificate fingerprint */
+    {
+        int j;
+        unsigned int n;
+        unsigned char md[EVP_MAX_MD_SIZE];
+
+        if (X509_digest(cert, digest, md, &n)) {
+            PyObject *fdict = PyDict_New(), *val = NULL;
+            char *str = (char *)malloc(3 * n);
+
+            val = makePyObjectFromPrintf("%s", OBJ_nid2sn(EVP_MD_type(digest)));
+            PyDict_SetItem(fdict, Py_BuildValue("s", "digest"), val);
+            Py_DECREF(val);
+            memset(str, 3 * n, 0);
+            for (j=0; j < (int)n; j++) {
+                sprintf(&str[3 * j], "%02X", md[j]);
+                if (j + 1 < (int)n)
+                    str[(3 * j) + 2] = ':';
+            }
+            val = makePyObjectFromPrintf("%s", str);
+            PyDict_SetItem(fdict, Py_BuildValue("s", "value"), val);
+            Py_DECREF(val);
+            PyDict_SetItem(dict, Py_BuildValue("s", "fingerprint"), fdict);
+            Py_DECREF(fdict);
+            free(str);
+        }
+    }
+
     /* Public Key information */
     {
         EVP_PKEY *pkey = X509_get_pubkey(cert);
@@ -238,6 +321,28 @@
 
         }
     }
+
+    /* get a list of purposes */
+    {
+        X509_PURPOSE *ptmp;
+        int j;
+        if (X509_PURPOSE_get_count() > 0) {
+            PyObject *adict = PyDict_New();
+            PyObject *pdict = PyDict_New(), *pcadict = PyDict_New();
+            for (j = 0; j < X509_PURPOSE_get_count(); j++) {
+                ptmp = X509_PURPOSE_get0(j);
+                addX509PurposeToPyDict(cert, ptmp, pdict, pcadict);
+            }
+            PyDict_SetItem(adict, Py_BuildValue("s", "NonCA"), pdict);
+            PyDict_SetItem(adict, Py_BuildValue("s", "CA"), pcadict);
+            Py_DECREF(pdict);
+            Py_DECREF(pcadict);
+            PyDict_SetItem(dict, Py_BuildValue("s", "purpose"), adict);
+            Py_DECREF(adict);
+
+        }
+    }
+
 
     return dict;
 err:

Modified: labs/badca/tests/03CertTestCase.py
URL: http://svn.apache.org/viewvc/labs/badca/tests/03CertTestCase.py?rev=602056&r1=602055&r2=602056&view=diff
==============================================================================
--- labs/badca/tests/03CertTestCase.py (original)
+++ labs/badca/tests/03CertTestCase.py Fri Dec  7 02:14:29 2007
@@ -58,7 +58,41 @@
                     "Failed to get correct email address from certificate"
         assert self.obj.getInformation("serial") == 'B80A8A59ACEB819B64C60F726A32E935', \
                          "Failed to get correct serial from certificate"
+        assert self.obj.getFingerprint() == \
+          '42:56:45:63:4F:1E:DA:62:35:6A:7D:EE:4C:D1:12:CB:1A:33:D6:92', \
+                        "Incorrect fingerprint returned for certificate"
+            
+#        print "info = " + str(self.obj.info)
 
+    def test04(self):
+        """ Checking certificate fingerprint """
+        assert self.obj.readFromFile('tests/certs/test1.pem') == 1, \
+                                        "Failed to read the Certificate"
+        assert self.obj.getFingerprint() == \
+          '42:56:45:63:4F:1E:DA:62:35:6A:7D:EE:4C:D1:12:CB:1A:33:D6:92', \
+                        "Incorrect fingerprint returned for certificate"
+
+    def test05(self):
+        """ Checking certificate purposes """
+        assert self.obj.readFromFile('tests/certs/test1.pem') == 1, \
+                                        "Failed to read the Certificate"
+
+        # These should all be no for non CA
+        for c in ( 'SSL client', 'S/MIME encryption' ):
+            errstr = "Purpose '%s' was incorrectly reflected for non-CA" % c
+            assert self.obj.checkPurpose(c, 0) == 0, errstr
+        # These should be yes for non CA
+        for c in ( 'Any Purpose', 'OCSP helper' ):
+            errstr = "Purpose '%s' was incorrectly reflected for non-CA" % c
+            assert self.obj.checkPurpose(c, 0) == 1, errstr
+
+        # These should all be no for CA
+        for c in ( 'SSL client', 'S/MIME encryption', 'OCSP helper' ):
+            errstr = "Purpose '%s' was incorrectly reflected for CA" % c
+            assert self.obj.checkPurpose(c, 1) == 0, errstr
+        # This should be yes for CA
+        errstr = "Purpose 'Any Purpose' was incorrectly reflected for CA"
+        assert self.obj.checkPurpose('Any Purpose', 1) == 1, errstr
 
 
 if __name__ == "__main__":



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org
For additional commands, e-mail: commits-help@labs.apache.org