07
16

OPENSSL-TCP SSL初心者之路

最近因為工作的關係,碰到一些加解密的問題,所以藉由這個機會,好好的回頭看了openssl這個只有編過但完全沒用過的library,還好有網友把整個openssl剖析的很透徹,在學習的過程中幾乎沒碰到太多的問題,因為openssl每組API的使用方式實在太固定了,所以md5 api試過後,後面的數位簽章和RSA都不會太困難,而在openssl裡,SSL framework是我覺得包裝相當漂亮的函式,所以下面的內容都著重在TCP SSL的使用介紹

使用http ssl基本上有幾個流程
1. Initial socket
2. Connect socket
3. Initial SSL
    <1>SSL_library_init:initial SSL library
    <2>SSL_CTX_new:create a new SSL_CTX object to enable SSL connection
    <3>SSL_new: create SSL data stucture
    <4>SSL_set_fd:bind ssl and socket fd
    <5>SSL_connect:connect to server
4. ssl_read or ssl_write: read ssl information

底下有個範例程式,簡單的展示SSL大致的架構,但我沒加上client驗server certificate這一段,有興趣的朋友可以參考此篇文章試試看

#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/ssl23.h>
#include <openssl/ssl2.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
 
#define GETMSG "GET https://192.168.15.3/sslok.htm\r\nHost:localhost\r\nUser-Agent:Joey\r\nAccept:text/html\r\nAccept-Language:en-us,zh-tw \r\nKeep-Alive:300"
//for demo purpose, it is not a good declaration
SSL_CTX *ctx;
SSL *ssl;
int fd;
 
void bug(char *string)
{
printf("error:%s\n",string);
exit(0);
}
 
void *readSSLSocket(void *arg)
{
fd_set fds;
int ret;
char buf[1400];
int len;
 
FD_ZERO(&fds);
FD_SET(fd, &fds);
ret=select(fd + 1, &fds, NULL, NULL, NULL);
if (ret>0)
{
ret=SSL_read(ssl, buf, 1400);
printf("client receive:\n %s",buf);
}
}
 
void destroySSL(SSL *ssl,SSL_CTX *ctx)
{
SSL_set_shutdown(ssl, 2);
SSL_shutdown(ssl);
SSL_free(ssl);
if(ctx)
SSL_CTX_free(ctx);
}
 
int main(int argc,char *argv[])
{
 
struct sockaddr_in srv;
pthread_t mythread;
char buf[1024];
 
memset(&srv,0,sizeof(srv));
srv.sin_addr.s_addr=inet_addr("192.168.15.3");
srv.sin_family=AF_INET;
srv.sin_port=htons(443);
fd=socket(AF_INET, SOCK_STREAM, 0);
if (fd<0) bug("fd");
 
if (connect(fd,(struct sockaddr *)&srv,sizeof(srv))==-1)
bug("connect");
 
SSL_load_error_strings();
if(SSL_library_init() != 1) bug("SSL_library_init");
ctx = SSL_CTX_new(SSLv3_method());
if (ctx==NULL) bug("ctx");
ssl=SSL_new(ctx);
if (ssl==NULL) return;
SSL_set_fd(ssl,fd);
if (SSL_connect(ssl)) printf("SSL connect OK\n");
pthread_create(&mythread,NULL,readSSLSocket,NULL);
pthread_detach(mythread);
sleep(1);
strcpy(buf,GETMSG);
SSL_write(ssl, (char *)buf,1024);
sleep(2);
destroySSL(ssl,ctx);
return 0;
 
}

 

標籤: linux
評論: 0 | 引用: 0 | 閱讀: 17753
發表評論
暱 稱: 密 碼:
網 址: E - mail:
驗證碼: 驗證碼圖片 選 項:
頭 像:
內 容: