Skip to content

Commit 0dd7725

Browse files
committed
fix: resolve comment for Patrick
Signed-off-by: Junjie Gao <[email protected]>
1 parent 096710c commit 0dd7725

File tree

13 files changed

+323
-120
lines changed

13 files changed

+323
-120
lines changed

test/e2e/internal/utils/crl.go

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -18,26 +18,48 @@ import (
1818
"net/http"
1919
)
2020

21-
// CRLRevoke sends http post request to http://localhost:8080/revoke
22-
func CRLRevoke() error {
23-
url := "http://localhost:10086/revoke"
21+
// LeafCRLRevoke sends http post request to http://localhost:8080/revoke
22+
func LeafCRLRevoke() error {
23+
url := "http://localhost:10086/leaf/revoke"
2424
resp, err := http.Post(url, "application/json", nil)
2525
if err != nil {
2626
return err
2727
}
2828
defer resp.Body.Close()
29-
fmt.Printf("CRL revoked with status code: %d\n", resp.StatusCode)
29+
fmt.Printf("CRL of leaf certificate revoked with status code: %d\n", resp.StatusCode)
3030
return nil
3131
}
3232

33-
// CRLUnrevoke sends http post request to http://localhost:8080/unrevoke
34-
func CRLUnrevoke() error {
35-
url := "http://localhost:10086/unrevoke"
33+
// LeafCRLUnrevoke sends http post request to http://localhost:8080/unrevoke
34+
func LeafCRLUnrevoke() error {
35+
url := "http://localhost:10086/leaf/unrevoke"
3636
resp, err := http.Post(url, "application/json", nil)
3737
if err != nil {
3838
return err
3939
}
4040
defer resp.Body.Close()
41-
fmt.Printf("CRL unrevoked with status code: %d\n", resp.StatusCode)
41+
fmt.Printf("CRL of leaf certificate unrevoked with status code: %d\n", resp.StatusCode)
42+
return nil
43+
}
44+
45+
func IntermediateCRLRevoke() error {
46+
url := "http://localhost:10086/intermediate/revoke"
47+
resp, err := http.Post(url, "application/json", nil)
48+
if err != nil {
49+
return nil
50+
}
51+
defer resp.Body.Close()
52+
fmt.Printf("CRL of intermediate certificate revoked with status code: %d\n", resp.StatusCode)
53+
return nil
54+
}
55+
56+
func IntermediateCRLUnrevoke() error {
57+
url := "http://localhost:10086/intermediate/unrevoke"
58+
resp, err := http.Post(url, "application/json", nil)
59+
if err != nil {
60+
return nil
61+
}
62+
defer resp.Body.Close()
63+
fmt.Printf("CRL of intermediate certificate unrevoked with status code: %d\n", resp.StatusCode)
4264
return nil
4365
}

test/e2e/internal/utils/host.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,6 @@ func UserConfigEnv(dir string) map[string]string {
8383
// create and set user dir for linux
8484
return map[string]string{
8585
"XDG_CONFIG_HOME": dir,
86-
"XDG_CACHE_HOME": filepath.Join(dir, ".cache"),
86+
"NOTATION_CACHE": filepath.Join(dir, ".cache"),
8787
}
8888
}

test/e2e/scripts/crl_server.py

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,16 @@
1717

1818
PORT = 10086
1919
DATA_DIR = './testdata/config/crl'
20-
revoke_flag = False
20+
leaf_revoke_flag = False
21+
intermediate_revoke_flag = False
2122

2223

2324
class CRLRequestHandler(http.server.SimpleHTTPRequestHandler):
2425
def do_GET(self):
25-
global revoke_flag
26+
global leaf_revoke_flag
27+
global intermediate_revoke_flag
2628
if self.path == '/leaf.crl':
27-
file_name = 'leaf_revoked.crl' if revoke_flag else 'leaf.crl'
29+
file_name = 'leaf_revoked.crl' if leaf_revoke_flag else 'leaf.crl'
2830
file_path = os.path.join(DATA_DIR, file_name)
2931
print("crl path", file_path)
3032
if os.path.exists(file_path):
@@ -35,17 +37,40 @@ def do_GET(self):
3537
self.wfile.write(f.read())
3638
else:
3739
self.send_error(404, 'File Not Found')
40+
elif self.path == '/intermediate.crl':
41+
file_name = 'intermediate_revoked.crl' if intermediate_revoke_flag else 'intermediate.crl'
42+
file_path = os.path.join(DATA_DIR, file_name)
43+
if os.path.exists(file_path):
44+
self.send_response(200)
45+
self.send_header('Content-Type', 'application/pkix-crl')
46+
self.end_headers()
47+
with open(file_path, 'rb') as f:
48+
self.wfile.write(f.read())
49+
else:
50+
self.send_error(404, 'File Not Found')
3851
else:
3952
self.send_error(404, 'Not Found')
53+
4054
def do_POST(self):
41-
global revoke_flag
42-
if self.path == '/revoke':
43-
revoke_flag = True
55+
global leaf_revoke_flag
56+
global intermediate_revoke_flag
57+
if self.path == '/leaf/revoke':
58+
leaf_revoke_flag = True
59+
self.send_response(201)
60+
self.end_headers()
61+
self.wfile.write(b'ok')
62+
elif self.path == '/leaf/unrevoke':
63+
leaf_revoke_flag = False
64+
self.send_response(201)
65+
self.end_headers()
66+
self.wfile.write(b'ok')
67+
elif self.path == '/intermediate/revoke':
68+
intermediate_revoke_flag = True
4469
self.send_response(201)
4570
self.end_headers()
4671
self.wfile.write(b'ok')
47-
elif self.path == '/unrevoke':
48-
revoke_flag = False
72+
elif self.path == '/intermediate/unrevoke':
73+
intermediate_revoke_flag = False
4974
self.send_response(201)
5075
self.end_headers()
5176
self.wfile.write(b'ok')

test/e2e/scripts/gen_crl_testing_certs.sh

Lines changed: 107 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
# This file include the script to generate testing certificates for CRL testing.
1616
# The generated files are:
1717
# - certchain_with_crl.pem: the fullchain file that includes the leaf
18-
# certificate with CRL and the root certificate.
18+
# certificate with CRL, intermediate certificate with invalid OCSP and valid
19+
# CRL, and the root certificate.
1920
# - leaf.crl: the CRL file that includes the revoked leaf certificate.
2021
# - leaf.key: the private key of the leaf certificate.
2122
# - leaf_revoked.crl: the CRL file that includes the revoked leaf certificate.
23+
# - intermediate.crl: the CRL file that includes the intermediate certificate.
24+
# - intermediate_revoked.crl: the CRL file that includes the revoked intermediate
2225
# - root.crt: the root certificate.
2326
#
2427
# Note: The script will not run in the pipeline, but we need to keep it for
@@ -78,14 +81,90 @@ authorityKeyIdentifier = keyid:always,issuer:always
7881
authorityKeyIdentifier = keyid:always
7982
EOF
8083

84+
# Set up OpenSSL CA directory structure
85+
mkdir -p demoCA/newcerts
86+
touch demoCA/index.txt
87+
echo '1002' > demoCA/serial
88+
echo '1002' > demoCA/crlnumber
89+
8190
# Generate root private key
8291
openssl genrsa -out root.key 2048
8392

8493
# Generate self-signed root certificate with extensions
8594
openssl req -x509 -new -key root.key -sha256 -days 36500 -out root.crt \
8695
-config root.cnf -extensions v3_ca
8796

88-
# Create leaf certificate configuration file
97+
# Update intermediate.cnf to include [ca] and [CA_default] sections
98+
cat > intermediate.cnf <<EOF
99+
[ req ]
100+
default_bits = 2048
101+
prompt = no
102+
distinguished_name = intermediate_distinguished_name
103+
x509_extensions = v3_intermediate_ca
104+
105+
[ intermediate_distinguished_name ]
106+
C = US
107+
ST = State
108+
L = City
109+
O = Organization
110+
OU = OrgUnit
111+
CN = IntermediateCA
112+
113+
[ ca ]
114+
default_ca = CA_default
115+
116+
[ CA_default ]
117+
dir = ./intermediateCA
118+
new_certs_dir = \$dir/newcerts
119+
database = \$dir/index.txt
120+
serial = \$dir/serial
121+
private_key = ./intermediate.key
122+
certificate = ./intermediate.crt
123+
default_md = sha256
124+
policy = policy_any
125+
x509_extensions = usr_cert
126+
copy_extensions = copy
127+
default_days = 36500
128+
default_crl_days = 36500
129+
crlnumber = \$dir/crlnumber
130+
crl_extensions = crl_ext
131+
132+
[ policy_any ]
133+
countryName = optional
134+
stateOrProvinceName = optional
135+
localityName = optional
136+
organizationName = optional
137+
organizationalUnitName = optional
138+
commonName = supplied
139+
140+
[ v3_intermediate_ca ]
141+
basicConstraints = critical,CA:TRUE,pathlen:0
142+
keyUsage = critical,keyCertSign,cRLSign
143+
subjectKeyIdentifier = hash
144+
authorityKeyIdentifier = keyid:always,issuer:always
145+
crlDistributionPoints = URI:http://localhost:10086/intermediate.crl
146+
authorityInfoAccess = OCSP;URI:http://localhost.test/ocsp
147+
148+
[ crl_ext ]
149+
authorityKeyIdentifier = keyid:always
150+
EOF
151+
152+
# Set up OpenSSL CA directory structure for intermediate CA
153+
mkdir -p intermediateCA/newcerts
154+
touch intermediateCA/index.txt
155+
echo '1000' > intermediateCA/serial
156+
echo '1000' > intermediateCA/crlnumber
157+
158+
# Generate intermediate private key
159+
openssl genrsa -out intermediate.key 2048
160+
161+
# Generate intermediate CSR
162+
openssl req -new -key intermediate.key -out intermediate.csr -config intermediate.cnf
163+
164+
# Sign intermediate certificate with root CA
165+
openssl ca -config root.cnf -in intermediate.csr -out intermediate.crt -batch -extensions v3_intermediate_ca -extfile intermediate.cnf -notext
166+
167+
# Update leaf.cnf to remove OCSP server
89168
cat > leaf.cnf <<EOF
90169
[ req ]
91170
default_bits = 2048
@@ -113,31 +192,40 @@ openssl genrsa -out leaf.key 2048
113192
# Generate leaf certificate signing request (CSR)
114193
openssl req -new -key leaf.key -out leaf.csr -config leaf.cnf
115194

116-
# Set up OpenSSL CA directory structure
117-
mkdir -p demoCA/newcerts
118-
touch demoCA/index.txt
119-
echo '1000' > demoCA/serial
120-
echo '1000' > demoCA/crlnumber
195+
# Sign leaf certificate with intermediate CA
196+
openssl ca -config intermediate.cnf -in leaf.csr -out leaf.crt -batch -extensions v3_req -extfile leaf.cnf -notext
197+
198+
# Generate intermediate CRL using root.cnf (before revocation)
199+
openssl ca -config root.cnf -gencrl -out intermediate.crl
200+
201+
# Convert root CRL to DER format
202+
openssl crl -in intermediate.crl -outform der -out intermediate.crl
203+
204+
# Revoke intermediate certificate using root CA
205+
openssl ca -config root.cnf -revoke intermediate.crt
206+
207+
# Generate intermediate CRL including revoked intermediate certificate
208+
openssl ca -config root.cnf -gencrl -out intermediate_revoked.crl
121209

122-
# Sign leaf certificate with root CA
123-
openssl ca -config root.cnf -in leaf.csr -out leaf.crt -batch -extensions v3_req -extfile leaf.cnf -notext
210+
# Convert intermediate CRL to DER format
211+
openssl crl -in intermediate_revoked.crl -outform der -out intermediate_revoked.crl
124212

125-
# Generate the CRL
126-
openssl ca -config root.cnf -gencrl -out leaf.crl
213+
# Generate leaf CRL
214+
openssl ca -config intermediate.cnf -gencrl -out leaf.crl
127215

128-
# Convert the CRL to DER format
216+
# Convert leaf CRL to DER format
129217
openssl crl -in leaf.crl -outform der -out leaf.crl
130218

131-
# Revoke the leaf certificate
132-
openssl ca -config root.cnf -revoke leaf.crt
219+
# Revoke leaf certificate
220+
openssl ca -config intermediate.cnf -revoke leaf.crt
133221

134-
# Generate the CRL including the revoked leaf certificate
135-
openssl ca -config root.cnf -gencrl -out leaf_revoked.crl
222+
# Generate leaf CRL including revoked leaf certificate
223+
openssl ca -config intermediate.cnf -gencrl -out leaf_revoked.crl
136224

137-
# Convert the updated CRL to DER format
225+
# Convert leaf CRL to DER format
138226
openssl crl -in leaf_revoked.crl -outform der -out leaf_revoked.crl
139227

140228
# merge leaf cert and root cert to create fullchain file
141-
cat leaf.crt root.crt > certchain_with_crl.pem
229+
cat leaf.crt intermediate.crt root.crt > certchain_with_crl.pem
142230

143-
rm -rf leaf.csr leaf.crt leaf.cnf root.srl root.cnf root.key demoCA
231+
rm -rf leaf.csr leaf.crt leaf.cnf root.srl root.cnf root.key root.crl demoCA intermediate.csr intermediate.cnf intermediate.key intermediate.crt intermediateCA

test/e2e/suite/plugin/install.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,8 @@ var _ = Describe("notation plugin install", func() {
154154

155155
It("with invalid plugin URL", func() {
156156
Host(nil, func(notation *utils.ExecOpts, _ *Artifact, vhost *utils.VirtualHost) {
157-
notation.ExpectFailure().Exec("plugin", "install", "--url", "https://invalid", "--sha256sum", "abcd").
158-
MatchErrKeyWords("failed to download plugin from URL https://invalid")
157+
notation.ExpectFailure().Exec("plugin", "install", "--url", "https://invalid.test", "--sha256sum", "abcd").
158+
MatchErrKeyWords("failed to download plugin from URL https://invalid.test")
159159
})
160160
})
161161
})

test/e2e/suite/scenario/crl.go

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
2626
notation.Exec("sign", artifact.ReferenceWithDigest()).
2727
MatchKeyWords(SignSuccessfully)
2828

29-
utils.CRLUnrevoke()
29+
utils.LeafCRLUnrevoke()
30+
utils.IntermediateCRLUnrevoke()
3031

3132
// verify without cache
3233
notation.Exec("verify", artifact.ReferenceWithDigest(), "-d").
@@ -37,6 +38,7 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
3738
"CRL file cache miss",
3839
"Retrieving crl bundle from file cache with key",
3940
"Storing crl bundle to file cache with key",
41+
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
4042
).
4143
NoMatchErrKeyWords(
4244
"is revoked",
@@ -49,6 +51,7 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
4951
).
5052
MatchErrKeyWords(
5153
"Retrieving crl bundle from file cache with key",
54+
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
5255
).
5356
NoMatchErrKeyWords(
5457
"CRL file cache miss",
@@ -63,7 +66,8 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
6366
notation.Exec("sign", artifact.ReferenceWithDigest()).
6467
MatchKeyWords(SignSuccessfully)
6568

66-
utils.CRLRevoke()
69+
utils.LeafCRLRevoke()
70+
utils.IntermediateCRLUnrevoke()
6771

6872
// verify without cache
6973
notation.ExpectFailure().Exec("verify", artifact.ReferenceWithDigest(), "-d").
@@ -73,6 +77,7 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
7377
"Retrieving crl bundle from file cache with key",
7478
"Storing crl bundle to file cache with key",
7579
"is revoked",
80+
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
7681
)
7782

7883
// verify with cache
@@ -81,6 +86,41 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
8186
VerifyFailed,
8287
"Retrieving crl bundle from file cache with key",
8388
"is revoked",
89+
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
90+
).
91+
NoMatchErrKeyWords(
92+
"CRL file cache miss",
93+
"Storing crl bundle to file cache with key",
94+
)
95+
})
96+
})
97+
98+
It("failed with revoked intermediate certificate", func() {
99+
Host(CRLOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
100+
notation.Exec("sign", artifact.ReferenceWithDigest()).
101+
MatchKeyWords(SignSuccessfully)
102+
103+
utils.LeafCRLUnrevoke()
104+
utils.IntermediateCRLRevoke()
105+
106+
// verify without cache
107+
notation.ExpectFailure().Exec("verify", artifact.ReferenceWithDigest(), "-d").
108+
MatchErrKeyWords(
109+
VerifyFailed,
110+
"CRL file cache miss",
111+
"Retrieving crl bundle from file cache with key",
112+
"Storing crl bundle to file cache with key",
113+
"is revoked",
114+
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
115+
)
116+
117+
// verify with cache
118+
notation.ExpectFailure().Exec("verify", artifact.ReferenceWithDigest(), "-d").
119+
MatchErrKeyWords(
120+
VerifyFailed,
121+
"Retrieving crl bundle from file cache with key",
122+
"is revoked",
123+
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
84124
).
85125
NoMatchErrKeyWords(
86126
"CRL file cache miss",

0 commit comments

Comments
 (0)