본 글은 HTTPS를 위한 Root certificate를 코드에 적용시키는 방법에 대한 글입니다.


Embedded SSL을 하다보니 자질구래한 일들이 꽤 많습니다. 그 중 하나가 바로 Certificate입니다. Certificate는 글자 그대로 인증서입니다. 모든 HTTPS 서버는 인증서를 가지고 있습니다. 그리고 그 인증서를 인증해주는 상위 인증서들이 있습니다. 맨 꼭대기에 위치해 있는 인증서가 바로 Root certificate이고 이 Root certificate는 시만텍 등 세계적인 보안기업들이 관리하고 있지요.


SSL을 하려면 이 인증서가 필요한데요 Server에 SSL을 적용하려면 돈을 내고 상위 인증기관으로부터 인증서를 발급받아야 하는데 ㅎㅎㅎ 당연하겠지만 돈이 필요합니다. 그럼 Client는 어떻게 할까요? 대부분의 경우에는 자체 인증서 발급이 필요가 없습니다. 하지만 접속하려는 SSL 서버의 Root 인증서가 필요합니다. 왜냐하면 내가 접속하려는 서버가 진짜 내가 접속하려는 서버가 맞는지 확인을 하기 위함입니다. 흔히들 그런 가짜 서버를 피싱서버/피싱사이트라고 부르죠 ㅎㅎ


Embedded SSL에도 가짜 서버/진짜 서버를 구현하기 위해 Root certificate가 필요합니다.(반드시 필요한 것은 아닙니다. 그리고 제 기억으로는 Root 인증서가 아니어도 차상위 인증서여도 체킹이 가능하다고 알고 있는데 오래되서 잘 기억이... 확실하게  확인 후에 포스팅을 수정토록 하겠습니다. 죄송.) 그러려면 certificate를 embedded system에 코드 형태로 내장해야 합니다. 그 방법을 이 포스팅에서 설명하려고 합니다.


!!!mbedTLS 기준입니다.!!!


1. Certificate는 어디서 찾는가?

바로 브라우져에서 다운로드 받을 수 있습니다. 예를 들어 https://twitter.com/의 경우를 보겠습니다.


가. chrome으로 트위터에 접속합니다.



나. F12 key를 눌러 개발자 모드로 바꾼 후 Security tap을 선택합니다.



다. View certificate를 클릭하면 나타나는 인증서 팝업창에서 인증 경로 탭을 선택합니다.



라. 가장 위에 있는 인증서를 선택 후 더블 클릭하면 해당 인증서의 팝업창이 나타납니다.



2. Certificate는 어떻게 다운로드 받는가?


가. 인증서 팝업창에서 "자세히" 탭으로 이동하여 파일에 복사 버튼을 클릭합니다.



다. 인증서 내보내기 마법사가 시작되면 다음을 클릭합니다.



라. Base64 형식을 선택 후 다음을 클릭합니다.



마. 찾아보기를 클릭하여 원하는 위치에 원하는 이름으로 인증서를 저장합니다.



3. Certificate를 code에 넣기!


가. Certificate를 메모장으로 open합니다.



나. certificate.h와 같은 header 파일을 하나 만들어 복사하여 붙여넣기 합니다.


다. 변수 선언 하고 각 행의 끝에 개행문자를 삽입합니다. ( 다음 코드 참고!)

const char	api_twitter_com[] =	\
"-----BEGIN CERTIFICATE-----\r\n"  \
"MIIF7DCCBNSgAwIBAgIQbsx6pacDIAm4zrz06VLUkTANBgkqhkiG9w0BAQUFADCB\r\n"  \
"yjELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQL\r\n"  \
"ExZWZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTowOAYDVQQLEzEoYykgMjAwNiBWZXJp\r\n"  \
"U2lnbiwgSW5jLiAtIEZvciBhdXRob3JpemVkIHVzZSBvbmx5MUUwQwYDVQQDEzxW\r\n"  \
"ZXJpU2lnbiBDbGFzcyAzIFB1YmxpYyBQcmltYXJ5IENlcnRpZmljYXRpb24gQXV0\r\n"  \
"aG9yaXR5IC0gRzUwHhcNMTAwMjA4MDAwMDAwWhcNMjAwMjA3MjM1OTU5WjCBtTEL\r\n"  \
"MAkGA1UEBhMCVVMxFzAVBgNVBAoTDlZlcmlTaWduLCBJbmMuMR8wHQYDVQQLExZW\r\n"  \
"ZXJpU2lnbiBUcnVzdCBOZXR3b3JrMTswOQYDVQQLEzJUZXJtcyBvZiB1c2UgYXQg\r\n"  \
"aHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL3JwYSAoYykxMDEvMC0GA1UEAxMmVmVy\r\n"  \
"aVNpZ24gQ2xhc3MgMyBTZWN1cmUgU2VydmVyIENBIC0gRzMwggEiMA0GCSqGSIb3\r\n"  \
"DQEBAQUAA4IBDwAwggEKAoIBAQCxh4QfwgxF9byrJZenraI+nLr2wTm4i8rCrFbG\r\n"  \
"5btljkRPTc5v7QlK1K9OEJxoiy6Ve4mbE8riNDTB81vzSXtig0iBdNGIeGwCU/m8\r\n"  \
"f0MmV1gzgzszChew0E6RJK2GfWQS3HRKNKEdCuqWHQsV/KNLO85jiND4LQyUhhDK\r\n"  \
"tpo9yus3nABINYYpUHjoRWPNGUFP9ZXse5jUxHGzUL4os4+guVOc9cosI6n9FAbo\r\n"  \
"GLSa6Dxugf3kzTU2s1HTaewSulZub5tXxYsU5w7HnO1KVGrJTcW/EbGuHGeBy0RV\r\n"  \
"M5l/JJs/U0V/hhrzPPptf4H1uErT9YU3HLWm0AnkGHs4TvoPAgMBAAGjggHfMIIB\r\n"  \
"2zA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLnZlcmlz\r\n"  \
"aWduLmNvbTASBgNVHRMBAf8ECDAGAQH/AgEAMHAGA1UdIARpMGcwZQYLYIZIAYb4\r\n"  \
"RQEHFwMwVjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cudmVyaXNpZ24uY29tL2Nw\r\n"  \
"czAqBggrBgEFBQcCAjAeGhxodHRwczovL3d3dy52ZXJpc2lnbi5jb20vcnBhMDQG\r\n"  \
"A1UdHwQtMCswKaAnoCWGI2h0dHA6Ly9jcmwudmVyaXNpZ24uY29tL3BjYTMtZzUu\r\n"  \
"Y3JsMA4GA1UdDwEB/wQEAwIBBjBtBggrBgEFBQcBDARhMF+hXaBbMFkwVzBVFglp\r\n"  \
"bWFnZS9naWYwITAfMAcGBSsOAwIaBBSP5dMahqyNjmvDz4Bq1EgYLHsZLjAlFiNo\r\n"  \
"dHRwOi8vbG9nby52ZXJpc2lnbi5jb20vdnNsb2dvLmdpZjAoBgNVHREEITAfpB0w\r\n"  \
"GzEZMBcGA1UEAxMQVmVyaVNpZ25NUEtJLTItNjAdBgNVHQ4EFgQUDURcFlNEwYJ+\r\n"  \
"HSCrJfQBY9i+eaUwHwYDVR0jBBgwFoAUf9Nlp8Ld7LvwMAnzQzn6Aq8zMTMwDQYJ\r\n"  \
"KoZIhvcNAQEFBQADggEBAAyDJO/dwwzZWJz+NrbrioBL0aP3nfPMU++CnqOh5pfB\r\n"  \
"WJ11bOAdG0z60cEtBcDqbrIicFXZIDNAMwfCZYP6j0M3m+oOmmxw7vacgDvZN/R6\r\n"  \
"bezQGH1JSsqZxxkoor7YdyT3hSaGbYcFQEFn0Sc67dxIHSLNCwuLvPSxe/20majp\r\n"  \
"dirhGi2HbnTTiN0eIsbfFrYrghQKlFzyUOyvzv9iNw2tZdMGQVPtAhTItVgooazg\r\n"  \
"W+yzf5VK+wPIrSbb5mZ4EkrZn0L74ZjmQoObj49nJOhhGbXdzbULJgWOw27EyHW4\r\n"  \
"Rs/iGAZeqa6ogZpHFt4MKGwlJ7net4RYxh84HqTEy2Y=\r\n"  \
"-----END CERTIFICATE-----\r\n";


쉽지요? 다른 사이트의 인증서도 위와 같은 방식으로 다운로드 후 code에 적용할 수 있습니다.


수고하셔요~~

저작자 표시
신고

'Interface' 카테고리의 다른 글

HTTPS Root Certificate 다운로드 및 코드 적용 방법  (0) 2017.06.27

SSL/TLS embedded for IoT #8

Embedded SSL 2017.06.27 16:34 Posted by Dwarp

SSL/TLS embedded for IoT


이 글은 embedded IoT device의 보안에 관한 글입니다.


embedded SSL/TLS 여덟번째입니다.


대만 출장으로 인해 이번 포스팅이 조금 늦었습니다. 그리고 이번 강의 후 인도 출장이 잡혀 있어 약 2-3주 간 글 업로드가 힘들 것 같습니다. 양해 바랍니다. 그럼 시작해봅시다.


저번 시간에 초기화와 handshake를 제외한 SSL 함수들을 만들어 보았습니다. 계속 이어서 가봅시다. 초기화입니다.


초기화 함수는 mbed의 example을 참고하였습니다. 해당 example은 다운로드 받은 mbedtls 소스 중 programs 폴더 -> ssl 폴더에 있습니다. 하지만 여러분들이 이 글을 읽는 이유는 embedded SSL을 구현에 시간을 단축하기 위함이므로 바로 정리해 놓은 초기화 함수를 올리겠습니다.



조금 길어요~


