クマは森で用を足しますか?

アウトプットは重要です。

SM-DP+ (IIJ) で学ぶ OpenSSL

先日、Pixel 4 の eSIM に STORE DATA コマンドを送信し、eSIM に入っていたプロファイルの情報を読み出しました。eSIM には IIJ のプロファイルが入っていますので、同プロファイルに関する Notification の送信先アドレスも得ることができました。プロファイル情報の読み出しについては、下記のエントリをご覧ください。

cheerio-the-bear.hatenablog.com

今回はその (おそらく SM-DP+ の) アドレスを使い、OpenSSL について少し学んでみました。ここのところ担当している業務でこれ系のコードを書くことは滅多にないので、良いエクササイズになりました。

OpenSSL で接続してみる : openssl s_client

まずは、SM-DP+ の FQDN をそのまま指定して openssl s_client を実行してみます。SM-DP+ から受け取った証明書の検証結果は、下記のように X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN (19) になります。

$ openssl s_client -connect SM-V4-033-A-GTM.PR.GO-ESIM.COM:443
...
    Start Time: 1612622663
    Timeout   : 7200 (sec)
    Verify return code: 19 (self signed certificate in certificate chain)
    Extended master secret: no

GSMA ルート CI の証明書を指定していないので、サーバー証明書の検証結果が X509_V_OK (0) にならないのは想定通りです。GSMA の下記サイトから、SGP.21 と SGP.22 に対応する方のルート CI 証明書をダウンロードして指定します。

www.gsma.com

結果は下記の通り、今度はサーバー証明書の検証結果が X509_V_OK (0) になりました。

$ openssl s_client -connect SM-V4-033-A-GTM.PR.GO-ESIM.COM:443 -CAfile ./Symantec_GSMA_RSPv2-Root-CI1.pem
...
    Start Time: 1612622673
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no

OpenSSL で接続してみる : 自作

次に、上記のコマンドと同じようなことをする小さな実行ファイルを、OpenSSL を使って久しぶりに C 言語で書いて作ってみました。引数で受け取った PEM ファイルを SSL_CTX_load_verify_locations() で指定して接続し、SSL_get_peer_certificate() と SSL_get_verify_result() を使ってサーバー証明書を検証します。あっ!コミットメッセージに typo ある ..

github.com

GSMA のルート CI 証明書を指定しない場合、サーバー証明書の検証結果は下記のように X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN (19) になります。IIJ の SM-DP+ でも楽天モバイルの SM-DP+ でも、結果は同じです。

$ ./sample -n SM-V4-033-A-GTM.PR.GO-ESIM.COM
Verify Result: 19

$ ./sample -n rakuten.prod.ondemandconnectivity.com
Verify Result: 19

GSMA のルート CI 証明書を指定すれば、X509_V_OK (0) になりました。それなりに期待した通りに動いてくれたようです。

$ ./sample -n SM-V4-033-A-GTM.PR.GO-ESIM.COM -c ./Symantec_GSMA_RSPv2-Root-CI1.pem
Verify Result: 0

$ ./sample -n rakuten.prod.ondemandconnectivity.com -c ./Symantec_GSMA_RSPv2-Root-CI1.pem
Verify Result: 0