Skip to content

Commit

Permalink
fix: resolve comment for Patrick
Browse files Browse the repository at this point in the history
Signed-off-by: Junjie Gao <[email protected]>
  • Loading branch information
JeyJeyGao committed Nov 11, 2024
1 parent 096710c commit 0dd7725
Show file tree
Hide file tree
Showing 13 changed files with 323 additions and 120 deletions.
38 changes: 30 additions & 8 deletions test/e2e/internal/utils/crl.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,26 +18,48 @@ import (
"net/http"
)

// CRLRevoke sends http post request to http://localhost:8080/revoke
func CRLRevoke() error {
url := "http://localhost:10086/revoke"
// LeafCRLRevoke sends http post request to http://localhost:8080/revoke
func LeafCRLRevoke() error {
url := "http://localhost:10086/leaf/revoke"
resp, err := http.Post(url, "application/json", nil)
if err != nil {
return err
}
defer resp.Body.Close()
fmt.Printf("CRL revoked with status code: %d\n", resp.StatusCode)
fmt.Printf("CRL of leaf certificate revoked with status code: %d\n", resp.StatusCode)
return nil
}

// CRLUnrevoke sends http post request to http://localhost:8080/unrevoke
func CRLUnrevoke() error {
url := "http://localhost:10086/unrevoke"
// LeafCRLUnrevoke sends http post request to http://localhost:8080/unrevoke
func LeafCRLUnrevoke() error {
url := "http://localhost:10086/leaf/unrevoke"
resp, err := http.Post(url, "application/json", nil)
if err != nil {
return err
}
defer resp.Body.Close()
fmt.Printf("CRL unrevoked with status code: %d\n", resp.StatusCode)
fmt.Printf("CRL of leaf certificate unrevoked with status code: %d\n", resp.StatusCode)
return nil
}

func IntermediateCRLRevoke() error {
url := "http://localhost:10086/intermediate/revoke"
resp, err := http.Post(url, "application/json", nil)
if err != nil {
return nil
}
defer resp.Body.Close()
fmt.Printf("CRL of intermediate certificate revoked with status code: %d\n", resp.StatusCode)
return nil
}

func IntermediateCRLUnrevoke() error {
url := "http://localhost:10086/intermediate/unrevoke"
resp, err := http.Post(url, "application/json", nil)
if err != nil {
return nil
}
defer resp.Body.Close()
fmt.Printf("CRL of intermediate certificate unrevoked with status code: %d\n", resp.StatusCode)
return nil
}
2 changes: 1 addition & 1 deletion test/e2e/internal/utils/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,6 @@ func UserConfigEnv(dir string) map[string]string {
// create and set user dir for linux
return map[string]string{
"XDG_CONFIG_HOME": dir,
"XDG_CACHE_HOME": filepath.Join(dir, ".cache"),
"NOTATION_CACHE": filepath.Join(dir, ".cache"),
}
}
41 changes: 33 additions & 8 deletions test/e2e/scripts/crl_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,16 @@

PORT = 10086
DATA_DIR = './testdata/config/crl'
revoke_flag = False
leaf_revoke_flag = False
intermediate_revoke_flag = False


class CRLRequestHandler(http.server.SimpleHTTPRequestHandler):
def do_GET(self):
global revoke_flag
global leaf_revoke_flag
global intermediate_revoke_flag
if self.path == '/leaf.crl':
file_name = 'leaf_revoked.crl' if revoke_flag else 'leaf.crl'
file_name = 'leaf_revoked.crl' if leaf_revoke_flag else 'leaf.crl'
file_path = os.path.join(DATA_DIR, file_name)
print("crl path", file_path)
if os.path.exists(file_path):
Expand All @@ -35,17 +37,40 @@ def do_GET(self):
self.wfile.write(f.read())
else:
self.send_error(404, 'File Not Found')
elif self.path == '/intermediate.crl':
file_name = 'intermediate_revoked.crl' if intermediate_revoke_flag else 'intermediate.crl'
file_path = os.path.join(DATA_DIR, file_name)
if os.path.exists(file_path):
self.send_response(200)
self.send_header('Content-Type', 'application/pkix-crl')
self.end_headers()
with open(file_path, 'rb') as f:
self.wfile.write(f.read())
else:
self.send_error(404, 'File Not Found')
else:
self.send_error(404, 'Not Found')

def do_POST(self):
global revoke_flag
if self.path == '/revoke':
revoke_flag = True
global leaf_revoke_flag
global intermediate_revoke_flag
if self.path == '/leaf/revoke':
leaf_revoke_flag = True
self.send_response(201)
self.end_headers()
self.wfile.write(b'ok')
elif self.path == '/leaf/unrevoke':
leaf_revoke_flag = False
self.send_response(201)
self.end_headers()
self.wfile.write(b'ok')
elif self.path == '/intermediate/revoke':
intermediate_revoke_flag = True
self.send_response(201)
self.end_headers()
self.wfile.write(b'ok')
elif self.path == '/unrevoke':
revoke_flag = False
elif self.path == '/intermediate/unrevoke':
intermediate_revoke_flag = False
self.send_response(201)
self.end_headers()
self.wfile.write(b'ok')
Expand Down
126 changes: 107 additions & 19 deletions test/e2e/scripts/gen_crl_testing_certs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,13 @@
# This file include the script to generate testing certificates for CRL testing.
# The generated files are:
# - certchain_with_crl.pem: the fullchain file that includes the leaf
# certificate with CRL and the root certificate.
# certificate with CRL, intermediate certificate with invalid OCSP and valid
# CRL, and the root certificate.
# - leaf.crl: the CRL file that includes the revoked leaf certificate.
# - leaf.key: the private key of the leaf certificate.
# - leaf_revoked.crl: the CRL file that includes the revoked leaf certificate.
# - intermediate.crl: the CRL file that includes the intermediate certificate.
# - intermediate_revoked.crl: the CRL file that includes the revoked intermediate
# - root.crt: the root certificate.
#
# Note: The script will not run in the pipeline, but we need to keep it for
Expand Down Expand Up @@ -78,14 +81,90 @@ authorityKeyIdentifier = keyid:always,issuer:always
authorityKeyIdentifier = keyid:always
EOF

# Set up OpenSSL CA directory structure
mkdir -p demoCA/newcerts
touch demoCA/index.txt
echo '1002' > demoCA/serial
echo '1002' > demoCA/crlnumber

# Generate root private key
openssl genrsa -out root.key 2048

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

# Create leaf certificate configuration file
# Update intermediate.cnf to include [ca] and [CA_default] sections
cat > intermediate.cnf <<EOF
[ req ]
default_bits = 2048
prompt = no
distinguished_name = intermediate_distinguished_name
x509_extensions = v3_intermediate_ca
[ intermediate_distinguished_name ]
C = US
ST = State
L = City
O = Organization
OU = OrgUnit
CN = IntermediateCA
[ ca ]
default_ca = CA_default
[ CA_default ]
dir = ./intermediateCA
new_certs_dir = \$dir/newcerts
database = \$dir/index.txt
serial = \$dir/serial
private_key = ./intermediate.key
certificate = ./intermediate.crt
default_md = sha256
policy = policy_any
x509_extensions = usr_cert
copy_extensions = copy
default_days = 36500
default_crl_days = 36500
crlnumber = \$dir/crlnumber
crl_extensions = crl_ext
[ policy_any ]
countryName = optional
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
[ v3_intermediate_ca ]
basicConstraints = critical,CA:TRUE,pathlen:0
keyUsage = critical,keyCertSign,cRLSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
crlDistributionPoints = URI:http://localhost:10086/intermediate.crl
authorityInfoAccess = OCSP;URI:http://localhost.test/ocsp
[ crl_ext ]
authorityKeyIdentifier = keyid:always
EOF

# Set up OpenSSL CA directory structure for intermediate CA
mkdir -p intermediateCA/newcerts
touch intermediateCA/index.txt
echo '1000' > intermediateCA/serial
echo '1000' > intermediateCA/crlnumber

# Generate intermediate private key
openssl genrsa -out intermediate.key 2048

# Generate intermediate CSR
openssl req -new -key intermediate.key -out intermediate.csr -config intermediate.cnf

# Sign intermediate certificate with root CA
openssl ca -config root.cnf -in intermediate.csr -out intermediate.crt -batch -extensions v3_intermediate_ca -extfile intermediate.cnf -notext

# Update leaf.cnf to remove OCSP server
cat > leaf.cnf <<EOF
[ req ]
default_bits = 2048
Expand Down Expand Up @@ -113,31 +192,40 @@ openssl genrsa -out leaf.key 2048
# Generate leaf certificate signing request (CSR)
openssl req -new -key leaf.key -out leaf.csr -config leaf.cnf

# Set up OpenSSL CA directory structure
mkdir -p demoCA/newcerts
touch demoCA/index.txt
echo '1000' > demoCA/serial
echo '1000' > demoCA/crlnumber
# Sign leaf certificate with intermediate CA
openssl ca -config intermediate.cnf -in leaf.csr -out leaf.crt -batch -extensions v3_req -extfile leaf.cnf -notext

# Generate intermediate CRL using root.cnf (before revocation)
openssl ca -config root.cnf -gencrl -out intermediate.crl

# Convert root CRL to DER format
openssl crl -in intermediate.crl -outform der -out intermediate.crl

# Revoke intermediate certificate using root CA
openssl ca -config root.cnf -revoke intermediate.crt

# Generate intermediate CRL including revoked intermediate certificate
openssl ca -config root.cnf -gencrl -out intermediate_revoked.crl

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

# Generate the CRL
openssl ca -config root.cnf -gencrl -out leaf.crl
# Generate leaf CRL
openssl ca -config intermediate.cnf -gencrl -out leaf.crl

# Convert the CRL to DER format
# Convert leaf CRL to DER format
openssl crl -in leaf.crl -outform der -out leaf.crl

# Revoke the leaf certificate
openssl ca -config root.cnf -revoke leaf.crt
# Revoke leaf certificate
openssl ca -config intermediate.cnf -revoke leaf.crt

# Generate the CRL including the revoked leaf certificate
openssl ca -config root.cnf -gencrl -out leaf_revoked.crl
# Generate leaf CRL including revoked leaf certificate
openssl ca -config intermediate.cnf -gencrl -out leaf_revoked.crl

# Convert the updated CRL to DER format
# Convert leaf CRL to DER format
openssl crl -in leaf_revoked.crl -outform der -out leaf_revoked.crl

# merge leaf cert and root cert to create fullchain file
cat leaf.crt root.crt > certchain_with_crl.pem
cat leaf.crt intermediate.crt root.crt > certchain_with_crl.pem

rm -rf leaf.csr leaf.crt leaf.cnf root.srl root.cnf root.key demoCA
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
4 changes: 2 additions & 2 deletions test/e2e/suite/plugin/install.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ var _ = Describe("notation plugin install", func() {

It("with invalid plugin URL", func() {
Host(nil, func(notation *utils.ExecOpts, _ *Artifact, vhost *utils.VirtualHost) {
notation.ExpectFailure().Exec("plugin", "install", "--url", "https://invalid", "--sha256sum", "abcd").
MatchErrKeyWords("failed to download plugin from URL https://invalid")
notation.ExpectFailure().Exec("plugin", "install", "--url", "https://invalid.test", "--sha256sum", "abcd").
MatchErrKeyWords("failed to download plugin from URL https://invalid.test")
})
})
})
44 changes: 42 additions & 2 deletions test/e2e/suite/scenario/crl.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
notation.Exec("sign", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

utils.CRLUnrevoke()
utils.LeafCRLUnrevoke()
utils.IntermediateCRLUnrevoke()

// verify without cache
notation.Exec("verify", artifact.ReferenceWithDigest(), "-d").
Expand All @@ -37,6 +38,7 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
"CRL file cache miss",
"Retrieving crl bundle from file cache with key",
"Storing crl bundle to file cache with key",
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
).
NoMatchErrKeyWords(
"is revoked",
Expand All @@ -49,6 +51,7 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
).
MatchErrKeyWords(
"Retrieving crl bundle from file cache with key",
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
).
NoMatchErrKeyWords(
"CRL file cache miss",
Expand All @@ -63,7 +66,8 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
notation.Exec("sign", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

utils.CRLRevoke()
utils.LeafCRLRevoke()
utils.IntermediateCRLUnrevoke()

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

// verify with cache
Expand All @@ -81,6 +86,41 @@ var _ = Describe("notation CRL revocation check", Serial, func() {
VerifyFailed,
"Retrieving crl bundle from file cache with key",
"is revoked",
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
).
NoMatchErrKeyWords(
"CRL file cache miss",
"Storing crl bundle to file cache with key",
)
})
})

It("failed with revoked intermediate certificate", func() {
Host(CRLOptions(), func(notation *utils.ExecOpts, artifact *Artifact, vhost *utils.VirtualHost) {
notation.Exec("sign", artifact.ReferenceWithDigest()).
MatchKeyWords(SignSuccessfully)

utils.LeafCRLUnrevoke()
utils.IntermediateCRLRevoke()

// verify without cache
notation.ExpectFailure().Exec("verify", artifact.ReferenceWithDigest(), "-d").
MatchErrKeyWords(
VerifyFailed,
"CRL file cache miss",
"Retrieving crl bundle from file cache with key",
"Storing crl bundle to file cache with key",
"is revoked",
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
)

// verify with cache
notation.ExpectFailure().Exec("verify", artifact.ReferenceWithDigest(), "-d").
MatchErrKeyWords(
VerifyFailed,
"Retrieving crl bundle from file cache with key",
"is revoked",
"OCSP check failed with unknown error and fallback to CRL check for certificate #2",
).
NoMatchErrKeyWords(
"CRL file cache miss",
Expand Down
Loading

0 comments on commit 0dd7725

Please sign in to comment.