unsigned char wiz_mbedtls_ssl_init(wiz_ssl_context* sslContext, uint8_t* SocketHandler)
{
	int ret = 1;
#if defined (MBEDTLS_ERROR_C)
	char error_buf[100];
#endif

#if defined (MBEDTLS_DEBUG_C)
	debug_set_threshold(DEBUG_LEVEL);
#endif

	/*
	Initialize session data
	*/
#if defined (MBEDTLS_ENTROPY_C)
	sslContext->entropy = malloc(sizeof(mbedtls_entropy_context));
	mbedtls_entropy_init( sslContext->entropy);
#endif
	sslContext->ctr_drbg = malloc(sizeof(mbedtls_ctr_drbg_context));
	sslContext->ssl = malloc(sizeof(mbedtls_ssl_context));
	sslContext->conf = malloc(sizeof(mbedtls_ssl_config));
	sslContext->cacert = malloc(sizeof(mbedtls_x509_crt));

	mbedtls_ctr_drbg_init(sslContext->ctr_drbg);
	mbedtls_x509_crt_init(sslContext->cacert);
	mbedtls_ssl_init(sslContext->ssl);
	mbedtls_ssl_config_init(sslContext->conf);
	/*
	Initialize certificates
	*/
#if defined (MBEDTLS_X509_CRT_PARSE_C)
#if defined (MBEDTLS_DEBUG_C)
	printf(" Loading the CA root certificate \r\n");
#endif
	mbedtls_ssl_config_defaults((sslContext->conf),
								MBEDTLS_SSL_IS_CLIENT,
								MBEDTLS_SSL_TRANSPORT_STREAM,
								MBEDTLS_SSL_PRESET_DEFAULT);
	mbedtls_ssl_setup((sslContext->ssl), (sslContext->conf));
	//mbedtls_ssl_set_timer_cb(sslContext->ssl,NULL,SSLFSetTimerCB,SSLFGetTimerCB);
	//mbedtls_ssl_set_hostname(sslContext->ssl, HOST_NAME);
#if defined (MBEDTLS_CERTS_C)
	ret = mbedtls_x509_crt_parse((sslContext->cacert),(unsigned char *)CERTIFICATE,strlen(CERTIFICATE));
#else
	ret = 1;
#if defined (MBEDTLS_DEBUG_C)
	printf("SSL_CERTS_C not define .\r\n");
#endif
#endif
#endif
	if(ret < 0)
	{
#if defined (MBEDTLS_CERTS_C)
		printf("x509_crt_parse failed.%x \r\n",ret);
#endif
		return 0;
	}
	/*
	set ssl session para
	*/
	mbedtls_ssl_conf_ca_chain(sslContext->conf, sslContext->cacert, NULL);
	mbedtls_ssl_conf_endpoint(sslContext->conf,MBEDTLS_SSL_IS_CLIENT); 		//set the current communication method is SSL Client
	mbedtls_ssl_conf_authmode(sslContext->conf,MBEDTLS_SSL_VERIFY_REQUIRED);
	mbedtls_ssl_conf_rng(sslContext->conf,SSLRandomCB,sslContext->ctr_drbg);
        mbedtls_ssl_conf_read_timeout(sslContext->conf,WIZ_RECV_TIMEOUT_VALUE);
#if defined (MBEDTLS_DEBUG_C)
	mbedtls_ssl_conf_dbg(sslContext->conf,wiz_mbedtls_ssl_debug_cb,stdout);
#endif
	mbedtls_ssl_set_bio(sslContext->ssl,SocketHandler, wiz_mbedtls_ssl_send, wiz_mbedtls_ssl_recv, wiz_mbedtls_ssl_recvtimeout); //set client's socket send and receive functions

	return 1;
}

코드를 간단하게 설명하겠습니다.

함수 자체는 wiz_ssl_context* sslContext와 uint8_t* sockethandler인자를 받습니다. 여기서 sslContext는 ssl에 필요한 context 변수들을 structure로 선언해 놓은 것이고 sockethandler는 단순하게 소켓 번호라고 생각하시면 됩니다.

아래는 wiz_ssl_context의 structure definition 입니다.

typedef struct{
#if defined (MBEDTLS_ENTROPY_C)
	mbedtls_entropy_context* entropy;
#endif
	mbedtls_ctr_drbg_context* ctr_drbg;
	mbedtls_ssl_context* ssl;
	mbedtls_ssl_config* conf;
	mbedtls_x509_crt* cacert;
}wiz_ssl_context;

structure 내부에 여러가지 변수들이 있는데 각각의 의미는 별도의 블로깅이 필요합니다. 일단 우리는 embedded ssl library를 사용하는 것에 목적을 두고 블로깅을 하고 있으니 너무 심오하게 생각하지 말고 넘어갑시다.


이 후에는 각각의 변수를 malloc을 통해 memory를 할당합니다. embedded에서 왠 malloc? 이라고 생각하시는 분들이 많을 수도 있습니다. 그냥 쓰세요. 어차피 mbedtls 자체가 malloc을 사용하고 있으니까요. 그래도 malloc이 불편하신 분들은 global로 선언해서 사용하셔도 되는데 대신 유연성이 엄청 떨어지겠죠? 트레이드 오프가 필요합니다.(malloc을 사용하기 때문에 최소 48kb보다 큰 sram을 가지고 있는 mcu를 추천하는 것입니다.)


그리고 각각을 mbedtls의 내장 함수들로 초기화 합니다. 그 다음은 ssl configuration을 설정하구요. 여기서 client로 할지 TCP로 할지 결정을 합니다. 그 이후에는 mbedtls_ssl_setup함수를 통해 sslcontext와 configuration을 setup 하구요.


이 후 Certificate를 등록합니다. 여기에서 CERTIFICATE에 주목할 필요가 있는데요. 이 CERTIFICATE는 Server의 ROOT certificate를 등록해야 합니다. 해당 certificate는 시스템에 내장해야 하는데요. 내장하지 않으면 내가 접속하려는 server가 진짜인지 가짜인지 구분을 할 수 없습니다. 한마디로 피싱 사이트를 구분해내지 못한다고 생각하시면 됩니다.

ret = mbedtls_x509_crt_parse((sslContext->cacert),(unsigned char *)CERTIFICATE,strlen(CERTIFICATE)); 

해당 Certificate는 인터넷 브라우져에서 다운로드 받아 text로 저장한 뒤 certificate.h 라는 파일을 하나 만들어서 복붙하시고 다음과 같은 형식으로 수정하시면 됩니다. (Certificate를 코드에 적용하는 방)

const char	graph_facebook_com[] = \
"-----BEGIN CERTIFICATE-----\r\n"  \
"MIIEsTCCA5mgAwIBAgIQBOHnpNxc8vNtwCtCuF0VnzANBgkqhkiG9w0BAQsFADBs\r\n"  \
"MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3\r\n"  \
"d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j\r\n"  \
"ZSBFViBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcDEL\r\n"  \
"MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3\r\n"  \
"LmRpZ2ljZXJ0LmNvbTEvMC0GA1UEAxMmRGlnaUNlcnQgU0hBMiBIaWdoIEFzc3Vy\r\n"  \
"YW5jZSBTZXJ2ZXIgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC2\r\n"  \
"4C/CJAbIbQRf1+8KZAayfSImZRauQkCbztyfn3YHPsMwVYcZuU+UDlqUH1VWtMIC\r\n"  \
"Kq/QmO4LQNfE0DtyyBSe75CxEamu0si4QzrZCwvV1ZX1QK/IHe1NnF9Xt4ZQaJn1\r\n"  \
"itrSxwUfqJfJ3KSxgoQtxq2lnMcZgqaFD15EWCo3j/018QsIJzJa9buLnqS9UdAn\r\n"  \
"4t07QjOjBSjEuyjMmqwrIw14xnvmXnG3Sj4I+4G3FhahnSMSTeXXkgisdaScus0X\r\n"  \
"sh5ENWV/UyU50RwKmmMbGZJ0aAo3wsJSSMs5WqK24V3B3aAguCGikyZvFEohQcft\r\n"  \
"bZvySC/zA/WiaJJTL17jAgMBAAGjggFJMIIBRTASBgNVHRMBAf8ECDAGAQH/AgEA\r\n"  \
"MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIw\r\n"  \
"NAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy\r\n"  \
"dC5jb20wSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybDQuZGlnaWNlcnQuY29t\r\n"  \
"L0RpZ2lDZXJ0SGlnaEFzc3VyYW5jZUVWUm9vdENBLmNybDA9BgNVHSAENjA0MDIG\r\n"  \
"BFUdIAAwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ\r\n"  \
"UzAdBgNVHQ4EFgQUUWj/kK8CB3U8zNllZGKiErhZcjswHwYDVR0jBBgwFoAUsT7D\r\n"  \
"aQP4v0cB1JgmGggC72NkK8MwDQYJKoZIhvcNAQELBQADggEBABiKlYkD5m3fXPwd\r\n"  \
"aOpKj4PWUS+Na0QWnqxj9dJubISZi6qBcYRb7TROsLd5kinMLYBq8I4g4Xmk/gNH\r\n"  \
"E+r1hspZcX30BJZr01lYPf7TMSVcGDiEo+afgv2MW5gxTs14nhr9hctJqvIni5ly\r\n"  \
"/D6q1UEL2tU2ob8cbkdJf17ZSHwD2f2LSaCYJkJA69aSEaRkCldUxPUd1gJea6zu\r\n"  \
"xICaEnL6VpPX/78whQYwvwt/Tv9XBZ0k7YXDK/umdaisLRbvfXknsuvCnQsH6qqF\r\n"  \
"0wGjIChBWUMo0oHjqvbsezt3tkBigAVBRQHvFwY+3sAzm2fTYS5yh+Rp/BIAV0Ae\r\n"  \
"cPUeybQ=\r\n"  \
"-----END CERTIFICATE-----\r\n";

이제 session 파라미터들을 입력하고 앞서 만들어 놓은 random, recv, send 등의 콜백 함수를 등록하면 마무리 됩니다.


