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 14:56:52 UTC

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

Author: dreid
Date: Thu Jan 10 05:56:51 2008
New Revision: 610797

URL: http://svn.apache.org/viewvc?rev=610797&view=rev
Log:
Add support for validity periods of CRL's and add a  
serial number for each crl (auto-incrementing)
Final step is to add stroing of dates/times

Also some code cleanup in the crl and cert modules to
cimplify things a little.

Modified:
    labs/badca/BaDCA/CRLs.py
    labs/badca/openssl/certmodule.c
    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=610797&r1=610796&r2=610797&view=diff
==============================================================================
--- labs/badca/BaDCA/CRLs.py (original)
+++ labs/badca/BaDCA/CRLs.py Thu Jan 10 05:56:51 2008
@@ -17,6 +17,10 @@
     xml = None
     xmlRoot = None
     certs = 0
+    crlSerial = 0
+    validity = 0
+    lastIssue = None
+    nextIssue = None
 
     def __init__(self, cert, dir):
         if not os.path.isdir(dir):
@@ -28,6 +32,9 @@
             return
         self.xmlFn = os.path.join(dir, self.certSerial + '.xml')
         self.parseXML()
+        self.getCurrentSerial()
+        self.getCurrentCount()
+        self.getCurrentValidity()
 
     def isValid(self):
         if self.directory is None or \
@@ -43,7 +50,6 @@
             self.xml = impl.createDocument(None, "badcaCRL", None)
             self.writeXML()
         self.xmlRoot = self.xml.documentElement
-        self.getCurrentCount()
 
     def writeXML(self):
         writer = open(self.xmlFn, 'w')
@@ -54,34 +60,59 @@
             return 1
         return 0
 
+    def getCurrentSerial(self):
+        node = self.findNode('serial', 1)
+        self.crlSerial = int(node.childNodes[0].data)
+
+    def setCurrentSerial(self, val):
+        node = self.findNode('serial', 1)
+        node.childNodes[0].data = str(val)
+        self.crlSerial = val
+
+    def getCurrentValidity(self):
+        node = self.findNode('validity', 30 * 24 * 60 * 60)
+        self.validity = int(node.childNodes[0].data)
+
+    def setValidity(self, val = None, days = None, hours = None):
+        newval = 0
+        if val is not None:
+            newval = val
+        elif days is not None or hours is not None:
+            hrs = 0
+            if days is not None:
+                hrs = days * 24
+            if hours is not None:
+                hrs += hours
+            newval = hrs * 60 * 60
+        if newval > 0:
+            node = self.findNode('validity', 0)
+            node.childNodes[0].data = str(newval)
+            self.validity = newval
 
     def getCurrentCount(self):
-        node = self.findCountNode()
-        if node is None:
-            self.count = 0
-            return
-        else:
-            self.count = int(node.childNodes[0].data)
+        node = self.findNode('count', 0)
+        self.count = int(node.childNodes[0].data)
 
     def incrementCount(self):
         self.updateCount(self.count + 1)
 
     def updateCount(self, qty):
-        node = self.findCountNode()
-        if node is None:
-            node = self.xml.createElement('count')
-            txt = self.xml.createTextNode(str(qty))
-            node.appendChild(txt)
-            self.xmlRoot.appendChild(node)
-        else:
-            node.childNodes[0].data = str(qty)
+        node = self.findNode('count', 0)
+        node.childNodes[0].data = str(qty)
         self.count = qty
 
-    def findCountNode(self):
+    # Use with caution!
+    # This not only tries to find the specified node, but it will create
+    # it if it's not present.
+    def findNode(self, which, defaultValue = None):
         try:
-            node = self.xmlRoot.getElementsByTagName('count')[0]
+            node = self.xmlRoot.getElementsByTagName(which)[0]
         except IndexError:
-            return None
+            node = self.xml.createElement(which)
+            if defaultValue is not None:
+                txt = self.xml.createTextNode(str(defaultValue))
+                node.appendChild(txt)
+            self.xmlRoot.appendChild(node)
         return node
 
 # Reason should be a string containing exactly one of...
@@ -91,7 +122,7 @@
 #    affiliationChanged
 #    superseded
 #    cessationOfOperation
-#    certificateHold
+#    certificateHold - what does this mean???
 
     def addCertificate(self, cert, reason = 'unspecified'):
         if cert is None or cert.serial is None:
@@ -134,8 +165,9 @@
             sn = n.getElementsByTagName('serialNumber')[0].childNodes[0].data
             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)
+            d[sn.strip()] = { 'reason': r.strip(), 'dateTime': dt.strip() }
+        d['serial'] = self.crlSerial
+        d['validity'] = self.validity
         return d
 
     def generateCRL(self, cert = None):
@@ -144,10 +176,12 @@
         if not cert.key.hasPrivate():
             return 0
         certs = self.makeDict()
-        
+
         thecrl = crl.createCRL(certs, cert.cert, cert.key.privRSA)
         if thecrl is not None:
             self.crl = thecrl
+            self.setCurrentSerial(self.crlSerial + 1)
+            self.writeXML()
             return 1
 
         return 0

Modified: labs/badca/openssl/certmodule.c
URL: http://svn.apache.org/viewvc/labs/badca/openssl/certmodule.c?rev=610797&r1=610796&r2=610797&view=diff
==============================================================================
--- labs/badca/openssl/certmodule.c (original)
+++ labs/badca/openssl/certmodule.c Thu Jan 10 05:56:51 2008
@@ -45,7 +45,7 @@
         char buf[512];
         int rv = X509_NAME_get_text_by_NID(name, parts[i].nid, buf, 512);
         if (rv > 0)
-            PyDict_SetItem(sdict, Py_BuildValue("s", parts[i].dict),
+            PyDict_SetItemString(sdict, parts[i].dict,
                            PyString_FromStringAndSize(buf, rv));
     }
     return sdict;
@@ -552,7 +552,7 @@
     {
         int ver = X509_get_version(cert);
         if (ver > 0)
-            PyDict_SetItem(dict, Py_BuildValue("s", "Version"),
+            PyDict_SetItemString(dict, "Version",
                              Py_BuildValue("i", (ver + 1)));
 
     }
@@ -575,7 +575,7 @@
             char *str = (char *)malloc(3 * n);
 
             val = makePyObjectFromPrintf("%s", OBJ_nid2sn(EVP_MD_type(digest)));
-            PyDict_SetItem(fdict, Py_BuildValue("s", "digest"), val);
+            PyDict_SetItemString(fdict, "digest", val);
             Py_DECREF(val);
             memset(str, 3 * n, 0);
             for (j=0; j < (int)n; j++) {
@@ -584,9 +584,9 @@
                     str[(3 * j) + 2] = ':';
             }
             val = makePyObjectFromPrintf("%s", str);
-            PyDict_SetItem(fdict, Py_BuildValue("s", "value"), val);
+            PyDict_SetItemString(fdict, "value", val);
             Py_DECREF(val);
-            PyDict_SetItem(dict, Py_BuildValue("s", "fingerprint"), fdict);
+            PyDict_SetItemString(dict, "fingerprint", fdict);
             Py_DECREF(fdict);
             free(str);
         }
@@ -606,21 +606,21 @@
                 long sz = BIO_get_mem_data(bp, &strPtr);
                 (void)BIO_set_close(bp, BIO_NOCLOSE);
                 BIO_free(bp);
-                PyDict_SetItem(pkdict, Py_BuildValue("s", "algorithm"),
+                PyDict_SetItemString(pkdict, "algorithm",
                                PyString_FromStringAndSize(strPtr, sz));
             }
         }
 
         /* Public key Strength */
         if (pkey->type == EVP_PKEY_RSA) 
