Skip to content

Commit

Permalink
Various SCT related cleanups
Browse files Browse the repository at this point in the history
Mainly don't manually encode/decode SCT list structure.
  • Loading branch information
rolandshoemaker authored and kisom committed Mar 22, 2018
1 parent d0cbfb5 commit 142cc3d
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 54 deletions.
Binary file modified certdb/testdb/certstore_development.db
Binary file not shown.
76 changes: 25 additions & 51 deletions helpers/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,15 @@ import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/binary"
"encoding/pem"
"errors"
"fmt"
"io"
"io/ioutil"
"os"

"github.com/google/certificate-transparency-go"
cttls "github.com/google/certificate-transparency-go/tls"
ctx509 "github.com/google/certificate-transparency-go/x509"
"golang.org/x/crypto/ocsp"

"strings"
Expand Down Expand Up @@ -484,64 +483,40 @@ func CreateTLSConfig(remoteCAs *x509.CertPool, cert *tls.Certificate) *tls.Confi

// SerializeSCTList serializes a list of SCTs.
func SerializeSCTList(sctList []ct.SignedCertificateTimestamp) ([]byte, error) {
var buf bytes.Buffer
list := ctx509.SignedCertificateTimestampList{}
for _, sct := range sctList {
sct, err := cttls.Marshal(sct)
sctBytes, err := cttls.Marshal(sct)
if err != nil {
return nil, err
}
binary.Write(&buf, binary.BigEndian, uint16(len(sct)))
buf.Write(sct)
list.SCTList = append(list.SCTList, ctx509.SerializedSCT{Val: sctBytes})
}

var sctListLengthField = make([]byte, 2)
binary.BigEndian.PutUint16(sctListLengthField, uint16(buf.Len()))
return bytes.Join([][]byte{sctListLengthField, buf.Bytes()}, nil), nil
return cttls.Marshal(list)
}

// DeserializeSCTList deserializes a list of SCTs.
func DeserializeSCTList(serializedSCTList []byte) (*[]ct.SignedCertificateTimestamp, error) {
sctList := new([]ct.SignedCertificateTimestamp)
sctReader := bytes.NewBuffer(serializedSCTList)

var sctListLen uint16
err := binary.Read(sctReader, binary.BigEndian, &sctListLen)
func DeserializeSCTList(serializedSCTList []byte) ([]ct.SignedCertificateTimestamp, error) {
var sctList ctx509.SignedCertificateTimestampList
rest, err := cttls.Unmarshal(serializedSCTList, &sctList)
if err != nil {
if err == io.EOF {
return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown,
errors.New("serialized SCT list could not be read"))
}
return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err)
return nil, err
}
if sctReader.Len() != int(sctListLen) {
return sctList, errors.New("SCT length field and SCT length don't match")
if len(rest) != 0 {
return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, errors.New("serialized SCT list contained trailing garbage"))
}

for err != io.EOF {
var sctLen uint16
err = binary.Read(sctReader, binary.BigEndian, &sctLen)
list := make([]ct.SignedCertificateTimestamp, len(sctList.SCTList))
for i, serializedSCT := range sctList.SCTList {
var sct ct.SignedCertificateTimestamp
rest, err := cttls.Unmarshal(serializedSCT.Val, &sct)
if err != nil {
if err == io.EOF {
return sctList, nil
}
return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err)
return nil, err
}

if sctReader.Len() < int(sctLen) {
return sctList, errors.New("SCT length field and SCT length don't match")
if len(rest) != 0 {
return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, errors.New("serialized SCT contained trailing garbage"))
}

serializedSCT := sctReader.Next(int(sctLen))
var sct ct.SignedCertificateTimestamp
if _, err := cttls.Unmarshal(serializedSCT, &sct); err != nil {
return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err)
}

temp := append(*sctList, sct)
sctList = &temp
list[i] = sct
}

return sctList, cferr.Wrap(cferr.CTError, cferr.Unknown, err)
return list, nil
}

// SCTListFromOCSPResponse extracts the SCTList from an ocsp.Response,
Expand All @@ -560,22 +535,21 @@ func SCTListFromOCSPResponse(response *ocsp.Response) ([]ct.SignedCertificateTim
}

// This code block extracts the sctList from the SCT extension.
var emptySCTList []ct.SignedCertificateTimestamp
sctList := &emptySCTList
var sctList []ct.SignedCertificateTimestamp
var err error
if numBytes := len(SCTListExtension.Value); numBytes != 0 {
serializedSCTList := new([]byte)
var serializedSCTList []byte
rest := make([]byte, numBytes)
copy(rest, SCTListExtension.Value)
for len(rest) != 0 {
rest, err = asn1.Unmarshal(rest, serializedSCTList)
rest, err = asn1.Unmarshal(rest, &serializedSCTList)
if err != nil {
return nil, cferr.Wrap(cferr.CTError, cferr.Unknown, err)
}
}
sctList, err = DeserializeSCTList(*serializedSCTList)
sctList, err = DeserializeSCTList(serializedSCTList)
}
return *sctList, err
return sctList, err
}

// ReadBytes reads a []byte either from a file or an environment variable.
Expand Down
2 changes: 1 addition & 1 deletion helpers/helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -544,7 +544,7 @@ func TestDeserializeSCTList(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if !sctEquals(zeroSCT, (*deserializedSCTList)[0]) {
if !sctEquals(zeroSCT, (deserializedSCTList)[0]) {
t.Fatal("SCTs don't match")
}

Expand Down
Binary file modified ocsp/testdata/sqlite_test.db
Binary file not shown.
4 changes: 2 additions & 2 deletions signer/local/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1361,10 +1361,10 @@ func TestSignFromPrecert(t *testing.T) {
}

// Create a cert from the precert
scts := []ct.SignedCertificateTimestamp{}
scts := []ct.SignedCertificateTimestamp{{}}
certBytes, err := testSigner.SignFromPrecert(precert, scts)
if err != nil {
t.Fatal("Failed to sign cert from precert")
t.Fatalf("Failed to sign cert from precert: %s", err)
}
block, _ = pem.Decode(certBytes)
cert, err := x509.ParseCertificate(block.Bytes)
Expand Down

0 comments on commit 142cc3d

Please sign in to comment.