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 2008/01/10 11:39:22 UTC

svn commit: r610748 - in /labs/badca: BaDCA/CRLs.py openssl/crlmodule.c tests/06CRLTestCase.py

Author: dreid
Date: Thu Jan 10 02:39:21 2008
New Revision: 610748

URL: http://svn.apache.org/viewvc?rev=610748&view=rev
Log:
Add the code that allows us to create CRL's with revoked certificate
details contained. We need a better way of dealing with the reasons,
but this works.

TODO - add some way of passing a validity period for a CRL


Modified:
    labs/badca/BaDCA/CRLs.py
    labs/badca/openssl/crlmodule.c
    labs/badca/tests/06CRLTestCase.py

Modified: labs/badca/BaDCA/CRLs.py
URL: http://svn.apache.org/viewvc/labs/badca/BaDCA/CRLs.py?rev=610748&r1=610747&r2=610748&view=diff
==============================================================================
--- labs/badca/BaDCA/CRLs.py (original)
+++ labs/badca/BaDCA/CRLs.py Thu Jan 10 02:39:21 2008
@@ -27,7 +27,6 @@
         if self.certSerial is None:
             return
         self.xmlFn = os.path.join(dir, self.certSerial + '.xml')
-        print "xmlFn => %s" % self.xmlFn
         self.parseXML()
 
     def isValid(self):
@@ -64,8 +63,6 @@
         else:
             self.count = int(node.childNodes[0].data)
 
-        print "node = %s, self.count = %d" % (str(node), self.count)
-
     def incrementCount(self):
         self.updateCount(self.count + 1)
 
@@ -138,7 +135,7 @@
             r = n.getElementsByTagName('reason')[0].childNodes[0].data
             dt = n.getElementsByTagName('dateTime')[0].childNodes[0].data
             d[sn] = { 'reason': r, 'dateTime': dt }
-        print str(d)
+#        print str(d)
         return d
 
     def generateCRL(self, cert = None):

Modified: labs/badca/openssl/crlmodule.c
URL: http://svn.apache.org/viewvc/labs/badca/openssl/crlmodule.c?rev=610748&r1=610747&r2=610748&view=diff
==============================================================================
--- labs/badca/openssl/crlmodule.c (original)
+++ labs/badca/openssl/crlmodule.c Thu Jan 10 02:39:21 2008
@@ -13,23 +13,171 @@
     X509_CRL_free((X509_CRL *)ptr);
 }
 
