Return-Path: Delivered-To: apmail-labs-commits-archive@locus.apache.org Received: (qmail 53464 invoked from network); 13 Dec 2007 14:14:46 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 13 Dec 2007 14:14:46 -0000 Received: (qmail 63588 invoked by uid 500); 13 Dec 2007 14:14:34 -0000 Delivered-To: apmail-labs-commits-archive@labs.apache.org Received: (qmail 63489 invoked by uid 500); 13 Dec 2007 14:14:34 -0000 Mailing-List: contact commits-help@labs.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: labs@labs.apache.org Delivered-To: mailing list commits@labs.apache.org Received: (qmail 63478 invoked by uid 99); 13 Dec 2007 14:14:34 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 13 Dec 2007 06:14:34 -0800 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 13 Dec 2007 14:14:09 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 8F26F1A9832; Thu, 13 Dec 2007 06:14:12 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r603922 - in /labs/badca: ./ BaDCA/ openssl/ tests/ Date: Thu, 13 Dec 2007 14:14:06 -0000 To: commits@labs.apache.org From: dreid@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20071213141412.8F26F1A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: dreid Date: Thu Dec 13 06:13:58 2007 New Revision: 603922 URL: http://svn.apache.org/viewvc?rev=603922&view=rev Log: Large refactoring of the key handling to adopt a model where the key code knows how to get keys from all the objects we need to deal with and so the other objects can be simpler and we have more potential for code reuse. Attempt to cure an issue with key lifetimes (which doesn't seem to have worked). Add a new test module to allow us to get different types of objects for tests and start using it for testing keys Status: this still crashes the certificate test on most systems. The problem appears to be a double free of a key, but how to cure it is proving awkward. Added: labs/badca/BaDCA/Testing.py labs/badca/openssl/testmodule.c Modified: labs/badca/ (props changed) labs/badca/BaDCA/CSRs.py labs/badca/BaDCA/Certificates.py labs/badca/BaDCA/Keys.py labs/badca/BaDCA/Utils.py labs/badca/Makefile.in labs/badca/openssl/cert.c labs/badca/openssl/certmodule.c labs/badca/openssl/certmodule_c.c labs/badca/openssl/csrmodule.c labs/badca/openssl/rsamodule.c labs/badca/openssl/setup.py.in labs/badca/tests/01KeysTestCase.py labs/badca/tests/03CertTestCase.py Propchange: labs/badca/ ------------------------------------------------------------------------------ --- svn:ignore (original) +++ svn:ignore Thu Dec 13 06:13:58 2007 @@ -2,3 +2,5 @@ configure config.* *.cache +*.pem + Modified: labs/badca/BaDCA/CSRs.py URL: http://svn.apache.org/viewvc/labs/badca/BaDCA/CSRs.py?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/BaDCA/CSRs.py (original) +++ labs/badca/BaDCA/CSRs.py Thu Dec 13 06:13:58 2007 @@ -140,13 +140,10 @@ if self.csr is None: return 0 # a CSR should contain a public key object - key = csr.getKey(self.csr) + key = Keys.RSAKey(csr = self.csr) if key is None: return 0 - self.rKey = Keys.RSAKey(public = key) - if self.rKey is None: - print "no key object..." - return 0 + self.rKey = key self.info = csr.parse(self.csr) return 1 Modified: labs/badca/BaDCA/Certificates.py URL: http://svn.apache.org/viewvc/labs/badca/BaDCA/Certificates.py?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/BaDCA/Certificates.py (original) +++ labs/badca/BaDCA/Certificates.py Thu Dec 13 06:13:58 2007 @@ -10,6 +10,7 @@ filename = None cert = None key = None + keyPaths = [] def __init__(self, filename = None, obj = None): if filename is not None: @@ -30,13 +31,12 @@ def getKey(self): if self.cert is None or self.key is None: return None - key = cert.getPublicKey(self.cert) - if key is not None: - return Keys.RSAKey(public = key) - return None + return self.key # should we store the path in the certificate object? def addKeyPath(self, path): + if not path in self.keyPaths: + self.keyPaths.append(path) if self.key is not None: self.key.addSearchDirectory(path) @@ -80,18 +80,19 @@ if self.cert is None: return self.info = cert.parse(self.cert) - key = cert.getPublicKey(self.cert) - if key is not None: - self.key = Keys.RSAKey(public = key) + key = Keys.RSAKey(searchPath = self.keyPaths, \ + certificate = self.cert) + if key.isValid(): + self.key = key def signRequest(self, csr = None): if csr is None or self.cert is None or not self.key.hasPrivate(): return None nCert = cert.signRequest(self.cert, csr.csr, self.key.privRSA) - print "nCert = " + str(nCert) thecert = Certificate(obj = nCert) - print "thecert = " + str(thecert) - return thecert + if thecert is not None: + return thecert + return None def writeToFile(self, filename = None): if self.cert is None: Modified: labs/badca/BaDCA/Keys.py URL: http://svn.apache.org/viewvc/labs/badca/BaDCA/Keys.py?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/BaDCA/Keys.py (original) +++ labs/badca/BaDCA/Keys.py Thu Dec 13 06:13:58 2007 @@ -44,14 +44,25 @@ avail = KEY_NONE directories = [] - def __init__(self, public = None, private = None): + def __init__(self, certificate = None, filename = None, csr = None, + string = None, searchPath = None): + # Start by adding in any search paths we've been supplied with + if searchPath is not None: + self.addSearchDirectories(searchPath) + # Have we been given a pointer to an X509 certificate pointer? + if certificate is not None: + # todo - should check type here! + self.fromCertificate(certificate) + if csr is not None: + self.fromCSR(csr) + # If we have been given either the public or private key object # save them here - if public is not None: - self.pubRSA = public - if private is not None: - self.privRSA = private - self.processKeys() +# if public is not None: +# self.pubRSA = public +# if private is not None: +# self.privRSA = private +# self.processKeys() def getPrivateKey(self): return self.privRSA @@ -62,6 +73,10 @@ def setDirectory(self, thedir): self.directory = thedir + def addSearchDirectories(self, dirlist): + for d in dirlist: + self.addSearchDirectory(d) + def addSearchDirectory(self, thedir): if not thedir in self.directories: self.directories.append(thedir) @@ -87,6 +102,22 @@ self.processKeys() return 1 + def fromCertificate(self, obj): + r = rsa.fromX509(obj) + if r is not None: + self.pubRSA = r + self.processKeys() + return 1 + return 0 + + def fromCSR(self, obj): + r = rsa.fromCSR(obj) + if r is not None: + self.pubRSA = r + self.processKeys() + return 1 + return 0 + def getPublicKeyAsString(self): if (self.avail & KEY_PRIVATE): if self.privRSA is None: @@ -138,6 +169,13 @@ self.sha1 = getSHA1(pubKey) self.avail = KEY_PUBLIC self.searchPrivateKey() + + def readPublicKeyFromMemory(self, string): + self.pubRSA = rsa.fromMemoryPublic(string) + if self.pubRSA is not None: + self.processKeys() + return 1 + return 0 def readPrivateKey(self, filename = None, internal = 0): if filename is None: Added: labs/badca/BaDCA/Testing.py URL: http://svn.apache.org/viewvc/labs/badca/BaDCA/Testing.py?rev=603922&view=auto ============================================================================== --- labs/badca/BaDCA/Testing.py (added) +++ labs/badca/BaDCA/Testing.py Thu Dec 13 06:13:58 2007 @@ -0,0 +1,21 @@ +import os, sys + +try: + import test +except: + print """ +Failed to find the OpenSSL python extension for tests. + +Have you built/installed them yet? +""" + +def readCertificate(fn): + if fn is None or not os.path.exists(fn): + return None + return test.readCert(fn) + +def readCSR(fn): + if fn is None or not os.path.exists(fn): + return None + return test.readCSR(fn) + Modified: labs/badca/BaDCA/Utils.py URL: http://svn.apache.org/viewvc/labs/badca/BaDCA/Utils.py?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/BaDCA/Utils.py (original) +++ labs/badca/BaDCA/Utils.py Thu Dec 13 06:13:58 2007 @@ -6,7 +6,6 @@ import hashlib s = hashlib.sha1() - except: try: import sha Modified: labs/badca/Makefile.in URL: http://svn.apache.org/viewvc/labs/badca/Makefile.in?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/Makefile.in (original) +++ labs/badca/Makefile.in Thu Dec 13 06:13:58 2007 @@ -6,7 +6,8 @@ (cd openssl && @PYTHON@ setup.py build) || exit 1 clean: - (cd openssl && @PYTHON@ setup.py clean) || exit 1 + @(cd openssl && @PYTHON@ setup.py clean) || exit 1 + @(cd openssl && make clean) || exit 1 @rm -rf @EXT_PATH@ test: @@ -16,6 +17,10 @@ testkey: PYTHONPATH=".:@EXT_PATH@:$$PYTHONPATH" \ @PYTHON@ @top_srcdir@/tests/runTests.py @top_srcdir@/tests Keys + +testkeygdb: + PYTHONPATH=".:@EXT_PATH@:$$PYTHONPATH" \ + gdb --args @PYTHON@ @top_srcdir@/tests/runTests.py @top_srcdir@/tests Keys testcsr: PYTHONPATH=".:@EXT_PATH@:$$PYTHONPATH" \ Modified: labs/badca/openssl/cert.c URL: http://svn.apache.org/viewvc/labs/badca/openssl/cert.c?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/openssl/cert.c (original) +++ labs/badca/openssl/cert.c Thu Dec 13 06:13:58 2007 @@ -44,18 +44,20 @@ printf("Trying to get copies of the certificates public key...\n"); printf("key object we created earlier is %p\n", key); - key2 = RSAPublicKey_dup(X509_get_pubkey(cert)->pkey.rsa); - printf("1st copy = %p\n", key2); - key3 = RSAPublicKey_dup(X509_get_pubkey(cert)->pkey.rsa); - printf("2nd copy = %p\n", key3); - + { + RSA *tmp = EVP_PKEY_get1_RSA(X509_get_pubkey(cert)); + key2 = RSAPublicKey_dup(tmp); + printf("1st copy = %p\n", key2); + key3 = RSAPublicKey_dup(tmp); + printf("2nd copy = %p\n", key3); + } RSA_free(key); X509_free(newcert); X509_REQ_free(csr); X509_free(cert); - if (key2 != key) +// if (key2 != key) RSA_free(key2); RSA_free(key3); Modified: labs/badca/openssl/certmodule.c URL: http://svn.apache.org/viewvc/labs/badca/openssl/certmodule.c?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/openssl/certmodule.c (original) +++ labs/badca/openssl/certmodule.c Thu Dec 13 06:13:58 2007 @@ -15,11 +15,6 @@ X509_free((X509 *)ptr); } -static void delrsa(void *ptr) -{ - RSA_free((RSA *)ptr); -} - /* We may want to make this more generic and able to cope with any * possible entry in an X509_NAME structure? */ @@ -315,37 +310,6 @@ } static PyObject * -getPublicKey(PyObject *self, PyObject *args) -{ - X509 *cert = NULL; - RSA *rsa = NULL; - EVP_PKEY *pkey = NULL; - PyObject *pCert = NULL; - - if (!PyArg_ParseTuple(args, "O", &pCert)) - return NULL; - cert = (X509 *)PyCObject_AsVoidPtr(pCert); - if (!cert) - return NULL; - - pkey = X509_get_pubkey(cert); - if (!pkey) { - PyErr_SetString(PyExc_ValueError, "Invalid certificate object supplied"); - return NULL; - } - - if (pkey->type == EVP_PKEY_RSA) - rsa = RSAPublicKey_dup(pkey->pkey.rsa); - - EVP_PKEY_free(pkey); - if (rsa) - return PyCObject_FromVoidPtr(rsa, delrsa); - - PyErr_SetString(PyExc_ValueError, "Invalid certificate object supplied"); - return NULL; -} - -static PyObject * parseCertificate(PyObject *self, PyObject *args) { void *tmp = NULL; @@ -714,7 +678,6 @@ static PyMethodDef CertMethods[] = { { "read", readCert, METH_VARARGS, "Read a certificate from a file" }, { "write", writeCert, METH_VARARGS, "Write a certificate to a file" }, - { "getPublicKey", getPublicKey, METH_VARARGS, "Get Public Key object" }, { "parse", parseCertificate, METH_VARARGS, "Parse a certificate" }, { "signRequest", signRequestWithCertificate, METH_VARARGS, "Create a certificate from a CSR using a root certificate" }, Modified: labs/badca/openssl/certmodule_c.c URL: http://svn.apache.org/viewvc/labs/badca/openssl/certmodule_c.c?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/openssl/certmodule_c.c (original) +++ labs/badca/openssl/certmodule_c.c Thu Dec 13 06:13:58 2007 @@ -123,7 +123,10 @@ pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); if (pkey) { + printf("evp_pkey -> rsa = %p\n", pkey->pkey.rsa); rsa = EVP_PKEY_get1_RSA(pkey); + RSA_up_ref(rsa); + printf("rsa = %p\n", rsa); EVP_PKEY_free(pkey); } else printf("Unable to get public RSA key from file"); Modified: labs/badca/openssl/csrmodule.c URL: http://svn.apache.org/viewvc/labs/badca/openssl/csrmodule.c?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/openssl/csrmodule.c (original) +++ labs/badca/openssl/csrmodule.c Thu Dec 13 06:13:58 2007 @@ -11,15 +11,6 @@ X509_REQ_free((X509_REQ *)ptr); } -/* This fucntion is called when an RSA pointer is finally freed by - * Python. This is done via setting this as the 2nd argument in - * PyCObject_FromVoidPtr(). - */ -static void delrsa(void *ptr) -{ - RSA_free((RSA *)ptr); -} - static X509_NAME *makeSubjectFromDict(PyObject *dict, unsigned long chtype) { X509_NAME *subj = X509_NAME_new(); @@ -125,35 +116,6 @@ } static PyObject * -getPublicKey(PyObject *self, PyObject *args) -{ - void *tmp = NULL; - X509_REQ *req = NULL; - EVP_PKEY *pkey = NULL; - RSA *rsa = NULL; - - if (! PyArg_ParseTuple(args, "O", &tmp)) - return NULL; - - req = (X509_REQ *)PyCObject_AsVoidPtr(tmp); - if (!req) { - PyErr_SetString(PyExc_TypeError, "Invalid X509_REQ object passed"); - return NULL; - } - - pkey = X509_REQ_get_pubkey(req); - if (pkey) { - if (pkey->type == EVP_PKEY_RSA) - rsa = RSAPublicKey_dup(pkey->pkey.rsa); - EVP_PKEY_free(pkey); - } - if (rsa) - return PyCObject_FromVoidPtr(rsa, delrsa); - PyErr_SetString(PyExc_ValueError, "Invalid CSR object"); - return NULL; -} - -static PyObject * parseRequest(PyObject *self, PyObject *args) { void *tmp = NULL; @@ -210,6 +172,7 @@ Py_BuildValue("l", BN_num_bits(pkey->pkey.rsa->n))); PyDict_SetItem(dict, Py_BuildValue("s", "public_key"), pkdict); + EVP_PKEY_free(pkey); } /* CSR Subject */ { @@ -346,7 +309,6 @@ static PyMethodDef CSRMethods[] = { { "fromFile", readCSRFromFile, METH_VARARGS, "Read a CSR from a file" }, { "fromMemory", readCSRFromMemory, METH_VARARGS, "Read a CSR from a block of memory" }, - { "getKey", getPublicKey, METH_VARARGS, "Get the X509_RSA public key object from the CSR" }, { "parse", parseRequest, METH_VARARGS, "Parse a request into a python dict" }, { "create", createRequest, METH_VARARGS, "Create a request from information supplied" }, { "asString", getRequestAsString, METH_VARARGS, "Get request as string" }, Modified: labs/badca/openssl/rsamodule.c URL: http://svn.apache.org/viewvc/labs/badca/openssl/rsamodule.c?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/openssl/rsamodule.c (original) +++ labs/badca/openssl/rsamodule.c Thu Dec 13 06:13:58 2007 @@ -80,10 +80,53 @@ return rv; } +static RSA *readKeyFromBio(BIO *in, int which) +{ + EVP_PKEY *pkey = NULL; + RSA *rsa = NULL; + + if (which == PUBLIC) + pkey=PEM_read_bio_PUBKEY(in, NULL, NULL, NULL); + else + pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); + + if (pkey) { + rsa = EVP_PKEY_get1_RSA(pkey); + EVP_PKEY_free(pkey); + } + return rsa; +} + +static RSA *readKeyFromMemory(char *ptr, int len, int which) +{ + BIO *in = BIO_new_mem_buf(ptr, len); + RSA *rsa = NULL; + + if (!in) { + PyErr_SetString(PyExc_MemoryError, "Unable to create a BIO object"); + return NULL; + } + + rsa = readKeyFromBio(in, which); + if (rsa == NULL) + PyErr_SetString(PyExc_IOError, "Unable to get public RSA key from memory"); + + (void)BIO_free_all(in); + + if (rsa) { + int strength = BN_num_bits(rsa->n); + if (strength < MINBITS || strength > MAXBITS) { + RSA_free(rsa); + rsa = NULL; + PyErr_SetString(keySizeError, "Invalid key strength"); + } + } + return rsa; +} + static RSA *readKey(const char *fn, int which) { RSA *rsa = NULL; - EVP_PKEY *pkey = NULL; BIO *in = BIO_new(BIO_s_file()); if (!in) { @@ -92,15 +135,8 @@ } if (BIO_read_filename(in, fn) == 1) { - if (which == PUBLIC) - pkey=PEM_read_bio_PUBKEY(in, NULL, NULL, NULL); - else - pkey=PEM_read_bio_PrivateKey(in, NULL, NULL, NULL); - - if (pkey) { - rsa = EVP_PKEY_get1_RSA(pkey); - EVP_PKEY_free(pkey); - } else + rsa = readKeyFromBio(in, which); + if (rsa == NULL) PyErr_SetString(PyExc_IOError, "Unable to get public RSA key from file"); } else PyErr_SetString(PyExc_IOError, "Unable to read from file supplied"); @@ -193,6 +229,90 @@ return Py_None; } +/* This function gets a pointer to the RSA object representing the + * key associated with the certificate. We simply get a pointer rather + * than duplicating presently and rely on the internal reference + * counting of OpenSSL to ensure it's always available to us. + */ +static PyObject * +fromX509(PyObject *self, PyObject *args) +{ + X509 *cert = NULL; + RSA *rsa = NULL; + EVP_PKEY *pkey = NULL; + PyObject *pCert = NULL; + + if (!PyArg_ParseTuple(args, "O", &pCert)) + return NULL; + cert = (X509 *)PyCObject_AsVoidPtr(pCert); + + pkey = X509_get_pubkey(cert); + if (!pkey) { + PyErr_SetString(PyExc_ValueError, "Invalid certificate object supplied"); + return NULL; + } + + if (pkey) { + if (pkey->type == EVP_PKEY_RSA) { + rsa = EVP_PKEY_get1_RSA(pkey); + /* When we call EVP_PKEY_free() it will decrement the ref counter + * for the object pointer we have stored in rsa, so we need to + * increment the reference ourselves so it stays in memory and isn't + * released at this point. + */ + if (rsa) + RSA_up_ref(rsa); + } + EVP_PKEY_free(pkey); + if (rsa) + return PyCObject_FromVoidPtr(rsa, delrsa); + } + PyErr_SetString(PyExc_ValueError, "No RSA key found in certificate"); + return NULL; +} + +static PyObject * +fromX509_REQ(PyObject *self, PyObject *args) +{ + void *tmp = NULL; + X509_REQ *req = NULL; + EVP_PKEY *pkey = NULL; + RSA *rsa = NULL; + + if (! PyArg_ParseTuple(args, "O", &tmp)) + return NULL; + + req = (X509_REQ *)PyCObject_AsVoidPtr(tmp); + if (!req) { + PyErr_SetString(PyExc_TypeError, "Invalid X509_REQ object passed"); + return NULL; + } + + pkey = X509_REQ_get_pubkey(req); + if (pkey) { + if (pkey->type == EVP_PKEY_RSA) { + rsa = EVP_PKEY_get1_RSA(pkey); + /* When we call EVP_PKEY_free() it will decrement the ref counter + * for the object pointer we have stored in rsa, so we need to + * increment the reference ourselves so it stays in memory and isn't + * released at this point. + */ + if (rsa) + RSA_up_ref(rsa); + } + EVP_PKEY_free(pkey); + if (rsa) + return PyCObject_FromVoidPtr(rsa, delrsa); + } + PyErr_SetString(PyExc_ValueError, "No RSA key found within CSR object"); + return NULL; +} + + + + + + /* Read an RSA key from a file. when we read it in we also need to * check the key size, as we don't allow keys with less than MINBITS * or greater than MAXBITS. @@ -230,6 +350,26 @@ } static PyObject * +readRSAPublicFromMemory(PyObject *self, PyObject *args) +{ + RSA *rsa = NULL; + char *ptr = NULL; + int len = 0; + + if (! PyArg_ParseTuple(args, "s#", &ptr, &len)) + return NULL; + if (len == 0) { + PyErr_SetString(PyExc_ValueError, "Invalid length of buffer!"); + return NULL; + } + rsa = readKeyFromMemory(ptr, len, PUBLIC); + if (!rsa) + return NULL; + + return PyCObject_FromVoidPtr(rsa, delrsa); +} + +static PyObject * writeRSAPrivate(PyObject *self, PyObject *args) { int i = 0; @@ -323,8 +463,11 @@ static PyMethodDef RSAMethods[] = { { "genrsa", genrsa, METH_VARARGS, "Generate an RSA Key" }, + { "fromX509", fromX509, METH_VARARGS, "Get an RSA key from an X509 certificate" }, + { "fromCSR", fromX509_REQ, METH_VARARGS, "Get an RSA key from an X509 request" }, { "read", readRSA, METH_VARARGS, "Read an RSA private key from a file" }, { "readPublic", readRSAPublic, METH_VARARGS, "Read an RSA public key from a file" }, + { "fromMemoryPublic", readRSAPublicFromMemory, METH_VARARGS, "Read an RSA key from memory" }, { "writePrivate", writeRSAPrivate, METH_VARARGS, "Write a private RSA key to a file" }, { "writePublic", writeRSAPublic, METH_VARARGS, "Write public key to file" }, { "getPublicKey", getRSAPublic, METH_VARARGS, "Get public key as an object" }, Modified: labs/badca/openssl/setup.py.in URL: http://svn.apache.org/viewvc/labs/badca/openssl/setup.py.in?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/openssl/setup.py.in (original) +++ labs/badca/openssl/setup.py.in Thu Dec 13 06:13:58 2007 @@ -25,8 +25,17 @@ sources = ['certmodule.c'] ) +testModule = Extension('test', + extra_link_args = ['-shared'], + include_dirs= ['@openssl_INCDIR@'], + library_dirs= ['@openssl_LIBDIR@'], + libraries = [@openssl_LIBSONLY@], + runtime_library_dirs = ['@openssl_LIBDIR@'], + sources = ['testmodule.c'] + ) + setup (name = 'OpenSSL', version = '0.1', description = 'OpenSSL Wrapper Package', - ext_modules = [rsaModule, csrModule, certModule] + ext_modules = [rsaModule, csrModule, certModule, testModule] ) Added: labs/badca/openssl/testmodule.c URL: http://svn.apache.org/viewvc/labs/badca/openssl/testmodule.c?rev=603922&view=auto ============================================================================== --- labs/badca/openssl/testmodule.c (added) +++ labs/badca/openssl/testmodule.c Thu Dec 13 06:13:58 2007 @@ -0,0 +1,126 @@ +#include + +#include +#include +#include +#include +#include +#include +#include + +#define SERIAL_RAND_BITS 128 + +static void delcsr(void *ptr) +{ + X509_REQ_free((X509_REQ *)ptr); +} + +static void delcert(void *ptr) +{ + X509_free((X509 *)ptr); +} + +static void delrsa(void *ptr) +{ + RSA_free((RSA *)ptr); +} + + +/*********************************************************************** + ** + ** Functions below this header are referenced from outside this file, + ** i.e. they appear in the list of methods exported from the module + ** + **********************************************************************/ +static PyObject * +readCert(PyObject *self, PyObject *args) +{ + X509 *cert = NULL; + char *fn = NULL; + BIO *in = NULL; + PyObject *rv = NULL; + + if (!PyArg_ParseTuple(args, "z", &fn)) + return NULL; + + if (!fn) { + PyErr_SetString(PyExc_ValueError, "Filename MUST be supplied"); + return NULL; + } + + in = BIO_new(BIO_s_file()); + if (!in) { + PyErr_SetString(PyExc_MemoryError, "failed to create a BIO"); + return NULL; + } + BIO_read_filename(in, fn); + cert = PEM_read_bio_X509_AUX(in, NULL, NULL, NULL); + (void) BIO_free_all(in); + + if (cert) + return PyCObject_FromVoidPtr(cert, delcert); + + PyErr_SetString(PyExc_IOError, "Failed to read certificate file"); + return rv; +} + +static PyObject * +readCSR(PyObject *self, PyObject *args) +{ + X509_REQ *req=NULL; + BIO *in = NULL; + char *fn = NULL; + + if (! PyArg_ParseTuple(args, "s", &fn)) + return NULL; + + if (! fn) + return NULL; + + in = BIO_new(BIO_s_file()); + if (!in) { + PyErr_SetString(PyExc_MemoryError, "Unable to create a BIO object"); + return NULL; + } + + if (BIO_read_filename(in, fn) <= 0) { + BIO_free_all(in); + PyErr_SetString(PyExc_IOError, "Unable to read CSR from filename"); + return NULL; + } + + /* We expect the CSR to be in PEM format, so try that first... */ + req = PEM_read_bio_X509_REQ(in, NULL, NULL, NULL); + /* If that fails, see if it was in ASN1 format */ + if (!req) + req = d2i_X509_REQ_bio(in, NULL); + + BIO_free_all(in); + + if (!req) { + PyErr_SetString(PyExc_IOError, "Unable to get REQ object from file"); + return NULL; + } + return PyCObject_FromVoidPtr(req, delcsr); +} + + +static PyMethodDef TestMethods[] = { + { "readCert", readCert, METH_VARARGS, "Read a certificate from a file" }, + { "readCSR", readCSR, METH_VARARGS, "Read a certificate request from a file" }, + { NULL, NULL, 0, NULL }, +}; + +PyMODINIT_FUNC +inittest(void) +{ + PyObject *mod = NULL; + + /* init OpenSSL */ + CRYPTO_malloc_init(); + ERR_load_crypto_strings(); + OpenSSL_add_all_algorithms(); + + mod = Py_InitModule("test", TestMethods); +} + Modified: labs/badca/tests/01KeysTestCase.py URL: http://svn.apache.org/viewvc/labs/badca/tests/01KeysTestCase.py?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/tests/01KeysTestCase.py (original) +++ labs/badca/tests/01KeysTestCase.py Thu Dec 13 06:13:58 2007 @@ -1,6 +1,7 @@ import unittest from BaDCA import Keys +from BaDCA.Testing import * class BaDCAKeysTestCase(unittest.TestCase): obj = None @@ -12,12 +13,12 @@ else: self.Reset() - def test01(self): - """ Testing creation of keys of different strengths """ - for r in ( 1024, 2048, 4096 ): - assert self.obj.create(r) == 1, \ - "Unable to create key of strength " + str(r) - assert self.obj.bits == r, "Incorrect strength key created" +# def test01(self): +# """ Testing creation of keys of different strengths """ +# for r in ( 1024, 2048, 4096 ): +# assert self.obj.create(r) == 1, \ +# "Unable to create key of strength " + str(r) +# assert self.obj.bits == r, "Incorrect strength key created" def test02(self): """ Checking we accept only keys of correct strengths """ @@ -50,6 +51,36 @@ assert self.obj.addSearchDirectory('tests/keys/private') == 1, \ "Unable to add search directory to key" assert self.obj.hasPrivate(), "Private key not available" + + def test07(self): + """ Test extracting a key from a certificate """ + certObj = readCertificate('tests/certs/test1.pem') + assert certObj is not None, "Failed to read certificate!" + self.obj = Keys.RSAKey(certificate = certObj) + assert self.obj.isValid(), "Invalid object created from certificate" + assert self.obj.hasPublic(), "Failed to process key from certificate" + assert self.obj.hasPrivate() is False, \ + "The private key is available?" + + def test08(self): + """ Test extracting a key from a CSR """ + csrObj = readCSR('tests/csr/test1.csr') + assert csrObj is not None, "Failed to read CSR!" + self.obj = Keys.RSAKey(csr = csrObj) + assert self.obj.isValid(), "Invalid object created from CSR" + assert self.obj.hasPublic(), "Failed to process key from CSR" + assert self.obj.hasPrivate() is False, \ + "The private key is available?" + + def test09(self): + """ Test reading from memory """ + f = open('tests/keys/public/test3.public.key', "r") + txt = f.read() + f.close() + assert len(txt) > 0, "Failed to read text!" + assert self.obj.readPublicKeyFromMemory(txt) == 1, \ + "Failed to create key from memory" + assert self.obj.hasPublic(), "Error creating key" if __name__ == "__main__": unittest.main() Modified: labs/badca/tests/03CertTestCase.py URL: http://svn.apache.org/viewvc/labs/badca/tests/03CertTestCase.py?rev=603922&r1=603921&r2=603922&view=diff ============================================================================== --- labs/badca/tests/03CertTestCase.py (original) +++ labs/badca/tests/03CertTestCase.py Thu Dec 13 06:13:58 2007 @@ -22,8 +22,8 @@ """ Can we get a public key from a certificate? """ assert self.obj.readFromFile('tests/certs/test1.pem') == 1, \ "Failed to read the Certificate" -# key = self.obj.getKey() -# assert key is not None, "Failed to get public key from certificate" + key = self.obj.getKey() + assert key is not None, "Failed to get public key from certificate" def test03(self): """ Can we get information from a certificate? """ @@ -112,8 +112,8 @@ assert self.obj.readFromFile('tests/certs/ca1.pem') == 1, \ "Failed to read the CA certificate" self.obj.addKeyPath('tests/keys/private') - print str(self.obj.info) - assert self.obj.key.hasPrivate(), "Failed to find private key!" + key = self.obj.getKey() + assert key.hasPrivate(), "Failed to find private key!" newcert = self.obj.signRequest(csr) assert newcert is not None, \ "Failed to create a certificate object from the CSR" --------------------------------------------------------------------- To unsubscribe, e-mail: commits-unsubscribe@labs.apache.org For additional commands, e-mail: commits-help@labs.apache.org