웁스! 한가지 말씀 안드린게 있어요. Debug용 call back도 등록하셔야 하는데 mbedtls에서 제공하는 형식만 맞추고 함수 내부에서 uart와 연결된 printf를 사용하시면 됩니다.

#if defined (MBEDTLS_DEBUG_C)
void wiz_mbedtls_ssl_debug_cb(void *ctx, int level, const char *file, int line, const char *str)
{
    if(level < DEBUG_LEVEL)
    {
       printf("%s\r\n",str);
    }
}
#endif

그럼 이것으로 초기화 함수에 대한 설명은 마무리 짓고 handshake로 넘어가겠습니다. SSL의 첫번째 과정이 바로 Handshake입니다. 구글링 해보시면 ssl handshake에 대해 많이 나오는데 딱히 이해못할 만한 내용은 없습니다. handshake 과정 중에서 암호화 방식을 결정하고 certificate 교환하는 게 전부입니다. handshake가 끝나면 암호화된 데이터로 통신이 가능하게 됩니다.


unsigned int wiz_mbedtls_ssl_handshake(wiz_ssl_context* sslContext)
{
    int ret;
    uint32_t flags;
//#if defined(MBEDTLS_ERROR_C)
//    unsigned char error_buf[100];
//    memset(error_buf, 0, 100);
//#endif
#if defined(WIZINTERFACE_DEBUG)
    printf( "  . Performing the SSL/TLS handshake..." );
#endif

    while( ( ret = mbedtls_ssl_handshake( sslContext->ssl ) ) != 0 )
    {
        if( ret != MBEDTLS_ERR_SSL_WANT_READ && ret != MBEDTLS_ERR_SSL_WANT_WRITE )
        {
//#if defined(MBEDTLS_ERROR_C)
//            mbedtls_strerror( ret, (char *) error_buf, 100 );
//            printf( " failed\n\r  ! mbedtls_ssl_handshake returned %d: %s\n\r", ret, error_buf );
//#endif
            return( -1 );
        }
    }
#if defined(WIZINTERFACE_DEBUG)
    printf( " ok\n\r    [ Ciphersuite is %s ]\n\r", mbedtls_ssl_get_ciphersuite( sslContext->ssl ) );
    printf( "  . Verifying peer X.509 certificate..." );
#endif
    /* In real life, we probably want to bail out when ret != 0 */
    if( ( flags = mbedtls_ssl_get_verify_result( sslContext->ssl ) ) != 0 )
    {
        //char vrfy_buf[512];
#if defined(WIZINTERFACE_DEBUG)
        printf( " failed.\n\r" );
#endif
        //mbedtls_x509_crt_verify_info( vrfy_buf, sizeof( vrfy_buf ), "  ! ", flags );

        //printf( "%s\n\r", vrfy_buf );
    }
    else
        printf( " ok.\n\r" );

    return( 0 );
}


handshake 함수는 생각보다 짧습니다. 위 코드를 보면 mbedtls_ssl_handshake로 handshake가 완료될 때까지 뺑뺑이를 돌린 후 certificate가 맞는지 확인만 하면 됩니다. 생각보다 간단하지요? 그럼 어느정도 ssl을 위한 함수가 준비되었습니다.


이제 실전!!! 실전!!! 실전!!! 음... SSL로 어디에 접속해보면 좋을까 생각해 올게요.


혹시 의견 있으시면 댓글 달아 주세요. 반영해 드립니다. ^^ 그럼 수고하시구요. 전 인도 벵갈루루에 다녀와야할 것 같아요.ㅠㅠ 인도는 덥고 지금 우기이고 ㅠㅠ 암튼 7월 10일 이후에나 다시 포스팅을 할 수 있을 것 같습니다. 다음에 봐요~ 안녕~


(일부 코드 내용이 틀린 점이 있습니다. 코드가 모두 완성되면 zip file로 업로드 할테니까 너무 조바심 내지 마시구요~ ^^)



저작자 표시
신고

'Embedded SSL' 카테고리의 다른 글

SSL/TLS embedded for IoT #8  (0) 2017.06.27
SSL/TLS embedded for IoT #7  (0) 2017.06.19
SSL/TLS embedded for IoT #6  (0) 2017.06.17
SSL/TLS embedded for IoT #5  (0) 2017.06.16
SSL/TLS embedded for IoT #4  (0) 2017.06.15
SSL/TLS embedded for IoT #3  (6) 2016.12.28

SSL/TLS embedded for IoT #7

Embedded SSL 2017.06.19 17:00 Posted by Dwarp

SSL/TLS embedded for IoT


이 글은 embedded IoT device의 보안에 관한 글입니다.


embedded SSL/TLS 일곱번째입니다.



다시 달려 보겠습니다.(뭐 물론 저 혼자만의 느낌이지만.. ㅠㅠ)


저번시간에 만들어야할 함수 목록들이 있었습니다. 7개 정도? 있었지요? 한 번 만들어 봅시다. 물론 mbedTLS configuration 등 신경써야 할 부분이 많습니다. 하지만 장담하건데 시작하시기도 전에 지치실 수 있습니다. 그러니 아무 생각 말고 걱정 말고 따라 오셔요 ㅎㅎ.


아래가 만들어야 할 함수 목록 이라고 말씀드렸습니다. 사실 안만드셔도 됩니다. 하지만 사용하시려면 결국 만드실 겁니다. 


wiz_mbedtls_ssl_init();

wiz_mbedtls_ssl_deinit();

wiz_mbedtls_ssl_handshake();

wiz_mbedtls_ssl_random();

wiz_mbedtls_ssl_send();

wiz_mbedtls_ssl_recv();

wiz_mbedtls_ssl_recvtimeout();


자 그럼 뭐부터 할까요? 전 언제나 가장 쉬운 것부터 합니다. 가장 기본적인 send와 recv 함수부터 만들어 보도록 하겠습니다. 이 함수는 매우 간단합니다. recv와 send를 할 수 있는 network interface를 정의하는 부분이어서 mbedTLS 형식에 맞게 ioLibrary를 포팅하면 됩니다. 코드를 먼저 보시는게 편할 것 같습니다. 아래가 해당 코드입니다. 기존의 ioLibrary에서 제공한 send함수와 recv 함수를 이용해 mbedTLS가 사용하는 형식이 맞추어 한번 싸준 것 뿐입니다.

int wiz_mbedtls_ssl_send(void *ctx, const unsigned char *buf, unsigned int len )
{
	while(getSn_TX_FSR(*((int *)ctx)) < len && len < getSn_TxMAX(*((int *)ctx))){};
	return send(*((int *)ctx),(uint8_t*)buf,len);
}

int wiz_mbedtls_ssl_recv(void *ctx, unsigned char *buf, unsigned int len )
{
      return (recv(*((int *)ctx),buf,len));
}

여기서 ctx는 read,write callback이 공유하는 parameter(context)라고 설명되어 있는데 그냥 socket 번호라고 생각하시면 됩니다. 자 벌써 2개 끝났습니다. 그럼 recvtimeout도 해볼까요? 뭐 어렵겠어요? recv와 똑같지만 timeout이 발생하면 error를 return하면 됩니다. 아래는 코드입니다.

int WIZnetRecvTimeOut(void *ctx, unsigned char *buf, unsigned int len, unsigned int timeout)
{
	uint32_t startTick = HAL_GetTick();
	unsigned int ret;
	do
	{
		if(getSn_RX_RSR(*((int *)ctx))){
			return recv(*((int *)ctx),buf,len);
		}
	}while((HAL_GetTick() - startTick) <= timeout);
	return MBEDTLS_ERR_SSL_TIMEOUT;
}

어때요? recv와 기본적으로 동일하지만 timeout 값을 인자로 하나 더 받아 HAL_GetTick()에 의해 timeout이 발생하면 MBEDTLS_ERR_SSL_TIMEOUT 이라는 에러를 반환합니다. 엄청 간단하죠? 이 역시 mbedTLS가 요구하는 형식입니다.


여기까지는 크게 어려움이 없는 것 같습니다. 그러면 그 다음으로 간단한 random()을 보겠습니다. 요기서부터는 약간 생각해 볼만한 여지가 있습니다. mbedTLS의 callback으로 등록해야 하는 함수의 원형을 보면 다음과 같습니다.


void mbedtls_ssl_conf_rng( mbedtls_ssl_config *conf, int (*f_rng)(void *, unsigned char *, size_t), void *p_rng );

여기에서 f_rng에 함수포인터로 등록을 시켜줘야 하는데 해당 함수를 또 찾아가면 p_rng를 f_rng의 첫번째 인자로 사용합니다. mbedTLS의 예제를 보면 더욱 혼란스러워집니다. ㅎㅎㅎ drbg라는 context를 넣는데 해당 변수는 AES 기반의 random을 만들어내는 context로 보이거든요. 그래서 다시 오기를 부려 찾아봤습니다. 그럼 f_rng가 등록이 안되어 있으면 p_rng를 사용할까요? 그건 또 아니었습니다. f_rng를 등록하지 않으면 에러는 아니지만 MBEDTLS_ERR_SSL_NO_RNG 이라는 error를 리턴합니다. 그리고 p_rng는 random의 seed도 아닙니다. 그냥 변수의 포인터이므로 seed로 사용하시면 안됩니다.!!!!

어쨌든 결론은 f_rng를 반드시 등록해야만 한다! 입니다. p_rng의 용도는 아직 저도 더 연구가 필요한 것 같습니다. 아무튼 용로를 잘 모르겠으니 무시하고 rand 함수를 감싸도록 하겠습니다.

int wiz_mbedtls_ssl_random( void *p_rng, unsigned char *output, size_t output_len )
{
    int i;

	if(output_len <= 0)
	{
         return (1);
	}
    for(i = 0;i < output_len;i++)
    {
       *output++ = rand() % 0xff;
	}
    srand(rand());
	return (0);
}