-            PyDict_SetItem(pkdict, Py_BuildValue("s", "strength"),
+            PyDict_SetItemString(pkdict, "strength",
                            Py_BuildValue("l", BN_num_bits(pkey->pkey.rsa->n)));
 
-        PyDict_SetItem(dict, Py_BuildValue("s", "public_key"), pkdict);
+        PyDict_SetItemString(dict, "public_key", pkdict);
     }
     {
         PyObject *ndict = parseX509Name(subject);
-        PyDict_SetItem(dict, Py_BuildValue("s", "subject"), ndict);
+        PyDict_SetItemString(dict, "subject", ndict);
         Py_DECREF(ndict);
     }
     {
@@ -655,11 +655,11 @@
                 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);
+            PyDict_SetItemString(adict, "NonCA", pdict);
+            PyDict_SetItemString(adict, "CA", pcadict);
             Py_DECREF(pdict);
             Py_DECREF(pcadict);
-            PyDict_SetItem(dict, Py_BuildValue("s", "purpose"), adict);
+            PyDict_SetItemString(dict, "purpose", adict);
             Py_DECREF(adict);
 
         }
@@ -703,9 +703,9 @@
     }
 
     if (optionsDict) {
-        attrDict = PyDict_GetItem(optionsDict, Py_BuildValue("s", "attributes"));
-        removeList = PyDict_GetItem(optionsDict, Py_BuildValue("s", "remove"));
-        ignoreList = PyDict_GetItem(optionsDict, Py_BuildValue("s", "ignore"));
+        attrDict = PyDict_GetItemString(optionsDict, "attributes");
+        removeList = PyDict_GetItemString(optionsDict, "remove");
+        ignoreList = PyDict_GetItemString(optionsDict, "ignore");
     }
 
     issuerSubject = X509_get_subject_name(issuer);

Modified: labs/badca/openssl/crlmodule.c
URL: http://svn.apache.org/viewvc/labs/badca/openssl/crlmodule.c?rev=610797&r1=610796&r2=610797&view=diff
==============================================================================
--- labs/badca/openssl/crlmodule.c (original)
+++ labs/badca/openssl/crlmodule.c Thu Jan 10 05:56:51 2008
@@ -16,8 +16,14 @@
 static char *
 stringFromDictEntry(PyObject *entry)
 {
-    char *sn = PyString_AsString(entry);
-    int sz = strlen(sn), i;
+    char *sn = NULL;
+    int sz, i;
+
+    sn = PyString_AsString(entry);
+    if (!sn)
+        return NULL;
+
+    sz = strlen(sn);
     
     for (i = 0; i < sz; i++) {
         if (*sn != ' ' && *sn != '\n')
@@ -167,8 +173,8 @@
         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"));
+        PyObject *rO = PyDict_GetItemString(pValue, "reason");
+        PyObject *dO = PyDict_GetItemString(pValue, "dateTime");
         if (!rO || !dO)
             continue;
         r = stringFromDictEntry(rO);
@@ -209,6 +215,8 @@
 {
     void *tmp[2] = { NULL, NULL};
     PyObject *certs = NULL;
+    PyObject *pKey = NULL, *pValue = NULL;
+    int pos = 0;
     X509 *cert = NULL;
     RSA *rsa = NULL;
     X509_CRL *crl = NULL;
@@ -230,9 +238,8 @@
         PyErr_SetString(PyExc_MemoryError, "Unable to create an X509_CRL object");
         return NULL;
     }
-    if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(cert))) {
-        PyErr_SetString(PyExc_RuntimeError, "Unable to set the issuer "
-                        "name for the new CRL");
+    if (!X509_CRL_set_version(crl, 1)) {
+        PyErr_SetString(PyExc_RuntimeError, "Unable to set CRL version!");
         goto out;
     }
 
@@ -244,13 +251,36 @@
     }
     X509_gmtime_adj(tm, 0);
     X509_CRL_set_lastUpdate(crl, tm);
