레이블이 ssl인 게시물을 표시합니다. 모든 게시물 표시
레이블이 ssl인 게시물을 표시합니다. 모든 게시물 표시

2014년 7월 14일 월요일

Tizen상에서 MQTT client 컴파일 하기 (with OpenSSL library)

Tizen 상에서 MQTT client들 중에서 C/C++ API들을 제공하는 solution 들을 테스트 하려 함.

대표적인 것은 Eclipse Paho와 libmosquitto 이며  (http://mqtt.org/wiki/doku.php/libraries)
대략 봤을 때는 두 solution들의 feature는 거의 유사하지만
코드 상으로는 libmosquitto가 다소 simple한 것 같아보임
(libmosquitto LOC 대략 7264, Paho LOC 대략 18395)..
(하지만 Paho도 simple한 것은 사실, 하지만 워낙 MQTT protocol 자체가 simple 하니...)

MQTT client를 테스트 해보려면
. 위 client library를 컴파일 해야 하고
. library 컴파일에 필요한 OpenSSL library를 컴파일 해야 하고
. application을 만들어 sample code를 포팅해야 함.



[MQTT client library compile]

1. Paho, libmosquitto를 tizen shared library로 컴파일 하기 위해서는
tizen sdk > File > New > Tizen Native Project > Library > Shared Library 프로젝트를 생성한다.


2. library 파일들을 inc, src 폴더로 복사한다.
 . Paho : sample 을 제외한 library 파일들을 복사
 . libmosquitto : python, js 파일들을 제외하고 복사

3. project setting
 . SSL/TLS 지원을 위해 preprocessor, include path 설정
  : Project properties > C/C++ Build > Settings > C++ Compiler/C Compiler > Preprocessor/Symbols
    >  Paho project : "OPEN_SSL", libmosquitto : "WITH_TLS" 설정
  : Project properties > C/C++ Build > Settings > C++ Compiler/C Compiler > Includes 에 OpenSSL source의 include path 설정 (아래)



[OpenSSL library compile]

Paho, libmosquitto에서 SSL/TLS 설정을 사용하고자 할 경우
Tizen에서 돌아가야할 OpenSSL의 libssl.so, libcrypto.so 가 필요함.
Tizen platform내의 OpenSSL shared library를 사용할 수 있겠지만
방법을 모르는 관계로 so를 만들어서 app과 함께 deploy해서 사용할 생각임.

일단 OpenSSL 최신버전을 다운 받을 수 있겠지만 Tizen용으로 빌드를 해야 하기에 git repository에 있는 것을 다운받아 컴파일 하자.
참고
 - Tizen GBS : https://source.tizen.org/ko/documentation/reference/git-build-system
 - GBS 빌드 방법 (by 서주영님)
    . source code download : http://seoz.egloos.com/3896390
    . GBS 설정 : http://seoz.egloos.com/3900549
 - cocos2d-x 포팅 후기 (by 이재홍님) : http://pyrasis.com/cocos2d-x/2013/05/19/cocos2d-x-tizen-port-post-mortem/


1. gerrit 등록 및 GBS 설정
 . gbs.conf는 는 tizen 홈피에 있는 것을 받아서 계정 정보(id, password) 추가
 . buildconf 주석'#' 처리
 . 서주영님 게시물 GBS 설정 3번 항목에 따라 URL 수정

2. OpenSSL repository clone
 . 일단 framework/security/openssl 를 다운 받았음... 사실 OpenSSL repository는 framework, platform 두개가 있는데 차이를 모르겠고 platform은 dependency가 있어 그냥 framework을 다운 받음.

3. 빌드 (gbs build -A armv7l)

빌드된 결과물은 rpm으로 나오겠지만 일단 so만 필요하므로
.gbs.conf 의 buildroot 경로에서 빌드 결과물 중 libssl.so, libcrypto.so 를
밑의 폴더에서  tizen app의 lib 폴더로 복사

~/GBS-ROOT-profile.tizen/local/BUILD-ROOTS/scratch.armv7l.0/home/abuild/rpmbuild/BUILD/openssl-1.0.0f

* 빌드 option 참고 (위쪽 서주영님 포스팅 발췌)

만약 빌드가 잘 안 되거나 GBS 설정 파일의 url을 바꾼 경우라면 아래와 같이 --clean 옵션을 이용하여 빌드를 하시기 바랍니다.

gbs build -A i586 --clean

만약 다운로드 받은 타이젠 소스코드를 수정하셨다면 아래와 같이 --include-all 옵션을 주어야 합니다.
GBS는 git에 커밋(commit)이 된 소스코드를 이용하여 빌드를 하기 때문에 소스코드를 수정했다면 git에 커밋을 해야 GBS로 빌드할 수 있습니다.
만약 커밋을 하지 않고 소스코드를 빌드하고 싶다면 --include-all 옵션을 주어야 합니다.

gbs build -A i586 --include-all

빌드 시 아키텍처를 선택하지 않았다면 기본적으로 i586으로 빌드가 되며 arm으로 빌드를 하려면 -A 옵션과 함께 armv7l을 인자로 주어야 합니다. (마지막의 l은 L의 소문자입니다.)

$ gbs build -A armv7l


[MQTT sample client app compile & run]

일단 MQTT client sample application을 만들어야 하므로
간단한 Tizen Form-based Application project를 만들어서
client 소스코드를 복사한다.

Paho의 경우 src/samples 내 pubsync.c, MQTTAsync_publish.c, MQTTAsync_subscribe.c 를 사용하고 mosquitto는 소스코드의 client 폴더 내 pub, sub sample를 사용

. 확장자를 cpp로 바꾸고
. main 함수의 이름을 바꾸고 header를 만들어 expose (단 naming mangling 방지를 위해 extern C 사용)
. sample들이 loop을 사용하므로 Tizen thread를 만들어 별도 thread에서 돌아가게 해야 함.
. application event handler에서 thread를 생성해서 실행하도록 코드 작성


그리고 application에서 위에서 만든 libpaho.so, libmosquitto.so 를 사용해야 하므로
application project에서 library project를 reference 하고 include path, library path & library 설정이 필요함 이 부분은 아래 링크에서 잘 설명 되어 있음.

- 오픈소스를 활용한 Tizen 용 web server 포팅 : http://tizenschools.com/?p=40
 . library들이 함께 사용하는 library들 - libdl, libssl, libcrypto

- 또한 SSL/TLS 를 사용하고자 할 경우 CA의 인증서가 필요하므로 이를 App과 함께 배포하고자 shared/data에 복사하고 mosquitto_tls_set, mosquitto_tls_opts_set 설정 함.
 * app과 자동배포가 안되는지 app에서 shared/data에 인증서가 없다. 그냥 public space에 인증서를 sdb pull로 밀어 넣고 해당 path로 접근하게 함.

2013년 12월 7일 토요일

Secure RESTful web service (HTTPS, SSL를 사용하는) 접속 방법

이전 블로그에서 이전 함 (원본 글 2013/12/07 작성)

한줄로 말해 
HTTPS 프로토콜로 접속을 해야 하는 RESTful web service를 위한 접속 방법에 대한 설명 (jersey를 사용)

자세한 것은 아래 링크에서 읽어 보면 되며 ....

Calling / Invoking Secure RESTful Web Service over HTTPS with JAX-RS in Java without Keystore & Truststore Information
 Posted by MyBhavesh on Dec 25, 2012 in Technical Blog | 0 comments
 The article is written for/using J2SE 6, Jersey 1.1.4.1 and Eclipse IDE for Java EE Developers [Ganymede].

그냥 마지막 샘플 코드를 수정해서 사용하면 ok 일듯..

다른 예제들을 찾아보긴 했는데 여기 예제가 제일 깔끔한듯하다. (Stackoverflow에서 무슨 공격에 취약해 질 수 있다는 보안 관련 언급이 있었는데 찾지는 못해서 적지는 못했음.)
SecureRestClientTrustManager, SecureRestClient 를 머지하고 jersey client만 생성하는 helper class로 수정 함.

 public class SSLClientHelper {

public static ClientConfig configureClient() {
TrustManager[ ] certs = new TrustManager[ ] {
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
}
};
SSLContext ctx = null;
try {
ctx = SSLContext.getInstance("TLS");
ctx.init(null, certs, new SecureRandom());
} catch (java.security.GeneralSecurityException ex) {
}
HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

ClientConfig config = new DefaultClientConfig();
try {
config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(
new HostnameVerifier() {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}, 
ctx
));
} catch(Exception e) {
}
return config;
}

public static Client createClient() {
return Client.create(SSLClientHelper.configureClient());
}
}

  Client client = null;
WebResource webResource = null;
JSONObject object = null;

try{
ServiceFind er.setIteratorProvider(new AndroidServiceIteratorProvider<Object>());

client = SSLClientHelper.createClient();
webResource = client.resource(wimple.getServicehost() + path);
ClientResponse response = webResource.type("application/x-www-form-urlencoded").post(ClientResponse.class, params);
String output = response.getEntity(String.class);
..... 생략....

 
* 참고로 Android에서 jersey를 사용하려면 아래의 글을 참고하여 추가 적인 helper class를 사용할 필요 있음.