그냥 간단하게 코딩했습니다. 하지만 이렇게 하면 안된다는 걸 여러분들은 알고 있지요~~~?????네 그렇습니다. 원칙적으로는 true random을 넣어야 하는데 그렇지 않으면 random의 페턴이 확인 가능합니다. 그러면 보안성이 떨이지겠죠? 그래서 MCU Pin 하나를 open시킨 상태로 Analog input으로 설정한 후 rand() 함수의 seed로 활용하는 분들도 계십니다. Pin을 open시킨 상태로 Analog 값을 측정하면 값이 계속 흔들리거든요.(사실 이 방법이 random에 완벽한 대응이 되는지는 저도 잘 모르겠습니다. 이론적으로 더 확실한 방법을 찾으면 별도로 포스팅하겠습니다.)


휴~ 그림 한장없이 진행하려니까 힘드네요.


<우워워워워워어 한가인!!!! 사랑해요 한가인! ㅠㅠ 유부녀 히잉>


한가인 사진을 보내 설레여서 더 이상 못 쓰겠습니다.


그리고 사실 초기화와 핸드쉐이크 부분은 조금 까다롭기 때문에 다음 시간에 이어서 하겠습니다. 오늘은 여기까지만 하시구요. 여러분들은 보는데 10분이지만 저는 작성하는데 반나절씩 걸립니다. ㅠㅠ 히잉


암튼 다음 강의도 너무 많이 기다리시지 않게 되도록 빨리 올리도록 하겠습니다.


월요일이네요 한주 화이팅 하세요.

저작자 표시
신고

'Embedded SSL' 카테고리의 다른 글

SSL/TLS embedded for IoT #8  (0) 2017.06.27
SSL/TLS embedded for IoT #7  (0) 2017.06.19
SSL/TLS embedded for IoT #6  (0) 2017.06.17
SSL/TLS embedded for IoT #5  (0) 2017.06.16
SSL/TLS embedded for IoT #4  (0) 2017.06.15
SSL/TLS embedded for IoT #3  (6) 2016.12.28

SSL/TLS embedded for IoT #6

Embedded SSL 2017.06.17 17:19 Posted by Dwarp

SSL/TLS embedded for IoT


이 글은 embedded IoT device의 보안에 관한 글입니다.


embedded SSL/TLS 여섯번째입니다.



너무 몰아붙이나요? ㅎㅎ 아니겠죠 ㅎㅎ 저만 ㅠㅠ 여러분들은 시간날 때 보면 되니까 ㅠㅠ 암튼 전 주말이지만 기다리시는 분들이 계셔서 계속 진행합니다. 오늘은 W5500 iolibrary와 mbedTLS를 이어 붙이는 시간이 될 거에요. 하지만 그 전에 SSL/TLS라는 게 서버든 클라이언트든 있어야 하잖아요?


또 그러기 위해서는 뭔가... 그 뭐냐... 그그그그그.... Application!이 있어야 하겠죠? 제가 건망증이 좀 있습니다. 양해 좀 ㅎㅎ


우리가 지금 IoT 하고 있잖아요? 그래서 네트워크 어플리케이션으로 MQTT를 정하겠습니다. MQTT는 뭐냐고요? 그건 뭐..... IoT에 특화된 네트워크 프로토콜입니다. 찾아보시면 금방 자료 나와요. 전 라즈베리파이에 MQTT 서버를 SSL 모드로 열어놨습니다. 특별한 문제가 없으면 오픈해 놓으려고 하니 테스트 해보셔요. 아래는 제가 open 해놓은 MQTT Broker(서버) 주소 입니다.


<라즈베리 파이>


IP: 222.98.173.239

Port 일반 TCP: 1883

Port 보안 TCP: 1884

Port 일반 websocket: 8883

Port 보안 websocket: 8884


** 경고!!!!!!!! 아시겠지만 테스트 용도로만 사용하시고 상업적인 용도로 사용하지 마세요. 제가 손해봐서 그러는게 아닙니다. 여러분들이 고생합니다. ㅠㅠ 사전 경고 없이 서버가 꺼지거나 할 수 있는데 정작 저는 모를 수 있어요.



<제 책상의 라즈베리파이 MQTT 서버 - 언제나 꺼질 지 모르는 완벽한 불안정 속에 위치해 있다.>


** 리눅스에 MQTT 서버 설치/Open SSL 인증서 만드는 법 등 요청하시면 따로 포스팅 하겠습니다.


자 그럼 다시 코드로 넘어가겠습니다. mbedTLS와 관련하여 만들어야 할 함수가 존재하겠죠? 근데 뭐가 필요하죠? mbedTLS 코드를 다운로드 받으면 여러 예제가 있긴 하지만 보고 있으면 괴롭기만 할 뿐입니다. 괴로운건 ㅠㅠ 제가 이미 봤으니까 여러분들은 핵심만 가져가세요. (왜 남 좋은 일 하냐구요? 뭐 고마운신 분들은 댓글 주세요. 계좌번호 드릴테니까 돈 좀 주세요. 아니면 연봉 1억쯤 주시고 데려가서 노예로 쓰시면 됩니다.)


자! 쓸데없는 소리 그만하고 만들어야 할 함수를 설명하겠습니다.


wiz_mbedtls_ssl_init();

먼저 SSL이라고 피해갈 수 없겠죠? 초기화를 해야만 합니다. 각종 메모리 할당, callback 등록 등의 과정이 들어 있을 겁니다.


wiz_mbedtls_ssl_deinit();

뭐 이건 초기화의 반대네요. mbedtls가 malloc/free를 쓰는 이상 리소스 관리를 하지 않을 수가 없겠죠? init가 malloc을 했다면 deinit은 free를 주로 하겠네요.


wiz_mbedtls_ssl_handshake();

handshake를 처음에 설명드렸는지 안했는지 기억이 안납니다. ㅎ 암튼 SSL은 암호화된 통신을 하기 전에 서버와 클라이언트 사이의 암호화 방법을 결정하고 인증서를 교환하는 등의 과정을 거칩니다. 이 과정을 handshake라고 부르는데요 이 과정도 약간 프로그래밍을 해줘야 합니다. 대놓고 mbedtls_ssl_handshake()라는 함수를 사용해도 되지만 전 일단 감싸주려고 합니다. 처리해야 할 것도 약간 있구요.


wiz_mbedtls_ssl_random();

거의 모든 보안 알고리즘들은 난수를 필요로 합니다. 완벽한 난수일 수록 좋지요. 어쨌든 mbedTLS도 random 함수를 callback으로 묶어줘야 합니다. 없으면 기본적으로 내장된 rand()함수를 사용하게 프로그래밍 되어 있겠지만 음.. analog 입력을 받아(open 상태로) 그거라도 SEED를 줘서 rand()를 돌리는 게 훨씬 좋을 것 같습니다.


wiz_mbedtls_ssl_send();

기본적인 send()라고 보시면 됩니다. 일반적인 socket프로그램을 사용하면 mbedtls option질로 안 만들어도 되는 함수가 되겠지만 iolibrary는 일반적인 socket 프로그래밍 방식과는 약간 차이가 있기 때문에 iolibrary의 send를 한 번 감싸준 함수입니다.


wiz_mbedtls_ssl_recv();

wiz_mbed_ssl_send() 함수와 같은 역할입니다. 기본적인 recv함수 입니다.


wiz_mbedtls_ssl_recvtimeout();

동작은 wiz_mbedtls_ssl_recv와 같지만 time out 값을 지정해 시간내 응답이 없으면 TIME_OUT ERROR를 발생시키기 위한 목적입니다. wiz_mbedtls_ssl_recv와 wiz_mbedtls_ssl_recvtimeout 둘 중 하나만 콜벡으로 등록하면 된다고 기억하고 있지만 어쨌든 둘 다 만들어 봅시다.


아~~ 오늘은 토요일이라서 하기 싫다~~~ 그냥 소주나 한잔 먹고 싶다~


그래서 오늘은 이만 여기까지 쓰겠습니다. ㅎㅎ 다음 시간에는 함수 구현해 봅시다~~


안녕~

저작자 표시
신고

'Embedded SSL' 카테고리의 다른 글

SSL/TLS embedded for IoT #8  (0) 2017.06.27
SSL/TLS embedded for IoT #7  (0) 2017.06.19
SSL/TLS embedded for IoT #6  (0) 2017.06.17
SSL/TLS embedded for IoT #5  (0) 2017.06.16
SSL/TLS embedded for IoT #4  (0) 2017.06.15
SSL/TLS embedded for IoT #3  (6) 2016.12.28

SSL/TLS embedded for IoT #5

Embedded SSL 2017.06.16 16:37 Posted by Dwarp

SSL/TLS embedded for IoT


이 글은 embedded IoT device의 보안에 관한 글입니다.


embedded SSL/TLS 다섯번째입니다.


업로드가 느려 죄송한 마음에 하나 더 포스팅을 하도록 하겠습니다. 계속 본격적이라고 해놓고는 SSL 포팅은 맛도 못봤기 때문에 이번 시간에 SSL 포팅 바로 전까지 마무리하고 이후에는 SSL 포팅과 application을 진행하도록 하겠습니다.


저번 시간에는 main에 W5500만 초기화하는 코드를 넣었습니다. 이제는 W5500을 초기화 하고 network 정보를 입력할 시간입니다.


W5500HardwareDriver.c에 W5500Initialize() 함수를 추가해 줄 거에요.


void W5500Initialize(void)
{
	unsigned char temp;
	unsigned int randSeed = 0;
	unsigned char W5500FifoSize[2][8] = {{2,8,1,1,1,1,1,1,},{2,8,1,1,1,1,1,1}};
	W5500DeSelect();

	/* spi function register */
	reg_wizchip_spi_cbfunc(W5500ReadByte, W5500WriteByte);

	/* CS function register */
	reg_wizchip_cs_cbfunc(W5500Select,W5500DeSelect);

	if(ctlwizchip(CW_INIT_WIZCHIP,(void*)W5500FifoSize) == -1)
	{
		printf("W5500 initialized fail.\r\n");
	}

//	do{//check phy status.
//		if(ctlwizchip(CW_GET_PHYLINK,(void*)&temp) == -1){
//			printf("Unknown PHY link status.\r\n");
//		}
//	}while(temp == PHY_LINK_OFF);
}


