📄 ssl.c
字号:
return (jint)APR_SUCCESS;
}
TCN_IMPLEMENT_CALL(jboolean, SSL, randLoad)(TCN_STDARGS, jstring file)
{
TCN_ALLOC_CSTRING(file);
int r;
UNREFERENCED(o);
r = SSL_rand_seed(J2S(file));
TCN_FREE_CSTRING(file);
return r ? JNI_TRUE : JNI_FALSE;
}
TCN_IMPLEMENT_CALL(jboolean, SSL, randSave)(TCN_STDARGS, jstring file)
{
TCN_ALLOC_CSTRING(file);
int r;
UNREFERENCED(o);
r = ssl_rand_save_file(J2S(file));
TCN_FREE_CSTRING(file);
return r ? JNI_TRUE : JNI_FALSE;
}
TCN_IMPLEMENT_CALL(jboolean, SSL, randMake)(TCN_STDARGS, jstring file,
jint length, jboolean base64)
{
TCN_ALLOC_CSTRING(file);
int r;
UNREFERENCED(o);
r = ssl_rand_make(J2S(file), length, base64);
TCN_FREE_CSTRING(file);
return r ? JNI_TRUE : JNI_FALSE;
}
TCN_IMPLEMENT_CALL(void, SSL, randSet)(TCN_STDARGS, jstring file)
{
TCN_ALLOC_CSTRING(file);
UNREFERENCED(o);
if (J2S(file)) {
ssl_global_rand_file = apr_pstrdup(tcn_global_pool, J2S(file));
}
TCN_FREE_CSTRING(file);
}
/* OpenSSL Java Stream BIO */
typedef struct {
int refcount;
apr_pool_t *pool;
tcn_callback_t cb;
} BIO_JAVA;
static apr_status_t generic_bio_cleanup(void *data)
{
BIO *b = (BIO *)data;
if (b) {
BIO_free(b);
}
return APR_SUCCESS;
}
void SSL_BIO_close(BIO *bi)
{
if (bi == NULL)
return;
if (bi->ptr != NULL && (bi->flags & SSL_BIO_FLAG_CALLBACK)) {
BIO_JAVA *j = (BIO_JAVA *)bi->ptr;
j->refcount--;
if (j->refcount == 0) {
if (j->pool)
apr_pool_cleanup_run(j->pool, bi, generic_bio_cleanup);
else
BIO_free(bi);
}
}
else
BIO_free(bi);
}
void SSL_BIO_doref(BIO *bi)
{
if (bi == NULL)
return;
if (bi->ptr != NULL && (bi->flags & SSL_BIO_FLAG_CALLBACK)) {
BIO_JAVA *j = (BIO_JAVA *)bi->ptr;
j->refcount++;
}
}
static int jbs_new(BIO *bi)
{
BIO_JAVA *j;
if ((j = OPENSSL_malloc(sizeof(BIO_JAVA))) == NULL)
return 0;
j->pool = NULL;
j->refcount = 1;
bi->shutdown = 1;
bi->init = 0;
bi->num = -1;
bi->ptr = (char *)j;
return 1;
}
static int jbs_free(BIO *bi)
{
if (bi == NULL)
return 0;
if (bi->ptr != NULL) {
BIO_JAVA *j = (BIO_JAVA *)bi->ptr;
if (bi->init) {
JNIEnv *e = NULL;
bi->init = 0;
tcn_get_java_env(&e);
TCN_UNLOAD_CLASS(e, j->cb.obj);
}
OPENSSL_free(bi->ptr);
}
bi->ptr = NULL;
return 1;
}
static int jbs_write(BIO *b, const char *in, int inl)
{
jint ret = 0;
if (b->init && in != NULL) {
BIO_JAVA *j = (BIO_JAVA *)b->ptr;
JNIEnv *e = NULL;
jbyteArray jb = (*e)->NewByteArray(e, inl);
tcn_get_java_env(&e);
if (!(*e)->ExceptionOccurred(e)) {
(*e)->SetByteArrayRegion(e, jb, 0, inl, (jbyte *)in);
ret = (*e)->CallIntMethod(e, j->cb.obj,
j->cb.mid[0], jb);
(*e)->ReleaseByteArrayElements(e, jb, (jbyte *)in, JNI_ABORT);
(*e)->DeleteLocalRef(e, jb);
}
}
return ret;
}
static int jbs_read(BIO *b, char *out, int outl)
{
jint ret = 0;
if (b->init && out != NULL) {
BIO_JAVA *j = (BIO_JAVA *)b->ptr;
JNIEnv *e = NULL;
jbyteArray jb = (*e)->NewByteArray(e, outl);
tcn_get_java_env(&e);
if (!(*e)->ExceptionOccurred(e)) {
ret = (*e)->CallIntMethod(e, j->cb.obj,
j->cb.mid[1], jb);
if (ret > 0) {
jbyte *jout = (*e)->GetPrimitiveArrayCritical(e, jb, NULL);
memcpy(out, jout, ret);
(*e)->ReleasePrimitiveArrayCritical(e, jb, jout, 0);
}
(*e)->DeleteLocalRef(e, jb);
}
}
return ret;
}
static int jbs_puts(BIO *b, const char *in)
{
int ret = 0;
if (b->init && in != NULL) {
BIO_JAVA *j = (BIO_JAVA *)b->ptr;
JNIEnv *e = NULL;
tcn_get_java_env(&e);
ret = (*e)->CallIntMethod(e, j->cb.obj,
j->cb.mid[2],
tcn_new_string(e, in));
}
return ret;
}
static int jbs_gets(BIO *b, char *out, int outl)
{
int ret = 0;
if (b->init && out != NULL) {
BIO_JAVA *j = (BIO_JAVA *)b->ptr;
JNIEnv *e = NULL;
jobject o;
tcn_get_java_env(&e);
if ((o = (*e)->CallObjectMethod(e, j->cb.obj,
j->cb.mid[3], (jint)(outl - 1)))) {
TCN_ALLOC_CSTRING(o);
if (J2S(o)) {
int l = (int)strlen(J2S(o));
if (l < outl) {
strcpy(out, J2S(o));
ret = outl;
}
}
TCN_FREE_CSTRING(o);
}
}
return ret;
}
static long jbs_ctrl(BIO *b, int cmd, long num, void *ptr)
{
return 0;
}
static BIO_METHOD jbs_methods = {
BIO_TYPE_FILE,
"Java Callback",
jbs_write,
jbs_read,
jbs_puts,
jbs_gets,
jbs_ctrl,
jbs_new,
jbs_free,
NULL
};
static BIO_METHOD *BIO_jbs()
{
return(&jbs_methods);
}
TCN_IMPLEMENT_CALL(jlong, SSL, newBIO)(TCN_STDARGS, jlong pool,
jobject callback)
{
BIO *bio = NULL;
BIO_JAVA *j;
jclass cls;
UNREFERENCED(o);
if ((bio = BIO_new(BIO_jbs())) == NULL) {
tcn_ThrowException(e, "Create BIO failed");
goto init_failed;
}
j = (BIO_JAVA *)bio->ptr;
if ((j = (BIO_JAVA *)bio->ptr) == NULL) {
tcn_ThrowException(e, "Create BIO failed");
goto init_failed;
}
j->pool = J2P(pool, apr_pool_t *);
if (j->pool) {
apr_pool_cleanup_register(j->pool, (const void *)bio,
generic_bio_cleanup,
apr_pool_cleanup_null);
}
cls = (*e)->GetObjectClass(e, callback);
j->cb.mid[0] = (*e)->GetMethodID(e, cls, "write", "([B)I");
j->cb.mid[1] = (*e)->GetMethodID(e, cls, "read", "([B)I");
j->cb.mid[2] = (*e)->GetMethodID(e, cls, "puts", "(Ljava/lang/String;)I");
j->cb.mid[3] = (*e)->GetMethodID(e, cls, "gets", "(I)Ljava/lang/String;");
/* TODO: Check if method id's are valid */
j->cb.obj = (*e)->NewGlobalRef(e, callback);
bio->init = 1;
bio->flags = SSL_BIO_FLAG_CALLBACK;
return P2J(bio);
init_failed:
return 0;
}
TCN_IMPLEMENT_CALL(jint, SSL, closeBIO)(TCN_STDARGS, jlong bio)
{
BIO *b = J2P(bio, BIO *);
UNREFERENCED_STDARGS;
SSL_BIO_close(b);
return APR_SUCCESS;
}
TCN_IMPLEMENT_CALL(void, SSL, setPasswordCallback)(TCN_STDARGS,
jobject callback)
{
jclass cls;
UNREFERENCED(o);
if (tcn_password_callback.cb.obj) {
TCN_UNLOAD_CLASS(e,
tcn_password_callback.cb.obj);
}
cls = (*e)->GetObjectClass(e, callback);
tcn_password_callback.cb.mid[0] = (*e)->GetMethodID(e, cls, "callback",
"(Ljava/lang/String;)Ljava/lang/String;");
/* TODO: Check if method id is valid */
tcn_password_callback.cb.obj = (*e)->NewGlobalRef(e, callback);
}
TCN_IMPLEMENT_CALL(void, SSL, setPassword)(TCN_STDARGS, jstring password)
{
TCN_ALLOC_CSTRING(password);
UNREFERENCED(o);
if (J2S(password)) {
strncpy(tcn_password_callback.password, J2S(password), SSL_MAX_PASSWORD_LEN);
tcn_password_callback.password[SSL_MAX_PASSWORD_LEN-1] = '\0';
}
TCN_FREE_CSTRING(password);
}
TCN_IMPLEMENT_CALL(jboolean, SSL, generateRSATempKey)(TCN_STDARGS, jint idx)
{
int r = 1;
UNREFERENCED_STDARGS;
SSL_TMP_KEY_FREE(RSA, idx);
switch (idx) {
case SSL_TMP_KEY_RSA_512:
r = SSL_TMP_KEY_INIT_RSA(512);
break;
case SSL_TMP_KEY_RSA_1024:
r = SSL_TMP_KEY_INIT_RSA(1024);
break;
case SSL_TMP_KEY_RSA_2048:
r = SSL_TMP_KEY_INIT_RSA(2048);
break;
case SSL_TMP_KEY_RSA_4096:
r = SSL_TMP_KEY_INIT_RSA(4096);
break;
}
return r ? JNI_FALSE : JNI_TRUE;
}
TCN_IMPLEMENT_CALL(jboolean, SSL, loadDSATempKey)(TCN_STDARGS, jint idx,
jstring file)
{
jboolean r = JNI_FALSE;
TCN_ALLOC_CSTRING(file);
DH *dh;
UNREFERENCED(o);
if (!J2S(file))
return JNI_FALSE;
SSL_TMP_KEY_FREE(DSA, idx);
if ((dh = SSL_dh_get_param_from_file(J2S(file)))) {
SSL_temp_keys[idx] = dh;
r = JNI_TRUE;
}
TCN_FREE_CSTRING(file);
return r;
}
TCN_IMPLEMENT_CALL(jstring, SSL, getLastError)(TCN_STDARGS)
{
char buf[256];
UNREFERENCED(o);
ERR_error_string(ERR_get_error(), buf);
return tcn_new_string(e, buf);
}
#else
/* OpenSSL is not supported.
* Create empty stubs.
*/
TCN_IMPLEMENT_CALL(jint, SSL, version)(TCN_STDARGS)
{
UNREFERENCED_STDARGS;
return 0;
}
TCN_IMPLEMENT_CALL(jstring, SSL, versionString)(TCN_STDARGS)
{
UNREFERENCED_STDARGS;
return NULL;
}
TCN_IMPLEMENT_CALL(jint, SSL, initialize)(TCN_STDARGS, jstring engine)
{
UNREFERENCED(o);
UNREFERENCED(engine);
tcn_ThrowAPRException(e, APR_ENOTIMPL);
return (jint)APR_ENOTIMPL;
}
TCN_IMPLEMENT_CALL(jboolean, SSL, randLoad)(TCN_STDARGS, jstring file)
{
UNREFERENCED_STDARGS;
UNREFERENCED(file);
return JNI_FALSE;
}
TCN_IMPLEMENT_CALL(jboolean, SSL, randSave)(TCN_STDARGS, jstring file)
{
UNREFERENCED_STDARGS;
return JNI_FALSE;
}
TCN_IMPLEMENT_CALL(jboolean, SSL, randMake)(TCN_STDARGS, jstring file,
jint length, jboolean base64)
{
UNREFERENCED_STDARGS;
UNREFERENCED(file);
UNREFERENCED(length);
UNREFERENCED(base64);
return JNI_FALSE;
}
TCN_IMPLEMENT_CALL(jlong, SSL, newBIO)(TCN_STDARGS, jlong pool,
jobject callback)
{
UNREFERENCED_STDARGS;
UNREFERENCED(pool);
UNREFERENCED(callback);
return 0;
}
TCN_IMPLEMENT_CALL(jint, SSL, closeBIO)(TCN_STDARGS, jlong bio)
{
UNREFERENCED_STDARGS;
UNREFERENCED(bio);
return (jint)APR_ENOTIMPL;
}
TCN_IMPLEMENT_CALL(void, SSL, setPasswordCallback)(TCN_STDARGS,
jobject callback)
{
UNREFERENCED_STDARGS;
UNREFERENCED(callback);
}
TCN_IMPLEMENT_CALL(void, SSL, setPassword)(TCN_STDARGS, jstring password)
{
UNREFERENCED_STDARGS;
UNREFERENCED(password);
}
TCN_IMPLEMENT_CALL(jboolean, SSL, generateRSATempKey)(TCN_STDARGS, jint idx)
{
UNREFERENCED_STDARGS;
UNREFERENCED(idx);
return JNI_FALSE;
}
TCN_IMPLEMENT_CALL(jboolean, SSL, loadDSATempKey)(TCN_STDARGS, jint idx,
jstring file)
{
UNREFERENCED_STDARGS;
UNREFERENCED(idx);
UNREFERENCED(file);
return JNI_FALSE;
}
TCN_IMPLEMENT_CALL(jstring, SSL, getLastError)(TCN_STDARGS)
{
UNREFERENCED_STDARGS;
return NULL;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -