2009/11/21

openssl haskell context

Haskell で Socket 使って少し通信できるようになったので
SSL で通信でもしてやろうかと思いました
クライアントとして
引きつづき HsOpenSSL を使って

OpenSSL でクライアントとして接続というと
context っていうクライアント認証の情報とか SSL のバージョンとかと
あと socket を作っておいて
その二つを合わせて SSL の接続へと socket を昇格? させます

で、ググりゃそりゃリファレンスが出てくるので
OpenSSL.Session
ghci で上に従ってやってみようと思ったんですが何か上手くいかず
色々ググったりして散々悩んでみたんですが
コード書いてコンパイルしたら通ってしまいました
ghci だとダメってよりは、withOpenSSL が無くてダメだったのかな

折角なんで Firefox から ThawtePremiumServerCA って証明書を抜き
引き数に hostname を取って 443 port で SSL 通信して
サーバ証明書を取ってきて証明書の検証ができるかどうか試してみました
$ ./cert_check www.google.com
VerifyFailure
$ ./cert_check www.blogger.com
VerifySuccess
有効期限の確認も FQDN と CN の比較もしてなくて
ルート証明書の公開鍵でサーバ証明書の署名の確認してるだけですが

import System
import Data.Maybe
import Network.Socket
import Network.BSD
import OpenSSL
import OpenSSL.Session
import OpenSSL.X509
import OpenSSL.PEM
import OpenSSL.RSA
import OpenSSL.EVP.PKey

main = withOpenSSL $
do
(host:_) <- getArgs
addr <- return . head . hostAddresses =<< getHostByName host

ctx <- context
sock <- socket AF_INET Stream 0
Network.Socket.connect sock (SockAddrInet 443 addr)
ssl <- connection ctx sock
OpenSSL.Session.connect ssl
x509 <- return . fromJust =<< getPeerCertificate ssl
-- putStr =<< writeX509 x509
OpenSSL.Session.shutdown ssl Unidirectional

root <- readX509 =<< readFile "ThawtePremiumServerCA.crt"
pk <- return . fromJust . toRSAKey =<< getPublicKey root
putStrLn . show =<< verifyX509 x509 pk
where
toRSAKey :: SomePublicKey -> Maybe RSAPubKey
toRSAKey = toPublicKey

0 件のコメント:

コメントを投稿