時には立ち止まってみるのもいいよ

仕事の合間の息抜き&備忘録。最近息抜きと仕事の区別がついていない。

SSLのサーバー証明書をVERIFYする(Windows)

例によって覚え書き。

 

前フリ

Windows上でOpenSSLを使ったクライアントアプリを作ったんだが、サーバーからもらった証明書をOpenSSLでVERIFYすると、X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY ってなエラーが出てしまう。

 

要するにOpenSSLでVERIFYする際にまともな証明書ストアを用意していないのが悪くて、ルート証明書の確認が出来ないよってことらしい。

 

アプローチとしては

  • OpenSSLにWindowsからインポートした証明書ストアを読み込ませる
  • WindowsAPIで証明書のVERIFYをやらせる

のどちらか。前者は準備が面倒だし、おもしろくないので後者を採用。

 

本題

 おもしろくないからっていう理由についてのツッコミはさておき、WindowsのCrypto APIの出番である。これ、めんどいんだよなー。

 

OpenSSLのリファレンスとかMSDNをちょろちょろ見ると、

  1. OpenSSLのSSL_CTX_set_cert_verify_callback()で自前VERIFY関数を登録。
  2. VERIFY関数に渡ってきたX509_STORE_CTXコンテキストを使って、i2d_X509()でサーバー証明書のバイナリデータ(DER)を抽出。
  3. CertCreateCertificateContext()でサーバー証明書を読み込む。
  4. CertGetCertificateChain()でサーバー証明書のチェインを列挙して、
  5. CertVerifyCertificateChainPolicy()でシステムの証明書ストアからVERIFY実行。

という流れ。1番目のi2d_X509()ってのはOpenSSLの関数。初めて使った。。

 

CertなにがしのAPIにいれる構造体がわけわからんのでうんざりしてたんだけど、Googleさんに聞いてみたら、でてきたよ。。→ 「Add peer certificate verification on windows」

 

なるほど。自己署名のはじき方ものってるな。よし。ってことで、完成!

 

Crypto APIはやっぱり面倒だった。

 

というお話でした。おわり。