keystore の中の certificate が有効か確認する

Kafka の helm chart の TLS を有効にしようとしたのだが、失敗した。

*[Couldn't find the expected Java Key Stores (JKS) files! They are mandatory when encryption via TLS is enabled with Kafka Bitnami helm chart](https://stackoverflow.com/questions/65661686/couldnt-find-the-expected-java-key-stores-jks-files-they-are-mandatory-when)

しょうもないミス（もしくはこのやり方が間違ってる）のだと思うのだが、自分で 前回 [openssl と keytool を使った keystore 作成スクリプトを解析する](https://qiita.com/TsuyoshiUshio@github/items/ed92ca8ce160907093fc) でストアした KeyStore が正しいのか検証してみることにした。

# 方針

1. Keysotre の中の （サーバー）証明書を取り出す
2. Keystore の中の　Private Key を取り出す
3. openssl の `server` `s_client` のサブコマンドで実際に通信できるか確認する。

# サーバー証明書の取り出し

```bash
$ keytool -keystore kafka-0.keystore.jks -export -alias localhost -rfc -file signed_exported.crt
Enter keystore password:  
Certificate stored in file <signed_exported.crt>
```

# Private Key の取り出し

まず、Private Key のエイリアスを見つけよう。

```
$ keytool -list -v -keystore kafka-0.keystore.jks -storepass cooder01
 :
Alias name: localhost
Creation date: Jan 10, 2021
Entry type: PrivateKeyEntry
Certificate chain length: 2
  :
```

localhost がキーペアのエイリアスのようだ。ちょっとめんどくさいが[次の方法](https://security.stackexchange.com/questions/3779/how-can-i-export-my-private-key-from-a-java-keytool-keystore)でできた。

## pkcs12 の keystore を作成する

```bash
$ keytool -importkeystore -srckeystore kafka-0.keystore.jks -destkeystore keystore.p12 -deststoretype PKCS12 -srcalias localhost -deststorepass PASSWORD -destkeypass PASSWORD

```

## pkcs12 のキーストアから　Private Key を出力。

```bash
openssl pkcs12 -in keystore.p12  --nodes -nocerts -out key.pem
```

# サーバーの起動

openssl のツールでサーバーを起動できる。export した証明書と、Private Key　を使ってサーバー起動する。

```bash 
openssl s_server -cert signed_exported.crt -key key.pem 
```

ローカルで動作している。

```bash
$ lsof -i:4433 -P
COMMAND   PID  USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
openssl 19336 ushio    3u  IPv6 460263      0t0  TCP *:4433 (LISTEN)
```

# クライアントの起動

これは失敗する（自己証明書なので）と思ってやったけど、しっかり失敗した。予想どおり。

```bash
$ openssl s_client -connect localhost:4433
  :
    Start Time: 1610343426
    Timeout   : 7200 (sec)
    Verify return code: 21 (unable to verify the first certificate)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK
```

じゃあ、CA 証明書を追加するオプションを探せばいいはずなので次のようにすると接続できた。

```bash
$ openssl s_client -connect localhost:4433 -CAfile ca.crt.exported 
    Start Time: 1610344811
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
    Extended master secret: no
    Max Early Data: 0
---
read R BLOCK

hello
```

サーバー側も受け取っている

```bash
Shared ciphers:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:DHE-RSA-AES256-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES128-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA
Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224:DSA+SHA224:DSA+SHA256:DSA+SHA384:DSA+SHA512
Shared Signature Algorithms: ECDSA+SHA256:ECDSA+SHA384:ECDSA+SHA512:Ed25519:Ed448:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA-PSS+SHA256:RSA-PSS+SHA384:RSA-PSS+SHA512:RSA+SHA256:RSA+SHA384:RSA+SHA512:ECDSA+SHA224:RSA+SHA224
Supported Elliptic Groups: X25519:P-256:X448:P-521:P-384
Shared Elliptic groups: X25519:P-256:X448:P-521:P-384
CIPHER is TLS_AES_256_GCM_SHA384
Secure Renegotiation IS supported

hello

```

# まとめ

oepnssl ツールは簡易なサーバーとクライアントを作れて動作確認できるのはかなりいい感じ。