この記事はTumblrで公開されていました
これは2016年4月の記事です。現在9legacyのパッチは修正されています。
うまくいかないメモ
とても混乱しているので記録する。
MacとiOSのMailアプリは、どちらもTLS 1.0までしか対応していない
未対応の暗号スイートを使うと、具体的にはこのようなメッセージがConsole.appに記録される。
2016/04/19 22:56:52.960 Mail[483]: CFNetwork SSLHandshake failed (-9824)
tlssrv -D -limap4d ...
と実行したら、ClientHelloに乗ってくるversionが301だった。301はTLS 1.0を表す。なのでFinishedメッセージのハッシュ関数はmd5+sha1が使われる*1。
RSA 4096bit鍵とSHA256withRSAの証明書を使うとTLS 1.2以外がエラー
おそらくPlan 9側の問題だと思う。curl $url -tlsv1.2
の場合はHTTPアクセスが通るけれど、-tlsv1.1
以下に強制すると証明書検証エラーになる。このときサーバのログをみると、
tls reports recv HFinished xxxxxxxxxxxxxxxxxxx tls reports tlsError: finished verification failed tls reports failed: incorrect .pem file format: bad header or trailer
と記録されるが、pemファイルのフォーマットは間違っていないはず。-tlsv1.2
の場合は、クライアントからFinishedを受け取って、サーバの検証も正常に終了して、Finishedをクライアントへ返せている。
tls reports recv HFinished xxxxxxxxxxxxxxxxxxx tls reports send HFinished yyyyyyyyyyyyyyyyyyy tls reports tls finished tls reports open
RSA 4096bit鍵とSHA256withRSAの証明書でもSTARTTLSは通過する
同じ証明書で、imap4sとhttpsではエラーになったものが、smtpのSTARTTLSを使った場合は接続ができる。これはMail.appで確認した。Plan 9の実装はtlsServerが呼ばれるだけなので、同じ気がするけど。
そもそも
何が関係しているのか
- カーネルのdevtls
- libsec.a
- factotum
devtls
#a/tls/$id/handでハンドシェイクを実施して、終わったら#a/tls/$id/data経由で暗号化したデータをやりとりする。#a/tls/$id/ctlあたりに鍵情報や暗号化アルゴリズムをwriteする。
libsecライブラリ
暗号化の関数と、ハンドシェイクを行うライブラリ。tlsServerはハンドシェイクを行い、最終的にはdevtlsの#a/tls/$id/dataを返す。
factotum
HClientKeyExchangeメッセージでクライアントと交換した鍵を取り扱う。factotumはprotoとroleの値によってプロトコルが変わる。proto=rsa role=client
の場合はRSAで暗号化された値をwriteして、そのままreadすると暗号解除された値が読める。
- 証明書のmoduloに一致するものがfactotumに入っているか探す
- 1のエントリと交換した鍵を使って、マスターsecretを生成する
テスト方法メモ
証明書の確認
$ openssl verify -CAfile ./ca.pem cert.pem
root.pemはCAのルート証明書と中間証明書をcatしたもの。
サーバの確認
OS Xから実行してもエラーになる。Linuxなら正常に動作する。opensslのバージョン差だろうか。
$ openssl s_client -verify 6 -state -msg -connect example.com:443 -CAfile ./root.pem
IMAPsの確認
$ curl imaps://example.com:993 -v -u user:pass
特にオプションを付けなければTLS 1.2で動作する。バージョンを強制したい場合は-tlsv1.1
等のオプションを加える。
ATSの確認
$ nscurl --ats-diagnostics https://example.com/