-/*
-    if (cac->crl_period) {
-        X509_gmtime_adj(tm, cac->crl_period);
-        X509_CRL_set_nextUpdate(crl, tm);
+ 
+    while (PyDict_Next(certs, &pos, &pKey, &pValue)) {
+        char *k = stringFromDictEntry(pKey);
+        long v = 0;
+
+        if (PyDict_CheckExact(pValue))
+            continue;
+
+        v = PyLong_AsLong(pValue);
+
+        if (strcasecmp(k, "serial") == 0) {
+            ASN1_INTEGER *tmpser = ASN1_INTEGER_new();
+            if (tmpser) {
+                ASN1_INTEGER_set(tmpser, v);
+                X509_CRL_add1_ext_i2d(crl, NID_crl_number, tmpser, 0, 0);
+                ASN1_INTEGER_free(tmpser);
+            }
+        }
+        if (strcasecmp(k, "validity") == 0) {
+            X509_gmtime_adj(tm, v);
+            X509_CRL_set_nextUpdate(crl, tm);
+        }
     }
-*/
     ASN1_TIME_free(tm);
+
+    if (!X509_CRL_set_issuer_name(crl, X509_get_subject_name(cert))) {
+        PyErr_SetString(PyExc_RuntimeError, "Unable to set the issuer "
+                        "name for the new CRL");
+        goto out;
+    }
 
     crlAddFromDict(crl, certs);
 

Modified: labs/badca/tests/06CRLTestCase.py
URL: http://svn.apache.org/viewvc/labs/badca/tests/06CRLTestCase.py?rev=610797&r1=610796&r2=610797&view=diff
==============================================================================
--- labs/badca/tests/06CRLTestCase.py (original)
+++ labs/badca/tests/06CRLTestCase.py Thu Jan 10 05:56:51 2008
@@ -12,6 +12,29 @@
         crl = CRLs.CRL(c, 'tests/crl')
         assert crl.isValid(), "CRL should be invalid!"
         assert crl.count == 0, "CRL count should be 0"
+
+    def test02(self):
+        """ Test validity period setting """
+        c = Certificates.Certificate(filename = 'tests/certs/ca1.pem',
+                                     keyPaths = [ 'tests/keys/private'])
+        assert c.isValid(), "Certificate should be valid!"
+        assert c.key.hasPrivate(), "Certificate doesn't have a private key"
+        crl = CRLs.CRL(c, 'tests/crl')
+        assert crl.isValid(), "CRL should be invalid!"
+        crl.setValidity(100)
+        assert crl.validity == 100, "Incorrect validity period set"
+        crl.setValidity(days = 1)
+        assert crl.validity == (24 * 60 * 60), \
+                                         "Incorrect validity period set"
+
+    def test03(self):
+        """ Test adding a certificate to the CRL """
+        c = Certificates.Certificate(filename = 'tests/certs/ca1.pem',
+                                     keyPaths = [ 'tests/keys/private'])
+        assert c.isValid(), "Certificate should be valid!"
+        assert c.key.hasPrivate(), "Certificate doesn't have a private key"
+        crl = CRLs.CRL(c, 'tests/crl')
+        assert crl.isValid(), "CRL should be invalid!"
         d = Certificates.Certificate(filename = 'tests/certs/test1.pem')
         assert d.isValid(), "Certificate should be valid"
         assert crl.addCertificate(d, 'unspecified') == 1, \
@@ -19,7 +42,7 @@
         assert crl.count == 1, "Incorrect count after adding certificate"
         assert crl.writeXML() == 1, "Unable to write XML file"
 
-    def test02(self):
+    def test04(self):
         """ Testing creation of actual CRL file """
         c = Certificates.Certificate(filename = 'tests/certs/ca1.pem',
                                      keyPaths = [ 'tests/keys/private'])



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