Next: rfc.uri - URIの解析と作成, Previous: rfc.sha - SHAメッセージダイジェスト, Up: ライブラリモジュール - ユーティリティ [Contents][Index]
rfc.tls - トランスポート・レイヤ・セキュリティこのモジュールはTCPソケット上のセキュアな接続を処理します。
rfc.httpで、https接続を実現するのに使われています
(rfc.http - HTTPクライアント参照)。
実行中のGaucheがTLSをサポートしているかどうかは機能識別子
gauche.net.tlsで判別できます。
機能識別子については機能条件式を参照してください。
GaucheはTLS実装としてMbedTLS(https://tls.mbed.org/)を使っています。 以前は複数のTLSサブシステムをサポートしていたので、ライブラリは複数のサブシステムを 切り替えて使えるようになっています。将来また別のTLSサブシステムをサポートするかもしれません。
{rfc.tls} TLS実装のベースクラスです。このクラスのインスタンスを使って、 セキュアなコネクションを張って通信ができます。 通常、具体的なサブクラスを気にする必要はありません。
このクラスは<connection>を継承します (gauche.connection - コネクションフレームワーク参照)。
{rfc.tls} MbedTLSサブシステムを実装しているクラスです。
{rfc.tls}
デフォルトのTLSサブシステムです。現在のバージョンでは、
これは<mbed-tls>クラスか#fです。
#fは、GaucheがTLSをサポートしていないことを示します。
{rfc.tls}
新たなTLSインスタンスを作って返します。インスタンスの具体的なクラスは
default-tls-classの値が使われます。
TLSインスタンスはtls-connectに渡すことでクライアントとして使ったり、
tls-bindとtls-acceptに渡すことでサーバーとして使うことができます。
以下のそれぞれのサブセクションを参照してください。
引数はTLSクラスに渡されるキーワード-値リストでなければなりません。 以下のキーワード引数が認識されます。
:server-nameTLS Server Name Indication拡張に使うサーバー名を指定します。 一般的には、TLSオブジェクトをクライアントとして使う場合に接続先サーバ名を渡します。 サーバとして使う場合は必要ありません。
:skip-verificationクライアントのみ。この引数が真の値の場合、接続時の証明書の認証を省略します。 これは危険な動作なので、実験目的以外では使わないでください。
{rfc.tls} TLSコネクションを閉じます。通信相手は接続が閉じられたことを知ります。 tlsがひとたびクローズされるとそれはもう使うことができません。
tlsに対しconnection-closeを呼び出すことでも同じ動作になります
(gauche.connection - コネクションフレームワーク参照)。
{rfc.tls} tlsが接続状態にある時、これらは相手と通信するための入力ポートと出力ポートを それぞれ返します。
tlsが接続状態に無い時にこれらを呼ぶと#fが返されます。
tlsに対しconnection-input-portおよび
connection-output-portを呼び出すことでも同じ動作になります
(gauche.connection - コネクションフレームワーク参照)。
{rfc.tls}
tlsが読み込みもしくは書き込み可能になるまで待ちます。tlsは既に
bindされているか接続されていなければなりません。そうでない場合は直ちに()が
返されます。
rwはシンボルread、writeの組み合わせのリストで、
待つべき条件を指定します。timeout引数は、
時刻を指定する<time>オブジェクトか、
現在からの経過時間を秒で指定する実数値か、
タイムアウトしないことを指示する#fです。省略時は#fが使われます。
戻り値は満たされた条件のリストです。例えばrw引数に
(read)もしくは(read write)を指定して、tlsが読み込み可能になったら
(read)が返されます。条件が満たされる前にタイムアウトした場合は()が
返されます。
クライアントとしてサーバにTLS接続する場合、
サーバの認証を適切に行うために、CA証明書が必要です。
Gaucheは自前でCA証明書を持っておらず、デフォルトでシステムのCA証明書バンドルを利用します。
Unixベースのシステムでは、いくつかのよくあるパスを探索します。
例えばLinuxディストリビューションならca-certificatesやそれに類する
パッケージをインストールしておくと良いでしょう。
OSXではopensslをHomebrewでインストールしておくのをおすすめします。
WindowsではWincrypt API経由でシステムの証明書ストアを使います。
デフォルトのコンフィグレーションでは、Gaucheは初期化時にシステムのCA証明書バンドルを探し、 見つかればそれを使うようになっています。かわりとなるCA証明書バンドルのパスを指定したり、 接続毎に独自の証明書を与えることもできます。
もし、何らかの理由で、システム全体で使えるCA証明書バンドルがインストールできない場合、 独自にCurlのCA証明書バンドルをhttps://curl.haxx.se/ca/cacert.pemから ダウンロードしてGaucheのインストールディレクトリに置いておくことができます。 便利なスクリプトが用意してあります。 Gaucheをインストールした後、次のコマンドを実行してください。
gosh tools/get-cacert
curlがシステムにインストールされている必要があります。また、Gaucheをインストールする時に root権限で行ったのであれば、このコマンドがCA証明書バンドルをインストールする時に sudoのパスワードを尋ねるでしょう。
もしこの方法を取ることに決めたなら、時々このコマンドを実行してCA証明書バンドルを 最新版に更新するのを忘れないようにしてください。 CA証明書は期限が切れたり無効化されることがあります。
{rfc.tls}
CA証明書バンドルのパスを保持しています。値は、CA証明書バンドルファイルの
パス名、シンボルsystem、あるいは#fのいずれかです。
この値がsystemの場合、Gaucheはシステムのデフォルトの証明書バンドルを
使おうとします。もしそれが見つからなければ接続時にエラーが報告されます。
この値が#fの場合、CA証明書は自動的にロードされないので、
tls-load-objectを使って自分で適切な証明書をロードしてやる必要があります。
(このオプションは<ax-tls>のみ有効です。
<mbed-tls>を使う場合は、必ず有効なCA証明書バンドルが必要です。)
デフォルトのコンフィグレーションでは、Gaucheはrfc.tlsモジュール初期化時に
システムのCA証明書バンドルが使えるかどうか調べて、使えるならtls-ca-bundle-pathの
初期値をsystemに、使えないなら#fにセットします。
したがって、デフォルトのコンフィグレーションで使っている限り、
この値がsystemであればシステムのCA証明書を使えると考えて良いでしょう。
このデフォルトの振る舞いはconfigure時に--with-ca-bundleオプションで
変えられます。使っているGaucheのコンフィグレーションが変えられているかどうかは、
gauche-config --reconfigureコマンドを実行して--with-ca-bundle
オプションがあるかどうかを見ればわかります。
{rfc.tls} クライアントとして、指定されたサーバにTLSで接続します。
tls引数はまだ接続されていないTLSオブジェクトでなければなりません。
hostとportは文字列で、それぞれサーバのホスト名とポートを指定します。
ホスト名についてはドメイン名のほか、IP表記が使えます
(例: "127.0.0.1"、"[::1]")。
ポートについては整数のポート番号も名前による指定(例: "https")も使えます。
proto引数はシンボルtcpかudpのどちらかでなければならず、
省略時はtcpとみなされます
(udpを指定した場合はTLSのかわりにDTLSが使われることになりますが、
今はDTLSを実用的に使うために必要なAPIがいくつか未実装です。)
サーバにコンタクトできたら、この手続きはサーバ証明書を入手して
CA証明書を使ってバリデーションを試みます。
バリデーションが失敗したらエラーが投げられます。正しく接続を確立するには、
有効なCA証明書ストアがパラメータtls-ca-bundle-pathで指定されていなければ
なりません。
接続が確立してTLSハンドシェイクが成功したら、 引数に渡したtlsオブジェクトはconnected状態になり、 相手とデータをやりとりすることができます。
TLSコネクションをサーバとして使うには、秘密鍵、サーバ証明書、および中間証明書を 用意する必要があります。これらはクライアントからのTLS接続を受け付ける前に 読み込まれている必要があります。
{rfc.tls} pathで示されるファイルに格納されたサーバ証明書を読み込みます。 ファイル中に複数の証明書を含めることができます。また、この関数は複数回呼び出せて、 tlsに中間証明書を追加してゆくことができます。
{rfc.tls}
pathed示されるファイルに格納されたサーバの秘密鍵を読み出して登録します。
秘密鍵が暗号化されている場合はpasswordにパスワードを指定します。
秘密鍵が暗号されていない場合はpasswordに#fを渡します。
{rfc.tls} TLS接続のサーバー側エンドポイントを作ります。
tls引数はまだ接続もbindもされていないTLSオブジェクトでなければなりません。
host引数は文字列のホスト名か#fです。
port引数は整数のポート番号か文字列によるポート名です。
protoにはシンボルtcpかudpを渡します。
省略時はtcpが仮定されます。
(NB: udpサーバー (DTLS) を使うにはいくつか追加のAPIサポートが
必要なので、今のところDTLSは使えません)。
socket-bindと同じように、portに0を指定することで、
空いているポート番号をシステムに選んでもらうことができます。
実際にどのポートにバインドされたかは
(sockaddr-port (connection-self-address tls))
でわかります。
{rfc.tls}
引数のtlsは、tls-bindでバインドされたTLSオブジェクトでなければなりません。
サーバ証明書と秘密鍵はtls-load-certificateおよびtls-load-private-key
によってtlsにロードされていなければなりません。
この手続きはクライアントの接続要求を待ちます。接続要求が来たら、 サーバ証明書をクライアントに提示し、TLSハンドシェークを行います。 全てが成功すれば、クライアントに接続された新たなtlsオブジェクトを作って返します。
<tls>クラスはコネクションフレームワークを実装しているので、
以下のメソッドがtlsオブジェクトに対して使えます。特に最初の2つは
下位にあるコネクションのIPアドレスを得るのに使えます。
connection-self-address (c <tls) connection-peer-address (c <tls>) connection-input-port (c <tls>) connection-output-port (c <tls>) connection-close (c <tls>)
Next: rfc.uri - URIの解析と作成, Previous: rfc.sha - SHAメッセージダイジェスト, Up: ライブラリモジュール - ユーティリティ [Contents][Index]