diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/regress/lib/libcrypto/certs/Makefile | 21 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/certs/README | 123 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/certs/make-certs.sh | 381 | ||||
| -rw-r--r-- | src/regress/lib/libcrypto/certs/verify_test.go | 111 |
4 files changed, 636 insertions, 0 deletions
diff --git a/src/regress/lib/libcrypto/certs/Makefile b/src/regress/lib/libcrypto/certs/Makefile new file mode 100644 index 0000000000..621c60907f --- /dev/null +++ b/src/regress/lib/libcrypto/certs/Makefile | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | # $OpenBSD: Makefile,v 1.1 2020/07/14 18:27:28 jsing Exp $ | ||
| 2 | |||
| 3 | .if ! (make(clean) || make(cleandir) || make(obj)) | ||
| 4 | GO_VERSION != sh -c "(go version) 2>/dev/null || true" | ||
| 5 | .endif | ||
| 6 | |||
| 7 | .if empty(GO_VERSION) | ||
| 8 | regress: | ||
| 9 | @echo package go is required for this regress | ||
| 10 | @echo SKIPPED | ||
| 11 | .endif | ||
| 12 | |||
| 13 | REGRESS_TARGETS=regress-go-verify | ||
| 14 | |||
| 15 | certs: | ||
| 16 | cd ${.CURDIR} && sh ./make-certs.sh | ||
| 17 | |||
| 18 | regress-go-verify: | ||
| 19 | cd ${.CURDIR} && go test -test.v . | ||
| 20 | |||
| 21 | .include <bsd.regress.mk> | ||
diff --git a/src/regress/lib/libcrypto/certs/README b/src/regress/lib/libcrypto/certs/README new file mode 100644 index 0000000000..0d6fa7d48a --- /dev/null +++ b/src/regress/lib/libcrypto/certs/README | |||
| @@ -0,0 +1,123 @@ | |||
| 1 | This directory contains tools for building certificate chains to | ||
| 2 | test verification. Each subdirectory contains a set of certificates | ||
| 3 | that test a particular scenario. The root certificate(s) are contained | ||
| 4 | in a roots.pem file, while the leaf certificate and any untrusted | ||
| 5 | intermediate certificates are contained in a bundle.pem file. | ||
| 6 | |||
| 7 | 1a. A leaf certificate signed by the root certificate with no | ||
| 8 | intermediates (should verify). | ||
| 9 | |||
| 10 | 2a. A leaf certificate signed by an intermediate, which is signed | ||
| 11 | by a root certificate (should verify). | ||
| 12 | |||
| 13 | 2b. Same as (2a), however the intermediate is missing which should | ||
| 14 | prevent verification. | ||
| 15 | |||
| 16 | 3a. A leaf certificate signed by three intermediates, the last of | ||
| 17 | which is signed by a root certificate (should verify). | ||
| 18 | |||
| 19 | 3b. Same as (3a) however the first intermediate is missing which should | ||
| 20 | prevent verification. | ||
| 21 | |||
| 22 | 3c. Same as (3a) however the second intermediate is missing which should | ||
| 23 | prevent verification. | ||
| 24 | |||
| 25 | 3d. Same as (3a) however the third intermediate is missing which should | ||
| 26 | prevent verification. | ||
| 27 | |||
| 28 | 3e. Same as (3a) however the order of the intermediates is reversed | ||
| 29 | (should verify). | ||
| 30 | |||
| 31 | 4a. A leaf certificate signed by an intermediate, that is cross | ||
| 32 | signed by two root certificates (should verify with two chains). | ||
| 33 | |||
| 34 | 4b. Same as (4a) but with one root missing (should verify with one chain). | ||
| 35 | |||
| 36 | 4c. Same as (4b) but with the other root missing (should verify with one | ||
| 37 | chain). | ||
| 38 | |||
| 39 | 4d. Same as (4a) but with one intermediate missing (should verify with one | ||
| 40 | chain). | ||
| 41 | |||
| 42 | 4e. Same as (4d) but with the other intermediate missing (should verify | ||
| 43 | with one chain). | ||
| 44 | |||
| 45 | 4f. Same as (4a) but with the intermediates reversed (should verify with | ||
| 46 | two chains). | ||
| 47 | |||
| 48 | 4g. Same as (4b) but with the intermediates reversed (should verify with | ||
| 49 | one chain). | ||
| 50 | |||
| 51 | 4h. Same as (4c) but with the intermediates reversed (should verify with | ||
| 52 | one chain). | ||
| 53 | |||
| 54 | 5a. A leaf certificate signed by an intermediate, that is cross | ||
| 55 | signed by one root certificate and an intermediate, which in turn | ||
| 56 | is signed by a second root (should verify with two chains). | ||
| 57 | |||
| 58 | 5b. Same as (5a) but missing the first root certificate (should verify | ||
| 59 | with one chain). | ||
| 60 | |||
| 61 | 5c. Same as (5a) but missing the second root certificate (should verify | ||
| 62 | with one chain). | ||
| 63 | |||
| 64 | 5d. Same as (5a) but missing the first intermediate (should verify with | ||
| 65 | one chain). | ||
| 66 | |||
| 67 | 5e. Same as (5a) but missing the second intermediate (should verify | ||
| 68 | with one chain). | ||
| 69 | |||
| 70 | 5f. Same as (5a) but missing the cross-signed intermediate (should verify | ||
| 71 | with one chain). | ||
| 72 | |||
| 73 | 5g. Same as (5a) but order of intermediates is reversed (should verify | ||
| 74 | with two chains). | ||
| 75 | |||
| 76 | 5h. Same as (5g) but missing the first root certificate (should verify | ||
| 77 | with two chains). | ||
| 78 | |||
| 79 | 5i. Same as (5g) but missing the second root certificate (should verify | ||
| 80 | with two chains). | ||
| 81 | |||
| 82 | 6a. A leaf certificate signed by an intermediate, that is cross | ||
| 83 | signed by an expired root certificate and an intermediate, which | ||
| 84 | in turn is signed by a second root (should verify with one chain). | ||
| 85 | |||
| 86 | 6b. Same as (6a) but the order of the intermediates is reversed (should | ||
| 87 | verify with one chain). | ||
| 88 | |||
| 89 | 7a. A leaf certificate signed by an intermediate, that is cross | ||
| 90 | signed by a root certificate and an intermediate, which in turn | ||
| 91 | is signed by a second root that has expired (should verify with one | ||
| 92 | chain). | ||
| 93 | |||
| 94 | 7b. Same as (7a) but the order of the intermediates is reversed (should | ||
| 95 | verify with one chain). | ||
| 96 | |||
| 97 | 8a. An expired leaf certificate signed by an intermediate that is then | ||
| 98 | signed by a root certificate (should fail to verify). | ||
| 99 | |||
| 100 | 9a. A leaf certificate signed by an expired intermediate, which is | ||
| 101 | signed by a root certificate (should fail to verify). | ||
| 102 | |||
| 103 | 10a. A leaf certificate signed by an intermediate, that is cross | ||
| 104 | signed by two root certificates, with one of the cross signings | ||
| 105 | having expired (should verify with one chain). | ||
| 106 | |||
| 107 | 10b. Same as (10a) but order of intermediates is reversed (should verify | ||
| 108 | with one chain. | ||
| 109 | |||
| 110 | 11a. A leaf certificate signed by an intermediate, that is cross | ||
| 111 | signed by one root certificate and an expired intermediate, which | ||
| 112 | in turn is signed by a second root (should verify with one chain). | ||
| 113 | |||
| 114 | 11b. Same as (11a) but order of intermediates is reversed (should verify | ||
| 115 | with one chain. | ||
| 116 | |||
| 117 | 12a. A leaf certificate signed by an intermediate, that is signed by a | ||
| 118 | root certificate and cross signed as an expired intermediate, by a | ||
| 119 | second root (should verify with one chain). | ||
| 120 | |||
| 121 | 13a. A leaf certificate signed by an intermediate, that is signed by an | ||
| 122 | expired root certificate and cross signed as an intermediate, by a | ||
| 123 | second root (should verify with one chain). | ||
diff --git a/src/regress/lib/libcrypto/certs/make-certs.sh b/src/regress/lib/libcrypto/certs/make-certs.sh new file mode 100644 index 0000000000..b34a547ba2 --- /dev/null +++ b/src/regress/lib/libcrypto/certs/make-certs.sh | |||
| @@ -0,0 +1,381 @@ | |||
| 1 | #!/bin/ksh | ||
| 2 | |||
| 3 | # | ||
| 4 | # Copyright (c) 2020 Joel Sing <jsing@openbsd.org> | ||
| 5 | # | ||
| 6 | # Permission to use, copy, modify, and distribute this software for any | ||
| 7 | # purpose with or without fee is hereby granted, provided that the above | ||
| 8 | # copyright notice and this permission notice appear in all copies. | ||
| 9 | # | ||
| 10 | # THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 11 | # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 12 | # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 13 | # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 14 | # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 15 | # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 16 | # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
| 17 | # | ||
| 18 | |||
| 19 | set -e | ||
| 20 | set -u | ||
| 21 | set -x | ||
| 22 | |||
| 23 | readonly SUBJECT="/CN=LibreSSL Test" | ||
| 24 | |||
| 25 | readonly TMPDIR=$(mktemp -d) | ||
| 26 | |||
| 27 | cleanup() { | ||
| 28 | rm -rf "${TMPDIR}" | ||
| 29 | } | ||
| 30 | |||
| 31 | trap cleanup EXIT INT | ||
| 32 | |||
| 33 | reset() { | ||
| 34 | echo '100001' > ${TMPDIR}/certserial | ||
| 35 | cat /dev/null > ${TMPDIR}/certindex | ||
| 36 | } | ||
| 37 | |||
| 38 | setup() { | ||
| 39 | reset | ||
| 40 | |||
| 41 | cat > ${TMPDIR}/openssl.cnf <<EOF | ||
| 42 | [ca] | ||
| 43 | default_ca = test_ca | ||
| 44 | |||
| 45 | [test_ca] | ||
| 46 | new_certs_dir = ${TMPDIR}/ | ||
| 47 | database = ${TMPDIR}/certindex | ||
| 48 | default_days = 365 | ||
| 49 | default_md = sha256 | ||
| 50 | policy = test_policy | ||
| 51 | serial = ${TMPDIR}/certserial | ||
| 52 | |||
| 53 | [test_policy] | ||
| 54 | countryName = optional | ||
| 55 | stateOrProvinceName = optional | ||
| 56 | localityName = optional | ||
| 57 | organizationName = optional | ||
| 58 | organizationalUnitName = optional | ||
| 59 | commonName = supplied | ||
| 60 | emailAddress = optional | ||
| 61 | |||
| 62 | [v3_ca_root] | ||
| 63 | subjectKeyIdentifier = hash | ||
| 64 | authorityKeyIdentifier = keyid:always,issuer | ||
| 65 | basicConstraints = critical, CA:true | ||
| 66 | keyUsage = critical, cRLSign, keyCertSign | ||
| 67 | |||
| 68 | [v3_ca_int] | ||
| 69 | subjectKeyIdentifier = hash | ||
| 70 | authorityKeyIdentifier = keyid:always,issuer | ||
| 71 | basicConstraints = critical, CA:true | ||
| 72 | keyUsage = critical, cRLSign, keyCertSign | ||
| 73 | |||
| 74 | [v3_other] | ||
| 75 | subjectKeyIdentifier = hash | ||
| 76 | authorityKeyIdentifier = keyid:always,issuer | ||
| 77 | basicConstraints = critical, CA:false | ||
| 78 | keyUsage = critical, digitalSignature | ||
| 79 | |||
| 80 | [req] | ||
| 81 | distinguished_name = req_distinguished_name | ||
| 82 | |||
| 83 | [ req_distinguished_name ] | ||
| 84 | EOF | ||
| 85 | } | ||
| 86 | |||
| 87 | create_root() { | ||
| 88 | local name=$1 file=$2 | ||
| 89 | |||
| 90 | openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 -x509 \ | ||
| 91 | -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ | ||
| 92 | -config ${TMPDIR}/openssl.cnf -extensions v3_ca_root \ | ||
| 93 | -out "${TMPDIR}/${file}.crt" | ||
| 94 | } | ||
| 95 | |||
| 96 | create_expired_root() { | ||
| 97 | local name=$1 file=$2 | ||
| 98 | |||
| 99 | openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \ | ||
| 100 | -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ | ||
| 101 | -config ${TMPDIR}/openssl.cnf -extensions v3_ca_root \ | ||
| 102 | -out "${TMPDIR}/${file}.csr" | ||
| 103 | openssl ca -batch -notext -selfsign \ | ||
| 104 | -keyfile "${TMPDIR}/${file}.key" \ | ||
| 105 | -startdate 20100101000000Z -enddate 20200101000000Z \ | ||
| 106 | -config ${TMPDIR}/openssl.cnf -extensions v3_ca_root \ | ||
| 107 | -in "${TMPDIR}/${file}.csr" -out "${TMPDIR}/${file}.crt" | ||
| 108 | } | ||
| 109 | |||
| 110 | create_intermediate() { | ||
| 111 | local name=$1 file=$2 issuer_file=$3 | ||
| 112 | |||
| 113 | openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \ | ||
| 114 | -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ | ||
| 115 | -out "${TMPDIR}/${file}.csr" | ||
| 116 | openssl x509 -req -days 3650 -CA "${TMPDIR}/${issuer_file}.crt" \ | ||
| 117 | -CAkey "${TMPDIR}/${issuer_file}.key" -CAcreateserial \ | ||
| 118 | -extfile ${TMPDIR}/openssl.cnf -extensions v3_ca_int \ | ||
| 119 | -in "${TMPDIR}/${file}.csr" -out "${TMPDIR}/${file}.crt" | ||
| 120 | } | ||
| 121 | |||
| 122 | create_expired_intermediate() { | ||
| 123 | local name=$1 file=$2 issuer_file=$3 | ||
| 124 | |||
| 125 | openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \ | ||
| 126 | -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ | ||
| 127 | -out "${TMPDIR}/${file}.csr" | ||
| 128 | openssl ca -batch -notext -cert "${TMPDIR}/${issuer_file}.crt" \ | ||
| 129 | -keyfile "${TMPDIR}/${issuer_file}.key" \ | ||
| 130 | -startdate 20100101000000Z -enddate 20200101000000Z \ | ||
| 131 | -config ${TMPDIR}/openssl.cnf -extensions v3_ca_int \ | ||
| 132 | -in "${TMPDIR}/${file}.csr" -out "${TMPDIR}/${file}.crt" | ||
| 133 | } | ||
| 134 | |||
| 135 | create_leaf() { | ||
| 136 | local name=$1 file=$2 issuer_file=$3 | ||
| 137 | |||
| 138 | openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \ | ||
| 139 | -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ | ||
| 140 | -out "${TMPDIR}/${file}.csr" | ||
| 141 | openssl x509 -req -days 3650 -CA "${TMPDIR}/${issuer_file}.crt" \ | ||
| 142 | -CAkey "${TMPDIR}/${issuer_file}.key" -CAcreateserial \ | ||
| 143 | -extfile ${TMPDIR}/openssl.cnf -extensions v3_other \ | ||
| 144 | -in "${TMPDIR}/${file}.csr" -out "${TMPDIR}/${file}.crt" | ||
| 145 | } | ||
| 146 | |||
| 147 | create_expired_leaf() { | ||
| 148 | local name=$1 file=$2 issuer_file=$3 | ||
| 149 | |||
| 150 | openssl req -new -days 3650 -nodes -newkey rsa:2048 -sha256 \ | ||
| 151 | -subj "${SUBJECT} ${name}" -keyout "${TMPDIR}/${file}.key" \ | ||
| 152 | -out "${TMPDIR}/${file}.csr" | ||
| 153 | openssl ca -batch -notext -cert "${TMPDIR}/${issuer_file}.crt" \ | ||
| 154 | -keyfile "${TMPDIR}/${issuer_file}.key" \ | ||
| 155 | -config ${TMPDIR}/openssl.cnf -extensions v3_other \ | ||
| 156 | -startdate 20100101000000Z -enddate 20200101000000Z \ | ||
| 157 | -in "${TMPDIR}/${file}.csr" -out "${TMPDIR}/${file}.crt" | ||
| 158 | } | ||
| 159 | |||
| 160 | create_cross_signed() { | ||
| 161 | local file=$1 csr_file=$2 issuer_file=$3 | ||
| 162 | |||
| 163 | openssl x509 -req -days 3650 -CA "${TMPDIR}/${issuer_file}.crt" \ | ||
| 164 | -CAkey "${TMPDIR}/${issuer_file}.key" -CAcreateserial \ | ||
| 165 | -extfile ${TMPDIR}/openssl.cnf -extensions v3_ca_int \ | ||
| 166 | -in "${TMPDIR}/${csr_file}.csr" -out "${TMPDIR}/${file}.crt" | ||
| 167 | } | ||
| 168 | |||
| 169 | create_expired_cross_signed() { | ||
| 170 | local file=$1 csr_file=$2 issuer_file=$3 | ||
| 171 | |||
| 172 | openssl ca -batch -notext -cert "${TMPDIR}/${issuer_file}.crt" \ | ||
| 173 | -keyfile "${TMPDIR}/${issuer_file}.key" \ | ||
| 174 | -startdate 20100101000000Z -enddate 20200101000000Z \ | ||
| 175 | -config ${TMPDIR}/openssl.cnf -extensions v3_ca_int \ | ||
| 176 | -in "${TMPDIR}/${csr_file}.csr" -out "${TMPDIR}/${file}.crt" | ||
| 177 | } | ||
| 178 | |||
| 179 | create_bundle() { | ||
| 180 | local bundle_file=$1 | ||
| 181 | shift | ||
| 182 | |||
| 183 | mkdir -p $(dirname ${bundle_file}) | ||
| 184 | cat /dev/null > ${bundle_file} | ||
| 185 | |||
| 186 | for _cert_file in $@; do | ||
| 187 | openssl x509 -nameopt oneline -subject -issuer -noout \ | ||
| 188 | -in "${TMPDIR}/${_cert_file}.crt" >> ${bundle_file} | ||
| 189 | done | ||
| 190 | for _cert_file in $@; do | ||
| 191 | cat "${TMPDIR}/${_cert_file}.crt" >> ${bundle_file} | ||
| 192 | done | ||
| 193 | } | ||
| 194 | |||
| 195 | create_root_bundle() { | ||
| 196 | local bundle_file=$1 | ||
| 197 | shift | ||
| 198 | |||
| 199 | mkdir -p $(dirname ${bundle_file}) | ||
| 200 | cat /dev/null > ${bundle_file} | ||
| 201 | |||
| 202 | for _cert_file in $@; do | ||
| 203 | openssl x509 -nameopt oneline -subject -issuer \ | ||
| 204 | -in "${TMPDIR}/${_cert_file}.crt" >> ${bundle_file} | ||
| 205 | done | ||
| 206 | } | ||
| 207 | |||
| 208 | setup | ||
| 209 | |||
| 210 | # Scenario 1a. | ||
| 211 | reset | ||
| 212 | create_root "Root CA 1" "ca-root" | ||
| 213 | create_leaf "Server 1" "server-1" "ca-root" | ||
| 214 | create_root_bundle "./1a/roots.pem" "ca-root" | ||
| 215 | create_bundle "./1a/bundle.pem" "server-1" | ||
| 216 | |||
| 217 | # Scenarios 2a and 2b. | ||
| 218 | reset | ||
| 219 | create_root "Root CA 1" "ca-root" | ||
| 220 | create_intermediate "Intermediate CA 1" "ca-int-1" "ca-root" | ||
| 221 | create_leaf "Server 1" "server-1" "ca-int-1" | ||
| 222 | create_root_bundle "./2a/roots.pem" "ca-root" | ||
| 223 | create_bundle "./2a/bundle.pem" "server-1" "ca-int-1" | ||
| 224 | create_root_bundle "./2b/roots.pem" "ca-root" | ||
| 225 | create_bundle "./2b/bundle.pem" "server-1" | ||
| 226 | |||
| 227 | # Scenarios 3a, 3b, 3c, 3d and 3e. | ||
| 228 | reset | ||
| 229 | create_root "Root CA 1" "ca-root" | ||
| 230 | create_intermediate "Intermediate CA 1" "ca-int-1" "ca-root" | ||
| 231 | create_intermediate "Intermediate CA 2" "ca-int-2" "ca-int-1" | ||
| 232 | create_intermediate "Intermediate CA 3" "ca-int-3" "ca-int-2" | ||
| 233 | create_leaf "Server 1" "server-1" "ca-int-3" | ||
| 234 | create_root_bundle "./3a/roots.pem" "ca-root" | ||
| 235 | create_bundle "./3a/bundle.pem" "server-1" "ca-int-3" "ca-int-2" "ca-int-1" | ||
| 236 | create_root_bundle "./3b/roots.pem" "ca-root" | ||
| 237 | create_bundle "./3b/bundle.pem" "server-1" "ca-int-3" "ca-int-2" | ||
| 238 | create_root_bundle "./3c/roots.pem" "ca-root" | ||
| 239 | create_bundle "./3c/bundle.pem" "server-1" "ca-int-3" "ca-int-1" | ||
| 240 | create_root_bundle "./3d/roots.pem" "ca-root" | ||
| 241 | create_bundle "./3d/bundle.pem" "server-1" "ca-int-2" "ca-int-1" | ||
| 242 | create_root_bundle "./3e/roots.pem" "ca-root" | ||
| 243 | create_bundle "./3e/bundle.pem" "server-1" "ca-int-1" "ca-int-2" "ca-int-3" | ||
| 244 | |||
| 245 | # Scenarios 4a, 4b, 4c, 4d, 4e, 4f, 4g and 4h. | ||
| 246 | reset | ||
| 247 | create_root "Root CA 1" "ca-root-1" | ||
| 248 | create_root "Root CA 2" "ca-root-2" | ||
| 249 | create_intermediate "Intermediate CA 1" "ca-int-1" "ca-root-1" | ||
| 250 | create_cross_signed "ca-int-1-xs" "ca-int-1" "ca-root-2" | ||
| 251 | create_leaf "Server 1" "server-1" "ca-int-1" | ||
| 252 | create_root_bundle "./4a/roots.pem" "ca-root-1" "ca-root-2" | ||
| 253 | create_bundle "./4a/bundle.pem" "server-1" "ca-int-1" "ca-int-1-xs" | ||
| 254 | create_root_bundle "./4b/roots.pem" "ca-root-1" | ||
| 255 | create_bundle "./4b/bundle.pem" "server-1" "ca-int-1" "ca-int-1-xs" | ||
| 256 | create_root_bundle "./4c/roots.pem" "ca-root-2" | ||
| 257 | create_bundle "./4c/bundle.pem" "server-1" "ca-int-1" "ca-int-1-xs" | ||
| 258 | create_root_bundle "./4d/roots.pem" "ca-root-1" "ca-root-2" | ||
| 259 | create_bundle "./4d/bundle.pem" "server-1" "ca-int-1" | ||
| 260 | create_root_bundle "./4e/roots.pem" "ca-root-1" "ca-root-2" | ||
| 261 | create_bundle "./4e/bundle.pem" "server-1" "ca-int-1-xs" | ||
| 262 | create_root_bundle "./4f/roots.pem" "ca-root-1" "ca-root-2" | ||
| 263 | create_bundle "./4f/bundle.pem" "server-1" "ca-int-1-xs" "ca-int-1" | ||
| 264 | create_root_bundle "./4g/roots.pem" "ca-root-1" | ||
| 265 | create_bundle "./4g/bundle.pem" "server-1" "ca-int-1-xs" "ca-int-1" | ||
| 266 | create_root_bundle "./4h/roots.pem" "ca-root-2" | ||
| 267 | create_bundle "./4h/bundle.pem" "server-1" "ca-int-1-xs" "ca-int-1" | ||
| 268 | |||
| 269 | # Scenario 5a, 5b, 5c, 5d, 5e, 5f, 5g, 5h and 5i. | ||
| 270 | reset | ||
| 271 | create_root "Root CA 1" "ca-root-1" | ||
| 272 | create_intermediate "Intermediate CA 1" "ca-int-1" "ca-root-1" | ||
| 273 | create_intermediate "Intermediate CA 2" "ca-int-2" "ca-int-1" | ||
| 274 | create_root "Root CA 2" "ca-root-2" | ||
| 275 | create_cross_signed "ca-int-2-xs" "ca-int-2" "ca-root-2" | ||
| 276 | create_leaf "Server 1" "server-1" "ca-int-2" | ||
| 277 | create_root_bundle "./5a/roots.pem" "ca-root-1" "ca-root-2" | ||
| 278 | create_bundle "./5a/bundle.pem" "server-1" "ca-int-2" "ca-int-2-xs" "ca-int-1" | ||
| 279 | create_root_bundle "./5b/roots.pem" "ca-root-2" | ||
| 280 | create_bundle "./5b/bundle.pem" "server-1" "ca-int-2" "ca-int-2-xs" "ca-int-1" | ||
| 281 | create_root_bundle "./5c/roots.pem" "ca-root-1" | ||
| 282 | create_bundle "./5c/bundle.pem" "server-1" "ca-int-2" "ca-int-2-xs" "ca-int-1" | ||
| 283 | create_root_bundle "./5d/roots.pem" "ca-root-1" "ca-root-2" | ||
| 284 | create_bundle "./5d/bundle.pem" "server-1" "ca-int-2-xs" "ca-int-1" | ||
| 285 | create_root_bundle "./5e/roots.pem" "ca-root-1" "ca-root-2" | ||
| 286 | create_bundle "./5e/bundle.pem" "server-1" "ca-int-2" "ca-int-2-xs" | ||
| 287 | create_root_bundle "./5f/roots.pem" "ca-root-1" "ca-root-2" | ||
| 288 | create_bundle "./5f/bundle.pem" "server-1" "ca-int-2" "ca-int-1" | ||
| 289 | create_root_bundle "./5g/roots.pem" "ca-root-1" "ca-root-2" | ||
| 290 | create_bundle "./5g/bundle.pem" "server-1" "ca-int-2-xs" "ca-int-2" "ca-int-1" | ||
| 291 | create_root_bundle "./5h/roots.pem" "ca-root-2" | ||
| 292 | create_bundle "./5h/bundle.pem" "server-1" "ca-int-2-xs" "ca-int-2" "ca-int-1" | ||
| 293 | create_root_bundle "./5i/roots.pem" "ca-root-1" | ||
| 294 | create_bundle "./5i/bundle.pem" "server-1" "ca-int-2-xs" "ca-int-2" "ca-int-1" | ||
| 295 | |||
| 296 | # Scenarios 6a and 6b. | ||
| 297 | reset | ||
| 298 | create_root "Root CA 1" "ca-root-1" | ||
| 299 | create_intermediate "Intermediate CA 1" "ca-int-1" "ca-root-1" | ||
| 300 | create_intermediate "Intermediate CA 2" "ca-int-2" "ca-int-1" | ||
| 301 | create_expired_root "Root CA 2" "ca-root-2" | ||
| 302 | create_cross_signed "ca-int-2-xs" "ca-int-2" "ca-root-2" | ||
| 303 | create_leaf "Server 1" "server-1" "ca-int-2" | ||
| 304 | create_root_bundle "./6a/roots.pem" "ca-root-1" "ca-root-2" | ||
| 305 | create_bundle "./6a/bundle.pem" "server-1" "ca-int-2" "ca-int-2-xs" "ca-int-1" | ||
| 306 | create_root_bundle "./6b/roots.pem" "ca-root-1" "ca-root-2" | ||
| 307 | create_bundle "./6b/bundle.pem" "server-1" "ca-int-2-xs" "ca-int-2" "ca-int-1" | ||
| 308 | |||
| 309 | # Scenarios 7a and 7b. | ||
| 310 | reset | ||
| 311 | create_expired_root "Root CA 1" "ca-root-1" | ||
| 312 | create_intermediate "Intermediate CA 1" "ca-int-1" "ca-root-1" | ||
| 313 | create_intermediate "Intermediate CA 2" "ca-int-2" "ca-int-1" | ||
| 314 | create_root "Root CA 2" "ca-root-2" | ||
| 315 | create_cross_signed "ca-int-2-xs" "ca-int-2" "ca-root-2" | ||
| 316 | create_leaf "Server 1" "server-1" "ca-int-2" | ||
| 317 | create_root_bundle "./7a/roots.pem" "ca-root-1" "ca-root-2" | ||
| 318 | create_bundle "./7a/bundle.pem" "server-1" "ca-int-2" "ca-int-2-xs" "ca-int-1" | ||
| 319 | create_root_bundle "./7b/roots.pem" "ca-root-1" "ca-root-2" | ||
| 320 | create_bundle "./7b/bundle.pem" "server-1" "ca-int-2-xs" "ca-int-2" "ca-int-1" | ||
| 321 | |||
| 322 | # Scenario 8a. | ||
| 323 | reset | ||
| 324 | create_root "Root CA 1" "ca-root" | ||
| 325 | create_intermediate "Intermediate CA 1" "ca-int-1" "ca-root" | ||
| 326 | create_expired_leaf "Server 1" "server-1" "ca-int-1" | ||
| 327 | create_root_bundle "./8a/roots.pem" "ca-root" | ||
| 328 | create_bundle "./8a/bundle.pem" "server-1" "ca-int-1" | ||
| 329 | |||
| 330 | # Scenario 9a. | ||
| 331 | reset | ||
| 332 | create_root "Root CA 1" "ca-root" | ||
| 333 | create_expired_intermediate "Intermediate CA 1" "ca-int-1" "ca-root" | ||
| 334 | create_leaf "Server 1" "server-1" "ca-int-1" | ||
| 335 | create_root_bundle "./9a/roots.pem" "ca-root" | ||
| 336 | create_bundle "./9a/bundle.pem" "server-1" "ca-int-1" | ||
| 337 | |||
| 338 | # Scenarios 10a and 10b. | ||
| 339 | reset | ||
| 340 | create_root "Root CA 1" "ca-root-1" | ||
| 341 | create_root "Root CA 2" "ca-root-2" | ||
| 342 | create_expired_intermediate "Intermediate CA 1" "ca-int-1" "ca-root-1" | ||
| 343 | create_cross_signed "ca-int-1-xs" "ca-int-1" "ca-root-2" | ||
| 344 | create_leaf "Server 1" "server-1" "ca-int-1" | ||
| 345 | create_root_bundle "./10a/roots.pem" "ca-root-1" "ca-root-2" | ||
| 346 | create_bundle "./10a/bundle.pem" "server-1" "ca-int-1" "ca-int-1-xs" | ||
| 347 | create_root_bundle "./10b/roots.pem" "ca-root-1" "ca-root-2" | ||
| 348 | create_bundle "./10b/bundle.pem" "server-1" "ca-int-1-xs" "ca-int-1" | ||
| 349 | |||
| 350 | # Scenarios 11a and 11b. | ||
| 351 | reset | ||
| 352 | create_root "Root CA 1" "ca-root-1" | ||
| 353 | create_expired_intermediate "Intermediate CA 1" "ca-int-1" "ca-root-1" | ||
| 354 | create_intermediate "Intermediate CA 2" "ca-int-2" "ca-int-1" | ||
| 355 | create_root "Root CA 2" "ca-root-2" | ||
| 356 | create_cross_signed "ca-int-2-xs" "ca-int-2" "ca-root-2" | ||
| 357 | create_leaf "Server 1" "server-1" "ca-int-2" | ||
| 358 | create_root_bundle "./11a/roots.pem" "ca-root-1" "ca-root-2" | ||
| 359 | create_bundle "./11a/bundle.pem" "server-1" "ca-int-2" "ca-int-2-xs" "ca-int-1" | ||
| 360 | create_root_bundle "./11b/roots.pem" "ca-root-1" "ca-root-2" | ||
| 361 | create_bundle "./11b/bundle.pem" "server-1" "ca-int-2-xs" "ca-int-2" "ca-int-1" | ||
| 362 | |||
| 363 | # Scenario 12a. | ||
| 364 | reset | ||
| 365 | create_root "Root CA 1" "ca-root-1" | ||
| 366 | create_expired_intermediate "Intermediate CA 1" "ca-int-1" "ca-root-1" | ||
| 367 | create_cross_signed "ca-root-2" "ca-int-1" "ca-root-1" | ||
| 368 | create_intermediate "Intermediate CA 2" "ca-int-2" "ca-int-1" | ||
| 369 | create_leaf "Server 1" "server-1" "ca-int-2" | ||
| 370 | create_root_bundle "./12a/roots.pem" "ca-root-1" "ca-root-2" | ||
| 371 | create_bundle "./12a/bundle.pem" "server-1" "ca-int-2" "ca-int-1" | ||
| 372 | |||
| 373 | # Scenario 13a. | ||
| 374 | reset | ||
| 375 | create_root "Root CA 1" "ca-root-1" | ||
| 376 | create_intermediate "Intermediate CA 1" "ca-int-1" "ca-root-1" | ||
| 377 | create_expired_cross_signed "ca-root-2" "ca-int-1" "ca-root-1" | ||
| 378 | create_intermediate "Intermediate CA 2" "ca-int-2" "ca-int-1" | ||
| 379 | create_leaf "Server 1" "server-1" "ca-int-2" | ||
| 380 | create_root_bundle "./13a/roots.pem" "ca-root-1" "ca-root-2" | ||
| 381 | create_bundle "./13a/bundle.pem" "server-1" "ca-int-2" "ca-int-1" | ||
diff --git a/src/regress/lib/libcrypto/certs/verify_test.go b/src/regress/lib/libcrypto/certs/verify_test.go new file mode 100644 index 0000000000..25301109e4 --- /dev/null +++ b/src/regress/lib/libcrypto/certs/verify_test.go | |||
| @@ -0,0 +1,111 @@ | |||
| 1 | package verify | ||
| 2 | |||
| 3 | import ( | ||
| 4 | "crypto/x509" | ||
| 5 | "encoding/pem" | ||
| 6 | "io/ioutil" | ||
| 7 | "path/filepath" | ||
| 8 | "testing" | ||
| 9 | ) | ||
| 10 | |||
| 11 | func TestVerify(t *testing.T) { | ||
| 12 | tests := []struct { | ||
| 13 | id string | ||
| 14 | wantChains int | ||
| 15 | }{ | ||
| 16 | {"1a", 1}, | ||
| 17 | {"2a", 1}, | ||
| 18 | {"2b", 0}, | ||
| 19 | {"3a", 1}, | ||
| 20 | {"3b", 0}, | ||
| 21 | {"3c", 0}, | ||
| 22 | {"3d", 0}, | ||
| 23 | {"3e", 1}, | ||
| 24 | {"4a", 2}, | ||
| 25 | {"4b", 1}, | ||
| 26 | {"4c", 1}, | ||
| 27 | {"4d", 1}, | ||
| 28 | {"4e", 1}, | ||
| 29 | {"4f", 2}, | ||
| 30 | {"4g", 1}, | ||
| 31 | {"4h", 1}, | ||
| 32 | {"5a", 2}, | ||
| 33 | {"5b", 1}, | ||
| 34 | {"5c", 1}, | ||
| 35 | {"5d", 1}, | ||
| 36 | {"5e", 1}, | ||
| 37 | {"5f", 1}, | ||
| 38 | {"5g", 2}, | ||
| 39 | {"5h", 1}, | ||
| 40 | {"5i", 1}, | ||
| 41 | {"6a", 1}, // Expired root. | ||
| 42 | {"6b", 1}, // Expired root. | ||
| 43 | {"7a", 1}, // Expired root. | ||
| 44 | {"7b", 1}, // Expired root. | ||
| 45 | {"8a", 0}, // Expired leaf. | ||
| 46 | {"9a", 0}, // Expired intermediate. | ||
| 47 | {"10a", 1}, // Cross signed with expired intermediate. | ||
| 48 | {"10b", 1}, // Cross signed with expired intermediate. | ||
| 49 | {"11a", 1}, // Cross signed with expired intermediate. | ||
| 50 | {"11b", 1}, // Cross signed with expired intermediate. | ||
| 51 | {"12a", 1}, // Cross signed with expired intermediate. | ||
| 52 | {"13a", 1}, // Cross signed with expired root. | ||
| 53 | } | ||
| 54 | |||
| 55 | for _, test := range tests { | ||
| 56 | t.Run(test.id, func(t *testing.T) { | ||
| 57 | rootsPEM, err := ioutil.ReadFile(filepath.Join(test.id, "roots.pem")) | ||
| 58 | if err != nil { | ||
| 59 | t.Fatalf("Failed to read roots PEM: %v", err) | ||
| 60 | } | ||
| 61 | bundlePEM, err := ioutil.ReadFile(filepath.Join(test.id, "bundle.pem")) | ||
| 62 | if err != nil { | ||
| 63 | t.Fatalf("Failed to read bundle PEM: %v", err) | ||
| 64 | } | ||
| 65 | |||
| 66 | // Pull the leaf certificate off the top of the bundle. | ||
| 67 | block, intermediatesPEM := pem.Decode(bundlePEM) | ||
| 68 | if block == nil { | ||
| 69 | t.Fatal("Failed to parse leaf from bundle") | ||
| 70 | } | ||
| 71 | cert, err := x509.ParseCertificate(block.Bytes) | ||
| 72 | if err != nil { | ||
| 73 | t.Fatalf("Failed to parse certificate: %v", err) | ||
| 74 | } | ||
| 75 | |||
| 76 | roots := x509.NewCertPool() | ||
| 77 | if !roots.AppendCertsFromPEM(rootsPEM) { | ||
| 78 | t.Fatal("Failed to parse root certificates") | ||
| 79 | } | ||
| 80 | intermediates := x509.NewCertPool() | ||
| 81 | if len(intermediatesPEM) > 0 { | ||
| 82 | if !intermediates.AppendCertsFromPEM(intermediatesPEM) { | ||
| 83 | t.Fatal("Failed to parse intermediate certificates") | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | opts := x509.VerifyOptions{ | ||
| 88 | Roots: roots, | ||
| 89 | Intermediates: intermediates, | ||
| 90 | } | ||
| 91 | |||
| 92 | chains, err := cert.Verify(opts) | ||
| 93 | if err != nil { | ||
| 94 | if test.wantChains > 0 { | ||
| 95 | t.Errorf("Failed to verify certificate: %v", err) | ||
| 96 | } | ||
| 97 | return | ||
| 98 | } | ||
| 99 | t.Logf("Found %d chains", len(chains)) | ||
| 100 | if got, want := len(chains), test.wantChains; got != want { | ||
| 101 | t.Errorf("Got %d chains, want %d", got, want) | ||
| 102 | } | ||
| 103 | for i, chain := range chains { | ||
| 104 | t.Logf("Chain %d\n", i) | ||
| 105 | for _, cert := range chain { | ||
| 106 | t.Logf(" %v\n", cert.Subject) | ||
| 107 | } | ||
| 108 | } | ||
| 109 | }) | ||
| 110 | } | ||
| 111 | } | ||
