wolfTips: 言語ラッパーを使いこなす– C# 編 —

C#言語用インターフェースを提供するwolfSSL C# ラッパーを使用する

wolfSSL をC# 言語から使用したいという方は、wolfSSL C# ラッパーを利用することが出来ます。wolfSSL C# ラッパー はSSL/TLS組み込みライブラリである wolfSSL とC#言語間のインターフェースを提供し、既存のC#アプリケーションへの wolfSSL ライブラリの統合を容易にします。

“言語ラッパーを使いこなす”、連載の最後は、wolfSSL C# ラッパー使用方法及びC#言語を使用したサーバーサンプルプログラムについて紹介します。

wolfSSL C# ラッパー に関する詳細は下記URLから参照可能です。

また、wolfSSL C# ラッパーのソースコードは wolfSSL のソースコードの“<wolfssl_root>/wrapper/CSharp” フォルダーに含まれます。

wolfSSL C# ラッパーをビルドする為に、Visual Studioの下記ソリューションファイルを開きます。

”<wolfssl_root>”/wrapper/CSharp/ wolfSSL_CSharp.sln

下記画面は、Visual Studio 2017 でソリューションファイルを開いたところです。wolfSSL C# ラッパーは、wolfSSL ライブラリと依存関係のある為、ソリューションファイルにプロジェクトとして含まれています。wolfSSL_CSharp プロジェクトをビルドすると wolfSSL ライブラリのプロジェクトもビルドされます。

この時wolfSSL ライブラリのプラットフォームツールセットはデフォルトでは、Visual Studio 2012(v110)ですので、お使いの Visual Studio のバージョンにあわせて変更します。また、.Net Framework はデフォルトで v4.5 です。こちらも、お使いの .Net Frameworkに変更するか v4.5 をインストールします。

ビルドを行うために、まず構成を選択するために、メニューの「ビルド」→「構成マネージャー」から構成マネージャーを起動します。

例えばRelease ビルド、64ビット版を作成する場合は、構成マネージャーのアクティブソリューション構成を「DLL Release」、アクティブソリューションプラットフォームを「x64」にそれぞれ選択します。

次に wolfSSL のビルドオプションとして HAVE_CSHARP をプリプロセッサマクロに追加します。wolfSSL プロジェクトのプロパティページから「C/C++」→プリプロセッサ→プリプロセッサの定義に HAVE_CSHARP を追加します。

ソリューションをビルドします。ビルドが成功すると、”<wolfssl_root>”/wrapper/CSharp/以下のフォルダーにDLL及び実行可能ファイルが作成されます。x64 の場合は下記フォルダーに作成されます。

”<wolfssl_root>”/wrapper/CSharp/x64/DLL Release

 

作成されたサンプルプログラムを実行してみます。コマンドプロンプトを起動し、上記フォルダーに移動し、実行します。

例えば、Pre-SharedKey を使用したTLSサーバーサンプルを起動します。

$cd ”<wolfssl_root>”/wrapper/CSharp/x64/DLL Release
$wolfSSL-TLS-PSK-Server.exe
Calling ctx Init from wolfSSL
Finished init of ctx …. now load in cert and key
Ciphers : RC4-SHA:RC4-MD5:DES-CBC3-SHA:AES128-SHA:AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:DHE-PSK-AES256-GCM-SHA384:DHE-PSK-AES128-GCM-SHA256:DHE-PSK-AES256-CBC-SHA384:DHE-PSK-AES128-CBC-SHA256:HC128-MD5:HC128-SHA:RABBIT-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-RC4-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-RC4-SHA:ECDHE-ECDSA-DES-CBC3-SHA:AES128-SHA256:AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:ECDH-RSA-AES128-SHA:ECDH-RSA-AES256-SHA:ECDH-ECDSA-AES128-SHA:ECDH-ECDSA-AES256-SHA:ECDH-RSA-RC4-SHA:ECDH-RSA-DES-CBC3-SHA:ECDH-ECDSA-RC4-SHA:ECDH-ECDSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDH-RSA-AES128-GCM-SHA256:ECDH-RSA-AES256-GCM-SHA384:ECDH-ECDSA-AES128-GCM-SHA256:ECDH-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDH-RSA-AES128-SHA256:ECDH-ECDSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDH-RSA-AES256-SHA384:ECDH-ECDSA-AES256-SHA384:ECDHE-PSK-AES128-CBC-SHA256:EDH-RSA-DES-CBC3-SHA
Setting cipher suite to DHE-PSK-AES128-CBC-SHA256
Started TCP and waiting for a connection

 

対向のクライアントは wolfSSL ライブラリ付属の/example/client を使用できます。PSKを有効にし、wolfSSL ライブラリをビルドします。

$./configure –enable-psk

$make

/example/client を PSK を使用し起動します。下記例では、サーバーのアドレスは192.168.163.1 です。お使いの環境にあわせて変更ください。

