/*
* Copyright (C) 2018 Android WallPad Project
*
* FileName : SslClient.java
* Project : Android WallPad Project
* Company : HDC I-CONTROLS ( www.icontrols.co.kr )
* Author : Kang Sang Ho , lairu@icontrols.co.kr
*/
package kr.co.icontrols.sslapi;
import android.util.Log;
import com.util.LogUtil;
import java.net.InetAddress;
import java.net.Socket;
import java.security.cert.X509Certificate;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
/**
* @description
* SSL Client 용 소켓 생성을 지원하는 api 이다.
*
* @import
* kr.co.icontrols.sslapi.SslClient
*/
public class SSLClient {
private final String TAG = "SSLClient";
private Socket sslSocket = null;
private byte [] ServerIP = null;
/**
* SSL 암호화된 Socket 을 생성한다. (client 전용)
*
* @param host - 소켓에 연결되어야 하는 호스트 주소
* @param port - 소켓이 접속되고있는 호스트의 포트 번호
*
*
* @Example
*
* // SslClient 정의
* SslClient sslClientSocket = new SslClient("10.0.1.1", 10000);
* // Socket 가져오기
* Socket socket = sslClientSocket.getSocket();
*
*/
public SSLClient(String host, int port) {
// 1. Param Check
if (host == null) {
Log.w(TAG, "[SSLClient] Param 'host' is null !!!");
return;
}
// 2. IP Convert & Check
byte [] retIP = IPConverting(host);
if (retIP == null) {
Log.w(TAG, "[SSLClient] IPConverting Error !!!");
return;
}
ServerIP = retIP;
// 3. TLS Socket Make
try {
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, trustAllCerts, null);
SSLSocketFactory sf = context.getSocketFactory();
// [2018-02-08]
// * 서버에 DNS Server (bind9)를 설치하여 문제는 해결하였으나, 불필요한 DNS Lookup을 막고자
// 호스트네임이 정의된 InetAddress 로 IP를 부여함.
// DNS Lookup 이 일어나지 않게 하기 위하여 호스트네임이 정의된 InetAddress 로 주소를 부여함.
// IP 만을 "10.0.1.1" 이런 형태로 부여할 경우 Cache 에 접속정보가 없을경우 DNS Lookup이 일어나게되며,
// DNS Server 가 없을 경우 지연현상이 발생됨.
InetAddress mInetAddress = InetAddress.getByAddress("", ServerIP);
sslSocket = sf.createSocket(mInetAddress, port);
} catch (RuntimeException re) {
LogUtil.errorLogInfo("", TAG, re);
}
catch (Exception e) {
Log.e(TAG, "[SSLClient] TLS Socket Make Exception Error");
LogUtil.errorLogInfo("", TAG, e);//e.printStackTrace();
}
}
/**
* 생성된 SSL Socket 을 반환한다.
*
* @return (Socket) sslSocket
*/
public Socket getSocket() {
return sslSocket;
}
/**
* 신뢰할 수 있는 인증기관의 공개키 인지 검증하는 코드를 사용자 코드로 대체
* 아무런 동작을 하지 않으며 모든 서버 연결을 신뢰한다는 의미이다.
*/
private TrustManager[] trustAllCerts = new TrustManager[] {
new X509TrustManager() {
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] myTrustedAnchors = new X509Certificate[0];
return myTrustedAnchors;
}
@Override
public void checkClientTrusted(X509Certificate[] certs, String authType) {}
@Override
public void checkServerTrusted(X509Certificate[] certs, String authType) {}
}
};
/**
* String IP 를 Byte [] IP 로 변환한다.
*
* @param inIP - (String) input IP
*
* @return (byte []) output IP
*/
private byte [] IPConverting(String inIP) {
// 1. Param Check
if (inIP == null) return null;
// 2. Convert
char [] CharArray = inIP.toCharArray();
if (CharArray == null) return null;
for (int i = 0; i < CharArray.length; i++) if (CharArray[i] == '.') CharArray[i] = ';';
String newIP = new String(CharArray);
String[] splitData = newIP.split(";");
if(splitData == null) return null;
if(splitData.length != 4) return null;
byte [] outIParray = new byte [4];
for(int i=0 ; i