in native/src/sslcontext.c [1782:1842]
static int SSL_cert_verify(X509_STORE_CTX *ctx, void *arg) {
/* Get Apache context back through OpenSSL context */
SSL *ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
tcn_ssl_ctxt_t *c = SSL_get_app_data2(ssl);
// Get a stack of all certs in the chain
STACK_OF(X509) *sk = X509_STORE_CTX_get0_untrusted(ctx);
int len = sk_X509_num(sk);
unsigned i;
X509 *cert;
int length;
unsigned char *buf;
JNIEnv *e;
jbyteArray array;
jbyteArray bArray;
const char *authMethod;
jstring authMethodString;
jboolean result;
int r;
tcn_get_java_env(&e);
// Create the byte[][] array that holds all the certs
array = (*e)->NewObjectArray(e, len, byteArrayClass, NULL);
for(i = 0; i < len; i++) {
cert = (X509*) sk_X509_value(sk, i);
buf = NULL;
length = i2d_X509(cert, &buf);
if (length < 0) {
// In case of error just return an empty byte[][]
array = (*e)->NewObjectArray(e, 0, byteArrayClass, NULL);
// We need to delete the local references so we not leak memory as this method is called via callback.
OPENSSL_free(buf);
break;
}
bArray = (*e)->NewByteArray(e, length);
(*e)->SetByteArrayRegion(e, bArray, 0, length, (jbyte*) buf);
(*e)->SetObjectArrayElement(e, array, i, bArray);
// Delete the local reference as we not know how long the chain is and local references are otherwise
// only freed once jni method returns.
(*e)->DeleteLocalRef(e, bArray);
OPENSSL_free(buf);
}
authMethod = SSL_authentication_method(ssl);
authMethodString = (*e)->NewStringUTF(e, authMethod);
result = (*e)->CallBooleanMethod(e, c->verifier, c->verifier_method, P2J(ssl), array,
authMethodString);
r = result == JNI_TRUE ? 1 : 0;
// We need to delete the local references so we not leak memory as this method is called via callback.
(*e)->DeleteLocalRef(e, authMethodString);
(*e)->DeleteLocalRef(e, array);
return r;
}