Visual StudioでwolfSSLを試してみる

[wolfSSL](http://www.wolfssl.jp)はIoTデバイス、組み込み向け小型、軽量のSSL/TLSライブラリーです。本来はクロスコンパイル環境で組み込み機器向けに利用されるケースが多いのですが、ここではVisual Studioを使ってWidndows上で簡単に動かしてみることにします。wolfSSLのダウンロード、ライブラリやサンプルプログラムのビルドから実行までの簡単な流れについて説明します。

###１. ソースコードのダウンロード

[wolfSSLのダウンロードページ](https://www.wolfssl.jp/download/) からwolfssl-x.x.0.zip を選択してダウンロード、解凍します。

###２. ビルド

wolfSSLルートフォルダーの下にあるソリューションファイル "wolfssl64.sln" をVisuial Studioで開きます。プロジェクトは古いVisual Studioのバージョンにも対応できるように古い形式で提供されています。そのため「プロジェクトの再ターゲット」ダイヤログが表示されるので、OKして新しい形式に変換します。次に、メニューバーで「ソリューションのビルド」を選択して、プロジェクト一式をビルドします。ソリューションには以下のようなプロジェクトが含まれています。

|プロジェクト| 説明 |
|---|---|
|wolfssl|wolfSSLライブラリー本体|
|testsuite|アルゴリズムごとのテストプログラム|
|benchmark|アルゴリズムごとのベンチマークプログラム|
|echoserver|簡単なserverサンプルプログラム|
|echoclient|簡単なclientサンプルプログラム|
|server|テスト用サーバ|
|client|テスト用クライアント|
|sslSniffer|SSLスニファー|

ビルドが完了すると.\Debugフォルダーの下にプロジェクト名と同名の実行ファイルが生成されます。

###３. サンプルプログラムの実行
以下に、代表的なサンプルプログラムの使い方を説明します。サンプルプログラムはコマンドウィンドウを開いて実行します。

暗号アルゴリズムの単体テスト。通常のWindows上のビルド、実行ではエラーは発生しないはずですが、念のため実行させてみます。本番の開発ではコンフィグレーション定義で指定した必要な暗号アルゴリズムが組み込まれているかどうかの確認のためなどにも使用します。

アルゴリズムテストの実行：

```
C:\wolfssl\Debug>testsuite.exe
------------------------------------------------------------------------------
 wolfSSL version 4.5.0
------------------------------------------------------------------------------
error    test passed!
MEMORY   test passed!
base64   test passed!
base16   test passed!
asn      test passed!
RANDOM   test passed!
MD5      test passed!
MD4      test passed!
SHA      test passed!
SHA-256  test passed!
SHA-384  test passed!
SHA-512  test passed!
...
```

TLSサーバ、クライアントのサンプルプログラムは、TLS接続と１往復のメッセージ送・受信の簡単な動作ですが、ユーザの作成した組み込みターゲットで動作するアプリケーションや既存のサーバサイトなどとの対向テストができるように各種のオプションを指定することができるようになっています。

同一ノード上で簡単なクライアント、サーバ間通信を確認するだけなら、それぞれのウィンドウを開いて次のようなコマンドをオプションなしで実行します。　./certsディレクトリ下には、テスト用の各種サンプル証明書、鍵も同梱されていて、デフォルトでは下記のようなサンプル証明書、鍵が使用されます。

[Server]
サーバー側証明書： .\certs\server-cert.pem
サーバー側秘密鍵： .\certs\server-key.pem
サーバー側のクライアント認証用自己証明書　.\certs\client-cert.pem

[Client]
クライアント側証明書： .\certs\client-cert.pem
クライアント側秘密鍵： .\certs\client-key.pem
クライアント側のサーバ認証用CA証明書： .\certs\ca-cert.pem

サーバ、クライアント用にそれぞれコマンドウィンドウを開いてプログラムを起動してみます。

サーバ側：

```
C:\wolfssl\Debug>server.exe
peer's cert info:
 issuer : /C=US/ST=Montana/L=Bozeman/O=wolfSSL_2048/OU=Programming-2048/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
 subject: /C=US/ST=Montana/L=Bozeman/O=wolfSSL_2048/OU=Programming-2048/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
 altname = example.com
 serial number:45:45:81:82:e6:3a:bd:a2:e3:06:0e:ba:2c:45:74:4b:be:c0:39:11
SSL version is TLSv1.2
SSL cipher suite is TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
SSL curve name is SECP256R1
Server Random : 8478CB6994AB05246FA9C1124D42B05A0B5213A8F39B0FBC93BBDCF598979B61
Client message: hello wolfssl!
```

クライアント側：

```
C:\wolfssl\Debug>client.exe
peer's cert info:
 issuer : /C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
 subject: /C=US/ST=Montana/L=Bozeman/O=wolfSSL/OU=Support/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
 altname = example.com
 serial number:01
SSL version is TLSv1.2
SSL cipher suite is TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
SSL curve name is SECP256R1
Session timeout set to 500 seconds
Client Random : 7356C2ED23FDB9010342244500962213BDE6631F22179091742E05DD307CB961
I hear you fa shizzle!
```

この時、Wiresharkでパケットをキャプチャーすれば、このようにハンドシェークやメッセージ送・受信の様子を確認できます。このサンプルはポート "11111" を使っているので、Analyze -> Decode As でこのポートをSSLとして登録します。

パケットキャプチャー：
![wireshark.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263939/dcc9c4c5-7caf-9c15-6ea3-17356c5a3fe7.jpeg)

サンプルのserver/clientは同一ノード上だけではなく、他のノードとの接続も可能です。サーバの場合、外部からアクセス可能となるように"-b"でバインドを指定します。また、クライアント認証をしない場合は"-d"を指定します。

サーバ側：

```
C:\wolfssl\Debug>server.exe -b -d
```

クライアントも、"-h"でホストドメイン,"-p"でポートを指定することができます。外部のWebサーバをアクセスする場合は、さらに"-A"でサーバ認証のためのCA証明書を指定、"-g" で送信メッセージとして簡単なHTTP GET要求を出すように指定します。GET要求の内容は単純な固定値なのでHTTPリクエストとしてはたいていエラーとなってしまいますが、TLSとしては正常に接続されることが確認できます。

クライアント側：

```
C:\wolfssl\Debug>client.exe  -h www.wolfssl.com -p 443 -A .\certs\wolfssl-website-ca.pem -g
peer's cert info:
 issuer : /C=BE/O=GlobalSign nv-sa/CN=GlobalSign RSA OV SSL CA 2018
 subject: /C=US/ST=California/L=San Francisco/O=Fastly, Inc./CN=e.sni.fastly.net
 altname = e.sni.fastly.net
 serial number:29:b4:e6:52:7c:9c:6c:b6:81:c7:57:fd
SSL version is TLSv1.2
SSL cipher suite is TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
Session timeout set to 500 seconds
Client Random : B5BC304AB1A5488A508694748A749B9C53EF66CBCB59C473935EDBD0090A75E1
SSL connect ok, sending GET...
HTTP/1.1 500 Domain Not Found
...
```

次に、TLS1.3を試してみます。.\IDE\WIN\user_setting.hのコンフィグレーション設定用のヘッダーファイルにTLS1.3と関連オプションを追加し、再度ソリューションをビルドします。

コンフィグレーションオプションの追加：

```
#define WOLFSSL_TLS13
#define HAVE_TLS_EXTENSIONS
#define HAVE_SUPPORTED_CURVES
#define HAVE_HKDF
#define WC_RSA_PSS
#define NO_DH
```

サンプルサーバ、クライアントはデフォルトではTLS1.2を使用しますが、利用するTLSのバージョンを指定することができます。オプションの数字は「1: SSLv3, 2: TLS1.0, 3: TLS1.2, 4: TLS1.3」となっているので、TLS1.3 (-v 4) を指定してみます。なお、オプション"-v d" のように指定すると、クライアント側が接続時に指定してきたバージョンをビルドで組み込まれているバージョンの範囲で受付けます。

サーバ側：

```
C:\wolfssl\Debug>server.exe -v 4
peer's cert info:
 issuer : /C=US/ST=Montana/L=Bozeman/O=wolfSSL_2048/OU=Programming-2048/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
 subject: /C=US/ST=Montana/L=Bozeman/O=wolfSSL_2048/OU=Programming-2048/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
 altname = example.com
 serial number:45:45:81:82:e6:3a:bd:a2:e3:06:0e:ba:2c:45:74:4b:be:c0:39:11
SSL version is TLSv1.3
SSL cipher suite is TLS_AES_128_GCM_SHA256
Server Random : 3C25D4780035642B627B4DB9986801366481CA8EA735C42725224D98D0D391E9
Client message: hello wolfssl!
```

クライアント側：

```
C:\wolfssl\Debug>client.exe -v 4
peer's cert info:
 issuer : /C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
 subject: /C=US/ST=Montana/L=Bozeman/O=wolfSSL/OU=Support/CN=www.wolfssl.com/emailAddress=info@wolfssl.com
 altname = example.com
 serial number:01
SSL version is TLSv1.3
SSL cipher suite is TLS_AES_128_GCM_SHA256
Session timeout set to 500 seconds
Client Random : 1B12E9AA333AC81CF76031BA749CB27171DE391226097A607F691045477D9EC7
I hear you fa shizzle!
```

WiresharkのキャプチャーでもTLS1.3で通信していることが確認できます。


![wireshark-tls13.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/263939/cec52b39-c2b7-2c54-750b-ec3eb3b88963.jpeg)



さらに詳細は "-?" オプションでヘルプメッセージを見ることができます。

##４. まとめ

wolfSSLをWindowsのVisual Studioで試してみました。詳細なドキュメント、製品情報については、wolfSSLの下記を参照してください。wolfSSLは、ソフトウェアの内容は同じですが無償のオープンソース版と有償商用版のデュアルライセンスとなっています。社内技術評価などにはオープンソース、製品への組み込みの際は商用ライセンス契約をお願いしています。

ドキュメント：https://www.wolfssl.jp/docs/
英語サイト：https://www.wolfssl.com
日本語サイト：https://www.wolfssl.jp
Twitter: https://twitter.com/wolfSSL_Japan