하단에 주석처리해 놓은 부분은 Ethernet LINK가 성립되길 기다리는 구문있데 있어도 되고 없어도 됩니다.

W5500HardwareDriver.h에도 함수 추가해 주시는 거 잊지 마시구요 ^^

그리고 나면 이 함수로 초기화를 시켜줄 수 있을 거에요.


이 다음에는 네트워크 정보를 입력해야겠죠? iolibrary에 있는 wizchip_setnetinfo() 함수를 사용할 거에요. 뭐 간단합니다. 아래와 같은 방식으로 사용하시면 됩니다. 구조체 선언하고 쓰면 됩니다.


wiz_NetInfo gWIZNETINFO = { .mac = {0x00,0x08,0xdc,0xff,0x11,0xff}, .ip = {192, 168, 0, 222}, .sn = {255, 255, 255, 0}, .gw = {192, 168, 0, 1}, .dns = {8,8,8,8}, .dhcp = NETINFO_STATIC}; wizchip_setnetinfo(&gWIZNETINFO);


각각에 맞는 네트워크 정보를 넣으셔야 하는데 공유기 있으시면 192.168.0.XXX로 하는 네트워크 정보를 넣으시면 되겠죠? 아니면 DHCP(IP 자동할당)을 사용하셔도 되는데 프로그램을 추가하셔야 해요. 일단은 고정 IP로 각자 집이나 회사에 가지고 있는 공유기 밑에 붙여보도록 합시다. 대부분의 공유기 default 값이 ip는 192.168.0.XXX subnet mask는 255.255.255.0, 그리고 gate way는 공유기 주소니까 192.168.0.1이 될거에요. dns는 그다지 상관없으니 구글꺼 쓰죠 뭐 8.8.8.8입니다. 그리고 mac은 남는 네트워크 카드나 PC 등등에서 빼오셔야 합니다. 내부망 통신은 상관없지만 외부망 통신하실 때 문제가 생깁니다.


이렇게 모두 설정하셨으면 main에 합쳐봅시다.


#include "W5500HardwareDriver.h"
#include "wizchip_conf.h"

wiz_NetInfo gWIZNETINFO = { .mac = {0x00,0x08,0xdc,0xff,0x11,0xff},
							.ip = {192, 168, 0, 222},
							.sn = {255, 255, 255, 0},
							.gw = {192, 168, 0, 1},
							.dns = {8, 8, 8, 8},
							.dhcp = NETINFO_STATIC};

int main(void)
{
	W5500HardwareInitilize();	//hardware init

	W5500Initialize();			//w5500 init

	wizchip_setnetinfo(&gWIZNETINFO);	//set network information
	
    while(1)
    {
    }
}


여기까지 다 했으면 F7번이나 컴파일 버튼을 눌러서 컴파일을 해봅시다. 에러가 없나요? 전 없군요. 그래서 다운로드 해보겠습니다.

음! 잘 되는 것 같군요. 그러면 network가 되는지  Ping 명령으로 확인해 볼까요? 설마 모르시려나? CMD 창에서 ping 192.168.XX.XXX -t 엔터


응? 안되네요? 왜 안되죠? 뭐죠? 멘붕멘붕. 멘붕... 멘붕은 안하지요 대신 디버그를 할 뿐 ㅋ.


음 디버그를 해보니 항상 HAL_GetTick()이 0을 반환하는 군요 ㅎㅎ Time 관련된 함수가 넘어가질 않고 있었습니다. STM에서 왜 그랬느지 모르겠지만 HAL_GetTick, HAL_IncTick 등을 weak으로 선언해서 모든 HAL library에 사용하고 있습니다. 음.. 어쨌든 그러면 uwTick이라는 global 변수가 1씩 증가하게 해야겠습니다. HAL_IncTick은 Systick을 활용하도록 설계되어 있는 것 같은데 전 OS가 Systick을 사용하도록 하게 하고 싶습니다. 그렇다면 간단하게 weak으로 선언되어 있는 HAL_Tick을 override 시킵시다. 재선언 하는 것이지요. 그래서 uwTick이 아닌 OS의 Tick 값을 가져오도록 하겠습니다. 우후훗


점점 짬뽕이 되어 가고 있군요 ㅠㅠ SSL하다가 OS까지 오신 여러분 환영합니다. ㅠㅠ 그래도 힘내세요 ㅎㅎ 하다보면 이정도는 껌입니다.


자 그럼 main.c로 돌아가서 아래 코드를 추가해줍니다.

uint32_t HAL_GetTick(void)
{
	return CoGetOSTime();
}


지금 사용하는 CoOS는 CoGetOSTime()이라는 함수로 OS tick을 리턴합니다. 그럼 Main.c 전체는 다음과 같아질 거에요.


#include "W5500HardwareDriver.h"
#include "wizchip_conf.h"

wiz_NetInfo gWIZNETINFO = { .mac = {0x00,0x08,0xdc,0xff,0x11,0xff},
							.ip = {192, 168, 77, 123},
							.sn = {255, 255, 255, 0},
							.gw = {192, 168, 77, 1},
							.dns = {8, 8, 8, 8},
							.dhcp = NETINFO_STATIC};

int main(void)
{
	CoInitOS();

	W5500HardwareInitilize();	//hardware init

	W5500Initialize();			//w5500 init

	wizchip_setnetinfo(&gWIZNETINFO);	//set network information

	//CoStartOS();

	while(1)
    {
    }
}

uint32_t HAL_GetTick(void)
{
	return CoGetOSTime();
}


여기서 주의할 것은 CoInitOS() 인데요. 이 함수에서 Systick을 Enable 해줘요. 그래서 가장 처음에 call 했습니다.


그럼 컴파일/다운로드 하시고 Ping이 가는지 확인해 볼까요? 설마 모르시려나? CMD 창에서 ping 192.168.XX.XXX -t 엔터


!!!!!!!!!!!!! 여기서 IP 여러분 것으로 바꾸세요~ !!!!!!!!!!!!!



음... 으흐흐흐 잘 되는 군요..


이제는 정말 SSL 포팅만 남은 것 같습니다.



앞으로는 임베디드에서 보기 힘들었던 malloc, free뿐만 아니라 함수포인터 그리고 OS 개념들이 난무할거에요. 하아....

(여러분들은 한 번만 하면 되지 전 수십번은 한 것 같아요 ㅠㅠ 하아...)


암튼 주말은 푹 쉬시고 다음 주에 다시 달려봅시다.


화이팅!!! 하아....



저작자 표시
신고

'Embedded SSL' 카테고리의 다른 글

SSL/TLS embedded for IoT #7  (0) 2017.06.19
SSL/TLS embedded for IoT #6  (0) 2017.06.17
SSL/TLS embedded for IoT #5  (0) 2017.06.16
SSL/TLS embedded for IoT #4  (0) 2017.06.15
SSL/TLS embedded for IoT #3  (6) 2016.12.28
SSL/TLS embedded for IoT #2  (0) 2016.12.27

SSL/TLS embedded for IoT #4

Embedded SSL 2017.06.15 10:43 Posted by Dwarp

SSL/TLS embedded for IoT


이 글은 embedded IoT device의 보안에 관한 글입니다.


embedded SSL/TLS 네번째입니다.


이번 글쓰기는 시간이 오래걸렸습니다. 기다려주시는 분들께 죄송한 마음뿐입니다.


바로 시작하겠습니다.



저번 포스팅까지는 기본적인 환경 구축을 완료했습니다. mbedTLS 소스와 ioLibrary도 추가했지요. 본격적으로 소스를 보겠습니다.




아무것도 없는 main을 보니 공허하네요 ㅠㅠ 저도 갑자기 하는 포팅이라 약간 가슴이 답답합니다. ㅎㅎㅎ 그래도 해보도록 하시지요~


먼저 iolibrary부터 포팅해서 ethernet이 원활하게 되는지 확인하도록 하겠습니다.


W5500을 사용하기 위해서는 3단계 정도만 거치면 됩니다.



1. SPI를 위한 GPIO 초기화


2. SPI 초기화


3. Read/Write 등록.



간단하지요? 우선 보드 초기화를 하기 위해 board.h라는 파일을 하나 만들겠습니다. (새로운 파일은 어떻게 만드나요? 같은 질문을 하시는 분들은 없으시겠지요?) 아래와 같이 작성합니다. 대략적으로 설명드리면 SPI1 사용하고 GPIOA 5,6,7 번이 SPI1으로 사용됩니다. reset port도 정의해주고, interrupt 핀도 정의 합니다.

#ifndef __BOARD_H_
#define __BOARD_H_

#define W5500_SPI			SPI1

#define W5500_RESET_PORT		GPIOC
#define W5500_RESET_PIN			GPIO_PIN_7

#define W5500_INT_PORT 			GPIOB
#define W5500_INT_PIN			GPIO_PIN_5

#define W5500_CS_PORT			GPIOB
#define W5500_CS_PIN			GPIO_PIN_6

#define W5500_SPI_GPIO_PORT		GPIOA
#define W5500_CLK_PIN			GPIO_PIN_5

#define W5500_MISO_PIN			GPIO_PIN_6

#define W5500_MOSI_PIN			GPIO_PIN_7

#endif


작성이 되었으면 이제 W5500를 위한 Peripheral을 초기화하는 W5500HardwareDriver.c를 작성해 봅시다.

#include "Board.h"

/*Include: Header file*/
#include "W5500HardwareDriver.h"

/*Include: W5500 Library*/
#include "wizchip_conf.h"

/*include: Standard IO library*/
#include <stdio.h>

SPI_HandleTypeDef hspi1W5500;

