Skip to content

Commit f47a591

Browse files
authored
Update certificates used in handlers_test.go (#218)
* modify gen.go to generate two chains with intermediates * generate new chain with intermediate * regenerate chain * use the new chain for addWhiteSpace tests * address comments
1 parent 2940bba commit f47a591

8 files changed

+294
-17
lines changed

internal/scti/handlers_test.go

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ import (
2020
"context"
2121
"crypto"
2222
"crypto/x509"
23+
"encoding/base64"
2324
"encoding/hex"
2425
"encoding/json"
26+
"encoding/pem"
2527
"fmt"
2628
"io"
2729
"net/http"
@@ -147,7 +149,7 @@ func (info handlerTestInfo) postHandlers(t *testing.T) pathHandlers {
147149
}
148150

149151
func TestPostHandlersRejectGet(t *testing.T) {
150-
info := setupTest(t, []string{testdata.FakeCACertPEM}, nil)
152+
info := setupTest(t, []string{testdata.CACertPEM}, nil)
151153
defer info.mockCtrl.Finish()
152154

153155
// Anything in the post handler list should reject GET
@@ -168,7 +170,7 @@ func TestPostHandlersRejectGet(t *testing.T) {
168170
}
169171

170172
func TestGetHandlersRejectPost(t *testing.T) {
171-
info := setupTest(t, []string{testdata.FakeCACertPEM}, nil)
173+
info := setupTest(t, []string{testdata.CACertPEM}, nil)
172174
defer info.mockCtrl.Finish()
173175

174176
// Anything in the get handler list should reject POST.
@@ -201,7 +203,7 @@ func TestPostHandlersFailure(t *testing.T) {
201203
{"wrong-chain", strings.NewReader(`{ "chain": [ "test" ] }`), http.StatusBadRequest},
202204
}
203205

204-
info := setupTest(t, []string{testdata.FakeCACertPEM}, nil)
206+
info := setupTest(t, []string{testdata.CACertPEM}, nil)
205207
defer info.mockCtrl.Finish()
206208
for path, handler := range info.postHandlers(t) {
207209
t.Run(path, func(t *testing.T) {
@@ -277,20 +279,30 @@ func TestAddChainWhitespace(t *testing.T) {
277279
t.Fatalf("Failed to create test signer: %v", err)
278280
}
279281

280-
info := setupTest(t, []string{testdata.FakeCACertPEM}, signer)
282+
info := setupTest(t, []string{testdata.CACertPEM}, signer)
281283
defer info.mockCtrl.Finish()
282284

283285
// Throughout we use variants of a hard-coded POST body derived from a chain of:
284-
pemChain := []string{testdata.LeafSignedByFakeIntermediateCertPEM, testdata.FakeIntermediateCertPEM}
286+
pemChain := []string{testdata.CertFromIntermediate, testdata.IntermediateFromRoot}
287+
cert, rest := pem.Decode([]byte(testdata.CertFromIntermediate))
288+
if len(rest) > 0 {
289+
t.Fatalf("got %d bytes remaining after decoding cert, want 0", len(rest))
290+
}
291+
certB64 := base64.StdEncoding.EncodeToString(cert.Bytes)
292+
intermediate, rest := pem.Decode([]byte(testdata.IntermediateFromRoot))
293+
if len(rest) > 0 {
294+
t.Fatalf("got %d bytes remaining after decoding intermediate, want 0", len(rest))
295+
}
296+
intermediateB64 := base64.StdEncoding.EncodeToString(intermediate.Bytes)
285297

286298
// Break the JSON into chunks:
287299
intro := "{\"chain\""
288300
// followed by colon then the first line of the PEM file
289-
chunk1a := "[\"MIIH6DCCBtCgAwIBAgIIQoIqW4Zvv+swDQYJKoZIhvcNAQELBQAwcjELMAkGA1UE"
301+
chunk1a := "[\"" + certB64[:64]
290302
// straight into rest of first entry
291-
chunk1b := "BhMCR0IxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwGTG9uZG9uMQ8wDQYDVQQKDAZHb29nbGUxDDAKBgNVBAsMA0VuZzEiMCAGA1UEAwwZRmFrZUludGVybWVkaWF0ZUF1dGhvcml0eTAeFw0xNjA1MTMxNDI2NDRaFw0xOTA3MTIxNDI2NDRaMIIBWDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDU1vdW50YWluIFZpZXcxEzARBgNVBAoMCkdvb2dsZSBJbmMxFTATBgNVBAMMDCouZ29vZ2xlLmNvbTGBwzCBwAYDVQQEDIG4UkZDNTI4MCBzNC4yLjEuOSAnVGhlIHBhdGhMZW5Db25zdHJhaW50IGZpZWxkIC4uLiBnaXZlcyB0aGUgbWF4aW11bSBudW1iZXIgb2Ygbm9uLXNlbGYtaXNzdWVkIGludGVybWVkaWF0ZSBjZXJ0aWZpY2F0ZXMgdGhhdCBtYXkgZm9sbG93IHRoaXMgY2VydGlmaWNhdGUgaW4gYSB2YWxpZCBjZXJ0aWZpY2F0aW9uIHBhdGguJzEqMCgGA1UEKgwhSW50ZXJtZWRpYXRlIENBIGNlcnQgdXNlZCB0byBzaWduMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAExAk5hPUVjRJUsgKc+QHibTVH1A3QEWFmCTUdyxIUlbI//zW9Io5N/DhQLSLWmB7KoCOvpJZ+MtGCXzFX+yj/N6OCBGMwggRfMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjCCA0IGA1UdEQSCAzkwggM1ggwqLmdvb2dsZS5jb22CDSouYW5kcm9pZC5jb22CFiouYXBwZW5naW5lLmdvb2dsZS5jb22CEiouY2xvdWQuZ29vZ2xlLmNvbYIWKi5nb29nbGUtYW5hbHl0aWNzLmNvbYILKi5nb29nbGUuY2GCCyouZ29vZ2xlLmNsgg4qLmdvb2dsZS5jby5pboIOKi5nb29nbGUuY28uanCCDiouZ29vZ2xlLmNvLnVrgg8qLmdvb2dsZS5jb20uYXKCDyouZ29vZ2xlLmNvbS5hdYIPKi5nb29nbGUuY29tLmJygg8qLmdvb2dsZS5jb20uY2+CDyouZ29vZ2xlLmNvbS5teIIPKi5nb29nbGUuY29tLnRygg8qLmdvb2dsZS5jb20udm6CCyouZ29vZ2xlLmRlggsqLmdvb2dsZS5lc4ILKi5nb29nbGUuZnKCCyouZ29vZ2xlLmh1ggsqLmdvb2dsZS5pdIILKi5nb29nbGUubmyCCyouZ29vZ2xlLnBsggsqLmdvb2dsZS5wdIISKi5nb29nbGVhZGFwaXMuY29tgg8qLmdvb2dsZWFwaXMuY26CFCouZ29vZ2xlY29tbWVyY2UuY29tghEqLmdvb2dsZXZpZGVvLmNvbYIMKi5nc3RhdGljLmNugg0qLmdzdGF0aWMuY29tggoqLmd2dDEuY29tggoqLmd2dDIuY29tghQqLm1ldHJpYy5nc3RhdGljLmNvbYIMKi51cmNoaW4uY29tghAqLnVybC5nb29nbGUuY29tghYqLnlvdXR1YmUtbm9jb29raWUuY29tgg0qLnlvdXR1YmUuY29tghYqLnlvdXR1YmVlZHVjYXRpb24uY29tggsqLnl0aW1nLmNvbYIaYW5kcm9pZC5jbGllbnRzLmdvb2dsZS5jb22CC2FuZHJvaWQuY29tggRnLmNvggZnb28uZ2yCFGdvb2dsZS1hbmFseXRpY3MuY29tggpnb29nbGUuY29tghJnb29nbGVjb21tZXJjZS5jb22CCnVyY2hpbi5jb22CCHlvdXR1LmJlggt5b3V0dWJlLmNvbYIUeW91dHViZWVkdWNhdGlvbi5jb20wDAYDVR0PBAUDAweAADBoBggrBgEFBQcBAQRcMFowKwYIKwYBBQUHMAKGH2h0dHA6Ly9wa2kuZ29vZ2xlLmNvbS9HSUFHMi5jcnQwKwYIKwYBBQUHMAGGH2h0dHA6Ly9jbGllbnRzMS5nb29nbGUuY29tL29jc3AwHQYDVR0OBBYEFNv0bmPu4ty+vzhgT5gx0GRE8WPYMAwGA1UdEwEB/wQCMAAwIQYDVR0gBBowGDAMBgorBgEEAdZ5AgUBMAgGBmeBDAECAjAwBgNVHR8EKTAnMCWgI6Ahhh9odHRwOi8vcGtpLmdvb2dsZS5jb20vR0lBRzIuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQAOpm95fThLYPDBdpxOkvUkzhI0cpSVjc8cDNZ4a+5mK1A2Inq+/yLH3ZMsQIMvoDcpj7uYIr+Oxmy0i4/pHg+9it/f9cmqeawA5sqmGnSOZ/lfCYI8+bRbMIULrijCuJwjfGpZZsqOvSBuIOSzRvgGVplcs0dituT2khCFrkblwa/BqIqztvP7LuEmVpjkqt4pC3HvD0XUxs5PIdZZGInfeqymk5feReWHBuPHpPIUObKxmQt+hcw6YsHE+0B84Xtx9BMe4qqUfrqmtWXn9unBwxqSYsCqxHQpQ+70pmuBxlB9s6LStIzE9syaDmUyjxRljKAwINV6z0j7hKQ6MPpE\""
303+
chunk1b := certB64[64:] + "\""
292304
// followed by comma then
293-
chunk2 := "\"MIIDnTCCAoWgAwIBAgIIQoIqW4Zvv+swDQYJKoZIhvcNAQELBQAwcTELMAkGA1UEBhMCR0IxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwGTG9uZG9uMQ8wDQYDVQQKDAZHb29nbGUxDDAKBgNVBAsMA0VuZzEhMB8GA1UEAwwYRmFrZUNlcnRpZmljYXRlQXV0aG9yaXR5MB4XDTE2MDUxMzE0MjY0NFoXDTE5MDcxMjE0MjY0NFowcjELMAkGA1UEBhMCR0IxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UEBwwGTG9uZG9uMQ8wDQYDVQQKDAZHb29nbGUxDDAKBgNVBAsMA0VuZzEiMCAGA1UEAwwZRmFrZUludGVybWVkaWF0ZUF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMqkDHpt6SYi1GcZyClAxr3LRDnn+oQBHbMEFUg3+lXVmEsq/xQO1s4naynV6I05676XvlMh0qPyJ+9GaBxvhHeFtGh4etQ9UEmJj55rSs50wA/IaDh+roKukQxthyTESPPgjqg+DPjh6H+h3Sn00Os6sjh3DxpOphTEsdtb7fmk8J0e2KjQQCjW/GlECzc359b9KbBwNkcAiYFayVHPLaCAdvzYVyiHgXHkEEs5FlHyhe2gNEG/81Io8c3E3DH5JhT9tmVRL3bpgpT8Kr4aoFhU2LXe45YIB1A9DjUm5TrHZ+iNtvE0YfYMR9L9C1HPppmX1CahEhTdog7laE1198UCAwEAAaM4MDYwDwYDVR0jBAgwBoAEAQIDBDASBgNVHRMBAf8ECDAGAQH/AgEAMA8GA1UdDwEB/wQFAwMH/4AwDQYJKoZIhvcNAQELBQADggEBAAHiOgwAvEzhrNMQVAz8a+SsyMIABXQ5P8WbJeHjkIipE4+5ZpkrZVXq9p8wOdkYnOHx4WNi9PVGQbLG9Iufh9fpk8cyyRWDi+V20/CNNtawMq3ClV3dWC98Tj4WX/BXDCeY2jK4jYGV+ds43HYV0ToBmvvrccq/U7zYMGFcQiKBClz5bTE+GMvrZWcO5A/Lh38i2YSF1i8SfDVnAOBlAgZmllcheHpGsWfSnduIllUvTsRvEIsaaqfVLl5QpRXBOq8tbjK85/2g6ear1oxPhJ1w9hds+WTFXkmHkWvKJebY13t3OfSjAyhaRSt8hdzDzHTFwjPjHT8h6dU7/hMdkUg=\""
305+
chunk2 := "\"" + intermediateB64 + "\""
294306
epilog := "]}\n"
295307

296308
req, leafChain := parseChain(t, false, pemChain, info.roots.RawCertificates()[0])
@@ -366,30 +378,30 @@ func TestAddChain(t *testing.T) {
366378
}{
367379
{
368380
descr: "leaf-only",
369-
chain: []string{testdata.LeafSignedByFakeIntermediateCertPEM},
381+
chain: []string{testdata.CertFromIntermediate},
370382
want: http.StatusBadRequest,
371383
},
372384
{
373385
descr: "wrong-entry-type",
374-
chain: []string{testdata.PrecertPEMValid},
386+
chain: []string{testdata.PreCertFromIntermediate},
375387
want: http.StatusBadRequest,
376388
},
377389
{
378390
descr: "backend-storage-fail",
379-
chain: []string{testdata.LeafSignedByFakeIntermediateCertPEM, testdata.FakeIntermediateCertPEM},
391+
chain: []string{testdata.CertFromIntermediate, testdata.IntermediateFromRoot},
380392
toSign: "1337d72a403b6539f58896decba416d5d4b3603bfa03e1f94bb9b4e898af897d",
381393
want: http.StatusInternalServerError,
382394
err: status.Errorf(codes.Internal, "error"),
383395
},
384396
{
385397
descr: "success-without-root",
386-
chain: []string{testdata.LeafSignedByFakeIntermediateCertPEM, testdata.FakeIntermediateCertPEM},
398+
chain: []string{testdata.CertFromIntermediate, testdata.IntermediateFromRoot},
387399
toSign: "1337d72a403b6539f58896decba416d5d4b3603bfa03e1f94bb9b4e898af897d",
388400
want: http.StatusOK,
389401
},
390402
{
391403
descr: "success",
392-
chain: []string{testdata.LeafSignedByFakeIntermediateCertPEM, testdata.FakeIntermediateCertPEM, testdata.FakeCACertPEM},
404+
chain: []string{testdata.CertFromIntermediate, testdata.IntermediateFromRoot, testdata.CACertPEM},
393405
toSign: "1337d72a403b6539f58896decba416d5d4b3603bfa03e1f94bb9b4e898af897d",
394406
want: http.StatusOK,
395407
},
@@ -400,7 +412,7 @@ func TestAddChain(t *testing.T) {
400412
t.Fatalf("Failed to create test signer: %v", err)
401413
}
402414

403-
info := setupTest(t, []string{testdata.FakeCACertPEM}, signer)
415+
info := setupTest(t, []string{testdata.CACertPEM}, signer)
404416
defer info.mockCtrl.Finish()
405417

406418
for _, test := range tests {

internal/testdata/certificates.go

Lines changed: 157 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ package testdata
1616

1717
import _ "embed"
1818

19-
// This file holds test certificates. It contain five issuance chains.
19+
// This file holds test certificates. It contains six issuance chains.
2020
// TODO(phboneff): clean this and make use of a single chain if possible.
2121

2222
// Issuance chain 1
@@ -287,6 +287,160 @@ var PreCertFromPreIntermediate string
287287

288288
// Issuance chain 3
289289
// ================
290+
// The next section holds:
291+
// - an intermediate signed with the root above.
292+
// - a pre-cert issued by this intermediate
293+
// - a cert issued by this intermediate
294+
//
295+
// IntermediateFromRoot is an intermedidate cert signed by the root above.
296+
//
297+
// Certificate:
298+
//
299+
// Data:
300+
// Version: 3 (0x2)
301+
// Serial Number: 2 (0x2)
302+
// Signature Algorithm: ecdsa-with-SHA384
303+
// Issuer: C=GB, O=TrustFabric Transparency.dev Test Root Test CA, CN=TrustFabric Transparency.dev Test Root Test CA
304+
// Validity
305+
// Not Before: Dec 5 18:05:50 2024 GMT
306+
// Not After : Dec 5 18:05:50 2029 GMT
307+
// Subject: C=GB, O=TrustFabric Transparency.dev Test Intermediate Test CA, CN=TrustFabric Transparency.dev Test Intermediate Test CA
308+
// Subject Public Key Info:
309+
// Public Key Algorithm: id-ecPublicKey
310+
// Public-Key: (384 bit)
311+
// pub:
312+
// 04:c6:3b:93:72:73:76:1b:f6:16:f6:93:2b:22:c0:
313+
// 1d:8e:e3:c9:1a:64:b8:42:58:0e:72:0a:38:49:84:
314+
// d2:d3:e7:23:52:ee:9d:8a:28:65:73:2e:2e:7e:05:
315+
// 1c:d5:4f:5b:42:37:e3:bb:8f:54:3d:68:a9:c3:07:
316+
// 31:aa:4a:cc:8b:93:d6:a4:31:b2:8e:d0:aa:56:3b:
317+
// 49:ed:07:d3:36:ff:17:50:ad:6d:65:d7:5d:76:70:
318+
// d5:08:f2:95:e0:11:0c
319+
// ASN1 OID: secp384r1
320+
// NIST CURVE: P-384
321+
// X509v3 extensions:
322+
// X509v3 Key Usage: critical
323+
// Certificate Sign, CRL Sign
324+
// X509v3 Basic Constraints: critical
325+
// CA:TRUE
326+
// X509v3 Subject Key Identifier:
327+
// A0:D7:2B:CF:08:6F:C0:07:39:9B:C5:A9:87:1D:F7:CC:7D:6B:6F:29
328+
// X509v3 Authority Key Identifier:
329+
// 77:1D:7C:21:61:2D:C2:05:7D:AA:30:1E:6B:7F:8F:9B:DC:61:20:68
330+
// Signature Algorithm: ecdsa-with-SHA384
331+
// Signature Value:
332+
// 30:65:02:30:13:7b:99:45:f5:f5:c2:8b:bf:b4:83:8c:10:27:
333+
// 5e:50:a7:05:c0:61:8a:50:3f:76:2e:ec:88:71:d7:a7:a1:46:
334+
// 56:3b:3a:bc:e7:74:22:94:56:91:95:80:a5:a1:43:08:02:31:
335+
// 00:81:a0:12:84:45:6f:35:b3:3d:9b:98:ca:28:33:d2:b9:bf:
336+
// 8b:82:f7:a9:77:ee:2e:9f:90:0f:36:00:3e:c8:63:4c:1c:6c:
337+
// de:e8:79:1a:32:44:4a:4e:47:6e:af:a3:24
338+
//
339+
//go:embed test_intermediate_ca_cert.pem
340+
var IntermediateFromRoot string
341+
342+
// CertFromIntermediate is a leaf cert signed by the intermediate above.
343+
//
344+
// Certificate:
345+
//
346+
// Data:
347+
// Version: 3 (0x2)
348+
// Serial Number: 100 (0x64)
349+
// Signature Algorithm: ecdsa-with-SHA384
350+
// Issuer: C=GB, O=TrustFabric Transparency.dev Test Intermediate Test CA, CN=TrustFabric Transparency.dev Test Intermediate Test CA
351+
// Validity
352+
// Not Before: Dec 5 18:05:50 2024 GMT
353+
// Not After : Dec 5 18:05:50 2025 GMT
354+
// Subject: C=GB, ST=London, L=London, O=TrustFabric Transparency.dev Test, OU=TrustFabric, CN=test.transparency.dev
355+
// Subject Public Key Info:
356+
// Public Key Algorithm: id-ecPublicKey
357+
// Public-Key: (384 bit)
358+
// pub:
359+
// 04:f4:15:a1:50:6c:d3:96:ad:9c:a0:f6:c0:90:4f:
360+
// 05:13:64:2d:bf:2f:7a:86:4e:c8:25:c3:7d:9e:6f:
361+
// c3:44:b6:29:98:01:f4:d5:06:58:c9:cc:82:21:79:
362+
// 97:88:3f:af:4c:bd:93:92:39:08:18:5f:81:c4:0b:
363+
// a0:ea:83:f8:6d:81:9a:68:20:bf:ad:2c:9b:1f:02:
364+
// 08:cc:c2:16:a3:18:92:62:fa:b5:b0:da:ba:8b:98:
365+
// 89:0a:d1:8c:65:3f:62
366+
// ASN1 OID: secp384r1
367+
// NIST CURVE: P-384
368+
// X509v3 extensions:
369+
// X509v3 Key Usage: critical
370+
// Digital Signature, Key Encipherment
371+
// X509v3 Extended Key Usage:
372+
// TLS Web Server Authentication
373+
// X509v3 Basic Constraints: critical
374+
// CA:FALSE
375+
// X509v3 Authority Key Identifier:
376+
// A0:D7:2B:CF:08:6F:C0:07:39:9B:C5:A9:87:1D:F7:CC:7D:6B:6F:29
377+
// X509v3 Subject Alternative Name:
378+
// DNS:test.transparency.dev
379+
// Signature Algorithm: ecdsa-with-SHA384
380+
// Signature Value:
381+
// 30:66:02:31:00:fd:08:f9:21:b5:a6:e0:32:aa:d0:aa:e2:07:
382+
// 9c:fd:cc:26:b5:9a:bc:27:60:4f:ea:52:76:9f:cd:5c:23:b0:
383+
// fd:9e:5d:e9:73:a4:8a:1a:b5:b7:12:c2:69:e7:f1:bd:eb:02:
384+
// 31:00:af:09:6b:61:78:6c:14:a3:9d:bd:e4:bf:91:43:a2:98:
385+
// a2:50:27:5d:2c:df:12:38:cd:b7:3d:d6:73:69:3a:5d:54:9c:
386+
// 58:63:35:3c:39:78:26:37:08:75:3f:4b:fb:68
387+
//
388+
//go:embed test_leaf_cert_signed_by_intermediate.pem
389+
var CertFromIntermediate string
390+
391+
// PreCertFromIntrmediate is a pre-cert signed by the intermediate above.
392+
//
393+
// Certificate:
394+
//
395+
// Data:
396+
// Version: 3 (0x2)
397+
// Serial Number: 200 (0xc8)
398+
// Signature Algorithm: ecdsa-with-SHA384
399+
// Issuer: C=GB, O=TrustFabric Transparency.dev Test Intermediate Test CA, CN=TrustFabric Transparency.dev Test Intermediate Test CA
400+
// Validity
401+
// Not Before: Dec 5 18:05:50 2024 GMT
402+
// Not After : Dec 5 18:05:50 2025 GMT
403+
// Subject: C=GB, ST=London, L=London, O=TrustFabric Transparency.dev Test, OU=TrustFabric, CN=test.transparency.dev
404+
// Subject Public Key Info:
405+
// Public Key Algorithm: id-ecPublicKey
406+
// Public-Key: (384 bit)
407+
// pub:
408+
// 04:f4:15:a1:50:6c:d3:96:ad:9c:a0:f6:c0:90:4f:
409+
// 05:13:64:2d:bf:2f:7a:86:4e:c8:25:c3:7d:9e:6f:
410+
// c3:44:b6:29:98:01:f4:d5:06:58:c9:cc:82:21:79:
411+
// 97:88:3f:af:4c:bd:93:92:39:08:18:5f:81:c4:0b:
412+
// a0:ea:83:f8:6d:81:9a:68:20:bf:ad:2c:9b:1f:02:
413+
// 08:cc:c2:16:a3:18:92:62:fa:b5:b0:da:ba:8b:98:
414+
// 89:0a:d1:8c:65:3f:62
415+
// ASN1 OID: secp384r1
416+
// NIST CURVE: P-384
417+
// X509v3 extensions:
418+
// X509v3 Key Usage: critical
419+
// Digital Signature, Key Encipherment
420+
// X509v3 Extended Key Usage:
421+
// TLS Web Server Authentication
422+
// X509v3 Basic Constraints: critical
423+
// CA:FALSE
424+
// X509v3 Authority Key Identifier:
425+
// A0:D7:2B:CF:08:6F:C0:07:39:9B:C5:A9:87:1D:F7:CC:7D:6B:6F:29
426+
// X509v3 Subject Alternative Name:
427+
// DNS:test.transparency.dev
428+
// CT Precertificate Poison: critical
429+
// NULL
430+
// Signature Algorithm: ecdsa-with-SHA384
431+
// Signature Value:
432+
// 30:64:02:30:51:d4:2e:f7:e0:50:06:e5:a5:97:1c:d2:f9:4f:
433+
// 6e:c2:3b:e0:db:59:16:db:8d:1b:a8:c4:c6:b8:0a:4f:a3:0d:
434+
// 38:43:72:d7:f8:e6:60:e3:b8:44:f2:1f:37:56:30:cb:02:30:
435+
// 13:62:9c:60:c9:57:d1:b9:e0:43:f7:cf:2c:99:eb:04:84:f7:
436+
// de:af:fd:d6:1a:63:90:14:4c:53:40:dd:28:0b:aa:69:59:87:
437+
// 78:8b:65:9e:00:63:75:7a:4c:a0:9f:ca
438+
//
439+
//go:embed test_leaf_pre_cert_signed_by_intermediate.pem
440+
var PreCertFromIntermediate string
441+
442+
// Issuance chain 4
443+
// ================
290444
// The next section holds a self signed root, an intermediate, and a leaf cert.
291445
//
292446
// FakeCACertPEM is a test CA cert for testing.
@@ -574,7 +728,7 @@ D0XUxs5PIdZZGInfeqymk5feReWHBuPHpPIUObKxmQt+hcw6YsHE+0B84Xtx9BMe
574728
INV6z0j7hKQ6MPpE
575729
-----END CERTIFICATE-----`
576730

577-
// Issuance chain 4
731+
// Issuance chain 5
578732
// ================
579733
// The next section holds a self signed root, intermediate certs
580734
// with various policy constraints, and a leaf cert.
@@ -864,7 +1018,7 @@ Brd3sq2ogxuDOGReOiVR6VcfAFNy2wgRZT30AiEAoU5dtZqLEG4Voyq92YCRlnwa
8641018
T4+R3ESfE/9X8F7OMjQ=
8651019
-----END CERTIFICATE-----`
8661020

867-
// Issuance chain 5
1021+
// Issuance chain 6
8681022
// ================
8691023
// The next section holds a real world intermediate and leaf cert.
8701024

internal/testdata/gen/gen.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ func main() {
103103

104104
genLeaves(rootCert, rootPrivKey, *notBefore)
105105
genPreIssuerAndLeaves(rootCert, rootPrivKey, *notBefore)
106+
genIntermediateAndLeaves(rootCert, rootPrivKey, *notBefore)
106107
}
107108

108109
// genLeaves generates a cert and a pre-cert.
@@ -135,6 +136,52 @@ func genLeaves(rootCert *x509.Certificate, rootPrivKey *ecdsa.PrivateKey, notBef
135136

136137
}
137138

139+
// genIntermediateAndLeaves generates an intermediate cert, a cert, a pre-cert.
140+
func genIntermediateAndLeaves(rootCert *x509.Certificate, rootPrivKey *ecdsa.PrivateKey, notBefore time.Time) {
141+
// Generate a new ECDSA intermediate CA private key.
142+
intermediatePrivKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
143+
if err != nil {
144+
klog.Fatalf("Failed to generate intermediate CA private key: %v", err)
145+
}
146+
if err := saveECDSAPrivateKeyPEM(intermediatePrivKey, path.Join(*outputPath, "test_intermediate_ca_private_key.pem")); err != nil {
147+
klog.Fatalf("Failed to save intermediate CA private key: %v", err)
148+
}
149+
150+
// Generate a new intermediate CA certificate with CT extension.
151+
intermediateCert, err := intermediateCACert(rootCert, rootPrivKey, intermediatePrivKey, false, notBefore)
152+
if err != nil {
153+
klog.Fatalf("Failed to generate intermediate CA certificate: %v", err)
154+
}
155+
if err := saveCertificatePEM(intermediateCert, path.Join(*outputPath, "test_intermediate_ca_cert.pem")); err != nil {
156+
klog.Fatalf("Failed to save intermediate CA certificate: %v", err)
157+
}
158+
159+
// Generate a new ECDSA leaf certificate signing private key.
160+
leafCertPrivateKey, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
161+
if err != nil {
162+
klog.Fatalf("Failed to generate leaf certificate signing private key: %v", err)
163+
}
164+
if err := saveECDSAPrivateKeyPEM(leafCertPrivateKey, path.Join(*outputPath, "test_leaf_signed_by_intermediate_signing_private_key.pem")); err != nil {
165+
klog.Fatalf("Failed to save leaf certificate signing private key: %v", err)
166+
}
167+
168+
chainGenerator := newChainGenerator(intermediateCert, intermediatePrivKey, leafCertPrivateKey.Public())
169+
leafCert, err := chainGenerator.certificate(100, false, notBefore)
170+
if err != nil {
171+
klog.Fatalf("Failed to generate leaf certificate: %v", err)
172+
}
173+
if err := saveCertificatePEM(leafCert, path.Join(*outputPath, "test_leaf_cert_signed_by_intermediate.pem")); err != nil {
174+
klog.Fatalf("Failed to save leaf cert: %v", err)
175+
}
176+
leafPreCert, err := chainGenerator.certificate(200, true, notBefore)
177+
if err != nil {
178+
klog.Fatalf("Failed to generate leaf pre-certificate: %v", err)
179+
}
180+
if err := saveCertificatePEM(leafPreCert, path.Join(*outputPath, "test_leaf_pre_cert_signed_by_intermediate.pem")); err != nil {
181+
klog.Fatalf("Failed to save leaf pre-cert: %v", err)
182+
}
183+
}
184+
138185
// genPreIssuerAndLeaves generates a pre-issuer intermediate cert, a cert,
139186
// a pre-cert.
140187
func genPreIssuerAndLeaves(rootCert *x509.Certificate, rootPrivKey *ecdsa.PrivateKey, notBefore time.Time) {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIICnjCCAiSgAwIBAgIBAjAKBggqhkjOPQQDAzB/MQswCQYDVQQGEwJHQjE3MDUG
3+
A1UEChMuVHJ1c3RGYWJyaWMgVHJhbnNwYXJlbmN5LmRldiBUZXN0IFJvb3QgVGVz
4+
dCBDQTE3MDUGA1UEAxMuVHJ1c3RGYWJyaWMgVHJhbnNwYXJlbmN5LmRldiBUZXN0
5+
IFJvb3QgVGVzdCBDQTAeFw0yNDEyMDUxODA1NTBaFw0yOTEyMDUxODA1NTBaMIGP
6+
MQswCQYDVQQGEwJHQjE/MD0GA1UEChM2VHJ1c3RGYWJyaWMgVHJhbnNwYXJlbmN5
7+
LmRldiBUZXN0IEludGVybWVkaWF0ZSBUZXN0IENBMT8wPQYDVQQDEzZUcnVzdEZh
8+
YnJpYyBUcmFuc3BhcmVuY3kuZGV2IFRlc3QgSW50ZXJtZWRpYXRlIFRlc3QgQ0Ew
9+
djAQBgcqhkjOPQIBBgUrgQQAIgNiAATGO5Nyc3Yb9hb2kysiwB2O48kaZLhCWA5y
10+
CjhJhNLT5yNS7p2KKGVzLi5+BRzVT1tCN+O7j1Q9aKnDBzGqSsyLk9akMbKO0KpW
11+
O0ntB9M2/xdQrW1l1112cNUI8pXgEQyjYzBhMA4GA1UdDwEB/wQEAwIBBjAPBgNV
12+
HRMBAf8EBTADAQH/MB0GA1UdDgQWBBSg1yvPCG/ABzmbxamHHffMfWtvKTAfBgNV
13+
HSMEGDAWgBR3HXwhYS3CBX2qMB5rf4+b3GEgaDAKBggqhkjOPQQDAwNoADBlAjAT
14+
e5lF9fXCi7+0g4wQJ15QpwXAYYpQP3Yu7Ihx16ehRlY7OrzndCKUVpGVgKWhQwgC
15+
MQCBoBKERW81sz2bmMooM9K5v4uC96l37i6fkA82AD7IY0wcbN7oeRoyREpOR26v
16+
oyQ=
17+
-----END CERTIFICATE-----

0 commit comments

Comments
 (0)