+static char *
+stringFromDictEntry(PyObject *entry)
+{
+    char *sn = PyString_AsString(entry);
+    int sz = strlen(sn), i;
+    
+    for (i = 0; i < sz; i++) {
+        if (*sn != ' ' && *sn != '\n')
+            break;
+        sn++;
+    }
+    sz = strlen(sn);
+    for (i = sz - 1; i > 0; i--) {
+        if (sn[i] != ' ' && sn[i] != '\n')
+            break;
+    }
+    sn[i + 1] = '\0';
+    return sn;
+}
+
+/* We use the reason codes from OpenSSL to try and keep some form
+ * of compatibility with OpenSSL.
+ */
+static int
+reasonCodeFromString(char *reasonString)
+{
+    int code = 0;
+    int i;
+    const char *crl_reasons[] = {
+	/* CRL reason strings */
+	"unspecified",
+	"keyCompromise",
+	"CACompromise",
+	"affiliationChanged",
+	"superseded", 
+	"cessationOfOperation",
+	"certificateHold",
+
+/* We don't support these just yet... */
+//	"removeFromCRL",
+
+	/* Additional pseudo reasons */
+//	"holdInstruction",
+//	"keyTime",
+//	"CAkeyTime"
+    };
+#define NUM_REASONS (sizeof(crl_reasons) / sizeof(char *))
+
+    for (i = 0; i < NUM_REASONS; i++) {
+        if(!strcasecmp(reasonString, crl_reasons[i])) {
+            code = i;
+            break;
+        }
+    }
+
+    return code;
+}
+
+static ASN1_ENUMERATED *
+getRevocationReason(char *reason)
+{
+    ASN1_ENUMERATED *code = ASN1_ENUMERATED_new();
+    int reasonCode = 0;
+
+    if (!code) {
+        PyErr_SetString(PyExc_MemoryError, "Unable to create an "
+                        "ASN1_ENUMERATED object");
+        return NULL;
+    }
+
+    reasonCode = reasonCodeFromString(reason);
+    if (ASN1_ENUMERATED_set(code, reasonCode))
+        return code;
+    PyErr_SetString(PyExc_RuntimeError, "Incorrect reason code");
+    ASN1_ENUMERATED_free(code);
+    return NULL;
+}
+
+static X509_REVOKED *
+makeRevoked(char *sn, char *reason, char *dt)
+{
+    X509_REVOKED *r = X509_REVOKED_new();
+    BIGNUM *bn = NULL;
+    ASN1_TIME *tm = NULL;
+    ASN1_ENUMERATED *rtmp = NULL;
+
+    if (!r) {
+        PyErr_SetString(PyExc_MemoryError, "Unable to create an "
+                        "X509_REVOKED object");
+        return NULL;
+    }
+
+    if (BN_hex2bn(&bn, sn)) {
+        ASN1_INTEGER *ser = BN_to_ASN1_INTEGER(bn, NULL);
+        if (ser) {
+            X509_REVOKED_set_serialNumber(r, ser);
+            ASN1_INTEGER_free(ser);
+        }
+        BN_free(bn);
+    } else {
+        PyErr_SetString(PyExc_RuntimeError, "makeRevoked: Unable to parse"
+                        " serial number");
+        goto out;
+    }
+
+    tm = ASN1_UTCTIME_new();
+    if (!tm) {
+        PyErr_SetString(PyExc_MemoryError, "Unable to create an ASN1_UTCTIME object");
+        goto out;
+    }
+    if (ASN1_UTCTIME_set_string(tm, dt)) {
+        if (!X509_REVOKED_set_revocationDate(r, tm)) {
+            PyErr_SetString(PyExc_RuntimeError, "makeRevoked: Unable to "
+                            "set revocation date");
+            goto out;
+        }
+    } else {
+        PyErr_SetString(PyExc_RuntimeError, "makeRevoked: Unable to parse "
+                        "date into an ASN1_UTCTIME");
+        goto out;
+    }
+    ASN1_UTCTIME_free(tm);
+
+    rtmp = getRevocationReason(reason);
+    if (!rtmp)
+        goto out;
+
+    if (!X509_REVOKED_add1_ext_i2d(r, NID_crl_reason, rtmp, 0, 0)) {
+        PyErr_SetString(PyExc_RuntimeError, "makeRevoked: Unable to set "
+                        "the reason for revocation");
+        goto out;
+    }
+    ASN1_ENUMERATED_free(rtmp);
+    return r;
+out:
+    if (rtmp)
+        ASN1_ENUMERATED_free(rtmp);
+    if (bn)
+        BN_free(bn);
+    if (r)
+        X509_REVOKED_free(r);
+    return NULL;
+}
+    
 static void
 crlAddFromDict(X509_CRL *crl, PyObject *dict)
 {
-    int rv = 0;
     PyObject *pKey = NULL, *pValue = NULL;
     int pos = 0;
     
     while (PyDict_Next(dict, &pos, &pKey, &pValue)) {
-        char *sn = PyString_AsString(pKey);
+        X509_REVOKED *rev = NULL;
+        char *sn = stringFromDictEntry(pKey);
         char *r = NULL, *dt = NULL;
         PyObject *rO = PyDict_GetItem(pValue, Py_BuildValue("s", "reason"));
         PyObject *dO = PyDict_GetItem(pValue, Py_BuildValue("s", "dateTime"));
         if (!rO || !dO)
             continue;
-        r = PyString_AsString(rO);
-        dt = PyString_AsString(dO);
-        printf("sn = %s, r = %s, dt = %s\n", sn, r, dt);
+        r = stringFromDictEntry(rO);
+        dt = stringFromDictEntry(dO);
+
+        rev = makeRevoked(sn, r, dt);
+        if (rev)
+            X509_CRL_add0_revoked(crl, rev);
+        /* As we used the add0 function, do not free rev! */
     }
 }
 

Modified: labs/badca/tests/06CRLTestCase.py
URL: http://svn.apache.org/viewvc/labs/badca/tests/06CRLTestCase.py?rev=610748&r1=610747&r2=610748&view=diff
==============================================================================
--- labs/badca/tests/06CRLTestCase.py (original)
+++ labs/badca/tests/06CRLTestCase.py Thu Jan 10 02:39:21 2008
@@ -20,7 +20,7 @@
         assert crl.writeXML() == 1, "Unable to write XML file"
 
     def test02(self):
-        """ Testing creation of CRL """
+        """ Testing creation of actual CRL file """
         c = Certificates.Certificate(filename = 'tests/certs/ca1.pem',
                                      keyPaths = [ 'tests/keys/private'])
         assert c.isValid(), "Certificate should be valid!"
@@ -31,6 +31,8 @@
         assert crl.generateCRL(c) == 1, "Unable to create a CRL"
         assert crl.write('tests/crl/test01.crl') == 1, \
                                        "Unable to write the CRL to file"
+        assert os.path.exists('tests/crl/test01.crl'), \
+                                            "CRL file was not written!!"
 
 if __name__ == "__main__":
     unittest.main()



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