/* * Globally defined verify callback * * Arguments: ok - True everything is OK "so far", false otherwise * x509_ctx - Contains the certificate being checked, the current * error number and depth, and the Connection we're * dealing with * Returns: True if everything is okay, false otherwise */ static int global_verify_callback( int ok, X509_STORE_CTX * x509_ctx ) { PyObject *argv, *ret; SSL *ssl; ssl_ConnectionObj *conn; crypto_X509Obj *cert; X509 *x509; int errnum = X509_STORE_CTX_get_error(x509_ctx); int errdepth = X509_STORE_CTX_get_error_depth(x509_ctx); #ifdef GSI_HANDSHAKE_DEBUG logMsg( 0, "GVC %d errnum %d errdepth", errnum, errdepth ); #endif ssl = (SSL *) X509_STORE_CTX_get_app_data(x509_ctx); conn = (ssl_ConnectionObj *) SSL_get_app_data(ssl); OBJ_END_THREADS( conn ); Py_INCREF( conn ); if ( conn->context->verify_callback != Py_None ) { x509 = X509_STORE_CTX_get_current_cert(x509_ctx); cert = crypto_X509_New(x509, 0); argv = Py_BuildValue("(OOiii)", (PyObject *) conn, (PyObject *) cert, errnum, errdepth, ok); Py_DECREF(cert); /* We need to get back our thread state before calling the callback */ ret = PyEval_CallObject(conn->context->verify_callback, argv); Py_DECREF(argv); if ( ret == NULL ) { ok = 0; } else { if ( PyObject_IsTrue(ret) ) { X509_STORE_CTX_set_error(x509_ctx, X509_V_OK); ok = 1; } else ok = 0; Py_DECREF(ret); } } //Set the remove verification flag in the end if ( errdepth == 0 && ok ) { conn->remoteCertVerified = 1; } Py_DECREF( conn ); OBJ_BEGIN_THREADS( conn ); return ok; }
/* * Constructor for PKCS12 objects, never called by Python code directly. * The strategy for this object is to create all the Python objects * corresponding to the cert/key/CA certs right away * * Arguments: p12 - A "real" PKCS12 object or NULL * passphrase - Passphrase to use when decrypting the PKCS12 object * Returns: The newly created PKCS12 object */ crypto_PKCS12Obj * crypto_PKCS12_New(PKCS12 *p12, char *passphrase) { crypto_PKCS12Obj *self = NULL; PyObject *cacertobj = NULL; unsigned char *alias_str; int alias_len; X509 *cert = NULL; EVP_PKEY *pkey = NULL; STACK_OF(X509) *cacerts = NULL; int i, cacert_count = 0; /* allocate space for the CA cert stack */ if((cacerts = sk_X509_new_null()) == NULL) { goto error; /* out of memory? */ } /* parse the PKCS12 lump */ if (p12) { if (!PKCS12_parse(p12, passphrase, &pkey, &cert, &cacerts)) { /* * If PKCS12_parse fails, and it allocated cacerts, it seems to * free cacerts, but not re-NULL the pointer. Zounds! Make sure * it is re-set to NULL here, else we'll have a double-free below. */ cacerts = NULL; exception_from_error_queue(crypto_Error); goto error; } else { /* * OpenSSL 1.0.0 sometimes leaves an X509_check_private_key error in * the queue for no particular reason. This error isn't interesting * to anyone outside this function. It's not even interesting to * us. Get rid of it. */ flush_error_queue(); } } if (!(self = PyObject_GC_New(crypto_PKCS12Obj, &crypto_PKCS12_Type))) { goto error; } /* client certificate and friendlyName */ if (cert == NULL) { Py_INCREF(Py_None); self->cert = Py_None; Py_INCREF(Py_None); self->friendlyname = Py_None; } else { if ((self->cert = (PyObject *)crypto_X509_New(cert, 1)) == NULL) { goto error; } /* Now we need to extract the friendlyName of the PKCS12 * that was stored by PKCS_parse() in the alias of the * certificate. */ alias_str = X509_alias_get0(cert, &alias_len); if (alias_str) { self->friendlyname = Py_BuildValue(BYTESTRING_FMT "#", alias_str, alias_len); if (!self->friendlyname) { /* * XXX Untested */ goto error; } /* success */ } else { Py_INCREF(Py_None); self->friendlyname = Py_None; } } /* private key */ if (pkey == NULL) { Py_INCREF(Py_None); self->key = Py_None; } else { if ((self->key = (PyObject *)crypto_PKey_New(pkey, 1)) == NULL) goto error; } /* CA certs */ cacert_count = sk_X509_num(cacerts); if (cacert_count <= 0) { Py_INCREF(Py_None); self->cacerts = Py_None; } else { if ((self->cacerts = PyTuple_New(cacert_count)) == NULL) { goto error; } for (i = 0; i < cacert_count; i++) { cert = sk_X509_value(cacerts, i); if ((cacertobj = (PyObject *)crypto_X509_New(cert, 1)) == NULL) { goto error; } PyTuple_SET_ITEM(self->cacerts, i, cacertobj); } } sk_X509_free(cacerts); /* Don't free the certs, just the container. */ PyObject_GC_Track(self); return self; error: sk_X509_free(cacerts); /* NULL safe. Free just the container. */ if (self) { crypto_PKCS12_clear(self); PyObject_GC_Del(self); } return NULL; }