void W5500HardwareInitilize(void)
{
  __GPIOH_CLK_ENABLE();
  /*W5500 CS/INT/RST Clock enable*/
  __GPIOB_CLK_ENABLE();
  __GPIOC_CLK_ENABLE();
  
  /*W5500 GPIO&SPI1 Clock enable*/
  __GPIOA_CLK_ENABLE();
  
  /*Initialize GPIO Structure*/
  GPIO_InitTypeDef	GPIO_InitStructure;

  /*Initialize CS Pin*/
  GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  GPIO_InitStructure.Pin = W5500_CS_PIN;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(W5500_CS_PORT,&GPIO_InitStructure);
  
  /*Initialize INT Pin*/
  GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  GPIO_InitStructure.Pin = W5500_INT_PIN;
  GPIO_InitStructure.Mode = GPIO_MODE_INPUT;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(W5500_INT_PORT,&GPIO_InitStructure);

  /*Ethernet shield does not have individual reset pin*/
  /* ==> Remove R23 and connect RSTN - D9 pin
        Now D9 is Reset pin.*/
  GPIO_InitStructure.Speed = GPIO_SPEED_HIGH;
  GPIO_InitStructure.Pin = W5500_RESET_PIN;
  GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStructure.Pull = GPIO_NOPULL;
  HAL_GPIO_Init(W5500_RESET_PORT,&GPIO_InitStructure);
  
  /*SPI init*/
  hspi1W5500.Instance = W5500_SPI;
  hspi1W5500.Init.Mode = SPI_MODE_MASTER;
  hspi1W5500.Init.Direction = SPI_DIRECTION_2LINES;
  hspi1W5500.Init.DataSize = SPI_DATASIZE_8BIT;
  hspi1W5500.Init.CLKPolarity = SPI_POLARITY_HIGH;
  hspi1W5500.Init.CLKPhase = SPI_PHASE_2EDGE;
  hspi1W5500.Init.NSS = SPI_NSS_SOFT;
  hspi1W5500.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2;
  hspi1W5500.Init.FirstBit = SPI_FIRSTBIT_MSB;
  hspi1W5500.Init.TIMode = SPI_TIMODE_DISABLED;
  hspi1W5500.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
  hspi1W5500.Init.CRCPolynomial = 10;
  HAL_SPI_Init(&hspi1W5500);
  
  W5500HardwareReset();
}

void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{

  GPIO_InitTypeDef GPIO_InitStruct;
  if(hspi->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspInit 0 */

  /* USER CODE END SPI1_MspInit 0 */
    /* Peripheral clock enable */
    __SPI1_CLK_ENABLE();
  
    /**SPI1 GPIO Configuration    
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI 
    */
    GPIO_InitStruct.Pin = W5500_CLK_PIN|W5500_MISO_PIN|W5500_MOSI_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF5_SPI1;
    HAL_GPIO_Init(W5500_SPI_GPIO_PORT, &GPIO_InitStruct);

  /* USER CODE BEGIN SPI1_MspInit 1 */

  /* USER CODE END SPI1_MspInit 1 */
  }
}

void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{

  if(hspi->Instance==SPI1)
  {
  /* USER CODE BEGIN SPI1_MspDeInit 0 */

  /* USER CODE END SPI1_MspDeInit 0 */
    /* Peripheral clock disable */
    __SPI1_CLK_DISABLE();
  
    /**SPI1 GPIO Configuration    
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI 
    */
    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7);

  }
  /* USER CODE BEGIN SPI1_MspDeInit 1 */

  /* USER CODE END SPI1_MspDeInit 1 */
} 

void W5500HardwareReset(void)
{
  uint32_t tempTick;
  HAL_GPIO_WritePin(W5500_RESET_PORT,W5500_RESET_PIN,GPIO_PIN_RESET);
  tempTick = HAL_GetTick();
  while((HAL_GetTick() - tempTick) < W5500_RESET_TIME){/*1 ms Delay: Do nothing*/}
  HAL_GPIO_WritePin(W5500_RESET_PORT,W5500_RESET_PIN,GPIO_PIN_SET);
}

void W5500WriteByte(unsigned char txByte)
{
  unsigned char rtnByte;
  while (HAL_SPI_GetState(&hspi1W5500) != HAL_SPI_STATE_READY);
  HAL_SPI_TransmitReceive(&hspi1W5500,&txByte,&rtnByte,1,10);
}

unsigned char W5500ReadByte(void)
{
  unsigned char txByte = 0xff;//dummy
  unsigned char rtnByte;
  while (HAL_SPI_GetState(&hspi1W5500) != HAL_SPI_STATE_READY);
  HAL_SPI_TransmitReceive(&hspi1W5500,&txByte,&rtnByte,1,10);
  return rtnByte;
}

void W5500Select(void)
{
  HAL_GPIO_WritePin(W5500_CS_PORT,W5500_CS_PIN,GPIO_PIN_RESET);
}

void W5500DeSelect(void)
{
  HAL_GPIO_WritePin(W5500_CS_PORT,W5500_CS_PIN,GPIO_PIN_SET);
}


.c 파일을 만들었으니 .h 파일도 만들어 볼까요?


#ifndef __W5500HARDWAREDRIVER_H_
#define __W5500HARDWAREDRIVER_H_

#ifdef __cplusplus
 extern "C" {
#endif
   
#include "stm32f4xx_hal.h"

#define W5500_RESET_TIME	1 //ms
extern SPI_HandleTypeDef hspi1W5500;

void W5500HardwareInitilize(void);
void W5500Initialze(void);
void W5500HardwareReset(void);
void W5500WriteByte(unsigned char byte);
unsigned char W5500ReadByte(void);
void W5500Select(void);
void W5500DeSelect(void);
unsigned char wizchip_read(void);
void  wizchip_write(unsigned char wb);

#ifdef __cplusplus
}
#endif
#endif /*__W5500HARDWAREDRIVER_H_ */


이제 main()문에 살짝 넣어보고 시험 삼아 컴파일을 해볼게요.


#include "W5500HardwareDriver.h"

int main(void)
{

	W5500HardwareInitilize();

    while(1)
    {
    }
}


에러가 많이 나네요 ㅠㅠ;; 하지만 내용을 보시면 거의다 mbedtls와 관련된 내용입니다.



이제부터 조금 짜증 나는 내용입니다. mbedtls를 include 시킨 적도 없는데 에러가 나는 건 컴파일 에러가 나는 거라고 보시면 됩니다. 옵션이 안맞으니 #error를 통해서 에러를 주라고 프로그래밍 되어 있는 것이죠. 그럼 한번 고쳐 봅시다 ㅎㅎ


아마 여기에서 포기하시는 분들이 많을 거라고 생각됩니다. 왜냐하면 config.h를 수정해야하는데 2600줄짜리 config입니다. 각종 옵션과 암호화 방식, 인증 방식 등 수많은 것들이 우릴 기다리고 있으니까요. 언제 공부해서 언제 코딩합니까? ㅎㅎ


결론은!!!! config.h를 버립시다!


mbedTLS의 모든 파일들은 다음과 같이 시작합니다. 굳이 해설하자면

#if !defined(MBEDTLS_CONFIG_FILE)
#include "mbedtls/config.h"
#else
#include MBEDTLS_CONFIG_FILE
#endif

"MBEDTLS_CONFIG_FILE이 없으면 mbedtls/config.h를 include합시다. 그렇지 않다면 MBEDTLS_CONFIG_FILE을 참조합시다~"

라고 되어 있습니다.


따라서 MBEDTLS_CONFIG_FILE를 다시 define하면 그만입니다. 2600줄짜리 코드가지고 한줄한줄 읽어가면서 고생하지 마세요.


그래서 새로운 config 파일을 하나 더 만들도록 하겠습니다. 이름은 SSLConfig.h라는 이름으로 하고 생성한 후에 저를 믿고 그냥 복붙하세요.!!컨트롤 + c, 컨트롤 + v~ 고고!!


#ifndef MBEDTLS_CONFIG_H
#define MBEDTLS_CONFIG_H

/************************ macro define ***********************************/
#define MBEDTLS_SSL_CLI_C   //complie SSL cleint protocols

/*
   The following setting is base on the protocol for gmail & yahoo servers (TLS v1.2)
*/

//#defien SSL_CLIENT_SUPPOR_AILPAY

/************************ ssl config *************************************/

/* System supports functions */
//#define MBEDTLS_FS_IO    //

/* ssl features supports functions */
//#define MBEDTLS_PROTO_TLS1    //supports TLS v1.0
//#define MBEDTLS_PROTO_TLS1_1  //supports TLS v1.1
#define MBEDTLS_SSL_PROTO_TLS1_2        //supports TL v1.2
//#define MBEDTLS_PROTO_SSL3         //supports SSL v3.0

#define MBEDTLS_CIPHER_MODE_CBC //Use verify certificate function
#define MBEDTLS_PKCS1_V15       //define public key padding method

//#define MBEDTLS_SRV_SUPPORT_SSLV2_CLIENT_HELLO //define suppots SSL v2

/* ssl function supports */
//#define MBEDTLS_CERTS_C             //define to use certication testing function
#define MBEDTLS_RSA_C               //define public key encryption method (Using RSA) !!!

//#define MBEDTLS_ECDH_C  //LIU
//#define MBEDTLS_ECP_C

//#define #define MBEDTLS_ARC4_C      //define public key encryption method (Using RC4)

#define MBEDTLS_X509_USE_C          //Using X509 frame function
#define MBEDTLS_X509_CRT_PARSE_C    //define supporting ssl x.509 certificate analyze !!!
#define MBEDTLS_PK_C                //Using private key encryption function
#define MBEDTLS_PK_PARSE_C          //Using private key encryption analyze function

#define MBEDTLS_BIGNUM_C            //define using Big number function !!!
#define MBEDTLS_CIPHER_C            //define using certificate function