$ ./example/client/client -s -l DHE-PSK-AES128-CBC-SHA256 -h 192.168.163.1

TLS通信が成功するとWindows側のコマンドプロンプトに下記のようなメッセージが出力されます。

Connection made wolfSSL_accept
SSL version is TLSv1.2
SSL cipher suite is TLS_DHE_PSK_WITH_AES_128_CBC_SHA256
hello wolfssl!

 

DTLSのサンプルプログラムを使用する際には、対向のクライアントは下記のオプションを有効にしてください。

$./configure –enable-dtls –enable-psk

$make

 

今回はwolfSSL を C# 言語より利用するためのwolfSSL C#ラッパーを紹介しました。サポート済みAPIに関する情報は下記を参照ください。

https://www.wolfssl.com/documentation/wolfSSL-CSharp-API-Reference.pdf

wolfSSL C#ラッパーやサンプルプログラムの使い方に関するご質問はお気軽に support@wolfssl.com までお知らせください。

wolfTips: 言語ラッパーを使いこなす– Python 編 —

Python言語用インターフェースを提供するwolfSSL Python を使用する

wolfSSL をPython環境で使用したいという方は、wolfSSL Pythonパッケージを利用することが出来ます。wolfSSL PythonはSSL/TLS組み込みライブラリである wolfSSL とPython言語間のインターフェースを提供します。

Python の標準TLSライブラリは OpenSSL を利用していますが、リソース環境の制限が厳しい場合にはwolfSSLが有効な場合があります。そのようなケースでは一度wolfSSL Python を試してみてください。

今回は、wolfSSL Python の使用方法について紹介します。

wolfSSL Python に関する詳細は下記URLから参照可能です。

また、wolfSSL Python のソースコードは下記からダウンロード可能です。

 

OSX 64 や Linux 64 ビットをお使いの場合、wolfSSL Pythonをインストールするには事前にコンパイル済みの Python Wheelから簡単にインストール可能です。下記、コマンドを実行します。

$ pip install wolfssl

 

その他の環境やカスタマイズを行った wolfSSL ライブラリに対応したwolfSSL Pythonを使用するには次の手順を行います。

1.事前にgithub から取得したwolfSSL を少なくとも次の2つのオプションを指定し、ビルド・インストールを行います。

$./configure –enable-opensslextra –enable-sni
$make && make check
$sudo make install
  1. 事前にgithub から取得した wolfssl-py のビルドを行いインストールします
$ cd wolfssl-py
// wolfSSL ライブラリがデフォルトのフォルダーにインストールされている場合
$USE_LOCAL_WOLFSSL=1 pip install .//wolfSSL ライブラリがカスタムのパスへインストールされている場合
$USE_LOCAL_WOLFSSL=/tmp/install pip install .

 

wolfSSL Python インストール後の確認は wolfssl-py フォルダーで下記コマンドを実行します。

$ pytest

または

$ py.test tests

インストールが正常に行われている場合、下記のようなログが出力されます。

$ pytest
====================== test session starts =================================
platform linux2 — Python 2.7.15+, pytest-3.3.2, py-1.5.2, pluggy-0.6.0
rootdir: /home/xxxx/gitrepo/wolfssl-py, inifile:
collected 35 items 

tests/test_client.py ….                                          [ 11%]
tests/test_context.py ……………………                [ 80%]
tests/test_methods.py …….                                  [100%]

================= 35 passed in 0.88 seconds =================================

 

 

次にhttps://wolfssl.github.io/wolfssl-py/index.html#document-installation にあるソケットを利用したTLSクライアントの例を試してみます。

wolfssl_TLSclient_ex.py などとファイル名で Python プログラムを作成します。このプログラムでは、TLS 1.2 を使用しwww.python.org と通信を試みます。

import socket
import wolfssl
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0)
context = wolfssl.SSLContext(wolfssl.PROTOCOL_TLSv1_2)
secure_socket = context.wrap_socket(sock)
secure_socket.connect((“www.python.org”, 443))
secure_socket.write(b”GET / HTTP/1.1\n\n”)
print(secure_socket.read())
secure_socket.close()

作成したプログラムを実行します。

$ python wolfssl_exa2.py
HTTP/1.1 500 Domain Not Found
Server: Varnish
Retry-After: 0
content-type: text/html
Cache-Control: private, no-cache
connection: keep-alive
X-Served-By: cache-hnd18736-HND
Content-Length: 221
Accept-Ranges: bytes
Date: Mon, 27 Jan 2020 00:50:34 GMT
Via: 1.1 varnish
Connection: keep-alive<html>
<head>
<title>Fastly error: unknown domain </title>
</head>
<body>
<p>Fastly error: unknown domain: . Please check that this domain has been added to a service.</p>
<p>Details: cache-hnd18736-HND</p></body></html>

 

WireShark などのツールを使うと TLS 1.2 で通信を行っていることが分かります。

