OpenTSAがあった時にはmod_tsaと言うApacheに組み込むモジュールがありました。ただOpenTSAが解散してOpenSSLに移管されてからこの辺りの状況が良く分かりません。OpenSSLコマンドではtsオプションでTimeStampRequestの生成・TimeStampResponseの生成・TimeStampTokenの検証が可能です。
FreeTSAではOpenSSLコマンドのtsオプションにより「TimeStampResponseの生成」をしてクライアントに返す事になります。材料は以下となります。
・TSA証明書と対応した秘密鍵(PEM形式)
・OpenSSL 1.0.0以降(opensslコマンド)
・Apache+CGI(Perl利用)
・ntpの設定
最初のTSA証明書の用意が一番めんどくさいですね。OpenSSLの認証局(CA)機能を使ってルート証明書とTSA証明書を用意するのが一番楽です。後日別途まとめたいと思いますがTSA証明書生成時にV3拡張として以下のようにしておくと良いでしょう。
[ v3_cert ]
keyUsage = digitalSignature, nonRepudiation
extendedKeyUsage = critical,timeStamping
後はOpenSSLは最新版をダウンロードしてインストール頂ければ良いですし、ApacheとPerlはLinux環境なら最初から入っていると思います。前提としてApacheがインストールされておりPerlでCGIが実行できることが必要です。これで準備完了です!
OpenSSLコマンドのtsオプションでTimeStampResponse(-replyオプション)の生成を行うには、入力として以下が必要です。
(1) -queryfile:タイムスタンプ要求(TimeStampRequest)のファイル
(2) -config:TSAの設定(config)ファイル(TSA証明書と秘密鍵含む)
(3) -passin:秘密鍵のパスワード
コマンドとして以下となります。
$ openssl ts -reply -queryfile (1) -config (2) -passin pass:(3)
パスワードは pass: 指定しています。タイムスタンプ要求は残念ながらファイルにする必要があります。設定ファイルは省略不可です。設定ファイルの例を以下に示します。dir設定と証明書や秘密鍵のファイルはあなたの環境に合わせて変更する必要があります。ポリシーも色々考える必要がありますね。またその辺りは別途まとめたいと思います。
#
# This config is used by the Time Stamp Authority tests.
#
RANDFILE = ./.rnd
# Extra OBJECT IDENTIFIER info:
oid_section = new_oids
TSDNSECT = ts_cert_dn
INDEX = 1
[ new_oids ]
any_policy = 2.5.29.32.0 # any policy
# Policies used by the TSA tests.
seiko_policy = 1.3.6.1.4.1.955.1.10.1.3.5
amano_policy = 0.2.440.200217.100.200.100
pfu_policy = 0.2.440.200185.1.3.1
#----------------------------------------------------------------------
[ tsa ]
default_tsa = tsa_config1 # the default TSA section
[ tsa_config1 ]
# These are used by the TSA reply generation only.
dir = /your_dir/tsa # TSA root directory
serial = $dir/tsa_serial # The current serial number (mandatory)
signer_cert = $dir/tsa.pem # The TSA signing certificate
certs = $dir/ca2.pem # Certificate chain to include in reply
signer_key = $dir/tsa.key # The TSA private key
default_policy = any_policy # Policy if request did not specify it
other_policies = seiko_policy, amano_policy, pfu_policy
digests = sha1, sha256, sha512 # Acceptable message digests (mandatory)
accuracy = secs:1, millisecs:500, microsecs:100 # (optional)
ordering = yes # Is ordering defined for timestamps?
tsa_name = yes # Must the TSA name be included in the reply?
#ess_cert_id_chain = yes # Must the ESS cert id chain be included?
タイムスタンプ要求はHTTPのPOSTメソッドなら送られてきたBodyそのままになりますがファイルにする必要があるので一時ファイルとして保存します。タイムスタンプ応答を生成してヘッダを付けて返してやれば動作するはず。と言うことでPerlのCGIのソースです。PASSWDは秘密鍵のパスワードをセットする必要があります。パスワードをCGIに直接書くのは危険なので別シェル等にする工夫はした方が良いですね。
#!/usr/bin/perl
use File::Temp;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
# die "not POST method.";
$buffer = "ERROR";
}
# --- output TimeStampRequest to temp file.
my($tmp_fh, $tmp_filename) = File::Temp::tempfile();
print $tmp_fh $buffer;
close($tmp_fh);
# --- generate and get TimeStampResponse.
$command = "openssl ts -reply -queryfile " . $tmp_filename;
$command = $command . " -config CAtsa.cnf -passin pass:PASSWD";
$response = `$command`;
# --- output header.
print "Content-type: application/timestamp-reply\n";
print "Content-length: ". length($response) . "\n";
print "\n";
# --- output body.
print $response;
# --- delete temp file.
unlink $tmp_filename;
# --- end.
exit 0;
これでこのCGIに対してタイムスタンプ要求を送れば応答が返ってくるはずです。動作確認したら以下のようにApacheの設定に追加してやれば "http://ホスト名/tsa" で利用可能です。
ScriptAlias /tsa "/http/www/cgi-bin/tsa.cgi"
また時刻同期は非常に大事ですのでntpの設定をきちんとやっておきましょう。NICT公開のNTPがお薦めです。アドレスは ntp.nict.jp で検索してみてください。
以上で完了です。なおサンプルのOpenSSL設定ファイルとCGIファイルは
ここでダウンロードできます。サンプルでは一応ログファイル出力も含んでいます。よろしければご覧ください。
[2013-10-01:追記]
S社のMさんからContent-Typeのapplication/timestamp-responseは誤りで正しくはapplication/timestamp-replyとのご指摘を頂きました。RFC3161原文のミスとのことで
日本語版では修正されていました。Mさんありがとうございました。
[追記終了]
FreeTSAその1:
フリータイムスタンプ局(FreeTSA)のすゝめ
FreeTSAその2:
10分でできるタイムスタンプ局(FreeTSA Project)
FreeTSAその3:
自由に使えるタイムスタンプ局(FreeTSA Service)