Skip to content

Commit

Permalink
Dynamically generate grpc-creds at integration test startup (letsencr…
Browse files Browse the repository at this point in the history
…ypt#7477)

The summary here is:
- Move test/cert-ceremonies to test/certs
- Move .hierarchy (generated by the above) to test/certs/webpki
- Remove our mapping of .hierarchy to /hierarchy inside docker
- Move test/grpc-creds to test/certs/ipki
- Unify the generation of both test/certs/webpki and test/certs/ipki
into a single script at test/certs/generate.sh
- Make that script the entrypoint of a new docker compose service
- Have t.sh and tn.sh invoke that service to ensure keys and certs are
created before tests run

No production changes are necessary, the config changes here are just
for testing purposes.

Part of letsencrypt#7476
  • Loading branch information
aarongable authored and Vladislav Baranovskiy committed May 30, 2024
1 parent 2ab1989 commit 324ef96
Show file tree
Hide file tree
Showing 145 changed files with 561 additions and 1,933 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,6 @@ tags
.idea

.vscode/*
.hierarchy/
.softhsm-tokens/

# ProxySQL log files
test/proxysql/*.log*
1 change: 0 additions & 1 deletion ca/ca_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,6 @@ func TestRejectValidityTooLong(t *testing.T) {
testCtx.fc)
test.AssertNotError(t, err, "Failed to create CA")

// This time is a few minutes before the notAfter in testdata/ca_cert.pem
future, err := time.Parse(time.RFC3339, "2025-02-10T00:30:00Z")

test.AssertNotError(t, err, "Failed to parse time")
Expand Down
33 changes: 0 additions & 33 deletions ca/testdata/ca_cert.pem

This file was deleted.

51 changes: 0 additions & 51 deletions ca/testdata/ca_key.pem

This file was deleted.

Binary file removed ca/testdata/dupe_name.der.csr
Binary file not shown.
Binary file removed ca/testdata/no_cn.der.csr
Binary file not shown.
Binary file removed ca/testdata/no_san.der.csr
Binary file not shown.
44 changes: 4 additions & 40 deletions ca/testdata/testcsr.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,53 +3,17 @@
package main

import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"log"
"os"
)

// A 2048-bit RSA private key
var rsaPrivateKey = `-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA5cpXqfCaUDD+hf93j5jxbrhK4jrJAzfAEjeZj/Lx5Rv/7eEO
uhS2DdCU2is82vR6yJ7EidUYVz/nUAjSTP7JIEsbyvfsfACABbqRyGltHlJnULVH
y/EMjt9xKZf17T8tOLHVUEAJTxsvjKn4TMIQJTNrAqm/lNrUXmCIR41Go+3RBGC6
YdAKEwcZMCzrjQGF06mC6/6xMmYMSMd6+VQRFIPpuPK/6BBp1Tgju2LleRC5uatj
QcFOoilGkfh1RnZp3GJ7q58KaqHiPmjl31rkY5vS3LP7yfU5TRBcxCSG8l8LKuRt
MArkbTEtj3PkDjbipL/SkLrZ28e5w9Egl4g1MwIDAQABAoIBABZqY5zPPK5f6SQ3
JHmciMitL5jb9SncMV9VjyRMpa4cyh1xW9dpF81HMI4Ls7cELEoPuspbQDGaqTzU
b3dVT1dYHFDzWF1MSzDD3162cg+IKE3mMSfCzt/NCiPtj+7hv86NAmr+pCnUVBIb
rn4GXD7UwjaTSn4Bzr+aGREpxd9Nr0JdNQwxVHZ75A92vTihCfaXyMCjhW3JEpF9
N89XehgidoGgtUxxeeb+WsO3nvVBpLv/HDxMTx/IDzvSA5nLlYMcqVzb7IJoeAQu
og0WJKlniYzvIdoQ6/hGydAW5sKd0qWh0JPYs7uLKAWrdAWvrFAp7//fYKVamalU
8pUu/WkCgYEA+tcTQ3qTnVh41O9YeM/7NULpIkuCAlR+PBRky294zho9nGQIPdaW
VNvyqqjLaHaXJVokYHbU4hDk6RbrhoWVd4Po/5g9cUkT1f6nrdZGRkg4XOCzHWvV
Yrqh3eYYX4bdiH5EhB78m0rrbjHfd7SF3cdYNzOUS2kJvCInYC6zPx8CgYEA6oRr
UhZFuoqRsEb28ELM8sHvdIMA/C3aWCu+nUGQ4gHSEb4uvuOD/7tQNuCaBioiXVPM
/4hjk9jHJcjYf5l33ANqIP7JiYAt4rzTWXF3iS6kQOhQhjksSlSnWqw0Uu1DtlpG
rzeG1ZkBuwH7Bx0yj4sGSz5sAvyF44aRsE6AC20CgYEArafWO0ISDb1hMbFdo44B
ELd45Pg3UluiZP+NZFWQ4cbC3pFWL1FvE+KNll5zK6fmLcLBKlM6QCOIBmKKvb+f
YXVeCg0ghFweMmkxNqUAU8nN02bwOa8ctFQWmaOhPgkFN2iLEJjPMsdkRA6c8ad1
gbtvNBAuWyKlzawrbGgISesCgYBkGEjGLINubx5noqJbQee/5U6S6CdPezKqV2Fw
NT/ldul2cTn6d5krWYOPKKYU437vXokst8XooKm/Us41CAfEfCCcHKNgcLklAXsj
ve5LOwEYQw+7ekORJjiX1tAuZN51wmpQ9t4x5LB8ZQgDrU6bPbdd/jKTw7xRtGoS
Wi8EsQKBgG8iGy3+kVBIjKHxrN5jVs3vj/l/fQL0WRMLCMmVuDBfsKyy3f9n8R1B
/KdwoyQFwsLOyr5vAjiDgpFurXQbVyH4GDFiJGS1gb6MNcinwSTpsbOLLV7zgibX
A2NgiQ+UeWMia16dZVd6gGDlY3lQpeyLdsdDd+YppNfy9vedjbvT
-----END RSA PRIVATE KEY-----`

// NISTP256 ECDSA private key
var ecdsaPrivateKey = `-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIKwK8ik0Zgw26bWaGuNYa/QAtCDRwpOPS5FIhbwuFqWuoAoGCCqGSM49
AwEHoUQDQgAEfkxXCNEy4/zfwQ4arciDYQql7/+ftYvf51JTLCJAFu8kWKvNBENT
X8ays994FANu2VsJTF5Ud5JPYWHT87hjAA==
-----END EC PRIVATE KEY-----`

func main() {
block, _ := pem.Decode([]byte(rsaPrivateKey))
rsaPriv, err := x509.ParsePKCS1PrivateKey(block.Bytes)
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
log.Fatalf("Failed to parse private key: %s", err)
}
Expand All @@ -65,7 +29,7 @@ func main() {
"Capitalizedletters.COM",
},
}
csr, err := x509.CreateCertificateRequest(rand.Reader, req, rsaPriv)
csr, err := x509.CreateCertificateRequest(rand.Reader, req, priv)
if err != nil {
log.Fatalf("unable to create CSR: %s", err)
}
Expand Down
77 changes: 18 additions & 59 deletions cmd/boulder-wfe2/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,77 +3,36 @@ package notmain
import (
"crypto/x509"
"encoding/pem"
"os"
"testing"

"github.com/letsencrypt/boulder/core"
"github.com/letsencrypt/boulder/test"
)

func TestLoadChain_Valid(t *testing.T) {
issuer, chainPEM, err := loadChain([]string{
"../../test/test-ca-cross.pem",
"../../test/test-root2.pem",
func TestLoadChain(t *testing.T) {
// Most of loadChain's logic is implemented in issuance.LoadChain, so this
// test only covers the construction of the PEM bytes.
_, chainPEM, err := loadChain([]string{
"../../test/hierarchy/int-e1.cert.pem",
"../../test/hierarchy/root-x2-cross.cert.pem",
"../../test/hierarchy/root-x1.cert.pem",
})
test.AssertNotError(t, err, "Should load valid chain")

expectedIssuer, err := core.LoadCert("../../test/test-ca-cross.pem")
test.AssertNotError(t, err, "Failed to load test issuer")

chainIssuerPEM, rest := pem.Decode(chainPEM)
test.AssertNotNil(t, chainIssuerPEM, "Failed to decode chain PEM")
parsedIssuer, err := x509.ParseCertificate(chainIssuerPEM.Bytes)
// Parse the first certificate in the PEM blob.
certPEM, rest := pem.Decode(chainPEM)
test.AssertNotNil(t, certPEM, "Failed to decode chain PEM")
_, err = x509.ParseCertificate(certPEM.Bytes)
test.AssertNotError(t, err, "Failed to parse chain PEM")

// The three versions of the intermediate (the one loaded by us, the one
// returned by loadChain, and the one parsed from the chain) should be equal.
test.AssertByteEquals(t, issuer.Raw, expectedIssuer.Raw)
test.AssertByteEquals(t, parsedIssuer.Raw, expectedIssuer.Raw)
// Parse the second certificate in the PEM blob.
certPEM, rest = pem.Decode(rest)
test.AssertNotNil(t, certPEM, "Failed to decode chain PEM")
_, err = x509.ParseCertificate(certPEM.Bytes)
test.AssertNotError(t, err, "Failed to parse chain PEM")

// The chain should contain nothing else.
rootIssuerPEM, _ := pem.Decode(rest)
if rootIssuerPEM != nil {
certPEM, rest = pem.Decode(rest)
if certPEM != nil || len(rest) != 0 {
t.Error("Expected chain PEM to contain one cert and nothing else")
}
}

func TestLoadChain_TooShort(t *testing.T) {
_, _, err := loadChain([]string{"/path/to/one/cert.pem"})
test.AssertError(t, err, "Should reject too-short chain")
}

func TestLoadChain_Unloadable(t *testing.T) {
_, _, err := loadChain([]string{
"does-not-exist.pem",
"../../test/test-root2.pem",
})
test.AssertError(t, err, "Should reject unloadable chain")

_, _, err = loadChain([]string{
"../../test/test-ca-cross.pem",
"does-not-exist.pem",
})
test.AssertError(t, err, "Should reject unloadable chain")

invalidPEMFile, _ := os.CreateTemp("", "invalid.pem")
err = os.WriteFile(invalidPEMFile.Name(), []byte(""), 0640)
test.AssertNotError(t, err, "Error writing invalid PEM tmp file")
_, _, err = loadChain([]string{
invalidPEMFile.Name(),
"../../test/test-root2.pem",
})
test.AssertError(t, err, "Should reject unloadable chain")
}

func TestLoadChain_InvalidSig(t *testing.T) {
_, _, err := loadChain([]string{
"../../test/test-root2.pem",
"../../test/test-ca-cross.pem",
})
test.AssertError(t, err, "Should reject invalid signature")
}

func TestLoadChain_NoRoot(t *testing.T) {
// TODO(#5251): Implement this when we have a hierarchy which includes two
// CA certs, neither of which is a root.
}
6 changes: 2 additions & 4 deletions cmd/ceremony/cert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ import (
"testing"
"time"

"github.com/miekg/pkcs11"

"github.com/letsencrypt/boulder/pkcs11helpers"
"github.com/letsencrypt/boulder/test"
"github.com/miekg/pkcs11"
)

// samplePubkey returns a slice of bytes containing an encoded
Expand Down Expand Up @@ -575,9 +576,6 @@ func TestLoadCert(t *testing.T) {

_, err = loadCert("../../test/hierarchy/int-e1.key.pem")
test.AssertError(t, err, "should have failed when trying to parse a private key")

_, err = loadCert("../../test/test-root.pubkey.pem")
test.AssertError(t, err, "should have failed when trying to parse a public key")
}

func TestGenerateSKID(t *testing.T) {
Expand Down
2 changes: 1 addition & 1 deletion cmd/ceremony/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import (
)

func TestLoadPubKey(t *testing.T) {
_, _, err := loadPubKey("../../test/test-root.pubkey.pem")
_, _, err := loadPubKey("../../test/test-ca.pubkey.pem")
test.AssertNotError(t, err, "should not have errored")

_, _, err = loadPubKey("../../test/hierarchy/int-e1.key.pem")
Expand Down
Loading

0 comments on commit 324ef96

Please sign in to comment.