зеркало из https://github.com/mozilla/gecko-dev.git
Make server-side SSL work. Put common code in common.c.
This commit is contained in:
Родитель
418c168bd1
Коммит
60d1142a0d
|
@ -0,0 +1,258 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Security Services for Java.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include <nspr.h>
|
||||
#include <jni.h>
|
||||
#include <ssl.h>
|
||||
#include <sslerr.h>
|
||||
#include <pk11func.h>
|
||||
#include <keyhi.h>
|
||||
|
||||
#include <jssutil.h>
|
||||
#include <jss_exceptions.h>
|
||||
#include <java_ids.h>
|
||||
#include <pk11util.h>
|
||||
#include "jssl.h"
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_socketCreate
|
||||
(JNIEnv *env, jobject self)
|
||||
{
|
||||
return JSSL_socketCreate(env, self, NULL, NULL);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_socketBind
|
||||
(JNIEnv *env, jobject self, jbyteArray addrBA, jint port)
|
||||
{
|
||||
JSSL_socketBind(env, self, addrBA, port);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_socketListen
|
||||
(JNIEnv *env, jobject self, jint backlog)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
if( PR_Listen(sock->fd, backlog) != PR_SUCCESS ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Failed to set listen backlog on socket");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_socketAccept
|
||||
(JNIEnv *env, jobject self, jobject newSock, jint timeout)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
PRNetAddr addr;
|
||||
PRFileDesc *newFD=NULL;
|
||||
PRIntervalTime ivtimeout;
|
||||
JSSL_SocketData *newSD=NULL;
|
||||
jbyteArray sdArray = NULL;
|
||||
SECStatus status;
|
||||
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
ivtimeout = (timeout > 0) ? PR_MillisecondsToInterval(timeout)
|
||||
: PR_INTERVAL_NO_TIMEOUT;
|
||||
|
||||
for(;;) {
|
||||
newFD = PR_Accept(sock->fd, &addr, ivtimeout);
|
||||
|
||||
if( newFD != NULL ) {
|
||||
/* success! */
|
||||
break;
|
||||
} else {
|
||||
switch( PR_GetError() ) {
|
||||
case PR_PENDING_INTERRUPT_ERROR:
|
||||
case PR_IO_PENDING_ERROR:
|
||||
break; /* out of the switch and loop again */
|
||||
default:
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Failed to accept new connection");
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newSD = JSSL_CreateSocketData(env, newSock, newFD);
|
||||
newFD = NULL;
|
||||
if( newSD == NULL ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* setup the handshake callback */
|
||||
status = SSL_HandshakeCallback(newSD->fd, JSSL_HandshakeCallback,
|
||||
newSD);
|
||||
if( status != PR_SUCCESS ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to install handshake callback");
|
||||
}
|
||||
|
||||
/* pass the pointer back to Java */
|
||||
sdArray = JSS_ptrToByteArray(env, (void*) newSD);
|
||||
if( sdArray == NULL ) {
|
||||
/* exception was thrown */
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if( (*env)->ExceptionOccurred(env) != NULL ) {
|
||||
if( newSD != NULL ) {
|
||||
JSSL_DestroySocketData(env, newSD);
|
||||
}
|
||||
if( newFD != NULL ) {
|
||||
PR_Close(newFD);
|
||||
}
|
||||
}
|
||||
return sdArray;
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_clearSessionCache(
|
||||
JNIEnv *env, jclass clazz)
|
||||
{
|
||||
SSL_ClearSessionCache();
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_socketClose(JNIEnv *env, jobject self)
|
||||
{
|
||||
JSSL_socketClose(env, self);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_configServerSessionIDCache(
|
||||
JNIEnv *env, jclass myClass, jint maxEntries, jint ssl2Timeout,
|
||||
jint ssl3Timeout, jstring nameString)
|
||||
{
|
||||
const char* dirName = NULL;
|
||||
SECStatus status;
|
||||
|
||||
if (nameString != NULL) {
|
||||
dirName = (*env)->GetStringUTFChars(env, nameString, NULL);
|
||||
}
|
||||
|
||||
status = SSL_ConfigServerSessionIDCache(
|
||||
maxEntries, ssl2Timeout, ssl3Timeout, dirName);
|
||||
if (status != SECSuccess) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Failed to configure server session ID cache");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if(dirName != NULL) {
|
||||
(*env)->ReleaseStringUTFChars(env, nameString, dirName);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_setServerCertNickname(
|
||||
JNIEnv *env, jobject self, jstring nicknameStr)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
const char *nickname=NULL;
|
||||
CERTCertificate* cert=NULL;
|
||||
SECKEYPrivateKey* privKey=NULL;
|
||||
SECStatus status;
|
||||
|
||||
if(nicknameStr == NULL) {
|
||||
goto finish;
|
||||
}
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
nickname = (*env)->GetStringUTFChars(env, nicknameStr, NULL);
|
||||
if( nickname == NULL ) goto finish;
|
||||
|
||||
cert = PK11_FindCertFromNickname((char *)nickname, NULL); /* CONST */
|
||||
if (cert != NULL) {
|
||||
privKey = PK11_FindKeyByAnyCert(cert, NULL);
|
||||
if (privKey != NULL) {
|
||||
status = SSL_ConfigSecureServer(sock->fd, cert, privKey, kt_rsa);
|
||||
if( status != SECSuccess) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Failed to configure secure server certificate and key");
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "Failed to locate private key");
|
||||
goto finish;
|
||||
}
|
||||
} else {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "Failed to locate private key");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if(privKey!=NULL) {
|
||||
SECKEY_DestroyPrivateKey(privKey);
|
||||
}
|
||||
if(cert!=NULL) {
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
if( nickname != NULL ) {
|
||||
(*env)->ReleaseStringUTFChars(env, nicknameStr, nickname);
|
||||
}
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_setNeedClientAuthNoExpiryCheck(
|
||||
JNIEnv *env, jobject self, jboolean b)
|
||||
{
|
||||
JSSL_setNeedClientAuthNoExpiryCheck(env, self, b);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLServerSocket_setNeedClientAuth(
|
||||
JNIEnv *env, jobject self, jboolean b)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
SECStatus status;
|
||||
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
status = SSL_OptionSet(sock->fd, SSL_REQUEST_CERTIFICATE, b);
|
||||
if( status != SECSuccess ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "Failed to set socket option");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
}
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Security Services for Java.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
package org.mozilla.jss.ssl;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.io.IOException;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketException;
|
||||
|
||||
public class SSLServerSocket {
|
||||
|
||||
private static final int DEFAULT_BACKLOG = 50;
|
||||
|
||||
public SSLServerSocket(int port) throws IOException {
|
||||
this(port, DEFAULT_BACKLOG, null);
|
||||
}
|
||||
|
||||
public SSLServerSocket(int port, int backlog) throws IOException {
|
||||
this(port, backlog, null);
|
||||
}
|
||||
|
||||
public SSLServerSocket(int port, int backlog, InetAddress bindAddr)
|
||||
throws IOException
|
||||
{
|
||||
// Dance the dance of fools. The superclass doesn't have a default
|
||||
// constructor, so we have to trick it here. This is an example
|
||||
// of WHY WE SHOULDN'T BE EXTENDING SERVERSOCKET.
|
||||
//super(0);
|
||||
//super.close();
|
||||
|
||||
// create the socket
|
||||
sockProxy = new SocketProxy( socketCreate() );
|
||||
|
||||
// bind it to the local address and port
|
||||
if( bindAddr == null ) {
|
||||
bindAddr = anyLocalAddr;
|
||||
}
|
||||
socketBind(bindAddr.getAddress(), port);
|
||||
socketListen(backlog);
|
||||
}
|
||||
|
||||
private SocketProxy sockProxy;
|
||||
private boolean handshakeAsClient=false;
|
||||
|
||||
private native byte[] socketCreate() throws SocketException;
|
||||
|
||||
private native void socketBind(byte[] addrBA, int port)
|
||||
throws SocketException;
|
||||
|
||||
private native void socketListen(int backlog) throws SocketException;
|
||||
|
||||
private static InetAddress anyLocalAddr;
|
||||
static {
|
||||
try {
|
||||
anyLocalAddr = InetAddress.getByName("0.0.0.0");
|
||||
} catch (java.net.UnknownHostException e) { }
|
||||
}
|
||||
|
||||
public Socket accept() throws IOException {
|
||||
SSLSocket s = new SSLSocket();
|
||||
s.setSockProxy( new SocketProxy( socketAccept(s, timeout) ) );
|
||||
return s;
|
||||
}
|
||||
|
||||
private int timeout;
|
||||
|
||||
public void setSoTimeout(int timeout) {
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
public int getSoTimeout() {
|
||||
return timeout;
|
||||
}
|
||||
|
||||
private native byte[] socketAccept(SSLSocket s, int timeout)
|
||||
throws SocketException;
|
||||
|
||||
public static native void clearSessionCache();
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
close();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
if( sockProxy != null ) {
|
||||
socketClose();
|
||||
sockProxy = null;
|
||||
}
|
||||
}
|
||||
|
||||
private native void socketClose() throws IOException;
|
||||
|
||||
// This directory is used as the default for the Session ID cache
|
||||
private final static String UNIX_TEMP_DIR = "/tmp";
|
||||
private final static String WINDOWS_TEMP_DIR = "\\temp";
|
||||
|
||||
public static native void configServerSessionIDCache(int maxSidEntries,
|
||||
int ssl2EntryTimeout, int ssl3EntryTimeout, String cacheFileDirectory);
|
||||
|
||||
public native void setServerCertNickname(String nickname)
|
||||
throws SocketException;
|
||||
|
||||
public native void setNeedClientAuth(boolean b) throws SocketException;
|
||||
|
||||
public native void setNeedClientAuthNoExpiryCheck(boolean b)
|
||||
throws SocketException;
|
||||
}
|
|
@ -42,94 +42,20 @@
|
|||
#include <pk11util.h>
|
||||
#include "jssl.h"
|
||||
|
||||
#ifdef JDK1_2
|
||||
/* JDK 1.2 and higher provide weak references in JNI. */
|
||||
|
||||
#define NEW_WEAK_GLOBAL_REF(env, obj) \
|
||||
((*env)->NewWeakGlobalRef((env), (obj)))
|
||||
#define DELETE_WEAK_GLOBAL_REF(env, obj) \
|
||||
((*env)->DeleteWeakGlobalRef((env), (obj)))
|
||||
|
||||
#else
|
||||
/* JDK 1.1 doesn't have weak references, so we'll have to use regular ones */
|
||||
|
||||
#define NEW_WEAK_GLOBAL_REF(env, obj) \
|
||||
((*env)->NewGlobalRef((env), (obj)))
|
||||
#define DELETE_WEAK_GLOBAL_REF(env, obj) \
|
||||
((*env)->DeleteGlobalRef((env), (obj)))
|
||||
|
||||
#endif
|
||||
|
||||
static PRStatus
|
||||
JSS_SSL_getSockData(JNIEnv *env, jobject sockObject, JSSL_SocketData **sd);
|
||||
|
||||
SECStatus
|
||||
JSSL_JavaCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig,
|
||||
PRBool isServer);
|
||||
|
||||
void
|
||||
JSSL_HandshakeCallback(PRFileDesc *fd, void *arg);
|
||||
|
||||
int
|
||||
JSSL_DefaultCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig,
|
||||
PRBool isServer);
|
||||
|
||||
int
|
||||
JSSL_CallCertSelectionCallback( void * arg,
|
||||
PRFileDesc * fd,
|
||||
CERTDistNames * caNames,
|
||||
CERTCertificate ** pRetCert,
|
||||
SECKEYPrivateKey ** pRetKey);
|
||||
|
||||
static void
|
||||
DestroyJSSL_SocketData(JNIEnv *env, JSSL_SocketData *sd)
|
||||
{
|
||||
PR_ASSERT(sd != NULL);
|
||||
|
||||
if( sd->fd != NULL ) {
|
||||
PR_Close(sd->fd);
|
||||
}
|
||||
if( sd->socketObject != NULL ) {
|
||||
DELETE_WEAK_GLOBAL_REF(env, sd->socketObject );
|
||||
}
|
||||
if( sd->certApprovalCallback != NULL ) {
|
||||
(*env)->DeleteGlobalRef(env, sd->certApprovalCallback);
|
||||
}
|
||||
if( sd->clientCertSelectionCallback != NULL ) {
|
||||
(*env)->DeleteGlobalRef(env, sd->clientCertSelectionCallback);
|
||||
}
|
||||
PR_Free(sd);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* These must match up with the constants defined in SSLSocket.java.
|
||||
*/
|
||||
static PRInt32 enums[] = {
|
||||
SSL_ENABLE_SSL2, /* 0 */
|
||||
SSL_ENABLE_SSL3, /* 1 */
|
||||
PR_SockOpt_NoDelay, /* 2 */
|
||||
PR_SockOpt_Keepalive, /* 3 */
|
||||
PR_SHUTDOWN_RCV, /* 4 */
|
||||
PR_SHUTDOWN_SEND, /* 5 */
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLSocket_setSSLOption(JNIEnv *env, jobject self,
|
||||
jint joption, jboolean on)
|
||||
jint joption, jint on)
|
||||
{
|
||||
SECStatus status;
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
/* get my fd */
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* set the option */
|
||||
status = SSL_OptionSet(sock->fd, enums[joption], on);
|
||||
status = SSL_OptionSet(sock->fd, JSSL_enums[joption], on);
|
||||
if( status != SECSuccess ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "SSL_OptionSet failed");
|
||||
goto finish;
|
||||
|
@ -141,12 +67,12 @@ finish:
|
|||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLSocket_setSSLDefaultOption(JNIEnv *env,
|
||||
jclass clazz, jint joption, jboolean on)
|
||||
jclass clazz, jint joption, jint on)
|
||||
{
|
||||
SECStatus status;
|
||||
|
||||
/* set the option */
|
||||
status = SSL_OptionSetDefault(enums[joption], on);
|
||||
status = SSL_OptionSetDefault(JSSL_enums[joption], on);
|
||||
if( status != SECSuccess ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "SSL_OptionSet failed");
|
||||
goto finish;
|
||||
|
@ -163,7 +89,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_forceHandshake(JNIEnv *env, jobject self)
|
|||
int rv;
|
||||
|
||||
/* get my fd */
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) goto finish;
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) goto finish;
|
||||
|
||||
/* do the work */
|
||||
rv = SSL_ForceHandshake(sock->fd);
|
||||
|
@ -188,7 +114,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_setSoLInger(JNIEnv *env, jobject self,
|
|||
PRStatus status;
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -216,7 +142,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_getTcpNoDelay(JNIEnv *env, jobject self)
|
|||
JSSL_SocketData *sock;
|
||||
PRStatus status;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -240,7 +166,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_setTcpNoDelay(JNIEnv *env, jobject self,
|
|||
PRStatus status;
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -264,7 +190,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_getSendBufferSize(JNIEnv *env, jobject self)
|
|||
JSSL_SocketData *sock;
|
||||
PRStatus status;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -288,7 +214,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_setSendBufferSize(JNIEnv *env, jobject self,
|
|||
PRStatus status;
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -312,7 +238,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_getKeepAlive(JNIEnv *env, jobject self)
|
|||
JSSL_SocketData *sock;
|
||||
PRStatus status;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -336,7 +262,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_getReceiveBufferSize(
|
|||
JSSL_SocketData *sock;
|
||||
PRStatus status;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -360,7 +286,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_setReceiveBufferSize(
|
|||
PRStatus status;
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -385,7 +311,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_setKeepAlive(JNIEnv *env, jobject self,
|
|||
PRStatus status;
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -410,7 +336,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_getSoLinger(JNIEnv *env, jobject self)
|
|||
jint retval;
|
||||
PRStatus status;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -441,7 +367,7 @@ getSockAddr(JNIEnv *env, jobject self, PRNetAddr *addr, LocalOrPeer localOrPeer)
|
|||
PRStatus status;
|
||||
|
||||
/* get my fd */
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -497,147 +423,15 @@ Java_org_mozilla_jss_ssl_SSLSocket_getPort(JNIEnv *env,
|
|||
return addr.inet.port;
|
||||
}
|
||||
|
||||
static PRStatus
|
||||
JSS_SSL_getSockData(JNIEnv *env, jobject sockObject, JSSL_SocketData **sd)
|
||||
{
|
||||
PR_ASSERT(env!=NULL && sockObject!=NULL && sd!=NULL);
|
||||
|
||||
return JSS_getPtrFromProxyOwner(env, sockObject, SSLSOCKET_PROXY_FIELD,
|
||||
SSLSOCKET_PROXY_SIG, (void**)sd);
|
||||
}
|
||||
|
||||
JNIEXPORT jbyteArray JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLSocket_socketCreate
|
||||
(JNIEnv *env, jobject self, jobject certApprovalCallback,
|
||||
jobject clientCertSelectionCallback)
|
||||
{
|
||||
jbyteArray sdArray = NULL;
|
||||
JSSL_SocketData *sockdata = NULL;
|
||||
PRStatus status;
|
||||
|
||||
/* make a JSSL_SocketData structure */
|
||||
sockdata = PR_Malloc( sizeof(JSSL_SocketData) );
|
||||
sockdata->fd = NULL;
|
||||
sockdata->socketObject = NULL;
|
||||
sockdata->certApprovalCallback = NULL;
|
||||
sockdata->clientCertSelectionCallback = NULL;
|
||||
|
||||
/* create a TCP socket */
|
||||
sockdata->fd = PR_NewTCPSocket();
|
||||
if( sockdata->fd == NULL ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_NewTCPSocket() returned NULL");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* enable SSL on the socket */
|
||||
sockdata->fd = SSL_ImportFD(NULL, sockdata->fd);
|
||||
if( sockdata->fd == NULL ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "SSL_ImportFD() returned NULL");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
status = SSL_OptionSet(sockdata->fd, SSL_SECURITY, PR_TRUE);
|
||||
if( status != SECSuccess ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to enable SSL security on socket");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a global ref to the socket. Since it is a weak reference, it will
|
||||
* get garbage collected if this is the only reference that remains.
|
||||
* We do this so that sockets will get closed when they go out of scope
|
||||
* in the Java layer.
|
||||
*/
|
||||
sockdata->socketObject = NEW_WEAK_GLOBAL_REF(env, self);
|
||||
if( sockdata->socketObject == NULL ) goto finish;
|
||||
|
||||
/* setup the handshake callback */
|
||||
status = SSL_HandshakeCallback(sockdata->fd, JSSL_HandshakeCallback,
|
||||
sockdata);
|
||||
if( status != PR_SUCCESS ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to install handshake callback");
|
||||
}
|
||||
|
||||
/* setup the cert authentication callback */
|
||||
if( certApprovalCallback != NULL ) {
|
||||
/* create global reference to the callback object */
|
||||
sockdata->certApprovalCallback =
|
||||
(*env)->NewGlobalRef(env, certApprovalCallback);
|
||||
if( sockdata->certApprovalCallback == NULL ) goto finish;
|
||||
|
||||
/* install the Java callback */
|
||||
status = SSL_AuthCertificateHook(
|
||||
sockdata->fd, JSSL_JavaCertAuthCallback,
|
||||
(void*) sockdata->certApprovalCallback);
|
||||
} else {
|
||||
/* install the default callback */
|
||||
status = SSL_AuthCertificateHook(
|
||||
sockdata->fd, JSSL_DefaultCertAuthCallback, NULL);
|
||||
}
|
||||
if( status != PR_SUCCESS ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to install certificate authentication callback");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* setup the client cert selection callback */
|
||||
if( clientCertSelectionCallback != NULL ) {
|
||||
/* create a new global ref */
|
||||
sockdata->clientCertSelectionCallback =
|
||||
(*env)->NewGlobalRef(env, clientCertSelectionCallback);
|
||||
if(sockdata->clientCertSelectionCallback == NULL) goto finish;
|
||||
|
||||
/* install the Java callback */
|
||||
status = SSL_GetClientAuthDataHook(
|
||||
sockdata->fd, JSSL_CallCertSelectionCallback,
|
||||
(void*) sockdata->clientCertSelectionCallback);
|
||||
if( status != PR_SUCCESS ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to install client certificate selection callback");
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
/* pass the pointer back to Java */
|
||||
sdArray = JSS_ptrToByteArray(env, (void*) sockdata);
|
||||
if( sdArray == NULL ) {
|
||||
/* exception was thrown */
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if( (*env)->ExceptionOccurred(env) != NULL ) {
|
||||
if( sockdata != NULL ) {
|
||||
DestroyJSSL_SocketData(env, sockdata);
|
||||
}
|
||||
} else {
|
||||
PR_ASSERT( sdArray != NULL );
|
||||
}
|
||||
return sdArray;
|
||||
return JSSL_socketCreate(env, self, certApprovalCallback,
|
||||
clientCertSelectionCallback);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void
|
||||
throwMsgPRErr(JNIEnv *env, char* exceptionClassName, char* msg)
|
||||
{
|
||||
PRErrorCode errcode;
|
||||
char *errstr;
|
||||
int len;
|
||||
|
||||
len = strlen(msg) + 26;
|
||||
errstr = (char*) PR_Malloc(len);
|
||||
errcode = PR_GetError();
|
||||
|
||||
snprintf(errstr, len, "%s (error code %d)", msg, errcode);
|
||||
|
||||
JSS_throwMsg(env, exceptionClassName, errstr);
|
||||
|
||||
PR_Free(errstr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This function assumes 4-byte IP addresses. It will need to be tweaked
|
||||
* for IPv6.
|
||||
|
@ -650,74 +444,13 @@ JNIEXPORT void JNICALL
|
|||
Java_org_mozilla_jss_ssl_SSLSocket_socketBind
|
||||
(JNIEnv *env, jobject self, jbyteArray addrBA, jint port)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
PRNetAddr addr;
|
||||
jbyte *addrBAelems = NULL;
|
||||
PRStatus status;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) {
|
||||
/* exception was thrown */
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup the PRNetAddr structure
|
||||
*/
|
||||
addr.inet.family = AF_INET;
|
||||
addr.inet.port = port;
|
||||
PR_ASSERT(sizeof(addr.inet.ip) == 4);
|
||||
PR_ASSERT( (*env)->GetArrayLength(env, addrBA) == 4);
|
||||
addrBAelems = (*env)->GetByteArrayElements(env, addrBA, NULL);
|
||||
if( addrBAelems == NULL ) {
|
||||
ASSERT_OUTOFMEM(env);
|
||||
goto finish;
|
||||
}
|
||||
memcpy(&addr.inet.ip, addrBAelems, 4);
|
||||
|
||||
/* do the bind() call */
|
||||
status = PR_Bind(sock->fd, &addr);
|
||||
if( status != PR_SUCCESS ) {
|
||||
PRErrorCode err = PR_GetError();
|
||||
switch( err ) {
|
||||
case PR_ADDRESS_NOT_AVAILABLE_ERROR:
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Binding exception: address not available");
|
||||
break;
|
||||
case PR_ADDRESS_IN_USE_ERROR:
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Binding exception: address in use");
|
||||
break;
|
||||
default:
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Binding exception");
|
||||
break;
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if( addrBAelems != NULL ) {
|
||||
(*env)->ReleaseByteArrayElements(env, addrBA, addrBAelems, JNI_ABORT);
|
||||
}
|
||||
JSSL_socketBind(env, self, addrBA, port);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLSocket_socketClose(JNIEnv *env, jobject self)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
printf("***\nClosing socket\n***\n");
|
||||
|
||||
/* get the FD */
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) {
|
||||
/* exception was thrown */
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* destroy the FD and any supporting data */
|
||||
DestroyJSSL_SocketData(env, sock);
|
||||
|
||||
finish:
|
||||
JSSL_socketClose(env, self);
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
|
@ -731,7 +464,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_socketConnect
|
|||
int stat;
|
||||
const char *hostnameStr=NULL;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) {
|
||||
/* exception was thrown */
|
||||
goto finish;
|
||||
}
|
||||
|
@ -802,7 +535,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_getStatus
|
|||
jobject serialNumObj = NULL;
|
||||
|
||||
/* get the fd */
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) {
|
||||
/* exception was thrown */
|
||||
goto finish;
|
||||
}
|
||||
|
@ -923,7 +656,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_socketRead(JNIEnv *env, jobject self,
|
|||
jint nread;
|
||||
|
||||
/* get the socket */
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -982,7 +715,7 @@ Java_com_netscape_jss_ssl_SSLSocketImpl_socketAvailable(
|
|||
jint available;
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -1013,7 +746,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_socketWrite(JNIEnv *env, jobject self,
|
|||
goto finish;
|
||||
}
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
@ -1064,9 +797,9 @@ Java_org_mozilla_jss_ssl_SSLSocket_shutdownNative(
|
|||
JSSL_SocketData *sock;
|
||||
PRStatus status;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
status = PR_Shutdown(sock->fd, enums[how]);
|
||||
status = PR_Shutdown(sock->fd, JSSL_enums[how]);
|
||||
if( status != PR_SUCCESS) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "Failed to shutdown socket");
|
||||
goto finish;
|
||||
|
@ -1081,7 +814,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_invalidateSession(JNIEnv *env, jobject self)
|
|||
JSSL_SocketData *sock;
|
||||
SECStatus status;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
status = SSL_InvalidateSession(sock->fd);
|
||||
if(status != SECSuccess) {
|
||||
|
@ -1099,7 +832,7 @@ Java_org_mozilla_jss_ssl_SSLSocket_redoHandshake(
|
|||
JSSL_SocketData *sock;
|
||||
SECStatus status;
|
||||
|
||||
if( JSS_SSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
status = SSL_ReHandshake(sock->fd, flushCache);
|
||||
if(status != SECSuccess) {
|
||||
|
@ -1109,3 +842,66 @@ Java_org_mozilla_jss_ssl_SSLSocket_redoHandshake(
|
|||
|
||||
finish:
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLSocket_resetHandshake(
|
||||
JNIEnv *env, jobject self, jboolean asClient)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
SECStatus status;
|
||||
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
status = SSL_ResetHandshake(sock->fd, !asClient);
|
||||
if(status != SECSuccess) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "Failed to redo handshake");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLSocket_setClientCertNicknameNative(
|
||||
JNIEnv *env, jobject self, jstring nickStr)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
const char *nick=NULL;
|
||||
SECStatus status;
|
||||
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
/*
|
||||
* Store the nickname in the SocketData.
|
||||
*/
|
||||
nick = (*env)->GetStringUTFChars(env, nickStr, NULL);
|
||||
if( nick == NULL ) goto finish;
|
||||
if( sock->clientCertNickname != NULL ) {
|
||||
PR_Free(sock->clientCertNickname);
|
||||
}
|
||||
sock->clientCertNickname = PL_strdup(nick);
|
||||
|
||||
/*
|
||||
* Install the callback.
|
||||
*/
|
||||
status = SSL_GetClientAuthDataHook(sock->fd, JSSL_GetClientAuthData,
|
||||
(void*)sock);
|
||||
if(status != SECSuccess) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to set client auth data hook");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if( nick != NULL ) {
|
||||
(*env)->ReleaseStringUTFChars(env, nickStr, nick);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_mozilla_jss_ssl_SSLSocket_setNeedClientAuthNoExpiryCheck(
|
||||
JNIEnv *env, jobject self, jboolean b)
|
||||
{
|
||||
JSSL_setNeedClientAuthNoExpiryCheck(env, self, b);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,9 @@
|
|||
package org.mozilla.jss.ssl;
|
||||
|
||||
import java.net.*;
|
||||
import java.net.SocketException;
|
||||
import java.io.*;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.ListIterator;
|
||||
|
||||
|
@ -46,6 +48,14 @@ public class SSLSocket extends java.net.Socket {
|
|||
SSLSocket() throws IOException {
|
||||
}
|
||||
|
||||
/**
|
||||
* Should only be called by SSLServerSocket after a successful
|
||||
* accept().
|
||||
*/
|
||||
void setSockProxy(SocketProxy sp) {
|
||||
sockProxy = sp;
|
||||
}
|
||||
|
||||
public SSLSocket(String host, int port)
|
||||
throws UnknownHostException, IOException
|
||||
{
|
||||
|
@ -194,7 +204,6 @@ public class SSLSocket extends java.net.Socket {
|
|||
return new SSLOutputStream(this);
|
||||
}
|
||||
|
||||
|
||||
public native void setTcpNoDelay(boolean on) throws SocketException;
|
||||
|
||||
public native boolean getTcpNoDelay() throws SocketException;
|
||||
|
@ -292,14 +301,66 @@ public class SSLSocket extends java.net.Socket {
|
|||
setSSLDefaultOption(SSL_ENABLE_SSL3, enable);
|
||||
}
|
||||
|
||||
public void requireClientAuth(boolean require, boolean onRedo)
|
||||
throws SocketException
|
||||
{
|
||||
setSSLOption(SSL_REQUIRE_CERTIFICATE, require ? (onRedo ? 1 : 2) : 0);
|
||||
}
|
||||
|
||||
public void requireClientAuthDefault(boolean require, boolean onRedo)
|
||||
throws SocketException
|
||||
{
|
||||
setSSLDefaultOption(SSL_REQUIRE_CERTIFICATE,
|
||||
require ? (onRedo ? 1 : 2) : 0);
|
||||
}
|
||||
|
||||
public native void forceHandshake() throws SocketException;
|
||||
|
||||
public void setUseClientMode(boolean b) {
|
||||
handshakeAsClient = b;
|
||||
}
|
||||
|
||||
public boolean getUseClientMode() {
|
||||
return handshakeAsClient;
|
||||
}
|
||||
|
||||
public void resetHandshake() throws SocketException {
|
||||
resetHandshakeNative(handshakeAsClient);
|
||||
}
|
||||
|
||||
private native void resetHandshakeNative(boolean asClient)
|
||||
throws SocketException;
|
||||
|
||||
public native SSLSecurityStatus getStatus() throws SocketException;
|
||||
|
||||
public void setClientCertNickname(String nick) throws SocketException {
|
||||
if( nick != null && nick.length() > 0 ) {
|
||||
setClientCertNicknameNative(nick);
|
||||
}
|
||||
}
|
||||
public native void setClientCertNicknameNative(String nick)
|
||||
throws SocketException;
|
||||
|
||||
public void setNeedClientAuth(boolean b) throws SocketException {
|
||||
setSSLOption(SSL_REQUEST_CERTIFICATE, b);
|
||||
}
|
||||
|
||||
public native void setNeedClientAuthNoExpiryCheck(boolean b)
|
||||
throws SocketException;
|
||||
|
||||
public void useCache(boolean b) throws SocketException {
|
||||
setSSLOption(SSL_NO_CACHE, !b);
|
||||
}
|
||||
|
||||
public void useCacheDefault(boolean b) throws SocketException {
|
||||
setSSLDefaultOption(SSL_NO_CACHE, !b);
|
||||
}
|
||||
|
||||
private InetAddress inetAddress;
|
||||
private int port;
|
||||
private SocketProxy sockProxy;
|
||||
private boolean open = false;
|
||||
private boolean handshakeAsClient=true;
|
||||
|
||||
/**
|
||||
* Enums. These must match the enums table in SSLSocket.c. This is
|
||||
|
@ -312,6 +373,9 @@ public class SSLSocket extends java.net.Socket {
|
|||
private static final int SO_KEEPALIVE = 3;
|
||||
private static final int PR_SHUTDOWN_RCV = 4;
|
||||
private static final int PR_SHUTDOWN_SEND = 5;
|
||||
private static final int SSL_REQUIRE_CERTIFICATE = 6;
|
||||
private static final int SSL_REQUEST_CERTIFICATE = 7;
|
||||
private static final int SSL_NO_CACHE = 8;
|
||||
|
||||
/**
|
||||
* SO_TIMEOUT timeout in millis. I don't know why we have to keep it here
|
||||
|
@ -319,9 +383,19 @@ public class SSLSocket extends java.net.Socket {
|
|||
*/
|
||||
private int timeout;
|
||||
|
||||
private native void setSSLOption(int option, boolean on)
|
||||
private void setSSLOption(int option, boolean on)
|
||||
throws SocketException
|
||||
{
|
||||
setSSLOption(option, on ? 1 : 0);
|
||||
}
|
||||
private native void setSSLOption(int option, int on)
|
||||
throws SocketException;
|
||||
private static native void setSSLDefaultOption(int option, boolean on)
|
||||
private static void setSSLDefaultOption(int option, boolean on)
|
||||
throws SocketException
|
||||
{
|
||||
setSSLDefaultOption(option, on ? 1 : 0);
|
||||
}
|
||||
private static native void setSSLDefaultOption(int option, int on)
|
||||
throws SocketException;
|
||||
|
||||
private native byte[] socketCreate(
|
||||
|
@ -424,20 +498,3 @@ public class SSLSocket extends java.net.Socket {
|
|||
|
||||
}
|
||||
|
||||
class SocketProxy extends org.mozilla.jss.util.NativeProxy {
|
||||
|
||||
public SocketProxy(byte[] pointer) {
|
||||
super(pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Theoretically, we don't need to do anything, since SSLSocket should
|
||||
* call close() when it finalizes. When a socket is closed all its
|
||||
* resources are freed, and there's nothing left to release.
|
||||
*/
|
||||
protected void releaseNativeResources() { }
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Security Services for Java.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
package org.mozilla.jss.ssl;
|
||||
|
||||
class SocketProxy extends org.mozilla.jss.util.NativeProxy {
|
||||
|
||||
public SocketProxy(byte[] pointer) {
|
||||
super(pointer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Theoretically, we don't need to do anything, since SSLSocket should
|
||||
* call close() when it finalizes. When a socket is closed all its
|
||||
* resources are freed, and there's nothing left to release.
|
||||
*/
|
||||
protected void releaseNativeResources() { }
|
||||
|
||||
protected void finalize() throws Throwable {
|
||||
super.finalize();
|
||||
}
|
||||
}
|
|
@ -607,3 +607,94 @@ finish:
|
|||
return retval;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT( int )
|
||||
JSSL_GetClientAuthData( void * arg,
|
||||
PRFileDesc * fd,
|
||||
CERTDistNames * caNames,
|
||||
CERTCertificate ** pRetCert,
|
||||
SECKEYPrivateKey ** pRetKey)
|
||||
{
|
||||
CERTCertificate * cert;
|
||||
SECKEYPrivateKey * privkey;
|
||||
JSSL_SocketData * sock;
|
||||
SECStatus rv = SECFailure;
|
||||
|
||||
PR_ASSERT(arg != NULL);
|
||||
sock = (JSSL_SocketData*) arg;
|
||||
|
||||
if (sock->clientCertNickname) {
|
||||
cert = PK11_FindCertFromNickname(sock->clientCertNickname,
|
||||
NULL /*pinarg*/);
|
||||
if ( cert ) {
|
||||
privkey = PK11_FindKeyByAnyCert(cert, NULL /*pinarg*/);
|
||||
if ( privkey ) {
|
||||
rv = SECSuccess;
|
||||
} else {
|
||||
CERT_DestroyCertificate(cert);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rv == SECSuccess) {
|
||||
*pRetCert = cert;
|
||||
*pRetKey = privkey;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
/*
|
||||
* Callback from SSL for checking a (possibly) expired
|
||||
* certificate the peer presents.
|
||||
*/
|
||||
PR_IMPLEMENT( int )
|
||||
JSSL_ConfirmExpiredPeerCert(void *arg, PRFileDesc *fd, PRBool checkSig,
|
||||
PRBool isServer)
|
||||
{
|
||||
char* hostname;
|
||||
SECStatus rv=SECFailure;
|
||||
SECCertUsage certUsage;
|
||||
CERTCertificate* peerCert=NULL;
|
||||
int64 notAfter, notBefore;
|
||||
|
||||
certUsage = isServer ? certUsageSSLClient : certUsageSSLServer;
|
||||
|
||||
peerCert = SSL_PeerCertificate(fd);
|
||||
|
||||
if (peerCert) {
|
||||
rv = CERT_GetCertTimes(peerCert, ¬Before, ¬After);
|
||||
if (rv != SECSuccess) goto finish;
|
||||
|
||||
/*
|
||||
* Verify the certificate based on it's expiry date. This should
|
||||
* always succeed, if the cert is trusted. It doesn't care if
|
||||
* the cert has expired.
|
||||
*/
|
||||
rv = CERT_VerifyCert(CERT_GetDefaultCertDB(), peerCert,
|
||||
checkSig, certUsage,
|
||||
notAfter, NULL /*pinarg*/,
|
||||
NULL /* log */);
|
||||
}
|
||||
if ( rv != SECSuccess ) goto finish;
|
||||
|
||||
if( ! isServer ) {
|
||||
/* This is the client side of an SSL connection.
|
||||
* Now check the name field in the cert against the desired hostname.
|
||||
* NB: This is our only defense against Man-In-The-Middle (MITM) attacks!
|
||||
*/
|
||||
if( peerCert == NULL ) {
|
||||
rv = SECFailure;
|
||||
} else {
|
||||
hostname = SSL_RevealURL(fd); /* really is a hostname, not a URL */
|
||||
if (hostname && hostname[0]) {
|
||||
rv = CERT_VerifyCertName(peerCert, hostname);
|
||||
} else {
|
||||
rv = SECFailure;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
if (peerCert!=NULL) CERT_DestroyCertificate(peerCert);
|
||||
return (int)rv;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,329 @@
|
|||
/*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the Netscape Security Services for Java.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU General Public License Version 2 or later (the
|
||||
* "GPL"), in which case the provisions of the GPL are applicable
|
||||
* instead of those above. If you wish to allow use of your
|
||||
* version of this file only under the terms of the GPL and not to
|
||||
* allow others to use your version of this file under the MPL,
|
||||
* indicate your decision by deleting the provisions above and
|
||||
* replace them with the notice and other provisions required by
|
||||
* the GPL. If you do not delete the provisions above, a recipient
|
||||
* may use your version of this file under either the MPL or the
|
||||
* GPL.
|
||||
*/
|
||||
|
||||
#include <nspr.h>
|
||||
#include <jni.h>
|
||||
#include <ssl.h>
|
||||
#include <sslerr.h>
|
||||
|
||||
#include <jssutil.h>
|
||||
#include <jss_exceptions.h>
|
||||
#include <java_ids.h>
|
||||
#include <pk11util.h>
|
||||
#include "jssl.h"
|
||||
|
||||
/*
|
||||
* This is done for regular sockets that we connect() and server sockets,
|
||||
* but not for sockets that come from accept.
|
||||
*/
|
||||
jbyteArray
|
||||
JSSL_socketCreate(JNIEnv *env, jobject self,
|
||||
jobject certApprovalCallback, jobject clientCertSelectionCallback)
|
||||
{
|
||||
jbyteArray sdArray = NULL;
|
||||
JSSL_SocketData *sockdata;
|
||||
PRStatus status;
|
||||
PRFileDesc *newFD;
|
||||
|
||||
/* create a TCP socket */
|
||||
newFD = PR_NewTCPSocket();
|
||||
if( newFD == NULL ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "PR_NewTCPSocket() returned NULL");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
sockdata = JSSL_CreateSocketData(env, self, newFD);
|
||||
if( sockdata == NULL ) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* enable SSL on the socket */
|
||||
sockdata->fd = SSL_ImportFD(NULL, sockdata->fd);
|
||||
if( sockdata->fd == NULL ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION, "SSL_ImportFD() returned NULL");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
status = SSL_OptionSet(sockdata->fd, SSL_SECURITY, PR_TRUE);
|
||||
if( status != SECSuccess ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to enable SSL security on socket");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* setup the handshake callback */
|
||||
status = SSL_HandshakeCallback(sockdata->fd, JSSL_HandshakeCallback,
|
||||
sockdata);
|
||||
if( status != PR_SUCCESS ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to install handshake callback");
|
||||
}
|
||||
|
||||
/* setup the cert authentication callback */
|
||||
if( certApprovalCallback != NULL ) {
|
||||
/* create global reference to the callback object */
|
||||
sockdata->certApprovalCallback =
|
||||
(*env)->NewGlobalRef(env, certApprovalCallback);
|
||||
if( sockdata->certApprovalCallback == NULL ) goto finish;
|
||||
|
||||
/* install the Java callback */
|
||||
status = SSL_AuthCertificateHook(
|
||||
sockdata->fd, JSSL_JavaCertAuthCallback,
|
||||
(void*) sockdata->certApprovalCallback);
|
||||
} else {
|
||||
/* install the default callback */
|
||||
status = SSL_AuthCertificateHook(
|
||||
sockdata->fd, JSSL_DefaultCertAuthCallback, NULL);
|
||||
}
|
||||
if( status != PR_SUCCESS ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to install certificate authentication callback");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* setup the client cert selection callback */
|
||||
if( clientCertSelectionCallback != NULL ) {
|
||||
/* create a new global ref */
|
||||
sockdata->clientCertSelectionCallback =
|
||||
(*env)->NewGlobalRef(env, clientCertSelectionCallback);
|
||||
if(sockdata->clientCertSelectionCallback == NULL) goto finish;
|
||||
|
||||
/* install the Java callback */
|
||||
status = SSL_GetClientAuthDataHook(
|
||||
sockdata->fd, JSSL_CallCertSelectionCallback,
|
||||
(void*) sockdata->clientCertSelectionCallback);
|
||||
if( status != PR_SUCCESS ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Unable to install client certificate selection callback");
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
/* pass the pointer back to Java */
|
||||
sdArray = JSS_ptrToByteArray(env, (void*) sockdata);
|
||||
if( sdArray == NULL ) {
|
||||
/* exception was thrown */
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if( (*env)->ExceptionOccurred(env) != NULL ) {
|
||||
if( sockdata != NULL ) {
|
||||
JSSL_DestroySocketData(env, sockdata);
|
||||
}
|
||||
} else {
|
||||
PR_ASSERT( sdArray != NULL );
|
||||
}
|
||||
return sdArray;
|
||||
}
|
||||
|
||||
JSSL_SocketData*
|
||||
JSSL_CreateSocketData(JNIEnv *env, jobject sockObj, PRFileDesc* newFD)
|
||||
{
|
||||
JSSL_SocketData *sockdata = NULL;
|
||||
|
||||
/* make a JSSL_SocketData structure */
|
||||
sockdata = PR_Malloc( sizeof(JSSL_SocketData) );
|
||||
sockdata->fd = NULL;
|
||||
sockdata->socketObject = NULL;
|
||||
sockdata->certApprovalCallback = NULL;
|
||||
sockdata->clientCertSelectionCallback = NULL;
|
||||
sockdata->clientCertNickname = NULL;
|
||||
|
||||
sockdata->fd = newFD;
|
||||
|
||||
/*
|
||||
* Make a global ref to the socket. Since it is a weak reference, it will
|
||||
* get garbage collected if this is the only reference that remains.
|
||||
* We do this so that sockets will get closed when they go out of scope
|
||||
* in the Java layer.
|
||||
*/
|
||||
sockdata->socketObject = NEW_WEAK_GLOBAL_REF(env, sockObj);
|
||||
if( sockdata->socketObject == NULL ) goto finish;
|
||||
|
||||
finish:
|
||||
if( (*env)->ExceptionOccurred(env) != NULL ) {
|
||||
if( sockdata != NULL ) {
|
||||
JSSL_DestroySocketData(env, sockdata);
|
||||
sockdata = NULL;
|
||||
} else {
|
||||
PR_ASSERT( sockdata != NULL );
|
||||
}
|
||||
}
|
||||
return sockdata;
|
||||
}
|
||||
|
||||
void
|
||||
JSSL_DestroySocketData(JNIEnv *env, JSSL_SocketData *sd)
|
||||
{
|
||||
PR_ASSERT(sd != NULL);
|
||||
|
||||
if( sd->fd != NULL ) {
|
||||
PR_Close(sd->fd);
|
||||
}
|
||||
if( sd->socketObject != NULL ) {
|
||||
DELETE_WEAK_GLOBAL_REF(env, sd->socketObject );
|
||||
}
|
||||
if( sd->certApprovalCallback != NULL ) {
|
||||
(*env)->DeleteGlobalRef(env, sd->certApprovalCallback);
|
||||
}
|
||||
if( sd->clientCertSelectionCallback != NULL ) {
|
||||
(*env)->DeleteGlobalRef(env, sd->clientCertSelectionCallback);
|
||||
}
|
||||
if( sd->clientCertNickname != NULL ) {
|
||||
PR_Free(sd->clientCertNickname);
|
||||
}
|
||||
PR_Free(sd);
|
||||
}
|
||||
|
||||
/*
|
||||
* These must match up with the constants defined in SSLSocket.java.
|
||||
*/
|
||||
PRInt32 JSSL_enums[] = {
|
||||
SSL_ENABLE_SSL2, /* 0 */
|
||||
SSL_ENABLE_SSL3, /* 1 */
|
||||
PR_SockOpt_NoDelay, /* 2 */
|
||||
PR_SockOpt_Keepalive, /* 3 */
|
||||
PR_SHUTDOWN_RCV, /* 4 */
|
||||
PR_SHUTDOWN_SEND, /* 5 */
|
||||
SSL_REQUIRE_CERTIFICATE, /* 6 */
|
||||
SSL_REQUEST_CERTIFICATE, /* 7 */
|
||||
SSL_NO_CACHE, /* 8 */
|
||||
|
||||
0
|
||||
};
|
||||
|
||||
void
|
||||
JSSL_socketBind(JNIEnv *env, jobject self, jbyteArray addrBA, jint port)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
PRNetAddr addr;
|
||||
jbyte *addrBAelems = NULL;
|
||||
PRStatus status;
|
||||
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) {
|
||||
/* exception was thrown */
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/*
|
||||
* setup the PRNetAddr structure
|
||||
*/
|
||||
addr.inet.family = AF_INET;
|
||||
addr.inet.port = htons(port);
|
||||
PR_ASSERT(sizeof(addr.inet.ip) == 4);
|
||||
PR_ASSERT( (*env)->GetArrayLength(env, addrBA) == 4);
|
||||
addrBAelems = (*env)->GetByteArrayElements(env, addrBA, NULL);
|
||||
if( addrBAelems == NULL ) {
|
||||
ASSERT_OUTOFMEM(env);
|
||||
goto finish;
|
||||
}
|
||||
memcpy(&addr.inet.ip, addrBAelems, 4);
|
||||
|
||||
/* do the bind() call */
|
||||
status = PR_Bind(sock->fd, &addr);
|
||||
if( status != PR_SUCCESS ) {
|
||||
PRErrorCode err = PR_GetError();
|
||||
switch( err ) {
|
||||
case PR_ADDRESS_NOT_AVAILABLE_ERROR:
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Binding exception: address not available");
|
||||
break;
|
||||
case PR_ADDRESS_IN_USE_ERROR:
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Binding exception: address in use");
|
||||
break;
|
||||
default:
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Binding exception");
|
||||
break;
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
|
||||
finish:
|
||||
if( addrBAelems != NULL ) {
|
||||
(*env)->ReleaseByteArrayElements(env, addrBA, addrBAelems, JNI_ABORT);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
JSSL_socketClose(JNIEnv *env, jobject self)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
|
||||
/* get the FD */
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) {
|
||||
/* exception was thrown */
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* destroy the FD and any supporting data */
|
||||
JSSL_DestroySocketData(env, sock);
|
||||
|
||||
finish:
|
||||
}
|
||||
|
||||
void
|
||||
JSSL_setNeedClientAuthNoExpiryCheck(JNIEnv *env, jobject self, jboolean b)
|
||||
{
|
||||
JSSL_SocketData *sock;
|
||||
SECStatus status;
|
||||
|
||||
if( JSSL_getSockData(env, self, &sock) != PR_SUCCESS) goto finish;
|
||||
|
||||
/*
|
||||
* Set the option on the socket
|
||||
*/
|
||||
status = SSL_OptionSet(sock->fd, SSL_REQUEST_CERTIFICATE, b);
|
||||
if( status != SECSuccess ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Failed to set REQUEST_CERTIFICATE option on socket");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if(b) {
|
||||
/*
|
||||
* Set the callback function
|
||||
*/
|
||||
status = SSL_AuthCertificateHook(sock->fd,
|
||||
JSSL_ConfirmExpiredPeerCert, NULL /*cx*/);
|
||||
if( status != SECSuccess ) {
|
||||
JSS_throwMsg(env, SOCKET_EXCEPTION,
|
||||
"Failed to set certificate authentication callback");
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
}
|
|
@ -39,7 +39,83 @@ struct JSSL_SocketData {
|
|||
jobject socketObject; /* weak global ref */
|
||||
jobject certApprovalCallback; /* global ref */
|
||||
jobject clientCertSelectionCallback; /* global ref */
|
||||
char *clientCertNickname;
|
||||
};
|
||||
typedef struct JSSL_SocketData JSSL_SocketData;
|
||||
|
||||
SECStatus
|
||||
JSSL_JavaCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig,
|
||||
PRBool isServer);
|
||||
|
||||
void
|
||||
JSSL_HandshakeCallback(PRFileDesc *fd, void *arg);
|
||||
|
||||
int
|
||||
JSSL_DefaultCertAuthCallback(void *arg, PRFileDesc *fd, PRBool checkSig,
|
||||
PRBool isServer);
|
||||
|
||||
int
|
||||
JSSL_CallCertSelectionCallback( void * arg,
|
||||
PRFileDesc * fd,
|
||||
CERTDistNames * caNames,
|
||||
CERTCertificate ** pRetCert,
|
||||
SECKEYPrivateKey ** pRetKey);
|
||||
|
||||
int
|
||||
JSSL_ConfirmExpiredPeerCert(void *arg, PRFileDesc *fd, PRBool checkSig,
|
||||
PRBool isServer);
|
||||
|
||||
int
|
||||
JSSL_GetClientAuthData( void * arg,
|
||||
PRFileDesc * fd,
|
||||
CERTDistNames * caNames,
|
||||
CERTCertificate ** pRetCert,
|
||||
SECKEYPrivateKey ** pRetKey);
|
||||
|
||||
|
||||
#ifdef JDK1_2
|
||||
/* JDK 1.2 and higher provide weak references in JNI. */
|
||||
|
||||
#define NEW_WEAK_GLOBAL_REF(env, obj) \
|
||||
((*env)->NewWeakGlobalRef((env), (obj)))
|
||||
#define DELETE_WEAK_GLOBAL_REF(env, obj) \
|
||||
((*env)->DeleteWeakGlobalRef((env), (obj)))
|
||||
|
||||
#else
|
||||
/* JDK 1.1 doesn't have weak references, so we'll have to use regular ones */
|
||||
|
||||
#define NEW_WEAK_GLOBAL_REF(env, obj) \
|
||||
((*env)->NewGlobalRef((env), (obj)))
|
||||
#define DELETE_WEAK_GLOBAL_REF(env, obj) \
|
||||
((*env)->DeleteGlobalRef((env), (obj)))
|
||||
|
||||
#endif
|
||||
|
||||
#define JSSL_getSockData(env, sockObject, sdptr) \
|
||||
JSS_getPtrFromProxyOwner(env, sockObject, SSLSOCKET_PROXY_FIELD, \
|
||||
SSLSOCKET_PROXY_SIG, (void**)sdptr)
|
||||
|
||||
|
||||
void
|
||||
JSSL_DestroySocketData(JNIEnv *env, JSSL_SocketData *sd);
|
||||
|
||||
|
||||
extern PRInt32 JSSL_enums[];
|
||||
|
||||
void
|
||||
JSSL_socketBind(JNIEnv *env, jobject self, jbyteArray addrBA, jint port);
|
||||
|
||||
void
|
||||
JSSL_socketClose(JNIEnv *env, jobject self);
|
||||
|
||||
jbyteArray
|
||||
JSSL_socketCreate(JNIEnv *env, jobject self,
|
||||
jobject certApprovalCallback, jobject clientCertSelectionCallback);
|
||||
|
||||
JSSL_SocketData*
|
||||
JSSL_CreateSocketData(JNIEnv *env, jobject sockObj, PRFileDesc* newFD);
|
||||
|
||||
void
|
||||
JSSL_setNeedClientAuthNoExpiryCheck(JNIEnv *env, jobject self, jboolean b);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -44,9 +44,12 @@ PACKAGE = org/mozilla/jss/ssl
|
|||
JNI_GEN = org.mozilla.jss.ssl.SSLSocket \
|
||||
$(NULL)
|
||||
|
||||
JSRCS = SSLHandshakeCompletedEvent.java \
|
||||
JSRCS = \
|
||||
SocketProxy.java \
|
||||
SSLHandshakeCompletedEvent.java \
|
||||
SSLSecurityStatus.java \
|
||||
SSLHandshakeCompletedListener.java \
|
||||
SSLServerSocket.java \
|
||||
SSLSocket.java \
|
||||
SSLInputStream.java \
|
||||
SSLOutputStream.java \
|
||||
|
@ -55,7 +58,9 @@ JSRCS = SSLHandshakeCompletedEvent.java \
|
|||
SSLClientCertificateSelectionCallback.java \
|
||||
$(NULL)
|
||||
|
||||
PRIVATE_JSRCS = SSLClient.java \
|
||||
PRIVATE_JSRCS = \
|
||||
SSLClient.java \
|
||||
SSLServer.java \
|
||||
TestCertApprovalCallback.java \
|
||||
TestClientCertificateSelectionCallback.java \
|
||||
$(NULL)
|
||||
|
@ -69,6 +74,7 @@ PRIVATE_JSRCS = SSLClient.java \
|
|||
CLASSES = SSLHandshakeCompletedEvent \
|
||||
SSLSecurityStatus \
|
||||
SSLHandshakeCompletedListener \
|
||||
SSLServerSocket \
|
||||
SSLSocket \
|
||||
PrintOutputStreamWriter \
|
||||
SSLCallbackNotifier \
|
||||
|
@ -76,7 +82,11 @@ CLASSES = SSLHandshakeCompletedEvent \
|
|||
SSLClientCertificateSelectionCallback \
|
||||
$(NULL)
|
||||
|
||||
#PRIVATE_CLASSES = SSLServer \
|
||||
PRIVATE_CLASSES = \
|
||||
SSLServer \
|
||||
SSLClient \
|
||||
$(NULL)
|
||||
|
||||
#SSLClient \
|
||||
#ServerHandshakeCB \
|
||||
#ClientHandshakeCB \
|
||||
|
@ -84,6 +94,8 @@ CLASSES = SSLHandshakeCompletedEvent \
|
|||
|
||||
CSRCS = SSLSocket.c \
|
||||
callbacks.c \
|
||||
SSLServerSocket.c \
|
||||
common.c \
|
||||
$(NULL)
|
||||
|
||||
LIBRARY_NAME = jssssl
|
||||
|
|
Загрузка…
Ссылка в новой задаче