client ---->proxy---->server
第一步:處理client傳送的client hello
第二步:和server 握手
第三步:和client 握手
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define maxbuf 4096
intpeek
(int sock,
char
*data,
int len)
if(errno == eintr)
printf
("sock: [%d]\n"
, sock);}
printf
("sock: %d, peek: %d\n"
, sock, n)
;return n;
}static
intsession_secret_cb
(ssl *s,
void
*secret,
int*secret_len,
stack_of
(ssl_cipher)
*peer_ciphers,
ssl_cipher *
*cipher,
void
*arg)
ssl_cipher *c =
skm_sk_value
(ssl_cipher, peer_ciphers,1)
; std::string str;
str =
ssl_cipher_get_name
(c);
printf
("str is %s\n"
,str.
c_str()
);return1;
}int
main
(int argc,
char
**ar**)
else
//最大客戶端連線數
if(ar**[2]
)else
/* ssl 庫初始化*/
ssl_library_init()
;/* 載入所有ssl 演算法*/
openssl_add_all_algorithms()
;/* 載入所有ssl 錯誤訊息*/
ssl_load_error_strings()
;/* 以ssl v2 和v3 標準相容方式產生乙個ssl_ctx ,即ssl content text */
ctx =
ssl_ctx_new
(sslv23_server_method()
);/* 也可以用sslv2_server_method() 或sslv3_server_method() 單獨表示v2 或v3標準
*/if(ctx ==
null
)/* 載入使用者的數字證書, 此證書用來傳送給客戶端。證書裡包含有公鑰*/if(
ssl_ctx_use_certificate_file
(ctx, ar**[4]
, ssl_filetype_pem)
<=0)
/* 載入使用者私鑰*/if(
ssl_ctx_use_privatekey_file
(ctx, ar**[5]
, ssl_filetype_pem)
<=0)
/* 檢查使用者私鑰是否正確*/if(
!ssl_ctx_check_private_key
(ctx)
)/* 開啟乙個socket 監聽*/if(
(sockfd =
socket
(pf_inet, sock_stream,0)
)==-1
)else
bzero
(&my_addr,
sizeof
(my_addr));
my_addr.sin_family = pf_inet;
my_addr.sin_port =
htons
(myport)
;//設定監聽的ip
if(ar**[3]
)elseif(
bind
(sockfd,
(struct sockaddr *
)&my_addr,
sizeof
(struct sockaddr))==
-1)elseif(
listen
(sockfd, lisnum)==-
1)else
while(1
)else
/* 基於ctx 產生乙個新的ssl */
ssl =
ssl_new
(ctx)
;/* 將連線使用者的socket 加入到ssl */
ssl_set_fd
(ssl, new_fd)
;char buf[
4096];
int len =
peek
(new_fd,buf,
sizeof
(buf));
bio *in =
null
; bio *out =
null
; in =
bio_new
(bio_s_mem()
);out =
bio_new
(bio_s_mem()
);if(
bio_write
(in, buf, len)
!= len)
ssl_set_bio
(ssl, in, out)
;ssl_set_session_secret_cb
(ssl, session_secret_cb,
null);
/* 建立ssl 連線*/if(
ssl_accept
(ssl)==-
1)/* 基於ctx 產生乙個新的ssl */
ssl =
ssl_new
(ctx)
;/* 將連線使用者的socket 加入到ssl */
ssl_set_fd
(ssl, new_fd)
;int ret =
ssl_accept
(ssl);if
(ret ==-1
)printf
("continue\n");
const
char
*servername;
servername =
ssl_get_servername
(ssl, tl***t_nametype_host_name)
;printf
("server name is %s\n"
,servername)
;const ssl_cipher *cipher =
ssl_get_current_cipher
(ssl)
;printf
("client ssl cipher: id: %lu, name: %s, version: %s\n"
,ssl_cipher_get_id
(cipher)
,ssl_cipher_get_name
(cipher)
,ssl_cipher_get_version
(cipher));
/* 開始處理每個新連線上的資料收發*/
/* 發訊息給客戶端*/
len =
ssl_write
(ssl, buf,
strlen
(buf));
if(len <=0)
else
bzero
(buf, maxbuf +1)
;/* 接收客戶端的訊息*/
len =
ssl_read
(ssl, buf, maxbuf);if
(len >0)
else
/* 處理每個新連線上的資料收發結束*/
finish:
/* 關閉ssl 連線*/
ssl_shutdown
(ssl)
;/* 釋放ssl */
ssl_free
(ssl)
;/* 關閉socket */
close
(new_fd);}
/* 關閉監聽的socket */
close
(sockfd)
;/* 釋放ctx */
ssl_ctx_free
(ctx)
;return0;
}
獲取client hello 使用了peek方法,他的意思是提前看一眼的意思,但是並沒有把資料取走,
這樣使用ssl_accept就會得到err。
使用ssl_set_session_secret_cb函式可以獲取client hello中的金鑰套件。
與server 握手。
之後再次和client進行握手,需要再次呼叫ssl_accept函式
openssl安裝及使用
乙個專案要用到openssl,因此寫個實時總結。統統都用的最新版本。安裝 perl 我的安裝目錄為c perl eg 執行 cmd 命令,使用cd命令指向perl安裝目錄的eg檔案,執行 perl example.pl 若顯示 hello from activeperl 則說明perl安裝成功,可以...
使用OpenSSL生成證書
step 1.create key password protected openssl genrsa out prvtkey.pem 1024 2038 with outpassword protected openssl genrsa des3 out prvtkey.pem 1024 2048...
使用OpenSSL生成證書
step 1.create key password protected openssl genrsa out prvtkey.pem 1024 2038 with outpassword protected openssl genrsa des3 out prvtkey.pem 1024 2048...