openssl arm cross compile and example code

본 글은 openssl linux arm용 빌드 방법과 사용 예제를 싣고 있다.
openssl 코드는 아래 링크에서 다운 받을 수 있다.


arm cross compile

1. 다운 받은 파일의 압축을 푼다.

2. 압축 해제한 폴더에서 아래와 같이 실행하여 빌드 환경을 설정한다.

./Configure linux-elf --cross-compile-prefix=/home/my_account/armbian_toolchain/gcc-linaro-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf- shared no-threads no-zlib no-asm --prefix=/home/my_account/openssl/openssl-arm --openssldir=/home/my_account/openssl/openssl-arm

armbian toolchain을 사용한 예이다. 사용하는 toolchain의 위치 및 파일 이름 prefix는 --cross-compile-prefix 파라메터를 수정하면 된다. 빌드 된 라이브러리는 /home/my_account/openssl/openssl-arm위치에 복사하도록 설정하였다.

3. make install을 통해 openssl 라이브러리를 빌드하고, 설정된 위치에 파일을 설치한다.



example code

아래 예제 코드는 https 서버와 통신하기 위해 만들어진 코드 중 openssl api를 사용한 부분을 발췌한 것이다.

1. openssl 라이브러리 초기화
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/pem.h>
#include <openssl/x509.h>
#include <openssl/x509_vfy.h>

SSL_CTX *sslctx = NULL;

OpenSSL_add_all_algorithms();
SSL_library_init();
SSLeay_add_ssl_algorithms();
SSL_load_error_strings();

sslctx = SSL_CTX_new(SSLv23_client_method());
if(sslctx != 0)
{
SSL_CTX_set_options(sslctx, SSL_OP_NO_SSLv2); //Disabling SSLv2 will leave v3 and TSLv1 for negotiation.
}

2. openssl 라이브러리 사용 해제

if(sslctx)
{
SSL_CTX_free (sslctx);
sslctx = NULL;
}

ERR_remove_state(0);
ENGINE_cleanup();
CONF_modules_unload(1);
ERR_free_strings();
EVP_cleanup();
sk_SSL_COMP_free(SSL_COMP_get_compression_methods());
CRYPTO_cleanup_all_ex_data();


3. 연결
int fd = 0;
struct sockaddr_in addr_in;
int connect_retry = 10;
SSL *ssl = NULL;


/* 소켓 연결
*/
fd= socket(PF_INET, SOCK_STREAM, 0);
if (fd<= 0)
{
return -1;
}
memset((void *)&addr_in, 0x00, sizeof(addr_in));
addr_in.sin_family = AF_INET;
addr_in.sin_addr.s_addr = inet_addr(host_addr);
addr_in.sin_port = htons(port);
if (connect(fd, (struct sockaddr *)&addr_in, sizeof(addr_in)) == -1)
{
close(fd);
return -1;
}

/**/
ssl = SSL_new (sslctx);
if(ssl == 0)
{
return -1;
}

SSL_set_tlsext_host_name(ssl, host_name);
SSL_set_fd (ssl, fd ); // host와 연결된 socket을 사용 !!!

while(connect_retry>0)
{
ret = SSL_connect(ssl);
connect_retry--;
if(ret == 1)
{
               // 연결 성공
break;
}
else if(ret == 0)
{
print_ssl_err(SSL_get_error(ssl,ret));
return -1;
}
else
{
int code = SSL_get_error(ssl,ret);
switch(code)
{
case SSL_ERROR_WANT_READ: 
case SSL_ERROR_WANT_WRITE: 
                        /* 데이터 읽고,쓰는 과정에 아직 처리하지 못한 데이터가 남아있음을 의미한다. 
                        일정 시간 기다리거나, 다른 예외 처리가 필요하다. */
delay_ms(100);
continue;
default:
print_ssl_err(code);
return -1;
}
}
}

사용 완료된 SSL 구조체의 데이터는 아래 코드를 통해 리소스 반환한다.
if(ssl)
{
SSL_shutdown(ssl);
SSL_free(ssl);
}


4. 읽기, 쓰기

tx_len = SSL_write(ssl, tx, len);
rx_len = SSL_read (ssl, rx, len);

댓글

이 블로그의 인기 게시물

간단한 cfar 알고리즘에 대해

python ctypes LoadLibrary로 windows dll 로드 및 함수 호출 예제

base64 인코딩 디코딩 예제 c 소스

쉽게 설명한 파티클 필터(particle filter) 동작 원리와 예제

mkfs.fat Device or resource busy 에러 해결법