はじめに
前回、OpenSSL ECDSA署名検証の仕組みおさらいにて中間CAで署名したメッセージの検証を行った。
証明書チェーンの完全な検証のために、中間CAとルートCAの間の検証を仕組みを理解する目的で行う。
環境
前回作成した環境にて検証を実施
OpenSSL ECDSAでの自己認証局作成
検証内容
中間CA証明書はルートCAで署名したものなので、前回同様
1、ルートCAの公開鍵
2、中間CA証明書の署名
3、署名対象のメッセージ
上記をそろえれば検証できるはず。
1、ルート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
2、中間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
3、署名対象のメッセージ
証明書の場合は何を指すのだろうか。署名対象が定義づけされているのだろうか。
そもそも・・・
証明書の構造は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実体を与えればよろしくやってくれるよう。