📄 sslcontext.c
字号:
lookup = X509_STORE_add_lookup(c->crl, X509_LOOKUP_file());
if (lookup == NULL) {
ERR_error_string(ERR_get_error(), err);
X509_STORE_free(c->crl);
c->crl = NULL;
tcn_Throw(e, "Lookup failed for file %s (%s)", J2S(file), err);
goto cleanup;
}
X509_LOOKUP_load_file(lookup, J2S(file), X509_FILETYPE_PEM);
}
if (J2S(path)) {
lookup = X509_STORE_add_lookup(c->crl, X509_LOOKUP_hash_dir());
if (lookup == NULL) {
ERR_error_string(ERR_get_error(), err);
X509_STORE_free(c->crl);
c->crl = NULL;
tcn_Throw(e, "Lookup failed for path %s (%s)", J2S(file), err);
goto cleanup;
}
X509_LOOKUP_add_dir(lookup, J2S(path), X509_FILETYPE_PEM);
}
rv = JNI_TRUE;
cleanup:
TCN_FREE_CSTRING(file);
TCN_FREE_CSTRING(path);
return rv;
}
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificateChainFile)(TCN_STDARGS, jlong ctx,
jstring file,
jboolean skipfirst)
{
tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
jboolean rv = JNI_FALSE;
TCN_ALLOC_CSTRING(file);
UNREFERENCED(o);
TCN_ASSERT(ctx != 0);
if (!J2S(file))
return JNI_FALSE;
if (SSL_CTX_use_certificate_chain(c->ctx, J2S(file), skipfirst) > 0)
rv = JNI_TRUE;
TCN_FREE_CSTRING(file);
return rv;
}
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCACertificate)(TCN_STDARGS,
jlong ctx,
jstring file,
jstring path)
{
tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
jboolean rv = JNI_TRUE;
TCN_ALLOC_CSTRING(file);
TCN_ALLOC_CSTRING(path);
UNREFERENCED(o);
TCN_ASSERT(ctx != 0);
if (file == NULL && path == NULL)
return JNI_FALSE;
/*
* Configure Client Authentication details
*/
if (!SSL_CTX_load_verify_locations(c->ctx,
J2S(file), J2S(path))) {
char err[256];
ERR_error_string(ERR_get_error(), err);
tcn_Throw(e, "Unable to configure locations "
"for client authentication (%s)", err);
rv = JNI_FALSE;
goto cleanup;
}
c->store = SSL_CTX_get_cert_store(c->ctx);
if (c->mode) {
STACK_OF(X509_NAME) *ca_certs;
c->ca_certs++;
ca_certs = SSL_CTX_get_client_CA_list(c->ctx);
if (ca_certs == NULL) {
SSL_load_client_CA_file(J2S(file));
if (ca_certs != NULL)
SSL_CTX_set_client_CA_list(c->ctx, (STACK *)ca_certs);
}
else {
if (!SSL_add_file_cert_subjects_to_stack((STACK *)ca_certs, J2S(file)))
ca_certs = NULL;
}
if (ca_certs == NULL && c->verify_mode == SSL_CVERIFY_REQUIRE) {
/*
* Give a warning when no CAs were configured but client authentication
* should take place. This cannot work.
*/
BIO_printf(c->bio_os,
"[WARN] Oops, you want to request client "
"authentication, but no CAs are known for "
"verification!?");
}
}
cleanup:
TCN_FREE_CSTRING(file);
TCN_FREE_CSTRING(path);
return rv;
}
TCN_IMPLEMENT_CALL(void, SSLContext, setShutdownType)(TCN_STDARGS, jlong ctx,
jint type)
{
tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
UNREFERENCED_STDARGS;
TCN_ASSERT(ctx != 0);
c->shutdown_type = type;
}
TCN_IMPLEMENT_CALL(void, SSLContext, setVerify)(TCN_STDARGS, jlong ctx,
jint level, jint depth)
{
tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
int verify = SSL_VERIFY_NONE;
UNREFERENCED(o);
TCN_ASSERT(ctx != 0);
c->verify_mode = level;
if (c->verify_mode == SSL_CVERIFY_UNSET)
c->verify_mode = SSL_CVERIFY_NONE;
if (depth > 0)
c->verify_depth = depth;
/*
* Configure callbacks for SSL context
*/
if (c->verify_mode == SSL_CVERIFY_REQUIRE)
verify |= SSL_VERIFY_PEER_STRICT;
if ((c->verify_mode == SSL_CVERIFY_OPTIONAL) ||
(c->verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
verify |= SSL_VERIFY_PEER;
if (!c->store) {
if (SSL_CTX_set_default_verify_paths(c->ctx)) {
c->store = SSL_CTX_get_cert_store(c->ctx);
X509_STORE_set_flags(c->store, 0);
}
else {
/* XXX: See if this is fatal */
}
}
SSL_CTX_set_verify(c->ctx, verify, SSL_callback_SSL_verify);
}
static EVP_PKEY *load_pem_key(tcn_ssl_ctxt_t *c, const char *file)
{
BIO *bio = NULL;
EVP_PKEY *key = NULL;
void *cb_data = c->cb_data;
if ((bio = BIO_new(BIO_s_file())) == NULL) {
return NULL;
}
if (BIO_read_filename(bio, file) <= 0) {
BIO_free(bio);
return NULL;
}
if (!cb_data)
cb_data = &tcn_password_callback;
key = PEM_read_bio_PrivateKey(bio, NULL,
(pem_password_cb *)SSL_password_callback,
cb_data);
BIO_free(bio);
return key;
}
static X509 *load_pem_cert(const char *file)
{
BIO *bio = NULL;
X509 *cert = NULL;
if ((bio = BIO_new(BIO_s_file())) == NULL) {
return NULL;
}
if (BIO_read_filename(bio, file) <= 0) {
BIO_free(bio);
return NULL;
}
cert = PEM_read_bio_X509_AUX(bio, NULL,
(pem_password_cb *)SSL_password_callback,
NULL);
BIO_free(bio);
return cert;
}
TCN_IMPLEMENT_CALL(void, SSLContext, setRandom)(TCN_STDARGS, jlong ctx,
jstring file)
{
tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
TCN_ALLOC_CSTRING(file);
TCN_ASSERT(ctx != 0);
UNREFERENCED(o);
if (J2S(file))
c->rand_file = apr_pstrdup(c->pool, J2S(file));
TCN_FREE_CSTRING(file);
}
TCN_IMPLEMENT_CALL(jboolean, SSLContext, setCertificate)(TCN_STDARGS, jlong ctx,
jstring cert, jstring key,
jstring password, jint idx)
{
tcn_ssl_ctxt_t *c = J2P(ctx, tcn_ssl_ctxt_t *);
jboolean rv = JNI_TRUE;
TCN_ALLOC_CSTRING(cert);
TCN_ALLOC_CSTRING(key);
TCN_ALLOC_CSTRING(password);
const char *key_file, *cert_file;
char err[256];
UNREFERENCED(o);
TCN_ASSERT(ctx != 0);
if (idx < 0 || idx >= SSL_AIDX_MAX) {
/* TODO: Throw something */
rv = JNI_FALSE;
goto cleanup;
}
if (J2S(password)) {
if (!c->cb_data)
c->cb_data = &tcn_password_callback;
strncpy(c->cb_data->password, J2S(password), SSL_MAX_PASSWORD_LEN);
c->cb_data->password[SSL_MAX_PASSWORD_LEN-1] = '\0';
}
key_file = J2S(key);
cert_file = J2S(cert);
if (!key_file)
key_file = cert_file;
if (!key_file) {
tcn_Throw(e, "No Certificate file specified");
rv = JNI_FALSE;
goto cleanup;
}
if ((c->keys[idx] = load_pem_key(c, key_file)) == NULL) {
ERR_error_string(ERR_get_error(), err);
tcn_Throw(e, "Unable to load certificate key %s (%s)",
key_file, err);
rv = JNI_FALSE;
goto cleanup;
}
if ((c->certs[idx] = load_pem_cert(cert_file)) == NULL) {
ERR_error_string(ERR_get_error(), err);
tcn_Throw(e, "Unable to load certificate %s (%s)",
cert_file, err);
rv = JNI_FALSE;
goto cleanup;
}
if (SSL_CTX_use_certificate(c->ctx, c->certs[idx]) <= 0) {
ERR_error_string(ERR_get_error(), err);
tcn_Throw(e, "Error setting certificate (%s)", err);
rv = JNI_FALSE;
goto cleanup;
}
if (SSL_CTX_use_PrivateKey(c->ctx, c->keys[idx]) <= 0) {
ERR_error_string(ERR_get_error(), err);
tcn_Throw(e, "Error setting private key (%s)", err);
rv = JNI_FALSE;
goto cleanup;
}
if (SSL_CTX_check_private_key(c->ctx) <= 0) {
ERR_error_string(ERR_get_error(), err);
tcn_Throw(e, "Private key does not match the certificate public key (%s)",
err);
rv = JNI_FALSE;
goto cleanup;
}
cleanup:
TCN_FREE_CSTRING(cert);
TCN_FREE_CSTRING(key);
TCN_FREE_CSTRING(password);
return rv;
}
#else
/* OpenSSL is not supported
* If someday we make OpenSSL optional
* APR_ENOTIMPL will go here
*/
#error "No OpenSSL Toolkit defined."
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -