Win32APIを使ってWindowsでSSLを実装する
SSPIやらSchannelでMSDNを検索するとわらわら出てくるけどメモってことで。
Client側の手順
- Hello送信
- ハンドシェイク
- データの送信
- EncryptMessageでデータブロックを暗号化
- sendで送信
- データの受信
- recvで受信
- DecryptMessageで復号
- DecryptMessageに渡したバッファの中からSECBUFFER_DATAタイプのものを探す
- そこに復号済みデータがあるので受信データ受け取り用バッファにコピーする
- DecryptMessageに渡したバッファの中のSECBUFFER_EXTRAタイプのものには未復号のデータが入っているので、復号後のデータ量が足りない場合や次回受信時に復号する
- DecryptMessageでSEC_E_INCOMPLETE_MESSAGEが返る場合は再度recv
- SEC_I_RENEGOTIATEが返ってきたときはハンドシェイクをやり直す
- 通信終了
- ApplyControlTokenを呼び出して自分にShutdownを通知
- InitializeSecurityContextでシャットダウントークンを生成
- sendで送信
Server側の手順
InitializeSecurityContextの代わりにAcceptSecurityContextを呼び出すだけで後はほとんど同じ。
ただしサーバー認証用の証明書をセットしたりしなきゃならないのでちと面倒。
サーバー証明書についてはPCredHandleをInitializeSecurityContextに渡せばよいだけなのでPCredHandleを作る方法をメモしておく。
- 証明書ストアから証明書(PCCERT_CONTEXT)を取得する
- CertOpenStoreまたはCertOpenSystemStoreを呼び出す
- CertFindCertificateInStoreやCertEnumCertificateInStoreで証明書を取得
- PCCERT_CONTEXTを破棄するにはCertFreeCertificateContext
- HCERTSTOREを破棄するにはCertCloseStore
- 証明書からクリデンシャル(PCredHandle)を取得する
- アルゴリズムとかフラグをいっぱい指定してAcquireCredentialsHandleを呼び出す
- 破棄するときはFreeCredentialHandleを使う