diff -C 3 -r trunk-orig/OpenSSL/crypto/crypto.c trunk/OpenSSL/crypto/crypto.c *** trunk-orig/OpenSSL/crypto/crypto.c 2013-03-07 10:18:54.000000000 +0100 --- trunk/OpenSSL/crypto/crypto.c 2013-03-07 10:20:04.000000000 +0100 *************** *** 728,733 **** --- 728,778 ---- return Py_None; } + static char crypto_verify_cert_doc[] = "\n\ + Verify a certificate signature\n\ + \n\ + :param issuer: issuer certificate (X509 object)\n\ + :param subject: signed certificate (X509 object)\n\ + :return: None if the signature is correct, raise exception otherwise\n\ + "; + + static PyObject * + crypto_verify_cert(PyObject *spam, PyObject *args) { + crypto_X509Obj *issuer, *subject; + int err, err_depth; + + if (!PyArg_ParseTuple(args, "O!O!:verify_cert", &crypto_X509_Type, &issuer, &crypto_X509_Type, &subject)) { + return NULL; + } + + X509_STORE *store = X509_STORE_new(); + X509_STORE_add_cert(store, issuer->x509); + + X509_STORE_CTX *ctx = X509_STORE_CTX_new(); + X509_STORE_CTX_init(ctx, store, subject->x509, NULL); + + err = X509_verify_cert(ctx); + err_depth = X509_STORE_CTX_get_error_depth(ctx); + + X509_STORE_CTX_cleanup(ctx); + X509_STORE_CTX_free(ctx); + X509_STORE_free(store); + + /* + * Don't accept verification failure at the leaf level, but DO accept + * failure one level above (this will always fail if the issuer is not a + * root certificate) + * */ + if ((err != 1) && (err_depth == 0)) { + exception_from_error_queue(crypto_Error); + return NULL; + } + + Py_INCREF(Py_None); + return Py_None; + } + + /* Methods in the OpenSSL.crypto module (i.e. none) */ static PyMethodDef crypto_methods[] = { /* Module functions */ *************** *** 742,747 **** --- 787,793 ---- { "load_pkcs12", (PyCFunction)crypto_load_pkcs12, METH_VARARGS, crypto_load_pkcs12_doc }, { "sign", (PyCFunction)crypto_sign, METH_VARARGS, crypto_sign_doc }, { "verify", (PyCFunction)crypto_verify, METH_VARARGS, crypto_verify_doc }, + { "verify_cert", (PyCFunction)crypto_verify_cert, METH_VARARGS, crypto_verify_cert_doc }, { "X509_verify_cert_error_string", (PyCFunction)crypto_X509_verify_cert_error_string, METH_VARARGS, crypto_X509_verify_cert_error_string_doc }, { "_exception_from_error_queue", (PyCFunction)crypto_exception_from_error_queue, METH_NOARGS, crypto_exception_from_error_queue_doc }, { NULL, NULL }