我目前正試圖在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中沒有被丟棄。