今回wolfSSL を Python言語より利用するためのパッケージwolfSSL Python を紹介しました。Python言語用のインターフェースは、他にも wolfCrypt 使用のみに特化した wolfCrypt Python パッケージもございます(URL: https://wolfssl.github.io/wolfcrypt-py/)。wolfSSL Python の使い方や、wolfCrypt Python に興味がある方はお気軽に support@wolfssl.com までお知らせください。

wolfTips: 言語ラッパーを使いこなす — JAVA 編 —

JAVA言語用インターフェースを提供するwolfSSL JNI を使用する

wolfSSL をJAVA環境でも使用したいという方は、wolfSSL JNIを利用することが出来ます。wolfSSL JNI はSSL/TLS組み込みライブラリである wolfSSL とJAVA言語間のインターフェースを提供します。今回は、wolfSSL JNI の使用方法について紹介します。

wolfSSL JNI は下記URL、もしくはGithubからダウンロード可能です。

[Github URL]

 

まずwolfSSL でJNIオプションを指定しビルドを行います。オプションは下記を指定します。

$./configure –enable-jni

$make

$sudo make install

 

次にJAVAのコンパイルを行いますが、事前に下記パッケージのインストールが必要になります。

  • Java SDK
    • Oracle JDK, Open JDK や Android を含むいずれかの JDK
  • JUnit (junit.org よりダウンロード可能)
    • junit-4.12.jar
    • hamcrest-core-1.3.jar

 

junit-4.12.jar 及び hamcrest-core-1.3.jarのダウンロード後にCLASSPATH環境変数を設定します。Linux 環境では例えば下記のように設定します。

$export CLASSPATH=$CLASSPATH:/usr/share/java/junit­4.12.jar:/usr/share/java/hamcrest­core­1.3.jar

 

次にJUNIT_HOME環境変数もセットします。

$export JUNIT_HOME=/usr/share/java

 

wolfSSL JNI のコンパイルを行います。ダウンロードサイトまたはGithub より取得したwolfSSL JNIソースコードのトップフォルダに移動後、次のコマンドを実行します。

$./java.sh

$ant

 

ant により、Unitテストも同時に実行されます。ビルドが成功している場合、下記のようなログが出力されます。

Buildfile: /home/foo/tmp/wolfssl-jni-1.4.0/build.xml

 

clean:

[delete] Deleting directory /home/ foo /tmp/wolfssl-jni-1.4.0/build/test

[delete] Deleting directory /home/ foo /tmp/wolfssl-jni-1.4.0/build

[delete] Deleting directory /home/ foo /tmp/wolfssl-jni-1.4.0/examples/build

 

default-javac-flags:

 

init:

[mkdir] Created dir: /home/ foo /tmp/wolfssl-jni-1.4.0/build

[mkdir] Created dir: /home/ foo /tmp/wolfssl-jni-1.4.0/examples/build

[mkdir] Created dir: /home/ foo /tmp/wolfssl-jni-1.4.0/build/test

[mkdir] Created dir: /home/ foo /tmp/wolfssl-jni-1.4.0/build/reports

……

[junit]          usePskIdentityHint()                       … passed

[junit]          getPskIdentityHint()                        … passed

[junit]          getPskIdentity()                 … passed

[junit]          freeSSL()                                         … passed

[junit]          Testing use after free                        … passed

[junit] RSA Class

[junit]          RSA()                                              … passed

[junit] ECC Class

[junit]          ECC()                                              … passed

[junit] Tests run: 5, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 1.904 sec

 

build:

 

BUILD SUCCESSFUL

Total time: 8 seconds

 

wolfSSL JNI パッケージには、サンプルのクライアントとサーバーが含まれています。使用方法は、ソースコードのルートフォルダでサーバーを起動します。

$./example/server.sh

 

次にクライアントを起動します。

$./example/client.sh

 

TLS通信が成功している場合、以下のログが表示されます。

$ ./examples/server.sh

Started server at ubuntu/127.0.1.1, port 11111

 

waiting for client connection…

client connection received from 127.0.0.1 at port 11111

 

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

SSL version is TLSv1.2

SSL cipher suite is TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

client says: hello from jni

 

$ ./examples/client.sh

Connected to 127.0.0.1 on port 11111

 

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

SSL version is TLSv1.2

SSL cipher suite is TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384

got back: I hear you fa shizzle, from Java!

 

サンプルのクライアントとサーバーには wolfSSL に含まれるサンプルのクライアントとサーバー同様、さまざまなオプションが存在しますので “-h” オプションで確認してみてください。

今回は wolfSSL を JAVA言語より利用するためのパッケージwolfSSL JNI を紹介しました。wolfSSL JNIは wolfSSL API のうちよく使われる主要なものだけを JNI として提供するものです。その他にも必要な API がある場合は追加サービスも提供しますのでお気軽にご相談ください。

またwolfSSL では wolfSSL JNI 以外にも、JavaでSSL/TLSプロトコルのフレームワークである JSSE をサポートする wolfJSSE の提供を予定しています。今回紹介しました、wolfSSL JNI の使い方や、新機能 wolfJSSE に興味がある方はお気軽に support@wolfssl.com までお知らせください。

wolfTips: 静的メモリー割り当てを使いこなす

静的メモリー割り当てを wolfSSL で使用する。

wolfSSL を静的メモリー割り当てと共に使用することが出来ます。ただし、使用メモリー量が大きくなるので使用には気をつけなければならない面もあります。搭載メモリー量に比較的余裕のある環境での選択肢として使用できます。今回はその仕組みを紹介します。

 

まず、wolfSSL で静的メモリー割り当てを有効にし、ビルドを行います。ビルドは以下のオプションをconfigure に指定します。

$./configure –enable-staticmemory

静的メモリー割り当ては、USE_FAST_MATHマクロの定義が必要で、WOLFSSL_SMAL_STACK定義が未定義あることが必要となります。64 ビットの環境では、configureの実行でこれらが自動的に設定されます。64ビット以外の環境では、–enable-fastmath を指定します。ヘッダーファイルを使用する場合は、

#define WOLFSSL_STATIC_MEMORY

を指定します。

 

静的メモリー割り当ての仕組みはWOLFSSL_CTX構造体に静的バッファを割り当て、WOLFSSL_CTX構造体から派生・生成される各構造体にヒープヒントを渡し、各構造体でヒープヒントからメモリー割り当てを行うことで実現しています。次の図で矢印はヒープを、四角枠は構造体を示しています。

静的メモリー割り当てを有効にしたWOLFSSL_CTX構造体を生成するために、下記のAPIを使用します。

wolfSSL_CTX_load_static_memory()

動的メモリーの使用を避けるために、wolfSSL_CTX_load_static_memory()は、ctxをNULLで渡し、静的メソッド関数(_exで終わる)を使用して静的バッファメモリーのみを使用し WOLFSSL_CTX構造体を生成します。

 

静的メモリー割り当てを使用した例は、wolfSSL に含まれるデフォルトのクライアント/サーバー、及びCryptテストを参照することができます。

 

下記はクライアントの例になります。ファイルの先頭で静的メモリーバッファを確保し、WOLFSSL_CTX構造体の生成に、wolfSSL_CTX_load_static_memory() を利用していることがわかります。

#ifdef WOLFSSL_STATIC_MEMORY

#if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) \
|| defined(SESSION_CERTS)
/* big enough to handle most cases including session certs */
byte memory[320000];
#else
byte memory[80000];
#endif
byte memoryIO[34500]; /* max for IO buffer (TLS packet can be 16k) */
WOLFSSL_MEM_CONN_STATS ssl_stats;
#ifdef DEBUG_WOLFSSL
WOLFSSL_MEM_STATS mem_stats;
#endif

#endif

#ifdef WOLFSSL_STATIC_MEMORY

if (wolfSSL_CTX_load_static_memory(&ctx, method, memory, sizeof(memory),
0, 1) != WOLFSSL_SUCCESS) {
err_sys(“unable to load static memory”);
}

 

if (wolfSSL_CTX_load_static_memory(&ctx, NULL, memoryIO, sizeof(memoryIO),
WOLFMEM_IO_POOL_FIXED | WOLFMEM_TRACK_STATS, 1) != WOLFSSL_SUCCESS) {
err_sys(“unable to load static memory”);
}

#else

ctx = wolfSSL_CTX_new(method(NULL));

#endif

静的メモリー割り当てのさらに詳しい内容については、静的バッファ割り当てドキュメントページ(英語)をご覧ください。いくつかの、特にOpenSSL互換レイヤのAPIは静的メモリーバッファの利用をサポートしていないものもありリストが掲載されています。併せて参照ください。

 

今回は静的メモリー割り当ての仕組みについて紹介しました。静的メモリーバッファを冒頭で用意するという特性上、動的メモリー割り当てと比較し多くのメモリーを消費する可能性があります。使用に際してはその特性を理解しお使い下さい。静的メモリー割り当ての使用に際し、ご質問等ありましたら、お気軽にsupport@wolfssl.com までお知らせください。

wolfTips: 証明書チェーンを理解する

階層になった証明書を wolfSSL で使用する

階層になった証明書を wolfSSL で使用する場合、その内部処理を理解しておくと使いやすさが抜群に向上します。今回は、証明書チェーンを検証する際の例を紹介し、wolfSSLの内部処理と共に見ていきたいと思います。

まず下記のように階層になった証明書があるとします。

 

これらの証明書のうち、中間サーバ公開鍵証明書をもつサーバを認証するには、認証用APIを用いて次のようにクライアント・サーバ間で引数を設定します。

// サーバサイド
wolfSSL_CTX_use_certificate_file( “中間サーバ公開鍵証明書「4」“)

// クライアントサイド
wolfSSL_CTX_load_verify_locations( “中間CA「3」“)

中間サーバ公開鍵証明書「4」に署名した中間CA「3」を使って検証することでクライアントはサーバを認証することが可能になります。

この時wolfSSL 内部では次図のようにCAを管理するためのCA管理用ハッシュテーブルが作成されます。インデックスのハッシュ値はサブジェクト鍵識別子から生成されます。

 

最初の例では証明書に署名したCAを直接読み込むことで認証を行いました。

 

では、ルートCA「1」使用し認証を行うためにはどうすれば良いのでしょう?

次のように証明書を読み込みます。

// サーバサイド
wolfSSL_CTX_use_certificate_file( “中間サーバ公開鍵証明書「2」+中間CA「3」“)

// クライアントサイド
wolfSSL_CTX_load_verify_locations( “ルートCA「1」“)

この時wolfSSLは先ほどと同様にCAを管理するためのCA管理用ハッシュテーブルを作成します。まずルートCAが最初に登録されます。次にルートCAによって検証された中間CAがテーブルに登録されます。中間サーバ公開鍵証明書は証明書に記述されたサブジェクト鍵識別子から、中間CAをテーブルから取り出します。取り出した中間CAを用いて検証を完了します。

 

wolfSSL に含まれる./certs フォルダの証明書を使って実際に試してみることも出来ます。まず最初の例、中間CAを直接ロードする場合、次のコマンドを使用します。

//サーバに中間公開鍵証明書をロード
$ ./examples/server/server -c ./certs/test-pathlen/server-1-cert.pem
//クライアントに中間CAをロード
$ ./examples/client/client -A ./certs/test-pathlen/server-1-ca.pem

次にルートCAを使用する場合は、次のように行います

//サーバ中間公開鍵証明書に中間CAを追記
$cat ./certs/test-pathlen/server-1-ca.pem >> ./certs/test-pathlen/server-1-cert.pem

//サーバに中間公開鍵証明書と中間CAをロード
$ ./examples/server/server -c ./certs/test-pathlen/server-1-cert.pem

//クライアントにルートCAをロード
$ ./examples/client/client

今回は階層になった証明書を検証するにあたって、APIに設定する引数とその内部処理について見てきました。実際の内部動作を頭にイメージでき、API使用時の手助けに少しでもなったら幸いです。証明書検証のAPI使用に際し、ご質問等ありましたら、お気軽にsupport@wolfssl.com までお知らせください。

 

wolfTips: テスト用デジタル証明書・鍵をつかいこなす

テスト用デジタル証明書・鍵、いろいろと取り揃えております。

wolfSSL では、テスト用にさまざまな証明書・鍵を揃えています。以前、少しだけ紹介しました。wolfTips : テスト用鍵、証明書(ファイルシステム有、無しの場合)

 

今回はさらにテスト用証明書・鍵の使い方をご紹介したいと思います。

 

サンプルサーバ、クライアントはデフォルトでは下記のものを参照します。

サーバ側証明書:./certs/server-cert.pem

サーバ側プライベート鍵:./certs/server-key.pem

クライアント側証明書:./certs/ca-cert.pem

 

楕円曲線暗号をサーバ認証に使用するには、下記の様に証明書を指定します。

サーバ側証明書:./certs/server-ecc.pem

サーバ側プライベート鍵:./certs/ecc-key.pem

クライアント側証明書:./certs/ca-ecc-cert.pem

 

$ ./examples/server/server  -c ./certs/server-ecc.pem -k ./certs/ecc-key.pem

 

$ ./examples/client/client -A ./certs/ca-ecc-cert.pem

 

暗号アルゴリズム ed25519 をサーバ認証に使用するには、certs/ed25519ファルダ内の証明書を下記のように使用します。

サーバ側証明書:./certs/ed25519/server-ed25519.pem

サーバ側プライベート鍵;./certs/ed25519/server-ed25519-key.pem

クライアント側証明書:./certs/ed25519/root-ed25519.pem

 

$ ./examples/server/server -c ./certs/ed25519/server-ed25519.pem \

-k ./certs/ed25519/server-ed25519-key.pem

 

$ ./examples/client/client -A ./certs/ed25519/root-ed25519.pem -C

 

中間認証局による証明書を使用する場合、certs/intermediateフォルダ内の証明書を利用します。例えば、中間認証局によって署名されたサーバ証明書を使用する場合、対向テストには下記の証明書を利用します。

 

サーバ側証明書(中間認証局によって署名):./certs/intermediate/server-int-cert.pem

クライアント側証明書:./certs/intermediate/ca-int-cert.pem

$./examples/server/server -v 3 -c ./certs/intermediate/server-int-cert.pem -V -d

 

$ ./examples/client/client -v 3 -l ECDHE-RSA-AES128-GCM-SHA256 \

-A ./certs/intermediate/ca-int-cert.pem -C

 

他にも下記の様にcerts/フォルダ内にはさまざまな証明書・鍵のファイルが存在します。基本的には、server サンプルプログラムの“-c” オプションでサーバ証明書、”-k”オプションでサーバの秘密鍵を指定します。また、client サンプルプログラムの”-A” でルート証明書を指定します。

./certs/1024 1024ビットの証明書・鍵ファイル
./certs/external パブリック認証局のルート証明書
ca/server/client-ecc384-xxx NIST 曲線 384 を使用する証明書・鍵ファイル
server/client-keyEnc フレーズ付きで暗号化された鍵ファイル

 

これらのファイルはテスト用に使用いただけます。使用に際し、ご質問等ありましたら、お気軽にsupport@wolfssl.comまでお知らせください。

 

wolfTips: 隠しコマンド!? TLSベンチマークテスト

もう一つベンチマークテストプログラムがあることをご存知ですか?

wolfSSLでは、ベンチマークテストのプログラムを提供していることを以前紹介しました。

wolfTips : ベンチマーク・プログラム

 

wolfSSL にはもう一つ別のベンチマークテストプログラムがあります。ソースレポジトリでは、下記に存在します。

/path/to/wolfSSL/examples/benchmark/tls_bench

前回ご紹介したベンチマークテストと区別する為に、TLSベンチマークテストと呼ぶことにします。今回はこのベンチマークテストプログラムをご紹介します。

 

早速、起動してみましょう。wolfSSL のルートフォルダから下記のように実行します。

$./examples/benchmark/tls_bench

 

下記は出力結果例です。

TLSベンチマークテストはServer/Client毎にスレッドを起動します。その後、ローカルマシン上でTLS通信を行いながら性能測定を実施し、デフォルトでは現在有効になっている全ての暗号スートについて測定を行います。

 

各出力項目は下記のような意味です。

上記から分かるように、送受信(write/readコマンド)実行に関する性能、TLS接続(ハンドシェーク)に関する性能を別々に測定しています。

 

これまでに登場した2つのテストプログラムに、TLSベンチマークテストプログラムを加え使用用途を場合分けすると、次のような使い分けが見えてきます。
 
1. 暗号アルゴリズムごとのベンチマークを行う場合
  → /wolfcrypt/test/testwolfcrypt

2. TCP/IP物理層を含む通信全体のベンチマークを行う場合

  → /examples/server/client

3. TLSハンドシェークとメッセージ送受信を区別しベンチマークを行う場合

  → /examples/benchmark/tls_bench

 

暗号アルゴリズム性能のみを評価したい場合、TLS通信も加味して性能測定を行いたい場合など用途にあわせてお使いください。また、デフォルト状態で実行する以外にもオプションスイッチをいくつか持っていますので、使用に際してご質問等ありましたらお気軽にsupport@wolfssl.com までお知らせください。

wolfTips: トラブルシューティング

繋がらない!最初にやることは:

準備万端、いざ接続…あれ、繋がらない!準備していても、少しの誤設定で問題は発生してしまいます。また組み込みという環境の性質上、問題発生時のデバック情報が少なく、解析に時間を要してしまうことがあります。
サポートに依頼しよう!そんな時、最初に思い出して頂きたい wolfSSLライブラリの必須デバックオプション、”–enable-debug” を紹介します。

使用方法は、”–enable-debug” オプションを指定し wolfSSL ライブラリをビルドします。
 $./configure --enable-debug
マクロ定義を使用する際は、DEBUG_WOLFSSL をヘッダーファイル(user_settings.h)に定義します。

あとはアプリケーション・プログラムの開始時に
 wolfSSL_Debugging_ON();
を呼び出します。

このオプションは、wolfSSL ライブラリのデバックメッセージ機能をオンにし、内部処理のトレースをデバックコンソールに出力します。得られたログをサポートへ送付頂くことで、処理の追跡が可能となりエラー解析の質が格段に向上します。

example/client/client を使用した際の出力例です。
初期のテスト構成はこちらを参照:wolfTips: 最初の対向テスト

ログをよく見ると
 wolfSSL Entering xxxx_yyy

 wolfSSL Leaving xxxx_yyy
というメッセージが見うけられます。これは xxxx_yyy という関数に入った(Entering)、そして処理終了後、離れた(Leaving)ということを示しています。
この例では、クライアントが間違ったCA証明書を使用しサーバ認証に失敗していました。正しい証明書を使用することでエラーを回避出来ました。

実際のエラーケースは、単純な場合から複数の要素が絡み合うものまで千差万別です。ちょっとした設定ミスでも、解析の方向を間違うと解決まで時間を要してしまうことがあります。今回紹介したデバックオプションで取得したログはデバックの方向を絞り込む上でとても有効です。
サポートへ現象とともにデバックログを送って頂くだけで問題解決はぐっと近くなります。デバックでお困りのことがあればお気軽にsupport@wolfssl.com までお知らせください。

wolfTips: デバック用オプション

メモリ使用状況が気になりますか?

wolfSSLには、多くのオプションスイッチがあります。その中には、事前に知っておくとその後のデバック効率が向上するものがあります。
今回はデバック時に有効なメモリ使用状況に関するオプションを紹介します。

使用方法は、configure にオプション “–enable-trackmemory” を指定し wolfSSL をビルドします。
$./configure --enable-trackmemory

マクロ定義を使用する場合は、WOLFSSL_TRACK_MEMORY を定義します。

後は、アプリケーション・プログラムの開始時に
InitMemoryTracker()
を呼び出し、メモリ使用状況を確認したい箇所で
ShowMemoryTracker()
を呼び出します。ShowMemoryTracker()は複数個所で呼び出しを行って構いません。メモリ使用状況を逐次確認するということも可能です。追加情報とし、これらの関数の呼び出しは、wolSSL_Init()及びwolfSSL_Cleanup()でそれぞれ自動的に行われます。

出力例は下記の通りです。

current Bytes に注目することでメモリリークの検出にも使用できます。

例として wolfSSL に同封されるtestwolfcrypt プログラムを “–enable-trackmemory” を指定しビルド・実行してみて下さい。

$ ./wolfcrypt/test/testwolfcrypt
error test passed!
base64 test passed!
asn test passed!
MD5 test passed!
……………
mutex test passed!
memcb test passed!
Test complete
total Allocs = 1445
total Deallocs = 1445
total Bytes = 4321945
peak Bytes = 71296
current Bytes = 0

“current Bytes = 0”。もちろんメモリリークしていません。

今回紹介したように wolfSSL ではアプリケーションのデバック作業効率を向上できるオプションがあります。個別環境でのデバック方法、特定の問題に対するデバックなどご質問ありましたらお気軽にsupport@wolfssl.com までお知らせください。

wolfTips: OpenSSL 互換APIを使いこなす

OpenSSL資産をムダにせず活用できます!

wolfSSLは、インプリメンテーション依存による脆弱性などを最小限にするためにクリーンルームによる独自開発のSSL/TLSライブラリです。一方で OpenSSL 互換の API も提供し既存の OpenSSL ユーザにも簡単にアプリケーションが開発できるように設計されています。ほかにも多くのオープンソースアプリケーションはOpenSSL 互換 API を使用し動作しています。

今回は、この wolfSSL のOpenSSL互換APIの使い方を紹介します。

1.wolfSSLライブラリのビルド

デフォルトで wolfSSL ライブラリのビルドシステムは、OpenSSL 互換 API を無効にしています。OpenSSL互換APIを有効にするには、configure で”–enable-opensslextra”オプションを指定します。

$./configure --enable-opensslextra
“–enable-opensslextra” 以外に、”–enable-opensslall”というオプションが指定可能です。”–enable-opensslall”オプションは、wolfSSL でサポートしている OpenSSL 互換API を使用頻度の低いものも含めて有効化します。

 2.アプリケーションのビルド

OpenSSL APIを使用するアプリケーションをwolfSSL OpenSSL互換APIを用いてビルドするには gcc の場合以下のオプションを指定して行います。

  • ヘッダーファイルパスに wolfSSL ヘッダーファイルのインストール先を指定します。
    gcc の場合:
    -I /path/to/wolfssl/wolfssl -I /path/to/wolfssl
  • wolfssl/openssl/ssl.hをincludeオプションを使用し、直接インクルードします
    -include wolfssl/options.h
  • wolfSSLライブラリをリンクします。
    gcc の場合:
    -lwolfsslを指定します。

次のプログラムはTLSサーバに接続し、”Hello”を送信するだけの簡単なOpenSSL API 使用のサンプルです。ソースコードを変更することなく wolfSSL ライブラリと共に動作させることができます。

/* simplified echoclient wolfSSL and OpenSSL */
#include <openssl/ssl.h>
#include <openssl/err.h>
#include "echoclient.h"

void hello_test()
{
    const char* msg = "Hello SSL!\n";
    SSL_CTX*    ctx = 0;
    SSL*        ssl = 0;
    int ret = 0, err = 0;
    int sendSz;
    char buffer[MAX_ERROR_SZ];
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in servaddr;

    /* server information */
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(11111);
    servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");

    /* init library */
    SSL_library_init();
    /* create a new CTX */
    ctx = SSL_CTX_new(SSLv23_client_method());
    /* set default locations for trusted CA certificates */
    if (SSL_CTX_load_verify_locations(ctx, caCertFile, 0) != SSL_SUCCESS)
        printf("can't load ca-ecc file.\n");    
    /* create a new SSL structure for a connection */
    ssl = SSL_new(ctx);
    /* connect socket */
    connect(sockfd, (const struct sockaddr*)&servaddr, sizeof(servaddr));
    /* connect the SSL object with a file descriptor */
    SSL_set_fd(ssl, sockfd);
    /* initiate the TLS/SSL handshake with an TLS/SSL server */
    err = 0; /* Reset error */
    ret = SSL_connect(ssl);
    if (ret != SSL_SUCCESS) {
        err = SSL_get_error(ssl, 0);
        printf("SSL_connect error %d, %s\n", err,
        ERR_error_string(err, buffer));
    }
    /* send message to server */
    sendSz = (int)strlen(msg);
    do {
        err = 0; /* reset error */
        ret = SSL_write(ssl, msg, sendSz);
        if (ret <= 0) {
            err = SSL_get_error(ssl, 0);
        }
    } while (err == _WANT_WRITE);
    /* clean up */
    SSL_shutdown(ssl);
    SSL_free(ssl);
    SSL_CTX_free(ctx);
    /* close descriptor */
    close(sockfd);
}
/* entry */
int main()
{
    hello_test();
    return 0;
}
コンパイル例 (gccの場合):
$gcc -o hello_wolfssl hello.c -I/path/to/wolfssl -I/path/to/wolfssl/wolfssl -include wolfssl/options -lwolfssl

上記のサンプルプログラムのようにOpenSSL互換APIを利用することで、簡単に既存のOpenSSLソースコードを再利用することができます。

3. サポート済み互換APIの確認方法

OpenSSLのAPIは膨大なため、wolfSSL では使用頻度の高いAPIのサブセットを提供しています。必要なOpenSSL APIがサポートされているかは、以下の3ステップを行い判断することができます。

  • /wolfssl/opensslディレクトリ内のヘッダーファイルを確認する。
    /wolfssl/opensslディレクトリ内のヘッダーには OpenSSL 互換レイヤのAPI定義を含む記述があります。 このフォルダ内のssl.hに定義があるかを確認します。
  • NO_WOLFSSL_STUBを定義しアプリケーションのリンクを行ってみる
    APIによっては関数の定義のみで、内部の実装が行われていないものも存在します。そのようなAPIを検出するために次のステップを行います。
  1. configure に NO_WOLFSSL_STUB マクロ定義を指定します。
    $./configure –enable-opensslextra CFLAGS=”-DNO_WOLFSSL_STUB”
    SSL_CTX_get_mode() を例にとって試してみます。
    /wolfssl/openssl/ssl.h を確認します。

    #define SSL_CTX_set_mode                wolfSSL_CTX_set_mode
    #define SSL_CTX_get_mode                wolfSSL_CTX_get_mode
    #define SSL_CTX_set_default_read_ahead  wolfSSL_CTX_set_default_read_ahead
    

    SSL_CTX_get_modeは、wolfSSL_CTX_get_mode に対応付けられています。

  2. 次に、src/ssl.c内にあるwolfSSL_CTX_get_modeの実装を確認してみます。
    #ifndef NO_WOLFSSL_STUB
    long wolfSSL_CTX_get_mode(WOLFSSL_CTX* ctx)
    {
        /* TODO: */
        (void)ctx;
        WOLFSSL_STUB("SSL_CTX_get_mode");
        return 0;
    }
    #endif
    

    未実装で、#ifndef #endif で括られていることが分かります。

  3. NO_WOLFSSL_STUB を指定し、wolfSSL ライブラリをビルドします。
    $./configure –enable-opensslextra CFLAGS=”-DNO_WOLFSSL_STUB”
    $make

    先ほどのアプリケーションにSSL_CTX_get_mode() 呼び出しを追加し、コンパイルしてみます。

    $gcc -o hello_wolfssl hello.c -I/path/to/wolfssl -I/path/to/wolfssl/wolfssl -include wolfssl/options -lwolfssl
    /tmp/cco4upmi.o: 関数 `hello_test' 内:
    echoclient.c:(.text+0xf6): `wolfSSL_CTX_get_mode' に対する定義されていない参照です
    collect2: error: ld returned 1 exit status

    エラーになり、実装されていないことが分かります。

4. 注意事項

サポート済みAPIの有無以外にOpenSSL互換APIを使用する上で注意しておく点があります。

  • 構造体に互換性がない

構造体の互換性を保証しませんので、構造体メンバーを直接参照は避けてください。

  • エラーチェック・エラーコードに互換性がない

API内部の実装が、まったくの同一ではないため、エラーチェックの段階で異なる戻り値を返すことがあります。下記に一例を挙げます。
例:SSL_CTX_load_verify_locations()

エラーの条件wolfSSLOpenSSL
指定した CA ファイルが存在しない-4(WOLFSSL_BAD_FILE)0(失敗)
CA ファイルの有効期限が無効(有効期限前)-150(ASN_BEFORE_DATE_E)1(成功)
成功1(WOLFSSL_SUCCESS)1(成功)

サポート済みAPIの確認方法、及び注意点で言及しましたように気を付けるポイントがいくつかありますが、今回紹介したように wolfSSL ではOpenSSL からのアプリケーションの移行に配慮しています。また、サポート済みAPIの有無、その動作についてや新たなAPIの追加サービスのご希望などありましたらお気軽にsupport@wolfssl.com までお知らせください。

 

Posts navigation

1 2