panda's tech note

Advent Calendar 2021:自作メッセージングプロトコル

Day 6: ID証明書の検証

ID管理ネットワークを実装する前に、ID証明書の(署名の)検証を実装していなかったので、今日は検証機能を実装します。

証明書の検証

OpenSSL モジュールを用いた証明書の検証は、 OpenSSL.crypto.X509Store() で作成する(CA)証明書ストアと検証対象の証明書に対して、OpenSSL.crypto.X509StoreContext() によりコンテキストを作成して、検証を行います。以下のコードのように、証明書ストアに add_cert() メソッドでCA証明書を登録し、この証明書ストアインスタンスと検証対象の証明書で検証のためのコンテキストを作成します。そのコンテキストで verify_certificate() メソッドを呼ぶことで証明書の検証を行います。

def verify_certificate(cert, cacert):
    try:
        store = OpenSSL.crypto.X509Store()
        store.add_cert(cacert)
        store_ctx = OpenSSL.crypto.X509StoreContext(store, cert)
        store_ctx.verify_certificate()
        return True
    except Exception as e:
        return False

上記のコードでは、 store_ctx.verify_certificate() メソッドにより証明書の検証をしています。このメソッドは、証明書 cert の署名者がCA証明書ストア store に登録されていない場合、例外 OpenSSL.crypto.X509StoreContextError を発生させます。今回は verify_certificate() 関数で、この検証が成功した場合は True を返し、例外が発生した場合は、証明書の検証ができなかったものとして False を返すようにしています。

実装

上記で説明した署名の検証を [github:drpnd/advmsg:sign.py] に実装しました。このプログラムを実行するとID証明書 crt.pem がCA証明書 ca/cacert.pem により署名されている場合は、verify_certificate() 関数は True を返し、以下のように Valid certificate となります。

$ python3 verify.py
Valid certificate

なお、CA証明書ではない適当な証明書(今回は自信のID証明書)を以下のようにCA証明書として読み込むと、署名が検証できず、 verify_certificate() 関数が False を返し、以下のように Invalid certificate となります。

$ python3 verify.py --cacert crt.pem
Invalid certificate

まとめと明日の予定

ID証明書の検証ができるようになったため、明日からは(今度こそ)ID管理ネットワークの実装をしていきます。