2013-08-24 90 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

使用的項目