Handle error cases of PySequence_Length() and PySequence_GetItem(). Add an test case for zero length CA.
diff --git a/src/crypto/pkcs12.c b/src/crypto/pkcs12.c
index 7a6a95c..6f1b697 100644
--- a/src/crypto/pkcs12.c
+++ b/src/crypto/pkcs12.c
@@ -139,18 +139,21 @@
{
PyObject *cacerts;
static char *kwlist[] = {"cacerts", NULL};
- int i; /* Py_ssize_t for Python 2.5+ */
+ int i, len; /* Py_ssize_t for Python 2.5+ */
if (!PyArg_ParseTupleAndKeywords(args, keywds, "O:set_ca_certificates",
kwlist, &cacerts))
return NULL;
if (cacerts == Py_None) {
/* We are good. */
- } else if (PySequence_Check(cacerts)) { /* is iterable */
+ } else if ((len = PySequence_Length(cacerts)) >= 0) { /* is iterable */
/* Check is's a simple list filled only with X509 objects. */
- for(i = 0;i < PySequence_Length(cacerts);i++) { /* For each CA cert */
+ for(i = 0;i < len;i++) { /* For each CA cert */
PyObject *obj;
obj = PySequence_GetItem(cacerts, i);
+ if(obj == NULL) {
+ break;
+ }
if (PyObject_Type(obj) != (PyObject *) &crypto_X509_Type) {
Py_DECREF(obj);
PyErr_SetString(PyExc_TypeError, "cacerts iterable must only contain X509Type");
diff --git a/test/test_crypto.py b/test/test_crypto.py
index 684ae06..528fde4 100644
--- a/test/test_crypto.py
+++ b/test/test_crypto.py
@@ -1005,6 +1005,20 @@
#p12 = load_pkcs12(dumped_p12, passwd)
+ def test_zero_len_list_for_ca(self):
+ """
+ Export a PKCS12 with a zero length list for CA.
+ Verify it with the openssl program.
+ """
+ passwd = 'Hobie 18'
+ p12 = self.gen_pkcs12( server_cert_pem, server_key_pem )
+ p12.set_ca_certificates( [] )
+ self.assertEqual((), p12.get_ca_certificates())
+ dumped_p12 = p12.export(passphrase=passwd, iter=3)
+ self.check_recovery(dumped_p12, key=server_key_pem,
+ cert=server_cert_pem, passwd=passwd, )
+
+
def test_export_without_args(self):
"""
Run L{OpenSSL.crypto.PKCS12.export} without any