630 lines
17 KiB
Go
630 lines
17 KiB
Go
package helpers
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/ecdsa"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"crypto/rsa"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/asn1"
|
|
"encoding/pem"
|
|
"io/ioutil"
|
|
"math"
|
|
"testing"
|
|
"time"
|
|
|
|
"golang.org/x/crypto/ocsp"
|
|
|
|
"github.com/google/certificate-transparency-go"
|
|
)
|
|
|
|
const (
|
|
testCertFile = "testdata/cert.pem"
|
|
testCertDERFile = "testdata/cert.der"
|
|
testBundleFile = "testdata/bundle.pem"
|
|
testExtraWSCertFile = "testdata/cert_with_whitespace.pem"
|
|
testExtraWSBundleFile = "testdata/bundle_with_whitespace.pem"
|
|
testMessedUpBundleFile = "testdata/messed_up_bundle.pem"
|
|
testMessedUpCertFile = "testdata/messedupcert.pem"
|
|
testEmptyCertFile = "testdata/emptycert.pem"
|
|
testPrivateRSAKey = "testdata/priv_rsa_key.pem"
|
|
testPrivateECDSAKey = "testdata/private_ecdsa_key.pem"
|
|
testUnsupportedECDSAKey = "testdata/secp256k1-key.pem"
|
|
testMessedUpPrivateKey = "testdata/messed_up_priv_key.pem"
|
|
testEncryptedPrivateKey = "testdata/enc_priv_key.pem"
|
|
testEmptyPem = "testdata/empty.pem"
|
|
testNoHeaderCert = "testdata/noheadercert.pem"
|
|
testSinglePKCS7 = "testdata/cert_pkcs7.pem" // openssl crl2pkcs7 -nocrl -out cert_pkcs7.pem -in cert.pem
|
|
testEmptyPKCS7DER = "testdata/empty_pkcs7.der" // openssl crl2pkcs7 -nocrl -out empty_pkcs7.der -outform der
|
|
testEmptyPKCS7PEM = "testdata/empty_pkcs7.pem" // openssl crl2pkcs7 -nocrl -out empty_pkcs7.pem -outform pem
|
|
testMultiplePKCS7 = "testdata/bundle_pkcs7.pem"
|
|
testPKCS12EmptyPswd = "testdata/emptypasswordpkcs12.p12"
|
|
testPKCS12Passwordispassword = "testdata/passwordpkcs12.p12"
|
|
testPKCS12MultipleCerts = "testdata/multiplecerts.p12"
|
|
testCSRPEM = "testdata/test.csr.pem"
|
|
testCSRPEMBad = "testdata/test.bad.csr.pem"
|
|
)
|
|
|
|
func TestParseCertificatesDER(t *testing.T) {
|
|
var password = []string{"password", "", ""}
|
|
for i, testFile := range []string{testPKCS12Passwordispassword, testPKCS12EmptyPswd, testCertDERFile} {
|
|
testDER, err := ioutil.ReadFile(testFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, _, err := ParseCertificatesDER(testDER, password[i]); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Incorrect Password for PKCS12 formatted files
|
|
if _, _, err := ParseCertificatesDER(testDER, "incorrectpassword"); err == nil && i != 2 {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
testDER, err := ioutil.ReadFile(testEmptyPKCS7DER)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// PKCS7 with no certificates
|
|
if _, _, err := ParseCertificatesDER(testDER, ""); err == nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestKeyLength(t *testing.T) {
|
|
expNil := 0
|
|
recNil := KeyLength(nil)
|
|
if expNil != recNil {
|
|
t.Fatal("KeyLength on nil did not return 0")
|
|
}
|
|
|
|
expNonsense := 0
|
|
inNonsense := "string?"
|
|
outNonsense := KeyLength(inNonsense)
|
|
if expNonsense != outNonsense {
|
|
t.Fatal("KeyLength malfunctioning on nonsense input")
|
|
}
|
|
|
|
//test the ecdsa branch
|
|
ecdsaPriv, _ := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
|
ecdsaIn, _ := ecdsaPriv.Public().(*ecdsa.PublicKey)
|
|
expEcdsa := ecdsaIn.Curve.Params().BitSize
|
|
outEcdsa := KeyLength(ecdsaIn)
|
|
if expEcdsa != outEcdsa {
|
|
t.Fatal("KeyLength malfunctioning on ecdsa input")
|
|
}
|
|
|
|
//test the rsa branch
|
|
rsaPriv, _ := rsa.GenerateKey(rand.Reader, 256)
|
|
rsaIn, _ := rsaPriv.Public().(*rsa.PublicKey)
|
|
expRsa := rsaIn.N.BitLen()
|
|
outRsa := KeyLength(rsaIn)
|
|
|
|
if expRsa != outRsa {
|
|
t.Fatal("KeyLength malfunctioning on rsa input")
|
|
}
|
|
}
|
|
|
|
func TestExpiryTime(t *testing.T) {
|
|
// nil case
|
|
var expNil time.Time
|
|
inNil := []*x509.Certificate{}
|
|
outNil := ExpiryTime(inNil)
|
|
if expNil != outNil {
|
|
t.Fatal("Expiry time is malfunctioning on empty input")
|
|
}
|
|
|
|
//read a pem file and use that expiry date
|
|
bytes, _ := ioutil.ReadFile(testBundleFile)
|
|
certs, err := ParseCertificatesPEM(bytes)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
expected := time.Date(2014, time.April, 15, 0, 0, 0, 0, time.UTC)
|
|
out := ExpiryTime(certs)
|
|
if out != expected {
|
|
t.Fatalf("Expected %v, got %v", expected, out)
|
|
}
|
|
}
|
|
|
|
func TestMonthsValid(t *testing.T) {
|
|
var cert = &x509.Certificate{
|
|
NotBefore: time.Date(2015, time.April, 01, 0, 0, 0, 0, time.UTC),
|
|
NotAfter: time.Date(2015, time.April, 01, 0, 0, 0, 0, time.UTC),
|
|
}
|
|
|
|
if MonthsValid(cert) != 0 {
|
|
t.Fail()
|
|
}
|
|
|
|
cert.NotAfter = time.Date(2016, time.April, 01, 0, 0, 0, 0, time.UTC)
|
|
if MonthsValid(cert) != 12 {
|
|
t.Fail()
|
|
}
|
|
|
|
// extra days should be rounded up to 1 month
|
|
cert.NotAfter = time.Date(2016, time.April, 02, 0, 0, 0, 0, time.UTC)
|
|
if MonthsValid(cert) != 13 {
|
|
t.Fail()
|
|
}
|
|
}
|
|
|
|
func TestHasValidExpiry(t *testing.T) {
|
|
// Issue period > April 1, 2015
|
|
var cert = &x509.Certificate{
|
|
NotBefore: time.Date(2015, time.April, 01, 0, 0, 0, 0, time.UTC),
|
|
NotAfter: time.Date(2016, time.April, 01, 0, 0, 0, 0, time.UTC),
|
|
}
|
|
|
|
if !ValidExpiry(cert) {
|
|
t.Fail()
|
|
}
|
|
|
|
cert.NotAfter = time.Date(2019, time.April, 01, 01, 0, 0, 0, time.UTC)
|
|
if ValidExpiry(cert) {
|
|
t.Fail()
|
|
}
|
|
|
|
// Issue period < July 1, 2012
|
|
cert.NotBefore = time.Date(2009, time.March, 01, 0, 0, 0, 0, time.UTC)
|
|
if ValidExpiry(cert) {
|
|
t.Fail()
|
|
}
|
|
|
|
// Issue period July 1, 2012 - April 1, 2015
|
|
cert.NotBefore = time.Date(2012, time.July, 01, 0, 0, 0, 0, time.UTC)
|
|
cert.NotAfter = time.Date(2017, time.July, 01, 0, 0, 0, 0, time.UTC)
|
|
if !ValidExpiry(cert) {
|
|
t.Fail()
|
|
}
|
|
}
|
|
|
|
func TestHashAlgoString(t *testing.T) {
|
|
if HashAlgoString(x509.MD2WithRSA) != "MD2" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.MD5WithRSA) != "MD5" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.SHA1WithRSA) != "SHA1" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.SHA256WithRSA) != "SHA256" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.SHA384WithRSA) != "SHA384" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.SHA512WithRSA) != "SHA512" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.DSAWithSHA1) != "SHA1" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.DSAWithSHA256) != "SHA256" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.ECDSAWithSHA1) != "SHA1" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.ECDSAWithSHA256) != "SHA256" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.ECDSAWithSHA384) != "SHA384" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(x509.ECDSAWithSHA512) != "SHA512" {
|
|
t.Fatal("standin")
|
|
}
|
|
if HashAlgoString(math.MaxInt32) != "Unknown Hash Algorithm" {
|
|
t.Fatal("standin")
|
|
}
|
|
}
|
|
|
|
func TestSignatureString(t *testing.T) {
|
|
if SignatureString(x509.MD2WithRSA) != "MD2WithRSA" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.MD5WithRSA) != "MD5WithRSA" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.SHA1WithRSA) != "SHA1WithRSA" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.SHA256WithRSA) != "SHA256WithRSA" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.SHA384WithRSA) != "SHA384WithRSA" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.SHA512WithRSA) != "SHA512WithRSA" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.DSAWithSHA1) != "DSAWithSHA1" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.DSAWithSHA256) != "DSAWithSHA256" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.ECDSAWithSHA1) != "ECDSAWithSHA1" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.ECDSAWithSHA256) != "ECDSAWithSHA256" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.ECDSAWithSHA384) != "ECDSAWithSHA384" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(x509.ECDSAWithSHA512) != "ECDSAWithSHA512" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
if SignatureString(math.MaxInt32) != "Unknown Signature" {
|
|
t.Fatal("Signature String functioning improperly")
|
|
}
|
|
}
|
|
|
|
func TestParseCertificatePEM(t *testing.T) {
|
|
for _, testFile := range []string{testCertFile, testExtraWSCertFile, testSinglePKCS7} {
|
|
certPEM, err := ioutil.ReadFile(testFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := ParseCertificatePEM(certPEM); err != nil {
|
|
t.Log(testFile)
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
for _, testFile := range []string{testBundleFile, testMessedUpCertFile, testEmptyPKCS7PEM, testEmptyCertFile, testMultiplePKCS7} {
|
|
certPEM, err := ioutil.ReadFile(testFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := ParseCertificatePEM(certPEM); err == nil {
|
|
t.Fatal("Incorrect cert failed to raise error")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestParseCertificatesPEM(t *testing.T) {
|
|
// expected cases
|
|
for _, testFile := range []string{testBundleFile, testExtraWSBundleFile, testSinglePKCS7, testMultiplePKCS7} {
|
|
bundlePEM, err := ioutil.ReadFile(testFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := ParseCertificatesPEM(bundlePEM); err != nil {
|
|
t.Log(testFile)
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
// test failure cases
|
|
// few lines deleted, then headers removed
|
|
for _, testFile := range []string{testMessedUpBundleFile, testEmptyPKCS7PEM, testNoHeaderCert} {
|
|
bundlePEM, err := ioutil.ReadFile(testFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := ParseCertificatesPEM(bundlePEM); err == nil {
|
|
t.Fatal("Incorrectly-formatted file failed to produce an error")
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSelfSignedCertificatePEM(t *testing.T) {
|
|
testPEM, _ := ioutil.ReadFile(testCertFile)
|
|
_, err := ParseSelfSignedCertificatePEM(testPEM)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
|
|
// a few lines deleted from the pem file
|
|
wrongPEM, _ := ioutil.ReadFile(testMessedUpCertFile)
|
|
_, err2 := ParseSelfSignedCertificatePEM(wrongPEM)
|
|
if err2 == nil {
|
|
t.Fatal("Improper pem file failed to raise an error")
|
|
}
|
|
|
|
// alter the signature of a valid certificate
|
|
blk, _ := pem.Decode(testPEM)
|
|
blk.Bytes[len(blk.Bytes)-10]++ // some hacking to get to the sig
|
|
alteredBytes := pem.EncodeToMemory(blk)
|
|
_, err = ParseSelfSignedCertificatePEM(alteredBytes)
|
|
if err == nil {
|
|
t.Fatal("Incorrect cert failed to produce an error")
|
|
}
|
|
|
|
}
|
|
|
|
func TestParsePrivateKeyPEM(t *testing.T) {
|
|
|
|
// expected cases
|
|
testRSAPEM, _ := ioutil.ReadFile(testPrivateRSAKey)
|
|
_, err := ParsePrivateKeyPEM(testRSAPEM)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
testECDSAPEM, _ := ioutil.ReadFile(testPrivateECDSAKey)
|
|
_, err = ParsePrivateKeyPEM(testECDSAPEM)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// error cases
|
|
errCases := []string{
|
|
testMessedUpPrivateKey, // a few lines deleted
|
|
testEmptyPem, // empty file
|
|
testEncryptedPrivateKey, // encrypted key
|
|
testUnsupportedECDSAKey, // ECDSA curve not currently supported by Go standard library
|
|
}
|
|
|
|
for _, fname := range errCases {
|
|
testPEM, _ := ioutil.ReadFile(fname)
|
|
_, err = ParsePrivateKeyPEM(testPEM)
|
|
if err == nil {
|
|
t.Fatal("Incorrect private key failed to produce an error")
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// Imported from signers/local/testdata/
|
|
const ecdsaTestCSR = "testdata/ecdsa256.csr"
|
|
|
|
func TestParseCSRPEM(t *testing.T) {
|
|
in, err := ioutil.ReadFile(ecdsaTestCSR)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
|
|
_, _, err = ParseCSR(in)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
|
|
in[12]++
|
|
_, _, err = ParseCSR(in)
|
|
if err == nil {
|
|
t.Fatalf("Expected an invalid CSR.")
|
|
}
|
|
in[12]--
|
|
}
|
|
|
|
func TestParseCSRPEMMore(t *testing.T) {
|
|
csrPEM, err := ioutil.ReadFile(testCSRPEM)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := ParseCSRPEM(csrPEM); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
csrPEM, err = ioutil.ReadFile(testCSRPEMBad)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := ParseCSRPEM(csrPEM); err == nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if _, err := ParseCSRPEM([]byte("not even pem")); err == nil {
|
|
t.Fatal("Expected an invalid CSR.")
|
|
}
|
|
}
|
|
|
|
// Imported from signers/local/testdata/
|
|
const rsaOldTestCSR = "testdata/rsa-old.csr"
|
|
|
|
func TestParseOldCSR(t *testing.T) {
|
|
in, err := ioutil.ReadFile(rsaOldTestCSR)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
|
|
_, _, err = ParseCSR(in)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
}
|
|
|
|
// Imported from signers/local/testdata/
|
|
const clientCertFile = "testdata/ca.pem"
|
|
const clientKeyFile = "testdata/ca_key.pem"
|
|
|
|
func TestClientCertParams(t *testing.T) {
|
|
_, err := LoadClientCertificate(testCertFile, testPrivateRSAKey)
|
|
if err == nil {
|
|
t.Fatal("Unmatched cert/key should generate error")
|
|
}
|
|
|
|
cert, err := LoadClientCertificate("", "")
|
|
if err != nil || cert != nil {
|
|
t.Fatal("Certificate atempted to loaded with missing key and cert")
|
|
}
|
|
cert, err = LoadClientCertificate(clientCertFile, "")
|
|
if err != nil || cert != nil {
|
|
t.Fatal("Certificate atempted to loaded with missing key")
|
|
}
|
|
cert, err = LoadClientCertificate("", clientKeyFile)
|
|
if err != nil || cert != nil {
|
|
t.Fatal("Certificate atempted to loaded with missing cert")
|
|
}
|
|
|
|
cert, err = LoadClientCertificate(clientCertFile, clientKeyFile)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if cert == nil {
|
|
t.Fatal("cert not created")
|
|
}
|
|
}
|
|
|
|
func TestLoadPEMCertPool(t *testing.T) {
|
|
certPool, err := PEMToCertPool([]byte{})
|
|
if certPool != nil || err != nil {
|
|
t.Fatal("Empty file name should not generate error or a cert pool")
|
|
}
|
|
|
|
in, err := ioutil.ReadFile(testEmptyPem)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
certPool, err = PEMToCertPool(in)
|
|
if certPool != nil {
|
|
t.Fatal("Empty file should not generate a cert pool")
|
|
} else if err == nil {
|
|
t.Fatal("Expected error for empty file")
|
|
}
|
|
|
|
in, err = ioutil.ReadFile(testEmptyCertFile)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
certPool, err = PEMToCertPool(in)
|
|
if certPool != nil {
|
|
t.Fatal("Empty cert should not generate a cert pool")
|
|
} else if err == nil {
|
|
t.Fatal("Expected error for empty cert")
|
|
}
|
|
|
|
in, err = ioutil.ReadFile(clientCertFile)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
}
|
|
certPool, err = PEMToCertPool(in)
|
|
if err != nil {
|
|
t.Fatalf("%v", err)
|
|
} else if certPool == nil {
|
|
t.Fatal("cert pool not created")
|
|
}
|
|
}
|
|
|
|
// sctEquals returns true if all fields of both SCTs are equivalent.
|
|
func sctEquals(sctA, sctB ct.SignedCertificateTimestamp) bool {
|
|
if sctA.SCTVersion == sctB.SCTVersion &&
|
|
sctA.LogID == sctB.LogID &&
|
|
sctA.Timestamp == sctB.Timestamp &&
|
|
bytes.Equal(sctA.Extensions, sctB.Extensions) &&
|
|
sctA.Signature.Algorithm == sctB.Signature.Algorithm &&
|
|
bytes.Equal(sctA.Signature.Signature, sctA.Signature.Signature) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// NOTE: TestDeserializeSCTList tests both DeserializeSCTList and
|
|
// SerializeSCTList.
|
|
func TestDeserializeSCTList(t *testing.T) {
|
|
// Here we make sure that empty SCT lists return an error
|
|
emptyLists := [][]byte{nil, {}}
|
|
for _, emptyList := range emptyLists {
|
|
_, err := DeserializeSCTList(emptyList)
|
|
if err == nil {
|
|
t.Fatalf("DeserializeSCTList(%v) should raise an error\n", emptyList)
|
|
}
|
|
}
|
|
|
|
// Here we make sure that an SCT list with a zero SCT is deserialized
|
|
// correctly
|
|
var zeroSCT ct.SignedCertificateTimestamp
|
|
serializedSCT, err := SerializeSCTList([]ct.SignedCertificateTimestamp{zeroSCT})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
deserializedSCTList, err := DeserializeSCTList(serializedSCT)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !sctEquals(zeroSCT, (deserializedSCTList)[0]) {
|
|
t.Fatal("SCTs don't match")
|
|
}
|
|
|
|
// Here we verify that an error is raised when the SCT list length
|
|
// field is greater than its actual length
|
|
serializedSCT, err = SerializeSCTList([]ct.SignedCertificateTimestamp{zeroSCT})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
serializedSCT[0] = 15
|
|
_, err = DeserializeSCTList(serializedSCT)
|
|
if err == nil {
|
|
t.Fatalf("DeserializeSCTList should raise an error when " +
|
|
"the SCT list length field and the list length don't match\n")
|
|
}
|
|
|
|
// Here we verify that an error is raised when the SCT list length
|
|
// field is less than its actual length
|
|
serializedSCT[0] = 0
|
|
serializedSCT[1] = 0
|
|
_, err = DeserializeSCTList(serializedSCT)
|
|
if err == nil {
|
|
t.Fatalf("DeserializeSCTList should raise an error when " +
|
|
"the SCT list length field and the list length don't match\n")
|
|
}
|
|
|
|
// Here we verify that an error is raised when the SCT length field is
|
|
// greater than its actual length
|
|
serializedSCT[0] = 0
|
|
serializedSCT[1] = 49
|
|
serializedSCT[2] = 1
|
|
_, err = DeserializeSCTList(serializedSCT)
|
|
if err == nil {
|
|
t.Fatalf("DeserializeSCTList should raise an error when " +
|
|
"the SCT length field and the SCT length don't match\n")
|
|
}
|
|
|
|
// Here we verify that an error is raised when the SCT length field is
|
|
// less than its actual length
|
|
serializedSCT[2] = 0
|
|
serializedSCT[3] = 0
|
|
_, err = DeserializeSCTList(serializedSCT)
|
|
if err == nil {
|
|
t.Fatalf("DeserializeSCTList should raise an error when " +
|
|
"the SCT length field and the SCT length don't match\n")
|
|
}
|
|
}
|
|
|
|
func TestSCTListFromOCSPResponse(t *testing.T) {
|
|
var response ocsp.Response
|
|
lst, err := SCTListFromOCSPResponse(&response)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(lst) != 0 {
|
|
t.Fatal("SCTListFromOCSPResponse should return an empty SCT list for an empty extension")
|
|
}
|
|
|
|
var zeroSCT ct.SignedCertificateTimestamp
|
|
serializedSCTList, err := SerializeSCTList([]ct.SignedCertificateTimestamp{zeroSCT})
|
|
if err != nil {
|
|
t.Fatal("failed to serialize SCT list")
|
|
}
|
|
serializedSCTList, err = asn1.Marshal(serializedSCTList)
|
|
if err != nil {
|
|
t.Fatal("failed to serialize SCT list")
|
|
}
|
|
// The value of Id below is the object identifier of the OCSP Stapling
|
|
// SCT extension (see section 3.3. of RFC 6962).
|
|
response.Extensions = []pkix.Extension{{
|
|
Id: asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 5},
|
|
Critical: false,
|
|
Value: serializedSCTList,
|
|
}}
|
|
lst, err = SCTListFromOCSPResponse(&response)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !sctEquals(zeroSCT, lst[0]) {
|
|
t.Fatal("SCTs don't match")
|
|
}
|
|
}
|