Skip to content

Commit 565af26

Browse files
committed
move entryFromChain to x509util
# Conflicts: # internal/hammer/loadtest/workers.go
1 parent 9a777ac commit 565af26

File tree

5 files changed

+82
-158
lines changed

5 files changed

+82
-158
lines changed

internal/hammer/loadtest/workers.go

Lines changed: 1 addition & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package loadtest
1616

1717
import (
1818
"context"
19-
"crypto/sha256"
2019
"crypto/x509"
2120
"encoding/base64"
2221
"encoding/json"
@@ -32,7 +31,6 @@ import (
3231
"github.com/transparency-dev/static-ct/internal/types/rfc6962"
3332
"github.com/transparency-dev/static-ct/internal/x509util"
3433
"github.com/transparency-dev/trillian-tessera/api/layout"
35-
"github.com/transparency-dev/trillian-tessera/ctonly"
3634
"k8s.io/klog/v2"
3735
)
3836

@@ -360,7 +358,7 @@ func (v *MMDVerifier) Run(ctx context.Context) {
360358
if err != nil {
361359
panic(fmt.Sprintf("Failed to parse certificates: %v", err))
362360
}
363-
entry, err := entryFromChain(certs, false, leafMMD.timestamp)
361+
entry, err := x509util.EntryFromChain(certs, false, leafMMD.timestamp)
364362
if err != nil {
365363
panic(fmt.Sprintf("Failed to create entry from chain: %v", err))
366364
}
@@ -380,78 +378,3 @@ func (v *MMDVerifier) Kill() {
380378
v.cancel()
381379
}
382380
}
383-
384-
// entryFromChain generates an Entry from a chain and timestamp.
385-
// Copied from certificate-transparency-go/serialization.go and internal/scti/handlers.go.
386-
// TODO(phboneff): move in a different file maybe?
387-
func entryFromChain(chain []*x509.Certificate, isPrecert bool, timestamp uint64) (*ctonly.Entry, error) {
388-
leaf := ctonly.Entry{
389-
IsPrecert: isPrecert,
390-
Timestamp: timestamp,
391-
}
392-
393-
if len(chain) > 1 {
394-
issuersChain := make([][32]byte, len(chain)-1)
395-
for i, c := range chain[1:] {
396-
issuersChain[i] = sha256.Sum256(c.Raw)
397-
}
398-
leaf.FingerprintsChain = issuersChain
399-
}
400-
401-
if !isPrecert {
402-
leaf.Certificate = chain[0].Raw
403-
return &leaf, nil
404-
}
405-
406-
// Pre-certs are more complicated. First, parse the leaf pre-cert and its
407-
// putative issuer.
408-
if len(chain) < 2 {
409-
return nil, fmt.Errorf("no issuer cert available for precert leaf building")
410-
}
411-
issuer := chain[1]
412-
cert := chain[0]
413-
414-
var preIssuer *x509.Certificate
415-
if isPreIssuer(issuer) {
416-
// Replace the cert's issuance information with details from the pre-issuer.
417-
preIssuer = issuer
418-
419-
// The issuer of the pre-cert is not going to be the issuer of the final
420-
// cert. Change to use the final issuer's key hash.
421-
if len(chain) < 3 {
422-
return nil, fmt.Errorf("no issuer cert available for pre-issuer")
423-
}
424-
issuer = chain[2]
425-
}
426-
427-
// Next, post-process the DER-encoded TBSCertificate, to remove the CT poison
428-
// extension and possibly update the issuer field.
429-
defangedTBS, err := x509util.BuildPrecertTBS(cert.RawTBSCertificate, preIssuer)
430-
if err != nil {
431-
return nil, fmt.Errorf("failed to remove poison extension: %v", err)
432-
}
433-
434-
leaf.Precertificate = cert.Raw
435-
// TODO(phboneff): do we need this?
436-
// leaf.PrecertSigningCert = issuer.Raw
437-
leaf.Certificate = defangedTBS
438-
439-
issuerKeyHash := sha256.Sum256(issuer.RawSubjectPublicKeyInfo)
440-
leaf.IssuerKeyHash = issuerKeyHash[:]
441-
return &leaf, nil
442-
}
443-
444-
// isPreIssuer indicates whether a certificate is a pre-cert issuer with the specific
445-
// certificate transparency extended key usage.
446-
// Copied from certificate-transparency-go/serialization.go and internal/scti/handlers.go.
447-
// TODO(phboneff): unify these.
448-
func isPreIssuer(cert *x509.Certificate) bool {
449-
// Look for the extension in the Extensions field and not ExtKeyUsage
450-
// since crypto/x509 does not recognize this extension as an ExtKeyUsage.
451-
for _, ext := range cert.Extensions {
452-
if rfc6962.OIDExtKeyUsageCertificateTransparency.Equal(ext.Id) {
453-
return true
454-
}
455-
}
456-
return false
457-
}

internal/scti/handlers.go

Lines changed: 1 addition & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package scti
1616

1717
import (
1818
"context"
19-
"crypto/sha256"
2019
"crypto/x509"
2120
"encoding/base64"
2221
"encoding/json"
@@ -36,7 +35,6 @@ import (
3635
"github.com/transparency-dev/static-ct/internal/x509util"
3736
"github.com/transparency-dev/static-ct/modules/dedup"
3837
tessera "github.com/transparency-dev/trillian-tessera"
39-
"github.com/transparency-dev/trillian-tessera/ctonly"
4038
"k8s.io/klog/v2"
4139
)
4240

@@ -280,7 +278,7 @@ func addChainInternal(ctx context.Context, opts *HandlerOptions, log *log, w htt
280278
nanosPerMilli := int64(time.Millisecond / time.Nanosecond)
281279
timeMillis := uint64(opts.TimeSource.Now().UnixNano() / nanosPerMilli)
282280

283-
entry, err := entryFromChain(chain, isPrecert, timeMillis)
281+
entry, err := x509util.EntryFromChain(chain, isPrecert, timeMillis)
284282
if err != nil {
285283
return http.StatusBadRequest, fmt.Errorf("failed to build MerkleTreeLeaf: %s", err)
286284
}
@@ -450,77 +448,3 @@ func marshalAndWriteAddChainResponse(sct *rfc6962.SignedCertificateTimestamp, w
450448

451449
return nil
452450
}
453-
454-
// entryFromChain generates an Entry from a chain and timestamp.
455-
// copied from certificate-transparency-go/serialization.go
456-
// TODO(phboneff): move to ct.go
457-
// TODO(phboneff): add tests
458-
func entryFromChain(chain []*x509.Certificate, isPrecert bool, timestamp uint64) (*ctonly.Entry, error) {
459-
leaf := ctonly.Entry{
460-
IsPrecert: isPrecert,
461-
Timestamp: timestamp,
462-
}
463-
464-
if len(chain) > 1 {
465-
issuersChain := make([][32]byte, len(chain)-1)
466-
for i, c := range chain[1:] {
467-
issuersChain[i] = sha256.Sum256(c.Raw)
468-
}
469-
leaf.FingerprintsChain = issuersChain
470-
}
471-
472-
if !isPrecert {
473-
leaf.Certificate = chain[0].Raw
474-
return &leaf, nil
475-
}
476-
477-
// Pre-certs are more complicated. First, parse the leaf pre-cert and its
478-
// putative issuer.
479-
if len(chain) < 2 {
480-
return nil, fmt.Errorf("no issuer cert available for precert leaf building")
481-
}
482-
issuer := chain[1]
483-
cert := chain[0]
484-
485-
var preIssuer *x509.Certificate
486-
if isPreIssuer(issuer) {
487-
// Replace the cert's issuance information with details from the pre-issuer.
488-
preIssuer = issuer
489-
490-
// The issuer of the pre-cert is not going to be the issuer of the final
491-
// cert. Change to use the final issuer's key hash.
492-
if len(chain) < 3 {
493-
return nil, fmt.Errorf("no issuer cert available for pre-issuer")
494-
}
495-
issuer = chain[2]
496-
}
497-
498-
// Next, post-process the DER-encoded TBSCertificate, to remove the CT poison
499-
// extension and possibly update the issuer field.
500-
defangedTBS, err := x509util.BuildPrecertTBS(cert.RawTBSCertificate, preIssuer)
501-
if err != nil {
502-
return nil, fmt.Errorf("failed to remove poison extension: %v", err)
503-
}
504-
505-
leaf.Precertificate = cert.Raw
506-
// TODO(phboneff): do we need this?
507-
// leaf.PrecertSigningCert = issuer.Raw
508-
leaf.Certificate = defangedTBS
509-
510-
issuerKeyHash := sha256.Sum256(issuer.RawSubjectPublicKeyInfo)
511-
leaf.IssuerKeyHash = issuerKeyHash[:]
512-
return &leaf, nil
513-
}
514-
515-
// isPreIssuer indicates whether a certificate is a pre-cert issuer with the specific
516-
// certificate transparency extended key usage.
517-
func isPreIssuer(cert *x509.Certificate) bool {
518-
// Look for the extension in the Extensions field and not ExtKeyUsage
519-
// since crypto/x509 does not recognize this extension as an ExtKeyUsage.
520-
for _, ext := range cert.Extensions {
521-
if rfc6962.OIDExtKeyUsageCertificateTransparency.Equal(ext.Id) {
522-
return true
523-
}
524-
}
525-
return false
526-
}

internal/scti/handlers_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ func parseChain(t *testing.T, isPrecert bool, pemChain []string, root *x509.Cert
326326
fullChain[len(leafChain)] = root
327327
leafChain = fullChain
328328
}
329-
entry, err := entryFromChain(leafChain, isPrecert, fakeTimeMillis)
329+
entry, err := x509util.EntryFromChain(leafChain, isPrecert, fakeTimeMillis)
330330
if err != nil {
331331
t.Fatalf("Failed to create entry")
332332
}

internal/scti/signatures_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -255,7 +255,7 @@ func TestBuildV1MerkleTreeLeafForCert(t *testing.T) {
255255
}
256256

257257
// Use the same cert as the issuer for convenience.
258-
entry, err := entryFromChain([]*x509.Certificate{cert, cert}, false, fixedTimeMillis)
258+
entry, err := x509util.EntryFromChain([]*x509.Certificate{cert, cert}, false, fixedTimeMillis)
259259
if err != nil {
260260
t.Fatalf("buildV1MerkleTreeLeafForCert()=nil,%v; want _,nil", err)
261261
}
@@ -318,7 +318,7 @@ func TestSignV1SCTForPrecertificate(t *testing.T) {
318318
}
319319

320320
// Use the same cert as the issuer for convenience.
321-
entry, err := entryFromChain([]*x509.Certificate{cert, cert}, true, fixedTimeMillis)
321+
entry, err := x509util.EntryFromChain([]*x509.Certificate{cert, cert}, true, fixedTimeMillis)
322322
if err != nil {
323323
t.Fatalf("buildV1MerkleTreeLeafForCert()=nil,%v; want _,nil", err)
324324
}

internal/x509util/ct.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@
1414
package x509util
1515

1616
import (
17+
"crypto/sha256"
1718
"crypto/x509"
1819
"crypto/x509/pkix"
1920
"encoding/asn1"
2021
"errors"
2122
"fmt"
2223
"math/big"
2324
"time"
25+
26+
"github.com/transparency-dev/static-ct/internal/types/rfc6962"
27+
"github.com/transparency-dev/trillian-tessera/ctonly"
2428
)
2529

2630
var (
@@ -191,3 +195,76 @@ func BuildPrecertTBS(tbsData []byte, preIssuer *x509.Certificate) ([]byte, error
191195
func RemoveCTPoison(tbsData []byte) ([]byte, error) {
192196
return BuildPrecertTBS(tbsData, nil)
193197
}
198+
199+
// EntryFromChain generates an Entry from a chain and timestamp.
200+
// copied from certificate-transparency-go/serialization.go
201+
// TODO(phboneff): add tests
202+
func EntryFromChain(chain []*x509.Certificate, isPrecert bool, timestamp uint64) (*ctonly.Entry, error) {
203+
leaf := ctonly.Entry{
204+
IsPrecert: isPrecert,
205+
Timestamp: timestamp,
206+
}
207+
208+
if len(chain) > 1 {
209+
issuersChain := make([][32]byte, len(chain)-1)
210+
for i, c := range chain[1:] {
211+
issuersChain[i] = sha256.Sum256(c.Raw)
212+
}
213+
leaf.FingerprintsChain = issuersChain
214+
}
215+
216+
if !isPrecert {
217+
leaf.Certificate = chain[0].Raw
218+
return &leaf, nil
219+
}
220+
221+
// Pre-certs are more complicated. First, parse the leaf pre-cert and its
222+
// putative issuer.
223+
if len(chain) < 2 {
224+
return nil, fmt.Errorf("no issuer cert available for precert leaf building")
225+
}
226+
issuer := chain[1]
227+
cert := chain[0]
228+
229+
var preIssuer *x509.Certificate
230+
if isPreIssuer(issuer) {
231+
// Replace the cert's issuance information with details from the pre-issuer.
232+
preIssuer = issuer
233+
234+
// The issuer of the pre-cert is not going to be the issuer of the final
235+
// cert. Change to use the final issuer's key hash.
236+
if len(chain) < 3 {
237+
return nil, fmt.Errorf("no issuer cert available for pre-issuer")
238+
}
239+
issuer = chain[2]
240+
}
241+
242+
// Next, post-process the DER-encoded TBSCertificate, to remove the CT poison
243+
// extension and possibly update the issuer field.
244+
defangedTBS, err := BuildPrecertTBS(cert.RawTBSCertificate, preIssuer)
245+
if err != nil {
246+
return nil, fmt.Errorf("failed to remove poison extension: %v", err)
247+
}
248+
249+
leaf.Precertificate = cert.Raw
250+
// TODO(phboneff): do we need this?
251+
// leaf.PrecertSigningCert = issuer.Raw
252+
leaf.Certificate = defangedTBS
253+
254+
issuerKeyHash := sha256.Sum256(issuer.RawSubjectPublicKeyInfo)
255+
leaf.IssuerKeyHash = issuerKeyHash[:]
256+
return &leaf, nil
257+
}
258+
259+
// isPreIssuer indicates whether a certificate is a pre-cert issuer with the specific
260+
// certificate transparency extended key usage.
261+
func isPreIssuer(cert *x509.Certificate) bool {
262+
// Look for the extension in the Extensions field and not ExtKeyUsage
263+
// since crypto/x509 does not recognize this extension as an ExtKeyUsage.
264+
for _, ext := range cert.Extensions {
265+
if rfc6962.OIDExtKeyUsageCertificateTransparency.Equal(ext.Id) {
266+
return true
267+
}
268+
}
269+
return false
270+
}

0 commit comments

Comments
 (0)