ルートCAと中間CAの検証分析

#はじめに
前回、[OpenSSL ECDSA署名検証の仕組みおさらい](https://qiita.com/kmitsu76/items/3853be6516fb2a0b013a)にて中間CAで署名したメッセージの検証を行った。
証明書チェーンの完全な検証のために、中間CAとルートCAの間の検証を仕組みを理解する目的で行う。

#環境
前回作成した環境にて検証を実施
[OpenSSL ECDSAでの自己認証局作成](https://qiita.com/kmitsu76/items/ac2db516ba46c50f43d6)

#検証内容
中間CA証明書はルートCAで署名したものなので、前回同様

１、ルートCAの公開鍵
２、中間CA証明書の署名
３、署名対象のメッセージ

上記をそろえれば検証できるはず。
#１、ルートCAの公開鍵　準備
これは前回もやっている手順で簡単にできる。

```
openssl x509 -in /etc/pki/AWS/cacert.pem -pubkey -noout
-----BEGIN PUBLIC KEY-----
MFkw...
       ....==
-----END PUBLIC KEY-----
openssl x509 -in /etc/pki/AWS/cacert.pem -pubkey -noout > capub.pem
```
#２、中間CA証明書の署名　準備
証明書に埋まっている署名をDER形式で取り出す。

```
SIGNATURE_HEX=$(openssl x509 -in /etc/pki/AWS/icacert.pem -text -noout -certopt ca_default -certopt no_validity -certopt no_serial -certopt no_subject -certopt no_extensions -certopt no_signame | grep -v 'Signature Algorithm' | tr -d '[:space:]:')

echo ${SIGNATURE_HEX} | xxd -r -p > certsig.bin

```

#３、署名対象のメッセージ
証明書の場合は何を指すのだろうか。署名対象が定義づけされているのだろうか。

#そもそも・・・
証明書の構造はRFC5280によると下記にようになっているよう。

```
   Certificate  ::=  SEQUENCE  {
        tbsCertificate       TBSCertificate,
        signatureAlgorithm   AlgorithmIdentifier,
        signatureValue       BIT STRING  }

   TBSCertificate  ::=  SEQUENCE  {
        version         [0]  EXPLICIT Version DEFAULT v1,
        serialNumber         CertificateSerialNumber,
        signature            AlgorithmIdentifier,
        issuer               Name,
        validity             Validity,
        subject              Name,
        subjectPublicKeyInfo SubjectPublicKeyInfo,
        issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
                             -- If present, version MUST be v2 or v3

        subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
                             -- If present, version MUST be v2 or v3
        extensions      [3]  EXPLICIT Extensions OPTIONAL
                             -- If present, version MUST be v3
        }

   Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }

   CertificateSerialNumber  ::=  INTEGER

   Validity ::= SEQUENCE {
        notBefore      Time,
        notAfter       Time }

   Time ::= CHOICE {
        utcTime        UTCTime,
        generalTime    GeneralizedTime }

   UniqueIdentifier  ::=  BIT STRING

   SubjectPublicKeyInfo  ::=  SEQUENCE  {
        algorithm            AlgorithmIdentifier,
        subjectPublicKey     BIT STRING  }

   Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension

   Extension  ::=  SEQUENCE  {
        extnID      OBJECT IDENTIFIER,
        critical    BOOLEAN DEFAULT FALSE,
        extnValue   OCTET STRING
                    -- contains the DER encoding of an ASN.1 value
                    -- corresponding to the extension type identified
                    -- by extnID
        }

```

大きく3つの構造になる。
        tbsCertificate       TBSCertificate,
        signatureAlgorithm   AlgorithmIdentifier,　
        signatureValue       BIT STRING

まさに署名対象がtbsCertificateとして定義されている。(to be signed)
中間証明書をASN1デコードしてみる。
PEMのままだとoffset too largeエラーがどうしても回避できず、DER形式に変換する。

```
openssl asn1parse -in icacert.pem -inform PEM
Error: offset too large　//PEMのままだとエラーが出る

openssl x509 -in icacert.pem -inform PEM -out icacert.der -outform DER

openssl asn1parse -in icacert.der -inform der
    0:d=0  hl=4 l= 572 cons: SEQUENCE
    4:d=1  hl=4 l= 482 cons: SEQUENCE
    8:d=2  hl=2 l=   3 cons: cont [ 0 ]
   10:d=3  hl=2 l=   1 prim: INTEGER           :02
   13:d=2  hl=2 l=   1 prim: INTEGER           :02
   16:d=2  hl=2 l=  10 cons: SEQUENCE
   18:d=3  hl=2 l=   8 prim: OBJECT            :ecdsa-with-SHA256
   28:d=2  hl=2 l= 114 cons: SEQUENCE
   30:d=3  hl=2 l=  11 cons: SET
   32:d=4  hl=2 l=   9 cons: SEQUENCE
   34:d=5  hl=2 l=   3 prim: OBJECT            :countryName
   39:d=5  hl=2 l=   2 prim: PRINTABLESTRING   :JP
   43:d=3  hl=2 l=  14 cons: SET
   45:d=4  hl=2 l=  12 cons: SEQUENCE
   47:d=5  hl=2 l=   3 prim: OBJECT            :stateOrProvinceName
   52:d=5  hl=2 l=   5 prim: PRINTABLESTRING   :Tokyo
   59:d=3  hl=2 l=  20 cons: SET
   61:d=4  hl=2 l=  18 cons: SEQUENCE
   63:d=5  hl=2 l=   3 prim: OBJECT            :localityName
   68:d=5  hl=2 l=  11 prim: PRINTABLESTRING   :<任意>
   81:d=3  hl=2 l=  17 cons: SET
   83:d=4  hl=2 l=  15 cons: SEQUENCE
   85:d=5  hl=2 l=   3 prim: OBJECT            :organizationName
   90:d=5  hl=2 l=   8 prim: PRINTABLESTRING   :<任意>
  100:d=3  hl=2 l=  12 cons: SET
  102:d=4  hl=2 l=  10 cons: SEQUENCE
  104:d=5  hl=2 l=   3 prim: OBJECT            :organizationalUnitName
  109:d=5  hl=2 l=   3 prim: PRINTABLESTRING   :<任意>
  114:d=3  hl=2 l=  28 cons: SET
  116:d=4  hl=2 l=  26 cons: SEQUENCE
  118:d=5  hl=2 l=   3 prim: OBJECT            :commonName
  123:d=5  hl=2 l=  19 prim: PRINTABLESTRING   :<ルートCAのCN>
  144:d=2  hl=2 l=  30 cons: SEQUENCE
  146:d=3  hl=2 l=  13 prim: UTCTIME           :
  161:d=3  hl=2 l=  13 prim: UTCTIME           :
  176:d=2  hl=2 l= 123 cons: SEQUENCE
  178:d=3  hl=2 l=  11 cons: SET
  180:d=4  hl=2 l=   9 cons: SEQUENCE
  182:d=5  hl=2 l=   3 prim: OBJECT            :countryName
  187:d=5  hl=2 l=   2 prim: PRINTABLESTRING   :JP
  191:d=3  hl=2 l=  14 cons: SET
  193:d=4  hl=2 l=  12 cons: SEQUENCE
  195:d=5  hl=2 l=   3 prim: OBJECT            :stateOrProvinceName
  200:d=5  hl=2 l=   5 prim: PRINTABLESTRING   :Tokyo
  207:d=3  hl=2 l=  17 cons: SET
  209:d=4  hl=2 l=  15 cons: SEQUENCE
  211:d=5  hl=2 l=   3 prim: OBJECT            :organizationName
  216:d=5  hl=2 l=   8 prim: PRINTABLESTRING   :<任意>
  226:d=3  hl=2 l=  73 cons: SET
  228:d=4  hl=2 l=  71 cons: SEQUENCE
  230:d=5  hl=2 l=   3 prim: OBJECT            :commonName
  235:d=5  hl=2 l=  64 prim: PRINTABLESTRING   :<中間認証局のCN>
  301:d=2  hl=2 l=  89 cons: SEQUENCE
  303:d=3  hl=2 l=  19 cons: SEQUENCE
  305:d=4  hl=2 l=   7 prim: OBJECT            :id-ecPublicKey
  314:d=4  hl=2 l=   8 prim: OBJECT            :prime256v1
  324:d=3  hl=2 l=  66 prim: BIT STRING
  392:d=2  hl=2 l=  96 cons: cont [ 3 ]
  394:d=3  hl=2 l=  94 cons: SEQUENCE
  396:d=4  hl=2 l=  29 cons: SEQUENCE
  398:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Subject Key Identifier
  403:d=5  hl=2 l=  22 prim: OCTET STRING      [HEX DUMP]:0414...
  427:d=4  hl=2 l=  31 cons: SEQUENCE
  429:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Authority Key Identifier
  434:d=5  hl=2 l=  24 prim: OCTET STRING      [HEX DUMP]:3016...
  460:d=4  hl=2 l=  15 cons: SEQUENCE
  462:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Basic Constraints
  467:d=5  hl=2 l=   8 prim: OCTET STRING      [HEX DUMP]:30060101FF020100
  477:d=4  hl=2 l=  11 cons: SEQUENCE
  479:d=5  hl=2 l=   3 prim: OBJECT            :X509v3 Key Usage
  484:d=5  hl=2 l=   4 prim: OCTET STRING      [HEX DUMP]:03020186
  490:d=1  hl=2 l=  10 cons: SEQUENCE
  492:d=2  hl=2 l=   8 prim: OBJECT            :ecdsa-with-SHA256
  502:d=1  hl=2 l=  72 prim: BIT STRING

```
上記から、d=1の3項目がそれにあたることがわかる。
    4:d=1  hl=4 l= 482 cons: SEQUENCE : tbsCertificate
    490:d=1  hl=2 l=  10 cons: SEQUENCE : signatureAlgorithm
    502:d=1  hl=2 l=  72 prim: BIT STRING : signatureValue
 
証明書の中からtbsCertificateだけを抜いてきて保存したい。
上記からicacert.derの中のオフセット4の486バイト（ヘッダー長4＋482）がそれになる。

```
dd if=icacert.der of=icatbs.der skip=4 bs=1 count=486
486+0 レコード入力
486+0 レコード出力
486 バイト (486 B) コピーされました、 0.00166907 秒、 291 kB/秒
```

これで材料がそろった。

```
openssl dgst -sha256 -verify capub.pem -signature certsig.bin icatbs.der
Verified OK
```

ルートCA公開鍵で、中間CAの署名を検証し、中間CAの内容（tbsCertificate）が正しいことが検証され、証明書チェーン全体が検証できた。

はじめ、icatbs.derのハッシュ（sha256）をコマンドに与えると思っていたが、tbsCertificate実体を与えればよろしくやってくれるよう。

#参考
[RFC5280 翻訳　4.  証明書および証明書拡張のプロファイル](https://www.ipa.go.jp/security/rfc/RFC5280-04JA.html)