2013-08-24 3 views
1

В настоящее время я пытаюсь внедрить DTLS на Android для шифрования дейтаграмм UDP. Для этого я построил проект openssl-android available here, из этого я получил две общие библиотеки libssl.so и libcrypto.so, которые я переименовал libsslx.so и libcryptox.so, чтобы избежать путаницы с включенной библиотекой в ​​системе Android.Неопределенная ссылка на 'DTLS_client_method'

Тогда я положил эти файлы (и поэтому для OpenSSL заголовка папки) в моем андроида проекта в папке JNI со следующей структурой:

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 } 

И вот проблема, когда я создаю этот код, все функции в порядке, кроме самого важного, который является DTLSv1_client_method(), когда я инициализирую объект контекста по строке 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 там, я проверил на android-config.mk файле OpenSSL-андроида проекта чтобы убедиться, что функции не были исключены из результата buid, и я попытался увидеть содержимое файлов .so без успеха, кстати, я работаю над Mac OS X.

У кого-нибудь есть опыт работы с DTLS на Android? Буду признателен за помощь в решении этой проблемы.

EDIT: Мне удалось получить содержимое моих файлов .so с помощью инструмента arm-linux-androideabi-objdump и никаких следов любой функции DTLS. Возможно, это связано с процессом сборки openssl, который я сделал, но это странно, потому что DTLS не был отброшен в android-config.mk.

ответ

1

ОК, это решается путем выбора другого проекта для создания openssl и изменения имен разделяемых библиотек в файлах .mk, локализованных в папках/apps/ssl и/crypto, чтобы избежать путаницы, как это сказано в этом topic.

Вы можете найти проект, который я использовал под этим кодом url

Смежные вопросы