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

Evenmore #155

Draft
wants to merge 39 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
0d4370a
use local BuildPrecertTBS instead of ctgo
phbnf Feb 11, 2025
5f00c13
sed ctgo/x509 - crypto/x509
phbnf Feb 4, 2025
1d04c47
reshuffle imports
phbnf Feb 4, 2025
670089d
fix requestLog: implements stringer
phbnf Feb 4, 2025
e5c5925
move pem_cert_pool to x509 package
phbnf Feb 4, 2025
27d8bca
fix a bunch of things
phbnf Feb 4, 2025
0c37eef
IN PROGRESS: migrate x509util to standard librairies
phbnf Feb 7, 2025
d9886f9
drop dep on c-t-go/x509 in x509util and delete print funcs
phbnf Feb 7, 2025
b1e738d
remove last IsFatal
phbnf Feb 7, 2025
1d23e13
inline isPreIssuer check
phbnf Feb 7, 2025
65095f4
remove unused PreCertificate method
phbnf Feb 7, 2025
e33394d
migrate x509/ct.go away from c-t-go
phbnf Feb 11, 2025
4fd7007
allow specific verify errors to go through
phbnf Feb 12, 2025
b080ba2
add comments
phbnf Feb 13, 2025
5945b5c
copy x509/verify.go and use exported functions when possible
phbnf Feb 14, 2025
a296e5e
c.checkNameConstraints --> checkNameConstraints(c)
phbnf Feb 14, 2025
f4fc974
c.isValid --> isValid(c)
phbnf Feb 14, 2025
bb60b2d
c.Verify --> Verify(c)
phbnf Feb 14, 2025
3c1a938
c.buildChains --> buildChains(c)
phbnf Feb 14, 2025
a20663f
c.VerifyHostName --> VerifyHostName(c)
phbnf Feb 14, 2025
84cdf2e
delete UnhandledCriticalExtensions
phbnf Feb 14, 2025
007487b
add TODO
phbnf Feb 14, 2025
0f8b59e
delete TooManyIntermediates
phbnf Feb 14, 2025
cf8d3af
delete CANotAuthorizedForThisName
phbnf Feb 14, 2025
6e69aef
delete EKU and Policy chain checks
phbnf Feb 14, 2025
372a3eb
delete unused code
phbnf Feb 14, 2025
760c605
copy hasSanExtension
phbnf Feb 14, 2025
6df0a3e
disable systemRoots
phbnf Feb 14, 2025
786800d
copy cert_pool.go take dep on crypto/x509
phbnf Feb 14, 2025
8b4a7b0
delete systemRootPool
phbnf Feb 14, 2025
8e2cc74
migrate options to local certPool
phbnf Feb 14, 2025
c498993
conver everythig to local cert_pool
phbnf Feb 14, 2025
5c722af
disable time checks
phbnf Feb 14, 2025
2066386
remove time check option
phbnf Feb 14, 2025
bd73f08
delete more unused things
phbnf Feb 14, 2025
be9db26
remove errors and hostname functions
phbnf Feb 14, 2025
f0c8bd0
remove more hostname functions
phbnf Feb 14, 2025
0e6886f
remove VerifyHostname: it's never used
phbnf Feb 14, 2025
0682fd1
remove error messages and options we don't use
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,16 +17,16 @@
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"

Check failure on line 29 in ctlog.go

View workflow job for this annotation

GitHub Actions / lint

could not import github.com/transparency-dev/static-ct/internal/x509util (-: # 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,15 +16,16 @@

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"

Check failure on line 28 in internal/scti/chain_validation.go

View workflow job for this annotation

GitHub Actions / lint

could not import github.com/transparency-dev/static-ct/internal/x509util (-: # github.com/transparency-dev/static-ct/internal/x509util
"k8s.io/klog/v2"
)

Expand Down Expand Up @@ -127,7 +128,7 @@
// 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 @@

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 @@
}
}

// 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