Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Evenmoreold #156

Draft
wants to merge 44 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
5be0e82
copy verify.go from x509
phbnf Feb 25, 2025
4957875
migrate packages
phbnf Feb 25, 2025
5f4d8b6
c.checkNameConstraints --> checkNameConstraints(c)
phbnf Feb 14, 2025
8b99bfd
c.isValid --> isValid(c)
phbnf Feb 14, 2025
9d503e1
c.Verify --> Verify(c)
phbnf Feb 14, 2025
16cd394
c.buildChains --> buildChains(c)
phbnf Feb 14, 2025
676da7e
c.VerifyHostName --> VerifyHostName(c)
phbnf Feb 14, 2025
7f0c6e4
delete UnhandledCriticalExtensions
phbnf Feb 14, 2025
270cad8
add TODO
phbnf Feb 14, 2025
88f2995
delete TooManyIntermediates
phbnf Feb 14, 2025
8f35b0d
delete CANotAuthorizedForThisName
phbnf Feb 14, 2025
619ca94
delete EKU and Policy chain checks
phbnf Feb 14, 2025
3656294
delete unused code
phbnf Feb 14, 2025
7393758
copy hasSanExtension
phbnf Feb 14, 2025
bc71c54
disable time checks
phbnf Feb 14, 2025
116c6dc
remove errors and hostname functions
phbnf Feb 14, 2025
9b9e4dc
remove more hostname functions
phbnf Feb 14, 2025
4b0ba83
remove VerifyHostname: it's never used
phbnf Feb 14, 2025
d7eeba0
remove error messages and options we don't use
phbnf Feb 14, 2025
54feb52
disable systemRoots
phbnf Feb 14, 2025
e7a5174
delete more unused things
phbnf Feb 14, 2025
94dee8a
delete hasSanExtension
phbnf Feb 25, 2025
19d0c02
use old error type
phbnf Feb 25, 2025
b802bf2
add struct field names
phbnf Feb 25, 2025
5c43dfa
copy cert_pool.go
phbnf Feb 25, 2025
6b5def7
migrate package
phbnf Feb 25, 2025
7f51119
delete systemRootPool
phbnf Feb 14, 2025
5f593b1
migrate options to local certPool
phbnf Feb 14, 2025
e3c120e
use local BuildPrecertTBS instead of ctgo
phbnf Feb 11, 2025
0dd97cb
sed ctgo/x509 - crypto/x509
phbnf Feb 4, 2025
38d66d3
reshuffle imports
phbnf Feb 4, 2025
ed53eb3
fix requestLog: implements stringer
phbnf Feb 4, 2025
6e5a5d8
move pem_cert_pool to x509 package
phbnf Feb 4, 2025
54c265a
fix a bunch of things
phbnf Feb 4, 2025
82ada8a
IN PROGRESS: migrate x509util to standard librairies
phbnf Feb 7, 2025
52cf529
drop dep on c-t-go/x509 in x509util and delete print funcs
phbnf Feb 7, 2025
a92cd43
remove last IsFatal
phbnf Feb 7, 2025
5f1793b
inline isPreIssuer check
phbnf Feb 7, 2025
4c09050
remove unused PreCertificate method
phbnf Feb 7, 2025
64c6af1
migrate x509/ct.go away from c-t-go
phbnf Feb 11, 2025
be01114
allow specific verify errors to go through
phbnf Feb 12, 2025
4d50e94
add comments
phbnf Feb 13, 2025
60c6c1d
conver everythig to local cert_pool
phbnf Feb 14, 2025
f39d90b
remove time check option
phbnf Feb 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions ctlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ package sctfe
import (
"context"
"crypto"
"crypto/x509"
"encoding/asn1"
"errors"
"fmt"
"net/http"
"strings"
"time"

"github.com/google/certificate-transparency-go/asn1"
"github.com/google/certificate-transparency-go/x509"
"github.com/transparency-dev/static-ct/internal/scti"
"github.com/transparency-dev/static-ct/internal/x509util"
"github.com/transparency-dev/static-ct/storage"
Expand Down
40 changes: 12 additions & 28 deletions internal/scti/chain_validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ package scti

import (
"bytes"
"crypto/x509"
"encoding/asn1"
"errors"
"fmt"
"strconv"
"strings"
"time"

"github.com/google/certificate-transparency-go/asn1"
"github.com/google/certificate-transparency-go/x509"
"github.com/transparency-dev/static-ct/internal/types"
"github.com/transparency-dev/static-ct/internal/x509util"
"k8s.io/klog/v2"
)
Expand Down Expand Up @@ -127,7 +128,7 @@ func NewChainValidationOpts(trustedRoots *x509util.PEMCertPool, rejectExpired, r
// by the spec.
func isPrecertificate(cert *x509.Certificate) (bool, error) {
for _, ext := range cert.Extensions {
if x509.OIDExtensionCTPoison.Equal(ext.Id) {
if types.OIDExtensionCTPoison.Equal(ext.Id) {
if !ext.Critical || !bytes.Equal(asn1.NullBytes, ext.Value) {
return false, fmt.Errorf("CT poison ext is not critical or invalid: %v", ext)
}
Expand All @@ -152,8 +153,8 @@ func validateChain(rawChain [][]byte, validationOpts ChainValidationOpts) ([]*x5

for i, certBytes := range rawChain {
cert, err := x509.ParseCertificate(certBytes)
if x509.IsFatal(err) {
return nil, err
if err != nil {
return nil, fmt.Errorf("x509.ParseCertificate(): %v", err)
}

chain = append(chain, cert)
Expand Down Expand Up @@ -223,32 +224,15 @@ func validateChain(rawChain [][]byte, validationOpts ChainValidationOpts) ([]*x5
}
}

// We can now do the verification. Use fairly lax options for verification, as
// We can now do the verification. Use fairly lax options for verification, as
// CT is intended to observe certificates rather than police them.
verifyOpts := x509.VerifyOptions{
Roots: validationOpts.trustedRoots.CertPool(),
CurrentTime: now,
Intermediates: intermediatePool.CertPool(),
DisableTimeChecks: true,
// Precertificates have the poison extension; also the Go library code does not
// support the standard PolicyConstraints extension (which is required to be marked
// critical, RFC 5280 s4.2.1.11), so never check unhandled critical extensions.
DisableCriticalExtensionChecks: true,
// Pre-issued precertificates have the Certificate Transparency EKU; also some
// leaves have unknown EKUs that should not be bounced just because the intermediate
// does not also have them (cf. https://github.com/golang/go/issues/24590) so
// disable EKU checks inside the x509 library, but we've already done our own check
// on the leaf above.
DisableEKUChecks: true,
// Path length checks get confused by the presence of an additional
// pre-issuer intermediate, so disable them.
DisablePathLenChecks: true,
DisableNameConstraintChecks: true,
DisableNameChecks: false,
KeyUsages: validationOpts.extKeyUsages,
verifyOpts := x509util.VerifyOptions{
Roots: validationOpts.trustedRoots.CertPool(),
Intermediates: intermediatePool.CertPool(),
KeyUsages: validationOpts.extKeyUsages,
}

verifiedChains, err := cert.Verify(verifyOpts)
verifiedChains, err := x509util.Verify(cert, verifyOpts)
if err != nil {
return nil, err
}
Expand Down
20 changes: 11 additions & 9 deletions internal/scti/chain_validation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,17 @@
package scti

import (
"crypto/md5"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"strings"
"testing"
"time"

"github.com/google/certificate-transparency-go/asn1"
"github.com/google/certificate-transparency-go/x509"
"github.com/google/certificate-transparency-go/x509/pkix"
"github.com/transparency-dev/static-ct/internal/testdata"
"github.com/transparency-dev/static-ct/internal/types"
"github.com/transparency-dev/static-ct/internal/x509util"
)

Expand All @@ -34,13 +36,13 @@ func wipeExtensions(cert *x509.Certificate) *x509.Certificate {

func makePoisonNonCritical(cert *x509.Certificate) *x509.Certificate {
// Invalid as a pre-cert because poison extension needs to be marked as critical.
cert.Extensions = []pkix.Extension{{Id: x509.OIDExtensionCTPoison, Critical: false, Value: asn1.NullBytes}}
cert.Extensions = []pkix.Extension{{Id: types.OIDExtensionCTPoison, Critical: false, Value: asn1.NullBytes}}
return cert
}

func makePoisonNonNull(cert *x509.Certificate) *x509.Certificate {
// Invalid as a pre-cert because poison extension is not ASN.1 NULL value.
cert.Extensions = []pkix.Extension{{Id: x509.OIDExtensionCTPoison, Critical: false, Value: []byte{0x42, 0x42, 0x42}}}
cert.Extensions = []pkix.Extension{{Id: types.OIDExtensionCTPoison, Critical: false, Value: []byte{0x42, 0x42, 0x42}}}
return cert
}

Expand Down Expand Up @@ -270,7 +272,7 @@ func TestValidateChain(t *testing.T) {
if len(gotPath) != test.wantPathLen {
t.Errorf("|ValidateChain()|=%d; want %d", len(gotPath), test.wantPathLen)
for _, c := range gotPath {
t.Logf("Subject: %s Issuer: %s", x509util.NameToString(c.Subject), x509util.NameToString(c.Issuer))
t.Logf("Subject: %s Issuer: %s", c.Subject, c.Issuer)
}
}
})
Expand Down Expand Up @@ -474,8 +476,8 @@ func pemToCert(t *testing.T, pemData string) *x509.Certificate {
}

cert, err := x509.ParseCertificate(bytes.Bytes)
if x509.IsFatal(err) {
t.Fatal(err)
if err != nil {
t.Fatalf("x509.ParseCertificate(): %v", err)
}

return cert
Expand Down Expand Up @@ -546,7 +548,7 @@ func TestPreIssuedCert(t *testing.T) {
t.Fatalf("failed to ValidateChain: %v", err)
}
for i, c := range chain {
t.Logf("chain[%d] = \n%s", i, x509util.CertificateToString(c))
t.Logf("chain[%d] = \n%s", i, md5.Sum(c.Raw))
}
})
}
Expand Down
2 changes: 1 addition & 1 deletion internal/scti/ctlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import (
"context"
"crypto"
"crypto/ecdsa"
"crypto/x509"
"errors"
"fmt"

"github.com/google/certificate-transparency-go/x509"
"github.com/transparency-dev/static-ct/internal/types"
"github.com/transparency-dev/static-ct/modules/dedup"
"github.com/transparency-dev/static-ct/storage"
Expand Down
12 changes: 6 additions & 6 deletions internal/scti/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package scti
import (
"context"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/json"
"errors"
Expand All @@ -29,10 +30,10 @@ import (
"time"

"github.com/google/certificate-transparency-go/tls"
"github.com/google/certificate-transparency-go/x509"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/transparency-dev/static-ct/internal/types"
"github.com/transparency-dev/static-ct/internal/x509util"
"github.com/transparency-dev/static-ct/modules/dedup"
tessera "github.com/transparency-dev/trillian-tessera"
"github.com/transparency-dev/trillian-tessera/ctonly"
Expand Down Expand Up @@ -491,7 +492,7 @@ func entryFromChain(chain []*x509.Certificate, isPrecert bool, timestamp uint64)

// Next, post-process the DER-encoded TBSCertificate, to remove the CT poison
// extension and possibly update the issuer field.
defangedTBS, err := x509.BuildPrecertTBS(cert.RawTBSCertificate, preIssuer)
defangedTBS, err := x509util.BuildPrecertTBS(cert.RawTBSCertificate, preIssuer)
if err != nil {
return nil, fmt.Errorf("failed to remove poison extension: %v", err)
}
Expand All @@ -508,10 +509,9 @@ func entryFromChain(chain []*x509.Certificate, isPrecert bool, timestamp uint64)

// isPreIssuer indicates whether a certificate is a pre-cert issuer with the specific
// certificate transparency extended key usage.
// copied form certificate-transparency-go/serialization.go
func isPreIssuer(issuer *x509.Certificate) bool {
for _, eku := range issuer.ExtKeyUsage {
if eku == x509.ExtKeyUsageCertificateTransparency {
func isPreIssuer(cert *x509.Certificate) bool {
for _, ext := range cert.Extensions {
if types.OIDExtKeyUsageCertificateTransparency.Equal(ext.Id) {
return true
}
}
Expand Down
2 changes: 1 addition & 1 deletion internal/scti/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"bytes"
"context"
"crypto"
"crypto/x509"
"encoding/hex"
"encoding/json"
"fmt"
Expand All @@ -30,7 +31,6 @@ import (
"time"

"github.com/golang/mock/gomock"
"github.com/google/certificate-transparency-go/x509"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"github.com/transparency-dev/static-ct/internal/testdata"
Expand Down
7 changes: 3 additions & 4 deletions internal/scti/requestlog.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ package scti

import (
"context"
"crypto/x509"
"encoding/hex"
"time"

"github.com/google/certificate-transparency-go/x509"
"github.com/google/certificate-transparency-go/x509util"
"k8s.io/klog/v2"
)

Expand Down Expand Up @@ -86,8 +85,8 @@ func (dlr *DefaultRequestLog) addDERToChain(_ context.Context, d []byte) {
// certificate that is part of a submitted chain.
func (dlr *DefaultRequestLog) addCertToChain(_ context.Context, cert *x509.Certificate) {
klog.V(vLevel).Infof("RL: Cert: Sub: %s Iss: %s notBef: %s notAft: %s",
x509util.NameToString(cert.Subject),
x509util.NameToString(cert.Issuer),
cert.Subject,
cert.Issuer,
cert.NotBefore.Format(time.RFC1123Z),
cert.NotAfter.Format(time.RFC1123Z))
}
Expand Down
2 changes: 1 addition & 1 deletion internal/scti/signatures.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ import (
"crypto"
"crypto/rand"
"crypto/sha256"
"crypto/x509"
"encoding/binary"
"fmt"
"time"

"github.com/google/certificate-transparency-go/tls"
"github.com/google/certificate-transparency-go/x509"
tfl "github.com/transparency-dev/formats/log"
"github.com/transparency-dev/static-ct/internal/types"
"golang.org/x/mod/sumdb/note"
Expand Down
8 changes: 4 additions & 4 deletions internal/scti/signatures_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@ import (
"bytes"
"crypto"
"crypto/sha256"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"testing"
"time"

"github.com/google/certificate-transparency-go/tls"
"github.com/google/certificate-transparency-go/x509"
"github.com/kylelemons/godebug/pretty"
"github.com/transparency-dev/static-ct/internal/testdata"
"github.com/transparency-dev/static-ct/internal/types"
Expand Down Expand Up @@ -245,7 +245,7 @@ func TestSerializeV1STHSignatureKAT(t *testing.T) {

func TestBuildV1MerkleTreeLeafForCert(t *testing.T) {
cert, err := x509util.CertificateFromPEM([]byte(testdata.LeafSignedByFakeIntermediateCertPEM))
if x509.IsFatal(err) {
if err != nil {
t.Fatalf("failed to set up test cert: %v", err)
}

Expand Down Expand Up @@ -308,7 +308,7 @@ func TestBuildV1MerkleTreeLeafForCert(t *testing.T) {

func TestSignV1SCTForPrecertificate(t *testing.T) {
cert, err := x509util.CertificateFromPEM([]byte(testdata.PrecertPEMValid))
if x509.IsFatal(err) {
if err != nil {
t.Fatalf("failed to set up test precert: %v", err)
}

Expand Down Expand Up @@ -367,7 +367,7 @@ func TestSignV1SCTForPrecertificate(t *testing.T) {
if got, want := keyHash[:], leaf.TimestampedEntry.PrecertEntry.IssuerKeyHash[:]; !bytes.Equal(got, want) {
t.Fatalf("Issuer key hash bytes mismatch, got %v, expected %v", got, want)
}
defangedTBS, _ := x509.RemoveCTPoison(cert.RawTBSCertificate)
defangedTBS, _ := x509util.RemoveCTPoison(cert.RawTBSCertificate)
if got, want := leaf.TimestampedEntry.PrecertEntry.TBSCertificate, defangedTBS; !bytes.Equal(got, want) {
t.Fatalf("TBS cert mismatch, got %v, expected %v", got, want)
}
Expand Down
20 changes: 6 additions & 14 deletions internal/types/rfc6962.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package types

import (
"crypto/sha256"
"crypto/x509"
"encoding/asn1"
"encoding/base64"
"encoding/json"
"fmt"

"github.com/google/certificate-transparency-go/tls"
"github.com/google/certificate-transparency-go/x509"
)

///////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -43,6 +44,10 @@ const (
TreeNodePrefix = byte(0x01)
)

// OIDExtensionCTPoison is defined in RFC 6962 s3.1.
var OIDExtensionCTPoison = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 3}
var OIDExtKeyUsageCertificateTransparency = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 4}

// MerkleLeafType represents the MerkleLeafType enum from section 3.4:
//
// enum { timestamped_entry(0), (255) } MerkleLeafType;
Expand Down Expand Up @@ -398,19 +403,6 @@ func (m *MerkleTreeLeaf) X509Certificate() (*x509.Certificate, error) {
return x509.ParseCertificate(m.TimestampedEntry.X509Entry.Data)
}

// Precertificate returns the X.509 Precertificate contained within the MerkleTreeLeaf.
//
// The returned precertificate is embedded in an x509.Certificate, but is in the
// form stored internally in the log rather than the original submitted form
// (i.e. it does not include the poison extension and any changes to reflect the
// final certificate's issuer have been made; see x509.BuildPrecertTBS).
func (m *MerkleTreeLeaf) Precertificate() (*x509.Certificate, error) {
if m.TimestampedEntry.EntryType != PrecertLogEntryType {
return nil, fmt.Errorf("cannot call Precertificate on a MerkleTreeLeaf that is not a precert entry")
}
return x509.ParseTBSCertificate(m.TimestampedEntry.PrecertEntry.TBSCertificate)
}

// APIEndpoint is a string that represents one of the Certificate Transparency
// Log API endpoints.
type APIEndpoint string
Expand Down
Loading
Loading