Skip to content

Commit

Permalink
test: add more x509 OCSP tests (aws#3970)
Browse files Browse the repository at this point in the history
  • Loading branch information
jmayclin authored May 10, 2023
1 parent 800b61f commit 3b639f0
Show file tree
Hide file tree
Showing 8 changed files with 459 additions and 10 deletions.
34 changes: 30 additions & 4 deletions tests/pems/ocsp/OCSP-TEST.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,25 @@ The CN for this cert matches the URI in the Server Cert's "Authority Information

The leaf cert/key. OCSP responses will be generated for this cert.

### Early Expiry Cert
The `server_cert_early_expire.pem` is a certificate that expires in 2037. This certificate is used to validate correct behavior of expired dates for unit tests on 32 bit platforms. This is necessary because 32 bit `time_t` values can't represent dates past 2038, so our unit tests on 32 bit platforms can't test the expiry of very long lived certs.

This cert and the corresponding ocsp response, `ocsp_response_early_expire.der` can be generated at any time by running the `./generate.sh` script. This will break the `Test OCSP validation at various offsets from update times` unit test, because the "This Update" timestamp of `ocsp_reponse_early_expire.der` will change.

This is fixed by setting `this_update_timestamp_nanoseconds` in `Test OCSP validation at various offsets from update times` to the new "This Update" timestamp. This can be found with
```
openssl ocsp -respin ocsp_response_early_expire.der -text -noverify | grep "This Update"
```
## OCSP response
* ocsp_response.der

DER formatted OCSP response for the Server Cert. This file will be configured in s2n for stapling.

The OCSP responses can be viewed in plaintext using the `ocsp` command.
```
openssl ocsp -respin ocsp_response_early_expire.der -text -noverify
```

## Generating a new OCSP response for the leaf cert
Should not be necessary. The current response expires in 100 years.

Expand All @@ -34,15 +48,15 @@ From the current directory:
### Run the server
```
# With nextUpdate
openssl ocsp -port 8889 -text -CA ca_cert.pem \ ocsp_test ✭ ✱ ◼
openssl ocsp -port 8889 -text -CA ca_cert.pem \
-index certs.txt \
-rkey ocsp_key.pem \
-rsigner ocsp_cert.pem \
-nrequest 1 \
-ndays $(( 365 * 100 ))
# Without nextUpdate
openssl ocsp -port 8890 -text -CA ca_cert.pem \ ocsp_test ✭ ✱ ◼
openssl ocsp -port 8890 -text -CA ca_cert.pem \
-index certs.txt \
-rkey ocsp_key.pem \
-rsigner ocsp_cert.pem \
Expand All @@ -52,16 +66,28 @@ openssl ocsp -port 8890 -text -CA ca_cert.pem \
### Run the client and save the result to file
```
# With nextUpdate
openssl ocsp -CAfile ca_cert.pem \ ocsp_test ✭ ✱ ◼
openssl ocsp -CAfile ca_cert.pem \
-url http://127.0.0.1:8889 \
-issuer ca_cert.pem \
-verify_other ocsp_cert.pem \
-cert server_cert.pem -respout ocsp_response.der
# Without nextUpdate
openssl ocsp -CAfile ca_cert.pem \ ocsp_test ✭ ✱ ◼
openssl ocsp -CAfile ca_cert.pem \
-url http://127.0.0.1:8890 \
-issuer ca_cert.pem \
-verify_other ocsp_cert.pem \
-cert server_cert.pem -respout ocsp_response_no_next_update.der
```

### Index Files
The index files in the previous commands are in the CA Database format, and are the source of truth for certificates being verified or rejected.

> The index file consists of zero or more lines, each containing the following fields separated by tab characters:
>
> Certificate status flag (V=valid, R=revoked, E=expired).
> Certificate expiration date in YYMMDDHHMMSSZ format.
> Certificate revocation date in YYMMDDHHMMSSZ[,reason] format. Empty if not revoked.
> Certificate serial number in hex.
> Certificate filename or literal string ‘unknown’.
> Certificate distinguished name.
> -- https://pki-tutorial.readthedocs.io/en/latest/cadb.html
26 changes: 26 additions & 0 deletions tests/pems/ocsp/config/ca.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[ ca ]
default_ca = CA_default
prompt = no

[ CA_default ]
dir = config
unique_subject = no
certificate = ca_cert.pem
private_key = ca_key.pem
# this is the database that the ocsp server reads in
database = certs_early_expire_index.txt
serial = $dir/serial
default_md = sha256
name_opt = ca_default
cert_opt = ca_default
default_enddate = 20360101010101Z
preserve = yes
policy = policy_strict

[ policy_strict ]
countryName = supplied
stateOrProvinceName = supplied
organizationName = supplied
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
29 changes: 29 additions & 0 deletions tests/pems/ocsp/config/server_early_expire.cnf
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[req]
distinguished_name = server_distinguished_name
prompt = no

# extensions csr request
x509_extensions = v3_req

# extensions included in the generated certificate
req_extensions = req_ext

[server_distinguished_name]
countryName = US
stateOrProvinceName = WA
organizationName = s2n
commonName = s2n Test Cert

[v3_req]
subjectAltName = @alt_names

[req_ext]
subjectAltName = @alt_names
basicConstraints=CA:FALSE
subjectKeyIdentifier=hash
keyUsage=digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
authorityInfoAccess = OCSP;URI:http://ocsp.s2ntest.com

[alt_names]
DNS = localhost
92 changes: 92 additions & 0 deletions tests/pems/ocsp/generate.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#!/bin/bash
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://aws.amazon.com/apache2.0
#
# or in the "license" file accompanying this file. This file is distributed
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
# express or implied. See the License for the specific language governing
# permissions and limitations under the License.

# immediately bail if any command fails
set -e

# This script assumes the existence of
# ca_key.pem
# ca_cert.pem
# server_key.pem - the private key for early expiry cert being generated
# config/ca.cnf
# config/server_early_expiry.cnf

echo "generating serial file"
touch config/serial
# the openssl ca command will read this file to figure out the serial number,
# increment it for each certificate that is signed. This is the serial number in
# hex notation.
echo "1024" > config/serial

echo "generating server early expiry CSR"
openssl req -new -nodes -key server_key.pem -out server_early_expire.csr -config config/server_early_expire.cnf

echo "creating empty CA database"
# it's mandatory for this to exist, although it is initially empty
# this data base will be updated during the ca command
touch certs_early_expire_index.txt

echo "generating server certificate and signing it"
# this directory holds the duplicate certs that the CA command generates
# https://security.stackexchange.com/questions/111448/how-to-avoid-writing-pem-while-signing-a-csr
mkdir -p to_nuke

# use the "batch" option to disable prompting
# the enddate argument is in YYYYMMDDHHMMSS format
# use the "notext" option because s2n can't parse .pem certificates with the
# text information inside of them
openssl ca -batch \
-in server_early_expire.csr \
-out server_cert_early_expire.pem \
-config config/ca.cnf \
-outdir to_nuke \
-enddate 20370101010101Z \
-extfile config/server_early_expire.cnf \
-extensions req_ext \
-notext

echo "verifying generated certificates"
openssl verify -CAfile ca_cert.pem server_cert_early_expire.pem

echo "generating ocsp response"
# This is the target next_update date for the OCSP response. This date needs to
# be before 2038 so that next_update field can be tested on 32 bit platforms.
target_date="2036-01-01"
current_date=$(date +%Y-%m-%d)
expiration_days=$(( ($(date -d "$target_date" +%s) - $(date -d "$current_date" +%s)) / 86400 ))

# The & launches the server in the background
openssl ocsp -port 8889 -text -CA ca_cert.pem \
-index certs_early_expire_index.txt \
-rkey ocsp_key.pem \
-rsigner ocsp_cert.pem \
-nrequest 1 \
-ndays $expiration_days \
&

openssl ocsp -CAfile ca_cert.pem \
-url http://127.0.0.1:8889 \
-issuer ca_cert.pem \
-verify_other ocsp_cert.pem \
-cert server_cert_early_expire.pem -respout ocsp_response_early_expire.der

echo "removing temporary files"
rm server_early_expire.csr
# openssl generates <file>, <file>.attr, <file>.old, and <file>.attr.old
# delete all of them
rm certs_early_expire_index* -f
rm to_nuke -rf
rm config/serial
rm config/serial.old

Binary file added tests/pems/ocsp/ocsp_response_early_expire.der
Binary file not shown.
27 changes: 27 additions & 0 deletions tests/pems/ocsp/server_cert_early_expire.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
-----BEGIN CERTIFICATE-----
MIIEoDCCAoigAwIBAgICECQwDQYJKoZIhvcNAQELBQAwKDELMAkGA1UEBhMCVVMx
CzAJBgNVBAgMAldBMQwwCgYDVQQKDANzMm4wHhcNMjMwNDI4MjIxMTU2WhcNMzcw
MTAxMDEwMTAxWjBAMQswCQYDVQQGEwJVUzELMAkGA1UECAwCV0ExDDAKBgNVBAoM
A3MybjEWMBQGA1UEAwwNczJuIFRlc3QgQ2VydDCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBALHTYiB2HrYZtddheWrwP3Jthd+Pi7+v351eXrzRqmlfXr9+
QdAb4vtLzE2sdkVI+CigDF3M58/hM0io2jeT3s7GVntCbDPfbMAGBTaN3JCJck2D
LtZCn12Pu2INk7tVWgG6O/ysxgxCbRA8kEw3/x/ezNkzKqovt8ktoyuHZY40jd0q
XILKHtva02liOEwgWYaryr7KTEl/tleaN/OgJS2sJSL/2BnoZr/M0wR6hBDq/dgf
gCPm5hojU/GljZgEdKIKVKJrbREcL3D/3aJ2OurWLxJaoDm7E7ETNPaWHrXo92WD
uwLKJE95vS1040u4SDplALW8JEg6V65+kaRxtykCAwEAAaOBuzCBuDAUBgNVHREE
DTALgglsb2NhbGhvc3QwCQYDVR0TBAIwADAdBgNVHQ4EFgQUBi2tMmK6rUbB1zR7
+P50pKvBrFQwCwYDVR0PBAQDAgWgMBMGA1UdJQQMMAoGCCsGAQUFBwMBMDMGCCsG
AQUFBwEBBCcwJTAjBggrBgEFBQcwAYYXaHR0cDovL29jc3AuczJudGVzdC5jb20w
HwYDVR0jBBgwFoAUEt+BdXHKktPOGywrdzueM3fz928wDQYJKoZIhvcNAQELBQAD
ggIBAGsZRE6vUP00ijOUftQc6GusUcZfvexwZkvv1VPq8Dz1M3L1QniFpqjHdUKl
9TlZ7t1pekfkj66XInK/5GevOWcY8ZVQf9q7DUFFojLFiIyFThgxicp5SVnUpYJq
ctSxLvbbwYBBOhl1noTG0MbzHyKLcy++A7Xp3U/XC/kdNfNtBgNgXu0FMrIXl8uo
Q0KqMf85rDr0aX2F1j2PB4JYB1xlnjydCAe9TlAwqfDN1fhoh9bJf1JLwUKndxgg
t3XXbftQ7W5GpJUQkuE18nAkKfG2LwVgEya1p+9XaxXncj5OuDR56BrDXaK3p4sy
NChliq4MBIMwWlE9h5tTjN6agXr14YMTEU2HI1QexVDScxyA2SDU6TiBiNBOCAH8
NHmd/h2QN/0hKWyZGpdwdobsXHXIAogAP8TX5udq9t9DjkHJXS93nBs3S0SJEPaJ
9PjaxCQ/zLC9BQKRoratij4iMS2k49suJof1SWyg5qqQ4DOHwj0rTJwQ+1zIklPR
0LiA8pEZnbl0Bswz2BL/XIWKdO33UVdTrYGQaoa+AtwNzlAlfFfjfF1Wi49Y1SJA
wqazI+u6wDy54GYaKWHlsf4WhmdRj+GtHOg44F1MRe74/e6IFl4YDmq7bHoQKlsh
nLsJt+daDCwC93EwBdkXlZEYsP6d1rvSXlfgwxyCFqqMFe+4
-----END CERTIFICATE-----
6 changes: 4 additions & 2 deletions tests/testlib/s2n_testlib.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,15 @@ S2N_RESULT s2n_connection_set_test_master_secret(struct s2n_connection *conn, co
#define S2N_NO_DASHES_CERT_CHAIN "../pems/rsa_2048_no_dashes_cert.pem"

/* OCSP Stapled Response Testing files */
#define S2N_OCSP_SERVER_CERT "../pems/ocsp/server_cert.pem"
#define S2N_OCSP_SERVER_ECDSA_CERT "../pems/ocsp/server_ecdsa_cert.pem"
#define S2N_OCSP_SERVER_CERT "../pems/ocsp/server_cert.pem"
#define S2N_OCSP_SERVER_CERT_EARLY_EXPIRE "../pems/ocsp/server_cert_early_expire.pem"
#define S2N_OCSP_SERVER_ECDSA_CERT "../pems/ocsp/server_ecdsa_cert.pem"

#define S2N_OCSP_SERVER_KEY "../pems/ocsp/server_key.pem"
#define S2N_OCSP_CA_CERT "../pems/ocsp/ca_cert.pem"
#define S2N_OCSP_CA_KEY "../pems/ocsp/ca_key.pem"
#define S2N_OCSP_RESPONSE_DER "../pems/ocsp/ocsp_response.der"
#define S2N_OCSP_RESPONSE_EARLY_EXPIRE_DER "../pems/ocsp/ocsp_response_early_expire.der"
#define S2N_OCSP_RESPONSE_NO_NEXT_UPDATE_DER "../pems/ocsp/ocsp_response_no_next_update.der"
#define S2N_OCSP_RESPONSE_REVOKED_DER "../pems/ocsp/ocsp_response_revoked.der"
#define S2N_OCSP_RESPONSE_WRONG_SIGNER_DER "../pems/ocsp/ocsp_response_wrong_signer.der"
Expand Down
Loading

0 comments on commit 3b639f0

Please sign in to comment.