//#define MBEDTLS_ENTROPY_C           //define using Entropy calcuation !!!
#define MBEDTLS_SHA512_C            //define using SHA512 calcuation
#define MBEDTLS_SHA1_C            //define using SHA128 calcuation
#define MBEDTLS_SHA256_C          //define using SHA256 calcuation

#define MBEDTLS_MD_C              //define using MD calculation
#define MBEDTLS_MD5_C             //define using MD5 calculation

#define MBEDTLS_CTR_DRBG_C          //define using random number function !!!

#define MBEDTLS_AES_C               //define using AES function (after handshake - communicate stage)
//#define MBEDTLS_DES_C                     //define using DES function
#define MBEDTLS_ASN1_PARSE_C        //define using ASN analysis function
#define MBEDTLS_ASN1_WRITE_C        //define using ASN write function
#define MBEDTLS_OID_C              //define using OID function

#define MBEDTLS_SSL_TLS_C           //define using TLS support function !!!

//#define MBEDTLS_ERROR_C             //define using ERROR function (Showing error message)
//#define MBEDTLS_DEBUG_C             //define using debug function (Showing debug message)

/* Testing certificate procedure */
#define MBEDTLS_CERTS_C        //define using certificate testing function
#define MBEDTLS_PEM_PARSE_C    //define testing certifcate will use ASCII format (Sending PEM file)
#define MBEDTLS_BASE64_C       //define testing certificate is in ASCII format

//define communicate encrytion methods 
//#define MBEDTLS_KEY_EXCHANGE_ECDHE_PSK_ENABLED
//#define MBEDTLS_KEY_EXCHANGE_ECDHE_RSDEBUG_DFL_MODEA_ENABLED

#define MBEDTLS_KEY_EXCHANGE_RSA_ENABLED        //
//#define MBEDTLS_KEY_EXCHANGE_RSA_PSK_ENABLED   //
//#define MBEDTLS_GCM_C    //AES in GCM mode짙짭base on parallel design짙짭therefore it can good performance on speed,cost and less delay
//#define MBEDTLS_CCM_C    //

//define encryption and discrete methods
#define MBEDTLS_SSL_CIPHERSUITES                    \
        MBEDTLS_TLS_RSA_WITH_AES_128_CBC_SHA,       \
		    MBEDTLS_TLS_RSA_WITH_AES_256_CBC_SHA,       \
			  MBEDTLS_TLS_RSA_WITH_RC4_128_SHA
				//TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
			 // TLS_RSA_WITH_AES_128_GCM_SHA256

//Save RAM 
#define MBEDTLS_MPI_MAX_SIZE   256
//#define MBEDTLS_ENTROPY_MAX_SOURCES   2

//#define SSL_MAX_CONTENT_LEN    4096

//According to SSL requested data length to define, if the data is long, it takes a larger RAM space 

#if defined (MBEDTLS_CLIENT_SUPPOR_AILPAY) //defines for alipay
		#define MBEDTLS_SSL_MAX_CONTENT_LEN   5120   //define SSL client for connection to AILPAY
#else
		#define MBEDTLS_SSL_MAX_CONTENT_LEN    4096 //2048
#endif

#define MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION

#include "mbedtls/check_config.h"
#endif /* ssl_config */

새로운 config 파일을 만들었으면 이제 조건에 맞게 define을 해줘야 하겠죠? 컴파일러 옵션으로 이동해서 추가하도록 하겠습니다.



위 그림처럼 Configuration -> Compile -> Advance setting에서 Misc Controls에 -DMBEDTLS_CONFIG_FILE=<SSLConfig>를 추가합니다. 그리고 나면 preview에서 뒤가 짤리는데 신경쓰지 마세요. 거기서만 안보일 뿐이지 컴파일은 정상적으로 됩니다.


그리고 C99 옵션 선택합니다. 추후에 Time 함수같은거 사용할 수도 있으니까요 ㅎㅎ 그리고 컴파일을 해봅시~~~드아~~~~~


컴파일이 정상적으로 되나요? 휴휴~ 그러면 한숨은 돌렸습니다.


