Chromium Code Reviews| Index: net/data/ssl/scripts/generate-multi-root-test-chains.sh |
| diff --git a/net/data/ssl/scripts/generate-multi-root-test-chains.sh b/net/data/ssl/scripts/generate-multi-root-test-chains.sh |
| index 6f88325a3ccf38debf443645a09a622b1d7b16cb..1f9f5f92e3135572f8d33c64feb076b2f857d6dd 100755 |
| --- a/net/data/ssl/scripts/generate-multi-root-test-chains.sh |
| +++ b/net/data/ssl/scripts/generate-multi-root-test-chains.sh |
| @@ -4,158 +4,308 @@ |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| -# This script generates two chains of test certificates: |
| +# This script generates several forms of test certificate chains, used to test |
| +# how the platform handles path building and revocations. They are designed |
| +# to mirror how the WebPKI has evolved. |
| # |
| -# 1. A (end-entity) -> B -> C -> D (self-signed root) |
| -# 2. A (end-entity) -> B -> C2 -> E (self-signed root) |
| +# Letters annotate which subject & key is used, while numbers indicate |
| +# the issuer (e.g. C1 and C2 share the same subject & key, but have different |
| +# issuers). They are ordered from leaf to root. |
| # |
| -# C and C2 have the same subject and keypair. |
| +# Tests for basic path building (e.g. when E is trusted, but D is not) |
| +# 1. A -> B -> C -> D |
| +# 2. A -> B -> C2 -> E |
| # |
| -# We use these cert chains in CertVerifyProcChromeOSTest |
| -# to ensure that multiple verification paths are properly handled. |
| +# Tests for basic intermediate revocation (e.g. when the client trusts both |
| +# E and F). |
| +# Note: To fully test for the cases, it's necessary to massage the structures |
| +# so that the various library sorting routines 'prefer' the revoked path first, |
| +# such as by modifying the issuance dates. |
| +# The goal is that for both cases, the client will find/use either paths #1 or |
| +# #2, despite being presented (by the server) with paths #3 or #4. |
| +# |
| +# 3. A -> B -> C3 [revoked by F by issuer & serial] -> F |
| +# 4. A -> B2 -> G [revoked by F by SPKI] -> F |
| +# |
| +# Tests for cross-certified hell - such as when roots mutually certify, |
| +# creating a potential 'loop'. |
| +# In this case, a version of J2-signed-by-K exists, as does a version of |
| +# K2-signed-by-J (thus, a loop). In addition, self-signed versions of both J |
| +# and K exist, which reflect what happens when OS stores phase out one root |
| +# while phasing in a new root. |
| +# |
| +# 5. H -> I -> J |
| +# 6. H -> I -> J2 -> K [revoked by SPKI] |
| +# 7. H -> I -> J2 -> K2 [revoked by SPKI] -> J |
| +# 8. H -> I -> J2 -> K2 [revoked by SPKI] -> J2 -> K [revoked by SPKI] |
|
Ryan Sleevi
2016/01/15 01:12:55
The complexities of these chains are for the inevi
davidben
2016/01/21 02:37:39
[Incidentally, this became so much easier to under
|
| -try () { |
| - echo "$@" |
| - "$@" || exit 1 |
| -} |
| +# Exit script as soon a something fails. |
| +set -e |
| -try rm -rf out |
| -try mkdir out |
| +rm -rf out |
| +mkdir out |
| -echo Create the serial number files. |
| +# Note: Serial files are created based on subject+key pair, thus cross-signed |
| +# certificates (C2, C3, J2, K2) do *not* have unique serial files generated for |
| +# them. |
| +echo Create the serial and index number files. |
| serial=1000 |
| -for i in B C C2 D E |
| +for i in B C D E F G I J K |
| do |
| - try /bin/sh -c "echo $serial > out/$i-serial" |
| - serial=$(expr $serial + 1) |
| + /bin/sh -c "echo ${serial} > out/${i}-serial" |
| + touch "out/${i}-index.txt" |
| done |
| echo Generate the keys. |
| -try openssl genrsa -out out/A.key 2048 |
| -try openssl genrsa -out out/B.key 2048 |
| -try openssl genrsa -out out/C.key 2048 |
| -try openssl genrsa -out out/D.key 2048 |
| -try openssl genrsa -out out/E.key 2048 |
| - |
| -echo Generate the D CSR. |
| -CA_COMMON_NAME="D Root CA" \ |
| - CERTIFICATE=D \ |
| - try openssl req \ |
| +for i in A B C D E F G H I J K |
| +do |
| + openssl genrsa -out "out/${i}.key" 2048 |
| +done |
| + |
| +echo "Generating the self-signed roots" |
| +for i in D E F J K |
| +do |
| + echo "Generating CSR ${i}" |
| + CA_COMMON_NAME="${i} Root CA" \ |
| + CERTIFICATE="${i}" \ |
| + openssl req \ |
| + -config redundant-ca.cnf \ |
| -new \ |
| - -key out/D.key \ |
| - -out out/D.csr \ |
| - -config redundant-ca.cnf |
| - |
| -echo D signs itself. |
| -CA_COMMON_NAME="D Root CA" \ |
| - try openssl x509 \ |
| - -req -days 3650 \ |
| - -in out/D.csr \ |
| + -key "out/${i}.key" \ |
| + -out "out/${i}.csr" |
| + |
| + echo "Generating self-signed ${i}" |
| + CA_COMMON_NAME="${i} Root CA" \ |
| + CERTIFICATE="${i}" \ |
| + openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160102000000Z \ |
| + -enddate 260102000000Z \ |
| -extensions ca_cert \ |
| -extfile redundant-ca.cnf \ |
| - -signkey out/D.key \ |
| - -out out/D.pem \ |
| - -text |
| - |
| -echo Generate the E CSR. |
| -CA_COMMON_NAME="E Root CA" \ |
| - CERTIFICATE=E \ |
| - try openssl req \ |
| + -selfsign \ |
| + -in "out/${i}.csr" \ |
| + -out "out/${i}.pem" |
| +done |
| + |
| +echo "Generating intermediate CSRs" |
| +for i in B C G I |
| +do |
| + echo "Generating CSR ${i}" |
| + CA_COMMON_NAME="${i} CA" \ |
| + CERTIFICATE="${i}" \ |
| + openssl req \ |
| + -config redundant-ca.cnf \ |
| -new \ |
| - -key out/E.key \ |
| - -out out/E.csr \ |
| - -config redundant-ca.cnf |
| - |
| -echo E signs itself. |
| -CA_COMMON_NAME="E Root CA" \ |
| - try openssl x509 \ |
| - -req -days 3650 \ |
| - -in out/E.csr \ |
| - -extensions ca_cert \ |
| - -extfile redundant-ca.cnf \ |
| - -signkey out/E.key \ |
| - -out out/E.pem \ |
| - -text |
| + -key "out/${i}.key" \ |
| + -out "out/${i}.csr" |
| +done |
| + |
| +echo D signs C |
| +CA_COMMON_NAME="D CA" \ |
| +CERTIFICATE=D \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160103000000Z \ |
| + -enddate 260102000000Z \ |
| + -extensions ca_cert \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/C.csr \ |
| + -out out/C.pem |
| -echo Generate the C2 intermediary CSR. |
| +echo C signs B |
| CA_COMMON_NAME="C CA" \ |
| - CERTIFICATE=C2 \ |
| - try openssl req \ |
| - -new \ |
| - -key out/C.key \ |
| - -out out/C2.csr \ |
| - -config redundant-ca.cnf |
| +CERTIFICATE=C \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160104000000Z \ |
| + -enddate 260102000000Z \ |
| + -extensions ca_cert \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/B.csr \ |
| + -out out/B.pem |
| + |
| +echo E signs C2 |
| +CA_COMMON_NAME="E CA" \ |
| +CERTIFICATE=E \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160105000000Z \ |
| + -enddate 260102000000Z \ |
| + -extensions ca_cert \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/C.csr \ |
| + -out out/C2.pem |
| + |
| +# Not necessary for C2 to sign B |
| +# TODO(rsleevi): AKI/SPKI issues? |
| + |
| +echo F signs C3 |
| +CA_COMMON_NAME="F CA" \ |
| +CERTIFICATE=F \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160106000000Z \ |
| + -enddate 260102000000Z \ |
| + -extensions ca_cert \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/C.csr \ |
| + -out out/C3.pem |
| + |
| +# Not necessary for C3 to sign B |
| +# TODO(rsleevi): AKI/SPKI issues? |
|
davidben
2016/01/21 02:37:39
Wouldn't it be equally unnecessary for C2 to sign
Ryan Sleevi
2016/01/21 02:54:05
See line 144 for the same comment
The AKI/SPKI is
|
| + |
| +echo F signs G |
| +CA_COMMON_NAME="F CA" \ |
| +CERTIFICATE=F \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160102000000Z \ |
| + -enddate 260102000000Z \ |
| + -extensions ca_cert \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/G.csr \ |
| + -out out/G.pem |
| -echo Generate the B and C intermediaries\' CSRs. |
| -for i in B C |
| +# Note: The startdate for B2 MUST be greater than B's start date. |
| +echo G signs B2 |
| +CA_COMMON_NAME="G CA" \ |
| +CERTIFICATE=G \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160105000000Z \ |
| + -enddate 260102000000Z \ |
| + -extensions ca_cert \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/B.csr \ |
| + -out out/B2.pem |
| + |
| +# Note: The startdate for K2 MUST be greater than K's start date. |
| +echo J signs K2 |
| +CA_COMMON_NAME="J CA" \ |
| +CERTIFICATE=J \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160104000000Z \ |
| + -enddate 260102000000Z \ |
| + -extensions ca_cert_with_aki \ |
|
davidben
2016/01/21 02:37:39
Why does this and the one below have AKI, but not
Ryan Sleevi
2016/01/21 02:54:05
Blergh, this was debugging for CAPI and how it han
|
| + -extfile redundant-ca.cnf \ |
| + -in out/K.csr \ |
| + -out out/K2.pem |
| + |
| +# Note: The startdate for J2 MUST be greater than J's start date, |
| +echo K signs J2 |
| +CA_COMMON_NAME="K CA" \ |
| +CERTIFICATE=K \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160104000000Z \ |
| + -enddate 260102000000Z \ |
| + -extensions ca_cert_with_aki \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/J.csr \ |
| + -out out/J2.pem |
| + |
| +echo J signs I |
| +CA_COMMON_NAME="J CA" \ |
| +CERTIFICATE=J \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -startdate 160103000000Z \ |
| + -enddate 260102000000Z \ |
| + -extensions ca_cert \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/I.csr \ |
| + -out out/I.pem |
| + |
| +# Not necessary for J2 to sign I |
| +# TODO(rsleevi): AKI/SPKI issues? |
|
davidben
2016/01/21 02:37:39
(Ditto about what this comment is for)
|
| + |
| +echo "Generating leaf CSRs" |
| +for i in A H |
| do |
| - CA_COMMON_NAME="$i CA" \ |
| - CERTIFICATE="$i" \ |
| - try openssl req \ |
| - -new \ |
| - -key "out/$i.key" \ |
| - -out "out/$i.csr" \ |
| - -config redundant-ca.cnf |
| + echo "Generating leaf ${i}" |
| + openssl req \ |
| + -config ee.cnf \ |
| + -new \ |
| + -key "out/${i}.key" \ |
| + -out "out/${i}.csr" |
| done |
| -echo D signs the C intermediate. |
| -# Make sure the signer's DB file exists. |
| -touch out/D-index.txt |
| -CA_COMMON_NAME="D Root CA" \ |
| - CERTIFICATE=D \ |
| - try openssl ca \ |
| - -batch \ |
| - -extensions ca_cert \ |
| - -in out/C.csr \ |
| - -out out/C.pem \ |
| - -config redundant-ca.cnf |
| - |
| -echo E signs the C2 intermediate. |
| -# Make sure the signer's DB file exists. |
| -touch out/E-index.txt |
| -CA_COMMON_NAME="E Root CA" \ |
| - CERTIFICATE=E \ |
| - try openssl ca \ |
| - -batch \ |
| - -extensions ca_cert \ |
| - -in out/C2.csr \ |
| - -out out/C2.pem \ |
| - -config redundant-ca.cnf |
| - |
| -echo C signs the B intermediate. |
| -touch out/C-index.txt |
| -CA_COMMON_NAME="C CA" \ |
| - CERTIFICATE=C \ |
| - try openssl ca \ |
| - -batch \ |
| - -extensions ca_cert \ |
| - -in out/B.csr \ |
| - -out out/B.pem \ |
| - -config redundant-ca.cnf |
| - |
| -echo Generate the A end-entity CSR. |
| -try openssl req \ |
| - -new \ |
| - -key out/A.key \ |
| - -out out/A.csr \ |
| - -config ee.cnf |
| - |
| -echo B signs A. |
| -touch out/B-index.txt |
| +echo "Signing leaves" |
| CA_COMMON_NAME="B CA" \ |
| - CERTIFICATE=B \ |
| - try openssl ca \ |
| - -batch \ |
| - -extensions user_cert \ |
| - -in out/A.csr \ |
| - -out out/A.pem \ |
| - -config redundant-ca.cnf |
| +CERTIFICATE=B \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -days 3650 \ |
| + -extensions user_cert \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/A.csr \ |
| + -out out/A.pem |
| -echo Create multi-root-chain1.pem |
| -try /bin/sh -c "cat out/A.key out/A.pem out/B.pem out/C.pem out/D.pem \ |
| - > ../certificates/multi-root-chain1.pem" |
| +CA_COMMON_NAME="I CA" \ |
| +CERTIFICATE=I \ |
| +openssl ca \ |
| + -config redundant-ca.cnf \ |
| + -batch \ |
| + -days 3650 \ |
| + -extensions user_cert \ |
| + -extfile redundant-ca.cnf \ |
| + -in out/H.csr \ |
| + -out out/H.pem |
| -echo Create multi-root-chain2.pem |
| -try /bin/sh -c "cat out/A.key out/A.pem out/B.pem out/C2.pem out/E.pem \ |
| +echo Creating chain files |
| +/bin/sh -c "cat out/A.key out/A.pem out/B.pem out/C.pem out/D.pem \ |
| + > ../certificates/multi-root-chain1.pem" |
| +/bin/sh -c "cat out/A.key out/A.pem out/B.pem out/C2.pem out/E.pem \ |
| > ../certificates/multi-root-chain2.pem" |
| +/bin/sh -c "cat out/A.key out/A.pem out/B.pem out/C3.pem out/F.pem \ |
| + > ../certificates/multi-root-chain3.pem" |
| +/bin/sh -c "cat out/A.key out/A.pem out/B2.pem out/G.pem out/F.pem \ |
| + > ../certificates/multi-root-chain4.pem" |
| +/bin/sh -c "cat out/H.key out/H.pem out/I.pem out/J.pem \ |
| + > ../certificates/multi-root-chain5.pem" |
| +/bin/sh -c "cat out/H.key out/H.pem out/I.pem out/J2.pem out/K.pem \ |
| + > ../certificates/multi-root-chain6.pem" |
| +/bin/sh -c "cat out/H.key out/H.pem out/I.pem out/J2.pem out/K2.pem out/J.pem \ |
| + > ../certificates/multi-root-chain7.pem" |
| +/bin/sh -c "cat out/H.key out/H.pem out/I.pem out/J2.pem out/K2.pem out/J2.pem \ |
| + out/K.pem > ../certificates/multi-root-chain8.pem" |
| +echo Generating CRLSets |
| +# Block C3 (serial number 0x1001), as issued by F, by way of serial number. |
| +python crlsetutil.py -o ../certificates/multi-root-crlset-C3.raw \ |
| +<<CRLSETBYSERIAL |
| +{ |
| + "BlockedByHash": { |
| + "out/F.pem": [4097] |
| + } |
| +} |
| +CRLSETBYSERIAL |
| + |
| +# Block G (serial number 0x1002), as issued by F, by way of SPKI |
| +python crlsetutil.py -o ../certificates/multi-root-crlset-G.raw \ |
| +<<CRLSETBYSPKI |
| +{ |
| + "BlockedBySPKI": [ "out/G.pem" ] |
| +} |
| +CRLSETBYSPKI |
| + |
| +# Block K (serial number 0x1000 as self-issued, 0x1001 as issued by J) |
| +python crlsetutil.py -o ../certificates/multi-root-crlset-K.raw \ |
| +<<CRLSETLOOPBYSPKI |
| +{ |
| + "BlockedBySPKI": [ "out/K.pem" ] |
| +} |
| +CRLSETLOOPBYSPKI |