Hello, OpenSSL!

SSL 通信用のライブラリを追加しようと少し調べたところ,OpenSSL ライブラリを使うのがやはり王道っぽいので OpenSSL を使って実装してみました.

gcc

gcc を使う環境 (Linux, cygwin, ...) だと大抵の場合は最初からインストールされているようです.ない場合は,ソースコードをダウンロードして make するか,apt-get install とか適当なコマンドでインストールするとすんなり入るだろうと思います.コンパイル時には,crypto と ssl をリンクする必要があるようです.

g++ -Wall -o test example_ssl.cpp -lcrypto -lssl

VC++

Windows 版は,Shining Ligth Productions - Win32 OpenSSL からバイナリをダウンロードすることができるようです.Light と付いているアーカイブにはインクルードファイルなどが含まれていないため,Light と付いてないものを選択します.インストールが終わったら次はインクルードパスとライブラリパスを設定します.私は,普段はターミナルから cl.exe を叩いて確認することが多いので,環境変数 (INCLUDE, LIB) に設定しています(参考:コマンドラインから VC++ のコンパイラ (cl.exe) を使用する - Life like a clown).例えば,c:\openssl にインストールしたとすると,INCLUDE および LIB の環境変数は以下のようになります.

INCLUDE="C:\openssl\include"
LIB="C:\openssl\lib"

Sample code

サンプルコードは以下の通り.http のサンプルコードの http を https に書き換えて,ポート番号を HTTPS 用にかえただけです.

#include <iostream>
#include "clx/https.h"

int main(int argc, char* argv[]) {
    if (argc < 3) return -1;
    
    clx::https session(argv[1], 443);
    session.get(argv[2]);
    	
    std::cout << "code: " << session.code() << std::endl;
    std::cout << std::endl;
    
    std::cout << "head" << std::endl;
    std::cout << "--" << std::endl;
    for (clx::http::head_iterator pos = session.head().begin(); pos != session.head().end(); pos++) {
        std::cout << pos->first << ": " << pos->second << std::endl;
    }
    std::cout << std::endl;
    
    std::cout << "body" << std::endl;
    std::cout << "--" << std::endl;
    std::cout << session.body() << std::endl;
    
    return 0;
}

上記は,サーバの証明書の認証は行っていません.サーバの認証を行う場合は,サーバと接続する前に rootCA の証明書のファイル(or ディレクトリ)の場所を指定しておく必要があります (example_https_verify.cpp).

clx::https session;
session.verify_locations("ca-bundle.crt"); // rootCA 証明書のファイル名
session.start(argv[1], 443);

verify_locations は,引数を 2 つ取ります(第 2 引数のデフォルト値は NULL).第 2 引数は,rootCA 証明書が複数存在するような場合に,それらの rootCA 証明書が置かれているディレクトリへのパスを指定します.第 2 引数を指定した場合は,第 1 引数は NULL でもかまいません.

References - CLX C++ Libraries

現在のところ,SSL 通信関連ライブラリとして以下のものを実装しています.また,sockstream も使用することができます.