2013-08-24 62 views
1

我目前正试图在android上实现DTLS以加密UDP数据报。 对于这一点,我建立了OpenSSL的,Android项目available here,从此我有两个共享库libssl.so和libcrypto.so我libsslx.so更名和libcryptox.so以避免在Android系统中包含的库混淆。未定义引用'DTLS_client_method'

然后我把这些文件(并因此对于OpenSSL的头文件夹)具有以下结构的JNI文件夹下到我的Android项目:

jni->|->includes--->openssl--->header files 
    | 
    |->precompiled-|->libcryptox.so 
    |    | 
    |    |->libsslx.so 
    | 
    |->Android.mk 
    | 
    |->security.cpp 

内容Android.mk文件:

LOCAL_PATH := $(call my-dir) 

include $(CLEAR_VARS) 

LOCAL_MODULE := sslx 
LOCAL_SRC_FILES := precompiled/libsslx.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/includes 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 
LOCAL_MODULE := cryptox 
LOCAL_SRC_FILES := precompiled/libcryptox.so 
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/includes 
include $(PREBUILT_SHARED_LIBRARY) 

include $(CLEAR_VARS) 

LOCAL_MODULE := security 
LOCAL_SRC_FILES := security.cpp 
LOCAL_SHARED_LIBRARIES := sslx cryptox 

include $(BUILD_SHARED_LIBRARY) 

内容security.cpp文件

1 #include <jni.h> 
2 #include <string.h> 
3 #include <sys/types.h> 
4 #include <sys/socket.h> 
5 #include <netinet/in.h> 
6 #include <arpa/inet.h> 

7 extern "C" { 

8 #include "openssl/bio.h" 
9 #include "openssl/ssl.h" 
10 #include "openssl/err.h" 

11 struct sockaddr_in dst; 

12 static int const SOCKET_ERROR = 1000; 
13 static int const SOCKET_CREATED = 1100; 
14 static int const BIO_ERROR = 1200; 
15 static int const BIO_CREATED = 1300; 
16 static int const CTX_ERROR = 1400; 
17 static int const CTX_CREATED = 1500; 
18 static int const SSL_ERROR = 1600; 
19 static int const SSL_CREATED = 1700; 

20 void Java_ch_gt_gcservjni_TestOpenSSLJni_initOpenSSL(JNIEnv *pEnv, jobject jObj){ 
21  SSL_load_error_strings(); 
22  ERR_load_BIO_strings(); 
23   OpenSSL_add_all_algorithms(); 
24 } 

25 jlong Java_ch_gt_gcservjni_TestOpenSSLJni_startConnection(JNIEnv *pEnv, jobject jObj, jstring jAddress, jint jPort){ 

26 char *address; 

27  jclass clazz = pEnv->GetObjectClass(jObj); 
28  jmethodID mid = pEnv->GetMethodID(clazz, "printMessage", "(I)V"); 
29  if(mid == 0) return -1; 

30  address = 0; 
31  if (jAddress) { 
32   address = (char *)pEnv->GetStringUTFChars(jAddress, 0); 
33   if (!jAddress) return 0; 
34  } 

    //Socket creation///////////////////////////////////////////////////////////////////////////// 
35  int sock = 0; 
36  int port = (int)jPort; 

37  struct sockaddr_in addr; 
38  addr.sin_addr.s_addr = htonl(INADDR_ANY); 
39  addr.sin_port = htons(port); 

40  sock = socket(PF_INET, SOCK_DGRAM, 0); 
41  if(sock < 0){ 
42   pEnv->CallVoidMethod(jObj, mid, SOCKET_ERROR); 
43  }else{ 
44   pEnv->CallVoidMethod(jObj, mid, SOCKET_CREATED); 
45  } 

    /////////////////////////////////////////////////////////////////////////////////////////////// 

    //Basic IO functionalities initialisation////////////////////////////////////////////////////// 
46  BIO* cnx = BIO_new_dgram(sock, BIO_NOCLOSE); 
47  if(cnx == NULL){ 
48   pEnv->CallVoidMethod(jObj, mid, BIO_ERROR); 
49  }else{ 
50   pEnv->CallVoidMethod(jObj, mid, BIO_CREATED); 
51  } 
    /////////////////////////////////////////////////////////////////////////////////////////////// 

52  struct sockaddr_in dst; 
53  struct sockaddr* d = (struct sockaddr*)&dst; 

54  dst.sin_family = AF_INET; 
55  dst.sin_port = htons(port); 
56  dst.sin_addr.s_addr = inet_addr(address); 

    //Set the BIO connection 
57  int err = BIO_dgram_set_peer(cnx, d); 

    //Initialisalisation of the Context/////////////////////////////////////////////////////////// 
58  SSL_CTX *ctx = SSL_CTX_new(DTLSv1_client_method()); 
59  if(ctx == NULL){ 
60   pEnv->CallVoidMethod(jObj, mid, CTX_ERROR); 
61  } 
62  else{ 
63   pEnv->CallVoidMethod(jObj, mid, CTX_CREATED); 
64  } 

65  SSL_CTX_set_read_ahead(ctx, 1); 
66  SSL_CTX_set_cipher_list(ctx, "HIGH:MEDIUM:aNull"); 

67  SSL *ssl = SSL_new(ctx); 
68  if(ssl == NULL){ 
69   pEnv->CallVoidMethod(jObj, mid, SSL_ERROR); 
70  } 
71  else{ 
72   pEnv->CallVoidMethod(jObj, mid, SSL_CREATED); 
73  } 

74  SSL_set_bio(ssl, cnx, cnx); 
75  SSL_set_connect_state(ssl); 
76  return 0; 
77 } 

78 } 

这里的问题是,当我编写这段代码时,除了最重要的一个函数,我在第58行初始化上下文对象时,所有函数都可以正常工作。

生成的错误是这一个:

/Applications/eclipse_bundle_mac/android-ndk-r8d/toolchains/arm-linux-androideabi-  4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/security/security.o: in function Java_ch_gt_gcservjni_TestOpenSSLJni_startConnection:jni/security.cpp:107: error: undefined reference to 'DTLSv1_client_method' 

如此看来,功能是不是在我建造图书馆参考,我检查了我的头文件中,DTLS功能在那里,我在的OpenSSL Android项目的android-config.mk文件检查看是否职能没有从打造专业化的结果排除在外,我想看看没有成功的.so文件的内容,顺便说一句,我的工作在Mac OS X

有没有人有关于android的DTLS的经验?我会很感激这个问题的一些帮助。

编辑:我设法让我的.so文件与ARM-Linux的androideabi-objdump的工具,并没有任何DTLS功能跟踪的内容。它可能来自我做过的openssl构建过程,但这很奇怪,因为DTLS在android-config.mk中没有被丢弃。

回答

1

好,它是由刚刚好转的另一个项目在/应用/ SSL localted的.mk文件和/加密的文件夹建立OpenSSL和修改共享库的名称,以避免混淆就像是在这个topic告诉迎刃而解。

你可以找到我根据本url

使用的项目