힘드네요.. 오늘은 여기까지만 하고 다음 포스팅은 최대한 빠르게 진행하도록 하겠습니다.(저도 오랜만에 하다보니 자꾸 까먹어서 ㅎ


그럼 안녕~~

저작자 표시
신고

'Embedded SSL' 카테고리의 다른 글

SSL/TLS embedded for IoT #6  (0) 2017.06.17
SSL/TLS embedded for IoT #5  (0) 2017.06.16
SSL/TLS embedded for IoT #4  (0) 2017.06.15
SSL/TLS embedded for IoT #3  (6) 2016.12.28
SSL/TLS embedded for IoT #2  (0) 2016.12.27
SSL/TLS for embedded IoT #1  (0) 2016.12.27

SSL/TLS embedded for IoT #3

Embedded SSL 2016.12.28 17:18 Posted by Dwarp

SSL/TLS embedded for IoT


이 글은 embedded IoT device의 보안에 관한 글입니다.


embedded SSL/TLS 세번째입니다.


준비물을 전부 준비하셨다면 시작해 보도록 하겠습니다.


CoIDE 설치는 아래 블로그에서 상세하게 설명되어 있습니다.


CoIDE 설치하기->> http://engschool.tistory.com/entry/CoIDE-2%EB%B2%88%EC%A7%B8


그럼 프로그램을 작성해보도록 하겠습니다.


메뉴에서 Project -> new project를 선택하시면 repository라는 이름의 탭이 추가되어 보여지면서 Chip 혹은 Board를 선택할 수 있습니다. 여기에서 우리는 board를 선택하도록 하지요. 그리고 나서 ST 탭을 선택하시면 제가 선택한 보드가 선택할 수 있습니다.



그 다음에는 알맞은 위치에 프로젝트명을 적어서 저장합니다.


그리고 사용할 라리브러리들을 삽입하도록 하겠습니다. 라리브러리는 클릭 몇번 만으로도 삽입이 됩니다.



스크롤 내리셔서 hal library도 추가하시구요.



그렇게 하고 나면 아래 그림처럼 CoIDE 왼편의 프로젝트 창에 라이브러리들이 추가된 것이 보일거에요.



이렇게 하면 기본적인 라이브러리들은 추가가 되었습니다. 이제 나머지는 mbedTLS 라이브러리와 W5500 Ethernet shield 라이브러리를 추가해봅시다.


* 전에서 설명을 안드렸는데 W5500용 라이브러리는 https://github.com/Wiznet/ioLibrary_Driver 에서 다운로드 하실 수 있습니다. *


방법은 간단합니다. 두 라이브러리를 복사한 후 해당 프로젝트 폴더에 붙입니다. CTRL+C, CTRL+V ㅎㅎ


mbedTLS 소스 코드에서 library 폴더와 include 폴더를 제외한 나머지 파일 및 폴더를 모두 지웁니다. (테스트 용도입니다.)


그 담에는 조금 깔끔하게 보이도록 프로젝트 이름 선택후 우클릭 -> add group 누르신 다음에 원하시는 이름으로 그룹을 만드세요.



저는 ExtLib라는 이름으로 만들었습니다. 그 다음에는 추가하고픈 라리브러리를 폴더 통째로 드래그 엔 드랍 하시면 됩니다.



휴 역시 그림 붙이기 작업은 여간 귀찮은 일이 아니네요 ㅎㅎㅎ 차라리 동영상으로 만드는 게 편하겠습니다. ㅎㅎ 다음에는 동영상으로 만들어 봐야겠습니다.


암튼 다 추가했으면 프로젝트 구조가 다음처럼 되어야 합니다. -_-+


후 정말 기네요. 너무 기니까 여기서 한번 끊고 다시 가도록 하겠습니다.


다음 시간에는 본격적으로 mbedTLS를 포팅해보도록 하겠습니다.


그럼 이만..


저작자 표시
신고

'Embedded SSL' 카테고리의 다른 글

SSL/TLS embedded for IoT #6  (0) 2017.06.17
SSL/TLS embedded for IoT #5  (0) 2017.06.16
SSL/TLS embedded for IoT #4  (0) 2017.06.15
SSL/TLS embedded for IoT #3  (6) 2016.12.28
SSL/TLS embedded for IoT #2  (0) 2016.12.27
SSL/TLS for embedded IoT #1  (0) 2016.12.27

SSL/TLS embedded for IoT #2

Embedded SSL 2016.12.27 17:28 Posted by Dwarp

SSL/TLS embedded for IoT


이 글은 embedded IoT device의 보안에 관한 글입니다.


embedded SSL/TLS 두번째입니다.


embedded용 SSL/TLS 라이브러리가 가장 궁금하실 것 같습니다. 우선 거의 대부분의 embedded용도의 SSL/TLS는 유료입니다. 그런데 이 와중에 ARM사가 Polar SSL을 인수하여 mbedTLS로 이름을 바꾸고 Apache 2.0 라이센스로 배포해버렸습니다. ARM 감사~

Apache 2.0의 의미는 아시겠지만 누구나 자유롭게 사용가능하고 상업적 목적도 가능합니다.


우선 mbedTLS 주소는 여기에요.-> https://tls.mbed.org/


Download mbed TLS 클릭하시면 바로 다운로드 됩니다.



소스 코드를 다운로드 하긴 했는데 ㅎㅎㅎ 어찌해야 할지를 모르시겠다구요? ㅎㅎ 네 저도 처음에 그랬습니다.


천천히 진행해보록 합시다. 우선 준비물이 필요합니다.


Embedded 보드와 IDE 정도 되겠네요.


준비물

1. embedded board: Nucleo F411re

2. network interface: W5500 Ethernet shield

3. IDE: CoIDE v1.7.8


    

<좌: Nucleo f411re embedded board // 우:W5500 Ethernet shield>


Necleo f411re 보드는 cortex m4인데다가 가격도 쌉니다. 마우저에서 16000원 정도 해요. 그리고 아두이노용 Ethernet shield를 꽂아 사용할 수 있습니다. 그래서 W5500 Ethernet shield도 준비했구요.


그리고 IDE는 완전 무료인 CoIDE를 이용했습니다. 아래 다운로드 링크를 걸어놨습니다.


다운로드 링크: https://www.coocox.org/download/Tools/CoIDE-1.7.8.exe


자 그럼 이정도면 준비가 된 것 같군요.


그러면 다음 시간에는 본격적으로 작업에 돌입을 해야하겠죠? 으흐흐흐


그럼 이만..

저작자 표시
신고

'Embedded SSL' 카테고리의 다른 글

SSL/TLS embedded for IoT #6  (0) 2017.06.17
SSL/TLS embedded for IoT #5  (0) 2017.06.16
SSL/TLS embedded for IoT #4  (0) 2017.06.15
SSL/TLS embedded for IoT #3  (6) 2016.12.28
SSL/TLS embedded for IoT #2  (0) 2016.12.27
SSL/TLS for embedded IoT #1  (0) 2016.12.27

SSL/TLS for embedded IoT #1

Embedded SSL 2016.12.27 14:57 Posted by Dwarp

SSL/TLS embedded for IoT


이 글은 embedded IoT device의 보안에 관한 글입니다.


SSL/TLS는 근래에 광범위하게 사용되는 암호화 방식입니다. 여기서 주저리 주저리 설명하는 것보다 제가 SSL 공부할 때 유용하게 방문했던 사이트 주소를 가르쳐 드릴게요.


https://wiki.kldp.org/HOWTO/html/SSL-Certificates-HOWTO/x70.html


어디서 사용되냐구요? 보통은 웹브라우저에서 많이 사용됩니다. 일반적으로 SSL이 적용된 사이트는 "http://"가 아닌 "https://"를 사용합니다. 그리고 SSL이 인증된 사이트는 크롬에서는 주소창 맨 앞에 녹색 자물쇠 모양이 표시되고 익스플로러에서는 주소 끝에 자물쇠 모양이 표시됩니다.


크롬 브라우저


익스플로러 브라우저


이렇게 표시된 사이트는 여러분들이 자료를 입력하고 전송해도 암호화되어 있어 볼 수가 없죠.

(보안이 적용되지 않은 사이트는 굳이 해킹을 하지 않더라도 외부에서도 쉽게 볼 수 있습니다. ^^)


암튼 요세 IoT 붐이 슬슬 불고 있는데 여기에도 보안이 중요하겠죠? IoT 기기 해킹 사례가 늘고 있으니까요.


IoT에 적용할만한 보안은 사실 SSL뿐이 없습니다. 왜냐하면 거의 모든 서버가 SSL 보안을 필요로 하니까요. AWS에도 Asure에도 Google cloud에도 SSL은 "필수"입니다. 그러면 어떻게 IoT Device에 SSL을 적용할 수 있을까요?


간단합니다. SSL은 그냥 프로그램이니까요 프로그램을 올리면 됩니다. 말이 쉽지 embedded에서 보안을 적용하는 것이 그다지 쉬운 작업은 아닙니다. 그래서 여러분들이 헤메지 않도록 차근차근 기술적으로 접근하려고 합니다.


너무 길게 글을 쓰면 지루하니까 쪼개서 여러 개의 글로 순서대로 올리도록 하겠습니다.


다음에는 이런 서론 말고 embedded ssl 용 소스 다운로드 부터 찬찬히 업로드하도록 하겠습니다.


그럼 이만..


저작자 표시
신고

'Embedded SSL' 카테고리의 다른 글

SSL/TLS embedded for IoT #6  (0) 2017.06.17
SSL/TLS embedded for IoT #5  (0) 2017.06.16
SSL/TLS embedded for IoT #4  (0) 2017.06.15
SSL/TLS embedded for IoT #3  (6) 2016.12.28
SSL/TLS embedded for IoT #2  (0) 2016.12.27
SSL/TLS for embedded IoT #1  (0) 2016.12.27

사장님 Project는 IoT와 Cloud를 결합한 IoT Cloud Service platform 입니다.

ㅎㅎ 거창해 보이지만 사실 서버와 클라이언트의 모음입니다. ^^;;;

사실 그렇게 어렵지도 않구요.(모르는 것들에 대한 궁금증을 배신하면 됩니다. ㅎㅎ)


사장님 Project를 함께 진행하고 나면 사장님이 될 수 있다는 뜻에서 사장님 Project라고 이름지은 것은 아닙니다.

다만 요세 트렌드를 따라보고 그에 대한 Idea를 더욱 구체화해보자는 의미에서 사장님 Project라고 이름 지었습니다.


다시 한번 말씀드리자면 사장님 Project는 IoT Cloud service platform을 구축하는 Project입니다. 단일 Job이 아니므로 생각보다 내용이 방대할 수 있어 큰 그림을 머리속에 박아두시는 것이 좋습니다. 언제나 말씀드리지만 처음에 컨셉을 잘못 잡으시면 목적이 뭐가 되었던 그 Project는 산으로 가게 되어 있습니다. ^^ 컨셉~컨셉~ 으하하하


사장님 프로젝트의 전체적인 컨셉은 아래 그림과 같습니다.


간단하게 설명드리자면 하나의 MQTT Broker Server, 그리고 하나의 Web server, Browser, 마지막으로 IoT Device로 구성됩니다.

1. MQTT Broker Server

2. Web Server

3. Browser

4. IoT Devices

이를 각각 간단하게 설명드리겠습니다.


1. MQTT Broker Server

 MQTT는 프로토콜의 이름 중 하나입니다. IBM에서 M2M 목적으로 제작되었고 주고 받는 데이터의 양이 작습니다. Facebook이 메신져에 적용하고 있습니다.(Facebook이 사용한다는 점에서 이 프로토콜을 사용해야 겠다고 결정했습니다. ㅎㅎ) MQTT는 Broker라고 불리우는 Server와 MQTT Client로 이루어져 있습니다. 왜 MQTT Server라고 부르지 않고 Broker라고 부를까요?

저도 많이 생각해 봤는데 정말 Broker의 역할만 하고 있기 때문이라고 생각합니다.

MQTT프로토콜의 데이터 교환은 Client들의 Publish(발행)와 Subcribe(구독)으로 이루어 집니다. 어떤 Client들은 Publish를 하고 어떤 Client는 Subscribe를 합니다. 혹은 둘다 하기도 합니다. 이 때 MQTT Broker의 역할은 Publish로 받은 명령을 Subscribe하고 있는 Client에게 전달해주는 역할만합니다. 그야말로 Broker일 뿐입니다.


어렵나요? TV 예약 시청이라고 생각하시면 편합니다. 여러분들이 무한도전을 보겠다고 예약을 해 놓으시면(Subscribe) 방송국에서는 일정 시간에 무한도전을 틀어주죠.(Publish) 그리고 여러분들은 무한도전을 시청하시면 되는 겁니다. 하하하 예가 더 어렵나요?


MQTT Broker도 많은 종류가 있습니다. 일단 유료는 제외하고 무료라도 제한이 있는 버전도 제외합니다. 그리고 유명한 것을 찾다보니 Mosquitto가 가장 적절하다고 판단했습니다. MQTT 표준도 거의 다 지원합니다.


http://mosquitto.org/


Linux 에서 동작하며 ubuntu에는 기본적으로 내장되어 있더라구요. 하지만 SSL등을 지원할 수 있게 하려면 다시 빌드해야 하므로 내장된 건 사용하지 말고 다운로드 받고 빌드해서 사용하셔야 합니다. ㅎㅎ 같이 천천히 해볼거니까 미리 걱정은 하지 맙시다.


2. Web Server

MQTT Broker만 있어도 통신이 가능한데 왜 Web Server가 필요하냐구요? 분명 이 프로젝트의 목적은 IoT Cloud service platform을 구축하는 것입니다. MQTT Message만 왔다갔다 하는 것은 그냥 MQTT일 뿐 Cloud Service라고 말할 수 없을 것 같죠? 데이터 시각화 도구(Visualizer)를 만들고 싶기 때문입니다. ㅎㅎ 데이터 시각화를 위해 다른 소프트웨어를 만드는 것보다 web을 사용하는 것이 더 낳은 방법이라고 판단했습니다. Web server는 Google app engine을 사용할 것이고 사용 언어는 go, java script, html 정도가 되겠습니다.


<요런거 만들고 싶습니다.>


3. Browser

PC던 휴대폰이던 걍 사용하시면 됩니다. 끗.


4. IoT Devices

IoT Devices는 임베디드 시스템이 되겠죠? 저는 위즈네트 직원이니까 WIZwiki-W7500 보드 사용할 거에요........ 직원이니까.. ㅠㅠ

WIZwiki-W7500은 mbed 환경에서 동작 가능합니다. mbed는 arm에서 지원하는 web compiler로 web 환경에서 빌드하고 바이너리 파일까지 추출할 수 있습니다. 이미 만들어 놓은 프로젝트 파일도 쉽게 import 할 수 있기 때문에 이 프로젝트에서도 mbed platform을 사용하도록 하겠습니다. mbed paho mqtt를 포팅하고 publish 할 수 있는 프로젝트도 이미 만들어 놓았습니다.


이제 어느 정도 윤곽이 잡히시나요? 차근 차근 따라오시면 스스로 어느 정도 완성된 IoT Cloud platform을 구성하실 수 있습니다.

Wiznet에서 진행하는 무료 강의를 오셔도 됩니다. (잘생긴 강사의 얼굴을 보실 수 있습니다.) 9월에는 실험적으로 진행했기 때문에 10월에는 강의가 없지만 11월부터는 새로 개설될 예정입니다.


블로깅도 순차적으로 진행할 예정이니 강의 때 하지 못했던 내용도 알 수 있을거에요.


그럼 다음 시간에 뵐게요~

- Dwarp -


저작자 표시
신고

'사장님 Project' 카테고리의 다른 글

사장님 Project - Project 개요 및 구조  (0) 2015.09.24
사장님 Project #1  (0) 2015.09.24