MD5_Init

OpenSSLには、MD5ハッシュ値の計算機能もある。
まずは、MD5_Initで初期化。

md5_init(3): MD2, MD4, and MD5 hash functions - Linux man page

MD5_Init.cで、

MD5_InitにMD5_CTX型md5_ctxのアドレスを渡す。
戻り値が1なら初期化成功。

$ vi MD5_Init.c
$ gcc -o MD5_Init MD5_Init.c -lcrypto
$ ./MD5_Init 
MD5_Init success!
$

初期化できた。

Sample/openssl/MD5_Init/MD5_Init/src/MD5_Init at master · bg1bgst333/Sample · GitHub

SSL_read

SSL_readでレスポンスを読み込む。

/docs/man1.1.0/ssl/SSL_read.html

SSL_read.cで、

SSL_readで1023バイトずつ読み込んで、読み込んだバイトを出力していくのを繰り返す。

$ vi SSL_read.c 
$ gcc -o SSL_read SSL_read.c -lssl -lcrypto
$ ./SSL_read 
connect success.
ctx = 01a05ff0
ssl = 01a06c20
SSL_set_fd success!
SSL_connect success!
request_len = 61
SSL_write written = 61
HTTP/1.1 200 OK
Date: Sun, 21 May 2017 08:22:55 GMT
Expires: -1
Cache-Control: private, max-age=0
Content-Type: text/html; charset=Shift_JIS
P3P: CP="This is not a P3P policy! See https://www.google.com/support/accounts/answer/151657?hl=en for more info."
Server: gws
X-XSS-Protection: 1; mode=block
X-Frame-Options: SAMEORIGIN
Set-Cookie: NID=103=Ax4uzv60vWI_ZCgYLlXAjuO383mkk7NyT9ukFIdzWn33HotKlafmUkjXAYVGl6iDsrkfGHjXZNTK0pooeYSX_mNU0xYMARamNB6ap-RiGfDWWnIhYrGD34XrAPdDkCsq; expires=Mon, 20-Nov-2017 08:22:55 GMT; path=/; domain=.google.co.jp; HttpOnly
Alt-Svc: quic=":443"; ma=2592000; v="37,36,35"
Accept-Ranges: none
Vary: Accept-Encoding
Connection: close

<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="ja"><head><meta 

(略)

</script></div></body></html>$

レスポンスを読み込んで出力した。

Sample/openssl/SSL_read/SSL_read/src/SSL_read at master · bg1bgst333/Sample · GitHub

SSL_write

SSL_writeでリクエストの書き込みを行う。

/docs/man1.1.0/ssl/SSL_write.html

SSL_write.cで、

用意したGETリクエスト文字列をSSL_writeで書き込み、戻り値のwrittenには書き込めたバイト数が返る。

$ vi SSL_write.c 
$ gcc -o SSL_write SSL_write.c -lssl -lcrypto
$ ./SSL_write 
connect success.
ctx = 00a94ff0
ssl = 00a95c20
SSL_set_fd success!
SSL_connect success!
request_len = 61
SSL_write written = 61
$

リクエストのバイト数と書き込めたバイト数が同じなので全て書き込めたことがわかる。

Sample/openssl/SSL_write/SSL_write/src/SSL_write at master · bg1bgst333/Sample · GitHub

SSL_connect

SSL_connectでサーバとのSSLハンドシェイクを行う。

/docs/man1.0.2/ssl/SSL_connect.html

SSL_connect.cで、

SSL_connectにsslを渡して、戻り値が1なら成功。
SSLの切断にはSSL_shutdownを呼ぶ。

$ vi SSL_connect.c 
$ gcc -o SSL_connect SSL_connect.c -lssl -lcrypto
$ ./SSL_connect 
connect success.
ctx = 0190dff0
ssl = 0190ec20
SSL_set_fd success!
SSL_connect success!
$

SSL接続できた。

Sample/openssl/SSL_connect/SSL_connect/src/SSL_connect at master · bg1bgst333/Sample · GitHub

SSL_set_fd

SSL_set_fdで、SSL接続情報とソケットファイルディスクリプタを紐づけることで、そのソケット通信をSSL通信とすることができる。

Manual:SSL set fd(3) - OpenSSLWiki

SSL_set_fd.cで、

"www.google.co.jp"にポート443で接続するソケットsocを作成し、SSL_set_fdでsslとsocを紐づける。
1が返ってきたら成功。

$ vi SSL_set_fd.c 
$ gcc -o SSL_set_fd SSL_set_fd.c -lssl -lcrypto
$ ./SSL_set_fd 
connect success.
ctx = 02416fc0
ssl = 02417bf0
SSL_set_fd success!
$

これでsslとsocを紐づけることはできた。

Sample/openssl/SSL_set_fd/SSL_set_fd/src/SSL_set_fd at master · bg1bgst333/Sample · GitHub

SSL_new

SSL_newで、SSL接続情報を作成することもできる。
BIOを使わないでSSL接続をする場合はこれを使う。

/docs/man1.0.2/ssl/SSL_new.html

SSL_new.cで、

SSL_newにctxを渡すことで、sslを作成。
sslの指すアドレスを出力。
SSL_newで作成した場合は、SSL_freeでsslを解放する必要がある。

$ vi SSL_new.c
$ gcc -o SSL_new SSL_new.c -lssl -lcrypto
$ ./SSL_new 
ctx = 01072820
ssl = 01073860
$

sslを作成できた。

Sample/openssl/SSL_new/SSL_new/src/SSL_new at master · bg1bgst333/Sample · GitHub

SSL_load_error_strings

SSL_load_error_stringsもエラー文字列を読み込む関数だが、ERR_load_BIO_stringsとはちょっと違う模様。

/docs/man1.0.2/crypto/SSL_load_error_strings.html

SSL_load_error_strings.cで、

ERR_load_BIO_stringsに加えて、SSL_load_error_stringsも呼ぶ。

$ vi SSL_load_error_strings.c
$ gcc -o SSL_load_error_strings SSL_load_error_strings.c -lssl -lcrypto
$ ./SSL_load_error_strings ctx = 00972ad0
SSL_CTX_load_verify_locations error!
139907107936152:error:02001002:system library:fopen:No such file or directory:bss_file.c:175:fopen('dummyurl','r')
139907107936152:error:2006D080:BIO routines:BIO_new_file:no such file:bss_file.c:182:
139907107936152:error:0B084002:x509 certificate routines:X509_load_cert_crl_file:system lib:by_file.c:258:
$

func(132)がX509_load_cert_crl_fileなのがわかった。

Sample/openssl/SSL_load_error_strings/SSL_load_error_strings/src/SSL_load_error_strings at master · bg1bgst333/Sample · GitHub