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