check hosts in ssl certificates
This commit is contained in:
1173
vendor/github.com/google/certificate-transparency-go/asn1/asn1_test.go
generated
vendored
1173
vendor/github.com/google/certificate-transparency-go/asn1/asn1_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
263
vendor/github.com/google/certificate-transparency-go/asn1/marshal_test.go
generated
vendored
263
vendor/github.com/google/certificate-transparency-go/asn1/marshal_test.go
generated
vendored
@ -1,263 +0,0 @@
|
||||
// Copyright 2009 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package asn1
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"math/big"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
type intStruct struct {
|
||||
A int
|
||||
}
|
||||
|
||||
type twoIntStruct struct {
|
||||
A int
|
||||
B int
|
||||
}
|
||||
|
||||
type bigIntStruct struct {
|
||||
A *big.Int
|
||||
}
|
||||
|
||||
type nestedStruct struct {
|
||||
A intStruct
|
||||
}
|
||||
|
||||
type rawContentsStruct struct {
|
||||
Raw RawContent
|
||||
A int
|
||||
}
|
||||
|
||||
type implicitTagTest struct {
|
||||
A int `asn1:"implicit,tag:5"`
|
||||
}
|
||||
|
||||
type explicitTagTest struct {
|
||||
A int `asn1:"explicit,tag:5"`
|
||||
}
|
||||
|
||||
type flagTest struct {
|
||||
A Flag `asn1:"tag:0,optional"`
|
||||
}
|
||||
|
||||
type generalizedTimeTest struct {
|
||||
A time.Time `asn1:"generalized"`
|
||||
}
|
||||
|
||||
type ia5StringTest struct {
|
||||
A string `asn1:"ia5"`
|
||||
}
|
||||
|
||||
type printableStringTest struct {
|
||||
A string `asn1:"printable"`
|
||||
}
|
||||
|
||||
type genericStringTest struct {
|
||||
A string
|
||||
}
|
||||
|
||||
type optionalRawValueTest struct {
|
||||
A RawValue `asn1:"optional"`
|
||||
}
|
||||
|
||||
type omitEmptyTest struct {
|
||||
A []string `asn1:"omitempty"`
|
||||
}
|
||||
|
||||
type defaultTest struct {
|
||||
A int `asn1:"optional,default:1"`
|
||||
}
|
||||
|
||||
type applicationTest struct {
|
||||
A int `asn1:"application,tag:0"`
|
||||
B int `asn1:"application,tag:1,explicit"`
|
||||
}
|
||||
|
||||
type numericStringTest struct {
|
||||
A string `asn1:"numeric"`
|
||||
}
|
||||
|
||||
type testAuthKeyID struct {
|
||||
ID []byte `asn1:"optional,tag:0"`
|
||||
Issuer RawValue `asn1:"optional,tag:1"`
|
||||
SerialNumber *big.Int `asn1:"optional,tag:2"`
|
||||
}
|
||||
|
||||
type testSET []int
|
||||
|
||||
var PST = time.FixedZone("PST", -8*60*60)
|
||||
|
||||
type marshalTest struct {
|
||||
in interface{}
|
||||
out string // hex encoded
|
||||
}
|
||||
|
||||
func farFuture() time.Time {
|
||||
t, err := time.Parse(time.RFC3339, "2100-04-05T12:01:01Z")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return t
|
||||
}
|
||||
|
||||
var marshalTests = []marshalTest{
|
||||
{10, "02010a"},
|
||||
{127, "02017f"},
|
||||
{128, "02020080"},
|
||||
{-128, "020180"},
|
||||
{-129, "0202ff7f"},
|
||||
{intStruct{64}, "3003020140"},
|
||||
{bigIntStruct{big.NewInt(0x123456)}, "30050203123456"},
|
||||
{twoIntStruct{64, 65}, "3006020140020141"},
|
||||
{nestedStruct{intStruct{127}}, "3005300302017f"},
|
||||
{[]byte{1, 2, 3}, "0403010203"},
|
||||
{implicitTagTest{64}, "3003850140"},
|
||||
{explicitTagTest{64}, "3005a503020140"},
|
||||
{flagTest{true}, "30028000"},
|
||||
{flagTest{false}, "3000"},
|
||||
{time.Unix(0, 0).UTC(), "170d3730303130313030303030305a"},
|
||||
{time.Unix(1258325776, 0).UTC(), "170d3039313131353232353631365a"},
|
||||
{time.Unix(1258325776, 0).In(PST), "17113039313131353134353631362d30383030"},
|
||||
{farFuture(), "180f32313030303430353132303130315a"},
|
||||
{generalizedTimeTest{time.Unix(1258325776, 0).UTC()}, "3011180f32303039313131353232353631365a"},
|
||||
{BitString{[]byte{0x80}, 1}, "03020780"},
|
||||
{BitString{[]byte{0x81, 0xf0}, 12}, "03030481f0"},
|
||||
{ObjectIdentifier([]int{1, 2, 3, 4}), "06032a0304"},
|
||||
{ObjectIdentifier([]int{1, 2, 840, 133549, 1, 1, 5}), "06092a864888932d010105"},
|
||||
{ObjectIdentifier([]int{2, 100, 3}), "0603813403"},
|
||||
{"test", "130474657374"},
|
||||
{
|
||||
"" +
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 127 times 'x'
|
||||
"137f" +
|
||||
"7878787878787878787878787878787878787878787878787878787878787878" +
|
||||
"7878787878787878787878787878787878787878787878787878787878787878" +
|
||||
"7878787878787878787878787878787878787878787878787878787878787878" +
|
||||
"78787878787878787878787878787878787878787878787878787878787878",
|
||||
},
|
||||
{
|
||||
"" +
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" +
|
||||
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", // This is 128 times 'x'
|
||||
"138180" +
|
||||
"7878787878787878787878787878787878787878787878787878787878787878" +
|
||||
"7878787878787878787878787878787878787878787878787878787878787878" +
|
||||
"7878787878787878787878787878787878787878787878787878787878787878" +
|
||||
"7878787878787878787878787878787878787878787878787878787878787878",
|
||||
},
|
||||
{ia5StringTest{"test"}, "3006160474657374"},
|
||||
{optionalRawValueTest{}, "3000"},
|
||||
{printableStringTest{"test"}, "3006130474657374"},
|
||||
{printableStringTest{"test*"}, "30071305746573742a"},
|
||||
{genericStringTest{"test"}, "3006130474657374"},
|
||||
{genericStringTest{"test*"}, "30070c05746573742a"},
|
||||
{genericStringTest{"test&"}, "30070c057465737426"},
|
||||
{rawContentsStruct{nil, 64}, "3003020140"},
|
||||
{rawContentsStruct{[]byte{0x30, 3, 1, 2, 3}, 64}, "3003010203"},
|
||||
{RawValue{Tag: 1, Class: 2, IsCompound: false, Bytes: []byte{1, 2, 3}}, "8103010203"},
|
||||
{testSET([]int{10}), "310302010a"},
|
||||
{omitEmptyTest{[]string{}}, "3000"},
|
||||
{omitEmptyTest{[]string{"1"}}, "30053003130131"},
|
||||
{"Σ", "0c02cea3"},
|
||||
{defaultTest{0}, "3003020100"},
|
||||
{defaultTest{1}, "3000"},
|
||||
{defaultTest{2}, "3003020102"},
|
||||
{applicationTest{1, 2}, "30084001016103020102"},
|
||||
{numericStringTest{"1 9"}, "30051203312039"},
|
||||
{testAuthKeyID{ID: []byte{0x01, 0x02, 0x03, 0x04}, SerialNumber: big.NewInt(0x12233445566)}, "300e8004010203048206012233445566"},
|
||||
{testAuthKeyID{ID: []byte{0x01, 0x02, 0x03, 0x04}}, "3006800401020304"},
|
||||
}
|
||||
|
||||
func TestMarshal(t *testing.T) {
|
||||
for i, test := range marshalTests {
|
||||
data, err := Marshal(test.in)
|
||||
if err != nil {
|
||||
t.Errorf("#%d failed: %s", i, err)
|
||||
}
|
||||
out, _ := hex.DecodeString(test.out)
|
||||
if !bytes.Equal(out, data) {
|
||||
t.Errorf("#%d got: %x want %x\n\t%q\n\t%q", i, data, out, data, out)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type marshalWithParamsTest struct {
|
||||
in interface{}
|
||||
params string
|
||||
out string // hex encoded
|
||||
}
|
||||
|
||||
var marshalWithParamsTests = []marshalWithParamsTest{
|
||||
{intStruct{10}, "set", "310302010a"},
|
||||
{intStruct{10}, "application", "600302010a"},
|
||||
}
|
||||
|
||||
func TestMarshalWithParams(t *testing.T) {
|
||||
for i, test := range marshalWithParamsTests {
|
||||
data, err := MarshalWithParams(test.in, test.params)
|
||||
if err != nil {
|
||||
t.Errorf("#%d failed: %s", i, err)
|
||||
}
|
||||
out, _ := hex.DecodeString(test.out)
|
||||
if !bytes.Equal(out, data) {
|
||||
t.Errorf("#%d got: %x want %x\n\t%q\n\t%q", i, data, out, data, out)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type marshalErrTest struct {
|
||||
in interface{}
|
||||
err string
|
||||
}
|
||||
|
||||
var marshalErrTests = []marshalErrTest{
|
||||
{bigIntStruct{nil}, "empty integer"},
|
||||
{numericStringTest{"a"}, "invalid character"},
|
||||
{ia5StringTest{"\xb0"}, "invalid character"},
|
||||
{printableStringTest{"!"}, "invalid character"},
|
||||
}
|
||||
|
||||
func TestMarshalError(t *testing.T) {
|
||||
for i, test := range marshalErrTests {
|
||||
_, err := Marshal(test.in)
|
||||
if err == nil {
|
||||
t.Errorf("#%d should fail, but success", i)
|
||||
continue
|
||||
}
|
||||
|
||||
if !strings.Contains(err.Error(), test.err) {
|
||||
t.Errorf("#%d got: %v want %v", i, err, test.err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestInvalidUTF8(t *testing.T) {
|
||||
_, err := Marshal(string([]byte{0xff, 0xff}))
|
||||
if err == nil {
|
||||
t.Errorf("invalid UTF8 string was accepted")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkMarshal(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
|
||||
for i := 0; i < b.N; i++ {
|
||||
for _, test := range marshalTests {
|
||||
Marshal(test.in)
|
||||
}
|
||||
}
|
||||
}
|
789
vendor/github.com/google/certificate-transparency-go/client/logclient_test.go
generated
vendored
789
vendor/github.com/google/certificate-transparency-go/client/logclient_test.go
generated
vendored
File diff suppressed because one or more lines are too long
482
vendor/github.com/google/certificate-transparency-go/client/multilog_test.go
generated
vendored
482
vendor/github.com/google/certificate-transparency-go/client/multilog_test.go
generated
vendored
@ -1,482 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/pem"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
tspb "github.com/golang/protobuf/ptypes/timestamp"
|
||||
ct "github.com/google/certificate-transparency-go"
|
||||
"github.com/google/certificate-transparency-go/client"
|
||||
"github.com/google/certificate-transparency-go/client/configpb"
|
||||
"github.com/google/certificate-transparency-go/testdata"
|
||||
"github.com/google/certificate-transparency-go/x509util"
|
||||
)
|
||||
|
||||
func TestNewTemporalLogClient(t *testing.T) {
|
||||
ts0, _ := ptypes.TimestampProto(time.Date(2010, 9, 19, 11, 00, 00, 00, time.UTC))
|
||||
ts1, _ := ptypes.TimestampProto(time.Date(2011, 9, 19, 11, 00, 00, 00, time.UTC))
|
||||
ts2, _ := ptypes.TimestampProto(time.Date(2012, 9, 19, 11, 00, 00, 00, time.UTC))
|
||||
ts2_5, _ := ptypes.TimestampProto(time.Date(2013, 3, 19, 11, 00, 00, 00, time.UTC))
|
||||
ts3, _ := ptypes.TimestampProto(time.Date(2013, 9, 19, 11, 00, 00, 00, time.UTC))
|
||||
ts4, _ := ptypes.TimestampProto(time.Date(2014, 9, 19, 11, 00, 00, 00, time.UTC))
|
||||
|
||||
tests := []struct {
|
||||
cfg configpb.TemporalLogConfig
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: nil, NotAfterLimit: nil},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: ts4},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: nil, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: ts4},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: nil, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: nil},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: nil},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "threeA", NotAfterStart: ts2_5, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: ts4},
|
||||
},
|
||||
},
|
||||
wantErr: "previous interval ended at",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: nil},
|
||||
},
|
||||
},
|
||||
wantErr: "previous interval ended at",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: nil, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts1},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: ts4},
|
||||
},
|
||||
},
|
||||
wantErr: "inverted",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: nil},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: nil},
|
||||
},
|
||||
},
|
||||
wantErr: "no upper bound",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "three", NotAfterStart: nil, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: nil},
|
||||
},
|
||||
},
|
||||
wantErr: "has no lower bound",
|
||||
},
|
||||
{
|
||||
wantErr: "empty",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{Shard: []*configpb.LogShardConfig{}},
|
||||
wantErr: "empty",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: ts1, NotAfterLimit: ts1},
|
||||
},
|
||||
},
|
||||
wantErr: "inverted",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: ts2, NotAfterLimit: ts1},
|
||||
},
|
||||
},
|
||||
wantErr: "inverted",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: &tspb.Timestamp{Seconds: -1, Nanos: -1}, NotAfterLimit: ts2},
|
||||
},
|
||||
},
|
||||
wantErr: "failed to parse",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "one", NotAfterStart: ts1, NotAfterLimit: &tspb.Timestamp{Seconds: -1, Nanos: -1}},
|
||||
},
|
||||
},
|
||||
wantErr: "failed to parse",
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{
|
||||
Uri: "one",
|
||||
NotAfterStart: nil,
|
||||
NotAfterLimit: nil,
|
||||
PublicKeyDer: []byte{0x01, 0x02},
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: "invalid public key",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
_, err := client.NewTemporalLogClient(test.cfg, nil)
|
||||
if err != nil {
|
||||
if test.wantErr == "" {
|
||||
t.Errorf("NewTemporalLogClient(%+v)=nil,%v; want _,nil", test.cfg, err)
|
||||
} else if !strings.Contains(err.Error(), test.wantErr) {
|
||||
t.Errorf("NewTemporalLogClient(%+v)=nil,%v; want _,%q", test.cfg, err, test.wantErr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.wantErr != "" {
|
||||
t.Errorf("NewTemporalLogClient(%+v)=_, nil; want _,%q", test.cfg, test.wantErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIndexByDate(t *testing.T) {
|
||||
time0 := time.Date(2010, 9, 19, 11, 00, 00, 00, time.UTC)
|
||||
time1 := time.Date(2011, 9, 19, 11, 00, 00, 00, time.UTC)
|
||||
time1_9 := time.Date(2012, 9, 19, 10, 59, 59, 00, time.UTC)
|
||||
time2 := time.Date(2012, 9, 19, 11, 00, 00, 00, time.UTC)
|
||||
time2_5 := time.Date(2013, 3, 19, 11, 00, 00, 00, time.UTC)
|
||||
time3 := time.Date(2013, 9, 19, 11, 00, 00, 00, time.UTC)
|
||||
time4 := time.Date(2014, 9, 19, 11, 00, 00, 00, time.UTC)
|
||||
|
||||
ts0, _ := ptypes.TimestampProto(time0)
|
||||
ts1, _ := ptypes.TimestampProto(time1)
|
||||
ts2, _ := ptypes.TimestampProto(time2)
|
||||
ts3, _ := ptypes.TimestampProto(time3)
|
||||
ts4, _ := ptypes.TimestampProto(time4)
|
||||
|
||||
allCfg := configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "zero", NotAfterStart: nil, NotAfterLimit: ts0},
|
||||
{Uri: "one", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: ts4},
|
||||
{Uri: "five", NotAfterStart: ts4, NotAfterLimit: nil},
|
||||
},
|
||||
}
|
||||
uptoCfg := configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "zero", NotAfterStart: nil, NotAfterLimit: ts0},
|
||||
{Uri: "one", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "two", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "three", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "four", NotAfterStart: ts3, NotAfterLimit: ts4},
|
||||
},
|
||||
}
|
||||
fromCfg :=
|
||||
configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "zero", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "one", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "two", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "three", NotAfterStart: ts3, NotAfterLimit: ts4},
|
||||
{Uri: "four", NotAfterStart: ts4, NotAfterLimit: nil},
|
||||
},
|
||||
}
|
||||
boundedCfg :=
|
||||
configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: "zero", NotAfterStart: ts0, NotAfterLimit: ts1},
|
||||
{Uri: "one", NotAfterStart: ts1, NotAfterLimit: ts2},
|
||||
{Uri: "two", NotAfterStart: ts2, NotAfterLimit: ts3},
|
||||
{Uri: "three", NotAfterStart: ts3, NotAfterLimit: ts4},
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
cfg configpb.TemporalLogConfig
|
||||
when time.Time
|
||||
want int
|
||||
wantErr bool
|
||||
}{
|
||||
{cfg: allCfg, when: time.Date(2000, 9, 19, 11, 00, 00, 00, time.UTC), want: 0},
|
||||
{cfg: allCfg, when: time0, want: 1},
|
||||
{cfg: allCfg, when: time1, want: 2},
|
||||
{cfg: allCfg, when: time1_9, want: 2},
|
||||
{cfg: allCfg, when: time2, want: 3},
|
||||
{cfg: allCfg, when: time2_5, want: 3},
|
||||
{cfg: allCfg, when: time3, want: 4},
|
||||
{cfg: allCfg, when: time4, want: 5},
|
||||
{cfg: allCfg, when: time.Date(2015, 9, 19, 11, 00, 00, 00, time.UTC), want: 5},
|
||||
|
||||
{cfg: uptoCfg, when: time.Date(2000, 9, 19, 11, 00, 00, 00, time.UTC), want: 0},
|
||||
{cfg: uptoCfg, when: time0, want: 1},
|
||||
{cfg: uptoCfg, when: time1, want: 2},
|
||||
{cfg: uptoCfg, when: time2, want: 3},
|
||||
{cfg: uptoCfg, when: time2_5, want: 3},
|
||||
{cfg: uptoCfg, when: time3, want: 4},
|
||||
{cfg: uptoCfg, when: time4, wantErr: true},
|
||||
{cfg: uptoCfg, when: time.Date(2015, 9, 19, 11, 00, 00, 00, time.UTC), wantErr: true},
|
||||
|
||||
{cfg: fromCfg, when: time.Date(2000, 9, 19, 11, 00, 00, 00, time.UTC), wantErr: true},
|
||||
{cfg: fromCfg, when: time0, want: 0},
|
||||
{cfg: fromCfg, when: time1, want: 1},
|
||||
{cfg: fromCfg, when: time2, want: 2},
|
||||
{cfg: fromCfg, when: time2_5, want: 2},
|
||||
{cfg: fromCfg, when: time3, want: 3},
|
||||
{cfg: fromCfg, when: time4, want: 4},
|
||||
{cfg: fromCfg, when: time.Date(2015, 9, 19, 11, 00, 00, 00, time.UTC), want: 4},
|
||||
|
||||
{cfg: boundedCfg, when: time.Date(2000, 9, 19, 11, 00, 00, 00, time.UTC), wantErr: true},
|
||||
{cfg: boundedCfg, when: time0, want: 0},
|
||||
{cfg: boundedCfg, when: time1, want: 1},
|
||||
{cfg: boundedCfg, when: time2, want: 2},
|
||||
{cfg: boundedCfg, when: time2_5, want: 2},
|
||||
{cfg: boundedCfg, when: time3, want: 3},
|
||||
{cfg: boundedCfg, when: time4, wantErr: true},
|
||||
{cfg: boundedCfg, when: time.Date(2015, 9, 19, 11, 00, 00, 00, time.UTC), wantErr: true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
tlc, err := client.NewTemporalLogClient(test.cfg, nil)
|
||||
if err != nil {
|
||||
t.Errorf("NewTemporalLogClient(%+v)=nil, %v; want _,nil", test.cfg, err)
|
||||
continue
|
||||
}
|
||||
got, err := tlc.IndexByDate(test.when)
|
||||
if err != nil {
|
||||
if !test.wantErr {
|
||||
t.Errorf("NewTemporalLogClient(%+v).idxByDate()=%d,%v; want %d,nil", test.cfg, got, err, test.want)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.wantErr {
|
||||
t.Errorf("NewTemporalLogClient(%+v).idxByDate(%v)=%d, nil; want _, 'no log found'", test.cfg, test.when, got)
|
||||
}
|
||||
if got != test.want {
|
||||
t.Errorf("NewTemporalLogClient(%+v).idxByDate(%v)=%d, nil; want %d, nil", test.cfg, test.when, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemporalAddChain(t *testing.T) {
|
||||
hs := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
switch r.URL.Path {
|
||||
case "/ct/v1/add-chain":
|
||||
data, _ := sctToJSON(testdata.TestCertProof)
|
||||
w.Write(data)
|
||||
case "/ct/v1/add-pre-chain":
|
||||
data, _ := sctToJSON(testdata.TestPreCertProof)
|
||||
w.Write(data)
|
||||
default:
|
||||
t.Fatalf("Incorrect URL path: %s", r.URL.Path)
|
||||
}
|
||||
}))
|
||||
defer hs.Close()
|
||||
|
||||
cert, err := x509util.CertificateFromPEM([]byte(testdata.TestCertPEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse certificate from PEM: %v", err)
|
||||
}
|
||||
certChain := []ct.ASN1Cert{{Data: cert.Raw}}
|
||||
precert, err := x509util.CertificateFromPEM([]byte(testdata.TestPreCertPEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse pre-certificate from PEM: %v", err)
|
||||
}
|
||||
issuer, err := x509util.CertificateFromPEM([]byte(testdata.CACertPEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse issuer certificate from PEM: %v", err)
|
||||
}
|
||||
precertChain := []ct.ASN1Cert{{Data: precert.Raw}, {Data: issuer.Raw}}
|
||||
// Both have Not After = Jun 1 00:00:00 2022 GMT
|
||||
ts1, _ := ptypes.TimestampProto(time.Date(2022, 5, 19, 11, 00, 00, 00, time.UTC))
|
||||
ts2, _ := ptypes.TimestampProto(time.Date(2022, 6, 19, 11, 00, 00, 00, time.UTC))
|
||||
p, _ := pem.Decode([]byte(testdata.LogPublicKeyPEM))
|
||||
if p == nil {
|
||||
t.Fatalf("Failed to parse public key from PEM: %v", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
cfg configpb.TemporalLogConfig
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: hs.URL, NotAfterStart: nil, NotAfterLimit: nil, PublicKeyDer: p.Bytes},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: hs.URL, NotAfterStart: nil, NotAfterLimit: ts2, PublicKeyDer: p.Bytes},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: hs.URL, NotAfterStart: ts1, NotAfterLimit: nil, PublicKeyDer: p.Bytes},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: hs.URL, NotAfterStart: ts1, NotAfterLimit: ts2, PublicKeyDer: p.Bytes},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: hs.URL, NotAfterStart: nil, NotAfterLimit: ts1, PublicKeyDer: p.Bytes},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
cfg: configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{Uri: hs.URL, NotAfterStart: ts2, NotAfterLimit: nil, PublicKeyDer: p.Bytes},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
for _, test := range tests {
|
||||
tlc, err := client.NewTemporalLogClient(test.cfg, nil)
|
||||
if err != nil {
|
||||
t.Errorf("NewTemporalLogClient(%+v)=nil, %v; want _,nil", test.cfg, err)
|
||||
continue
|
||||
}
|
||||
|
||||
_, err = tlc.AddChain(ctx, certChain)
|
||||
if err != nil {
|
||||
if !test.wantErr {
|
||||
t.Errorf("AddChain()=nil,%v; want sct,nil", err)
|
||||
}
|
||||
} else if test.wantErr {
|
||||
t.Errorf("AddChain()=sct,nil; want nil,_")
|
||||
}
|
||||
|
||||
_, err = tlc.AddPreChain(ctx, precertChain)
|
||||
if err != nil {
|
||||
if !test.wantErr {
|
||||
t.Errorf("AddPreChain()=nil,%v; want sct,nil", err)
|
||||
}
|
||||
} else if test.wantErr {
|
||||
t.Errorf("AddPreChain()=sct,nil; want nil,_")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTemporalAddChainErrors(t *testing.T) {
|
||||
hs := serveSCTAt(t, "/ct/v1/add-chain", testdata.TestCertProof)
|
||||
defer hs.Close()
|
||||
|
||||
cfg := configpb.TemporalLogConfig{
|
||||
Shard: []*configpb.LogShardConfig{
|
||||
{
|
||||
Uri: hs.URL,
|
||||
NotAfterStart: nil,
|
||||
NotAfterLimit: nil,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
tlc, err := client.NewTemporalLogClient(cfg, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewTemporalLogClient(%+v)=nil, %v; want _,nil", cfg, err)
|
||||
}
|
||||
|
||||
_, err = tlc.AddChain(ctx, nil)
|
||||
if err == nil {
|
||||
t.Errorf("AddChain(nil)=sct,nil; want nil, 'missing chain'")
|
||||
}
|
||||
_, err = tlc.AddChain(ctx, []ct.ASN1Cert{{Data: []byte{0x01, 0x02}}})
|
||||
if err == nil {
|
||||
t.Errorf("AddChain(nil)=sct,nil; want nil, 'failed to parse'")
|
||||
}
|
||||
|
||||
}
|
37
vendor/github.com/google/certificate-transparency-go/gossip/minimal/testdata/Makefile
generated
vendored
37
vendor/github.com/google/certificate-transparency-go/gossip/minimal/testdata/Makefile
generated
vendored
@ -1,37 +0,0 @@
|
||||
all: ca
|
||||
|
||||
# The following private keys are never regenerated.
|
||||
SERVER_PRIVKEYS=gossiper.privkey.pem
|
||||
|
||||
# Server public keys are derived from the corresponding private keys.
|
||||
SERVER_PUBKEYS=$(subst .privkey,.pubkey,$(SERVER_PRIVKEYS))
|
||||
|
||||
# Build public keys from private keys
|
||||
pubkeys: $(SERVER_PUBKEYS)
|
||||
gossiper.pubkey.pem: gossiper.privkey.pem
|
||||
openssl ec -in $< -pubout -out $@ -passin pass:$(GOSSIPER_PWD)
|
||||
|
||||
ROOT_CA_PRIVKEY=gossiper.privkey.pem
|
||||
ROOT_CA_PWD=hissing-sid
|
||||
|
||||
ca: root-ca.cert
|
||||
|
||||
# Fake Root CA
|
||||
root-ca.cert: gossiper.privkey.pem root-ca.cfg
|
||||
openssl req -new -x509 -config root-ca.cfg -set_serial 0x0406cafe -days 3650 -extensions v3_ca -inform pem -key gossiper.privkey.pem -passin pass:$(ROOT_CA_PWD) -out $@
|
||||
show-ca: root-ca.cert
|
||||
openssl x509 -inform pem -in $< -text -noout
|
||||
|
||||
# clean removes things that regenerate exactly the same.
|
||||
clean:
|
||||
rm -f $(SERVER_PUBKEYS)
|
||||
# distclean removes things that regenerate with changes (e.g. timestamped, randomized).
|
||||
distclean: clean
|
||||
rm -f $(SERVER_PUBKEYS) root-ca.cert
|
||||
|
||||
# The newkey target creates a fresh private key; should never be needed.
|
||||
newkey: fresh.privkey.pem
|
||||
fresh.privkey.pem:
|
||||
openssl ecparam -genkey -name prime256v1 -noout -out $@.unencrypted
|
||||
openssl ec -in $@.unencrypted -out $@ -des # Prompts for password
|
||||
rm -f $@.unencrypted
|
@ -1,32 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
public_key: {
|
||||
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
|
||||
}
|
||||
>
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source-2"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
public_key: {
|
||||
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
|
||||
}
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
17
vendor/github.com/google/certificate-transparency-go/gossip/minimal/testdata/goshawk.cfg
generated
vendored
17
vendor/github.com/google/certificate-transparency-go/gossip/minimal/testdata/goshawk.cfg
generated
vendored
@ -1,17 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
public_key: {
|
||||
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
|
||||
}
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
@ -1,8 +0,0 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-CBC,559BE893ECD7A88C
|
||||
|
||||
UOwSw+WlSv5LLiBZSCnR12FX13Hk1a3vavdpUde4W4qawQgJSMqLa3it8Lfadtnm
|
||||
GfGVqN+gF5KFiNWxgMs2qRcbdQ03ZlMmoH8Z8jPQHXvKseJvME8tZQWPvJ15rbXh
|
||||
G9Lcx7NYlm0miHPy3ras8ci58HSDqz9Z7yOdgHzPpiU=
|
||||
-----END EC PRIVATE KEY-----
|
@ -1,27 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
public_key: {
|
||||
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
|
||||
}
|
||||
>
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source-2"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
public_key: {
|
||||
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
|
||||
}
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
@ -1,13 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
@ -1,7 +0,0 @@
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
@ -1,13 +0,0 @@
|
||||
source_log: <
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
@ -1,19 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gone.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,19 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CARTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,20 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 10
|
||||
nanos: -20
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,22 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
public_key: {
|
||||
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d"
|
||||
}
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,15 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
public_key: {
|
||||
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
|
||||
}
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,18 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,15 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
@ -1,18 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,12 +0,0 @@
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,18 +0,0 @@
|
||||
source_log: <
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,15 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICQTCCAeegAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP
|
||||
MA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds
|
||||
ZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4
|
||||
MDIyNTA4MTA1M1oXDTI4MDIyMzA4MTA1M1owaTELMAkGA1UEBhMCR0IxDzANBgNV
|
||||
BAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK
|
||||
BgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49
|
||||
AgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH
|
||||
ccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijfTB7MB0GA1UdDgQWBBRq
|
||||
6hoXslGgHhrCVJMu4jrYlksyZjAfBgNVHSMEGDAWgBRq6hoXslGgHhrCVJMu4jrY
|
||||
lksyZjASBgNVHRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwICBDAVBgNVHSUE
|
||||
DjAMBgorBgEEAdZ5AgQGMAoGCCqGSM49BAMCA0gAMEUCIQCQCnWTIOlC6LqkcdH0
|
||||
fWZeNo5E3AaZBb9Tkv76ET2fJAIgOeGJvfiiOIlDV41/bIOg5eTHb/fxg80TCQBe
|
||||
6ia6ZS8=
|
||||
-----END CERTIFICATE-----
|
28
vendor/github.com/google/certificate-transparency-go/gossip/minimal/testdata/root-ca.cfg
generated
vendored
28
vendor/github.com/google/certificate-transparency-go/gossip/minimal/testdata/root-ca.cfg
generated
vendored
@ -1,28 +0,0 @@
|
||||
# OpenSSL configuration file.
|
||||
|
||||
[ req ]
|
||||
# Options for the `req` tool (`man req`).
|
||||
default_bits = 2048
|
||||
distinguished_name = req_distinguished_name
|
||||
prompt = no
|
||||
# SHA-1 is deprecated, so use SHA-2 instead.
|
||||
default_md = sha256
|
||||
# Extension to add when the -x509 option is used.
|
||||
x509_extensions = v3_ca
|
||||
# Try to force use of PrintableString throughout
|
||||
string_mask = pkix
|
||||
|
||||
[ req_distinguished_name ]
|
||||
C=GB
|
||||
ST=London
|
||||
L=London
|
||||
O=Google
|
||||
OU=Eng
|
||||
CN=TestGossiperRoot
|
||||
|
||||
[ v3_ca ]
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer
|
||||
basicConstraints = critical, CA:true, pathlen:3
|
||||
keyUsage = critical, keyCertSign
|
||||
extendedKeyUsage = 1.3.6.1.4.1.11129.2.4.6
|
22
vendor/github.com/google/certificate-transparency-go/gossip/minimal/testdata/test.cfg
generated
vendored
22
vendor/github.com/google/certificate-transparency-go/gossip/minimal/testdata/test.cfg
generated
vendored
@ -1,22 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
public_key: {
|
||||
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
|
||||
}
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
|
||||
>
|
@ -1,19 +0,0 @@
|
||||
source_log: <
|
||||
name: "theSourceOfAllSTHs"
|
||||
url: "http://example.com/ct-source"
|
||||
min_req_interval: <
|
||||
seconds: 3600
|
||||
>
|
||||
>
|
||||
dest_log: <
|
||||
name: "theDestinationOfAllSTHs"
|
||||
url: "http://example.com/ct-dest"
|
||||
min_req_interval: <
|
||||
seconds: 60
|
||||
>
|
||||
>
|
||||
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
|
||||
private_key: <
|
||||
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
|
||||
value: "\n\035testdata/gossiper.privkey.pem\022\013passing-sid"
|
||||
>
|
91
vendor/github.com/google/certificate-transparency-go/gossip/minimal/x509ext/x509ext.go
generated
vendored
91
vendor/github.com/google/certificate-transparency-go/gossip/minimal/x509ext/x509ext.go
generated
vendored
@ -1,91 +0,0 @@
|
||||
// Copyright 2018 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package x509ext holds extensions types and values for minimal gossip.
|
||||
package x509ext
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/certificate-transparency-go"
|
||||
"github.com/google/certificate-transparency-go/asn1"
|
||||
"github.com/google/certificate-transparency-go/tls"
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
)
|
||||
|
||||
// OIDExtensionCTSTH is the OID value for an X.509 extension that holds
|
||||
// a log STH value.
|
||||
// TODO(drysdale): get an official OID value
|
||||
var OIDExtensionCTSTH = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 5}
|
||||
|
||||
// OIDExtKeyUsageCTMinimalGossip is the OID value for an extended key usage
|
||||
// (EKU) that indicates a leaf certificate is used for the validation of STH
|
||||
// values from public CT logs.
|
||||
// TODO(drysdale): get an official OID value
|
||||
var OIDExtKeyUsageCTMinimalGossip = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 6}
|
||||
|
||||
// LogSTHInfo is the structure that gets TLS-encoded into the X.509 extension
|
||||
// identified by OIDExtensionCTSTH.
|
||||
type LogSTHInfo struct {
|
||||
LogURL []byte `tls:"maxlen:255"`
|
||||
Version tls.Enum `tls:"maxval:255"`
|
||||
TreeSize uint64
|
||||
Timestamp uint64
|
||||
SHA256RootHash ct.SHA256Hash
|
||||
TreeHeadSignature ct.DigitallySigned
|
||||
}
|
||||
|
||||
// LogSTHInfoFromCert retrieves the STH information embedded in a certificate.
|
||||
func LogSTHInfoFromCert(cert *x509.Certificate) (*LogSTHInfo, error) {
|
||||
for _, ext := range cert.Extensions {
|
||||
if ext.Id.Equal(OIDExtensionCTSTH) {
|
||||
var sthInfo LogSTHInfo
|
||||
rest, err := tls.Unmarshal(ext.Value, &sthInfo)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal STH: %v", err)
|
||||
} else if len(rest) > 0 {
|
||||
return nil, fmt.Errorf("trailing data (%d bytes) after STH", len(rest))
|
||||
}
|
||||
return &sthInfo, nil
|
||||
}
|
||||
}
|
||||
return nil, errors.New("no STH extension found")
|
||||
}
|
||||
|
||||
// HasSTHInfo indicates whether a certificate has embedded STH information.
|
||||
func HasSTHInfo(cert *x509.Certificate) bool {
|
||||
for _, ext := range cert.Extensions {
|
||||
if ext.Id.Equal(OIDExtensionCTSTH) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// STHFromCert retrieves the STH embedded in a certificate; note the returned STH
|
||||
// does not have the LogID field filled in.
|
||||
func STHFromCert(cert *x509.Certificate) (*ct.SignedTreeHead, error) {
|
||||
sthInfo, err := LogSTHInfoFromCert(cert)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ct.SignedTreeHead{
|
||||
Version: ct.Version(sthInfo.Version),
|
||||
TreeSize: sthInfo.TreeSize,
|
||||
Timestamp: sthInfo.Timestamp,
|
||||
SHA256RootHash: sthInfo.SHA256RootHash,
|
||||
TreeHeadSignature: sthInfo.TreeHeadSignature,
|
||||
}, nil
|
||||
}
|
150
vendor/github.com/google/certificate-transparency-go/gossip/minimal/x509ext/x509ext_test.go
generated
vendored
150
vendor/github.com/google/certificate-transparency-go/gossip/minimal/x509ext/x509ext_test.go
generated
vendored
@ -1,150 +0,0 @@
|
||||
// Copyright 2018 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package x509ext_test
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/certificate-transparency-go"
|
||||
"github.com/google/certificate-transparency-go/gossip/minimal/x509ext"
|
||||
"github.com/google/certificate-transparency-go/tls"
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
"github.com/google/certificate-transparency-go/x509/pkix"
|
||||
)
|
||||
|
||||
var (
|
||||
// pilotPubKeyPEM is the public key for Google's Pilot log.
|
||||
pilotPubKeyPEM = []byte(`-----BEGIN PUBLIC KEY-----
|
||||
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHT
|
||||
DM0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA==
|
||||
-----END PUBLIC KEY-----`)
|
||||
)
|
||||
|
||||
func TestSTHFromCert(t *testing.T) {
|
||||
rawPubKey, _ := pem.Decode(pilotPubKeyPEM)
|
||||
pubKey, _, _, err := ct.PublicKeyFromPEM(pilotPubKeyPEM)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to decode test pubkey data: %v", err)
|
||||
}
|
||||
validSTH := x509ext.LogSTHInfo{
|
||||
LogURL: []byte("http://ct.example.com/log"),
|
||||
Version: 0,
|
||||
TreeSize: 7834120,
|
||||
Timestamp: 1519395540364,
|
||||
SHA256RootHash: [...]byte{
|
||||
0xfe, 0xc0, 0xed, 0xe1, 0xbe, 0xf1, 0xa2, 0x25, 0xc3, 0x72, 0xa6, 0x44, 0x1b, 0xa2, 0xd5, 0xdd, 0x3b, 0xbb, 0x9b, 0x7b, 0xa9, 0x79, 0xd1, 0xa7, 0x03, 0xe7, 0xfe, 0x81, 0x49, 0x75, 0x85, 0xfb,
|
||||
},
|
||||
TreeHeadSignature: ct.DigitallySigned{
|
||||
Algorithm: tls.SignatureAndHashAlgorithm{Hash: tls.SHA256, Signature: tls.ECDSA},
|
||||
Signature: dehex("220164e031604aa2a0b68887ba668cefb3e0046e455d6323c3df38b8d50108895d70220146199ee1d759a029d8b37ce8701d2ca47a387bad8ac8ef1cb84b77bc0820ed"),
|
||||
},
|
||||
}
|
||||
sthData, err := tls.Marshal(validSTH)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to marshal STH: %v", err)
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
name string
|
||||
cert x509.Certificate
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
name: "ValidSTH",
|
||||
cert: x509.Certificate{
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
PublicKey: pubKey,
|
||||
RawSubjectPublicKeyInfo: rawPubKey.Bytes,
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Test STH holder",
|
||||
},
|
||||
Extensions: []pkix.Extension{
|
||||
{Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: sthData},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "MissingSTH",
|
||||
cert: x509.Certificate{
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Test STH holder",
|
||||
},
|
||||
},
|
||||
wantErr: "no STH extension found",
|
||||
},
|
||||
{
|
||||
name: "TrailingData",
|
||||
cert: x509.Certificate{
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Test STH holder",
|
||||
},
|
||||
Extensions: []pkix.Extension{
|
||||
{Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: append(sthData, 0xff)},
|
||||
},
|
||||
},
|
||||
wantErr: "trailing data",
|
||||
},
|
||||
{
|
||||
name: "InvalidSTH",
|
||||
cert: x509.Certificate{
|
||||
NotBefore: time.Now(),
|
||||
NotAfter: time.Now().Add(24 * time.Hour),
|
||||
Subject: pkix.Name{
|
||||
CommonName: "Test STH holder",
|
||||
},
|
||||
Extensions: []pkix.Extension{
|
||||
{Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: []byte{0xff}},
|
||||
},
|
||||
},
|
||||
wantErr: "failed to unmarshal",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
got, err := x509ext.STHFromCert(&test.cert)
|
||||
if err != nil {
|
||||
if test.wantErr == "" {
|
||||
t.Errorf("STHFromCert(%+v)=nil,%v; want _,nil", test.cert, err)
|
||||
} else if !strings.Contains(err.Error(), test.wantErr) {
|
||||
t.Errorf("STHFromCert(%+v)=nil,%v; want nil,err containing %q", test.cert, err, test.wantErr)
|
||||
}
|
||||
return
|
||||
}
|
||||
if test.wantErr != "" {
|
||||
t.Errorf("STHFromCert(%+v)=_,nil; want nil,err containing %q", test.cert, test.wantErr)
|
||||
}
|
||||
t.Logf("retrieved STH %+v", got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func dehex(h string) []byte {
|
||||
d, err := hex.DecodeString(h)
|
||||
if err != nil {
|
||||
panic(fmt.Sprintf("hard-coded data %q failed to decode! %v", h, err))
|
||||
}
|
||||
return d
|
||||
}
|
117
vendor/github.com/google/certificate-transparency-go/jsonclient/backoff_test.go
generated
vendored
117
vendor/github.com/google/certificate-transparency-go/jsonclient/backoff_test.go
generated
vendored
@ -1,117 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package jsonclient
|
||||
|
||||
import (
|
||||
"math"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
const testLeeway = 25 * time.Microsecond
|
||||
|
||||
func fuzzyTimeEquals(a, b time.Time, leeway time.Duration) bool {
|
||||
diff := math.Abs(float64(a.Sub(b).Nanoseconds()))
|
||||
if diff < float64(leeway.Nanoseconds()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func fuzzyDurationEquals(a, b time.Duration, leeway time.Duration) bool {
|
||||
diff := math.Abs(float64(a.Nanoseconds() - b.Nanoseconds()))
|
||||
if diff < float64(leeway.Nanoseconds()) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func TestBackoff(t *testing.T) {
|
||||
b := backoff{}
|
||||
|
||||
// Test that the interval increases as expected
|
||||
for i := uint(0); i < maxMultiplier; i++ {
|
||||
n := time.Now()
|
||||
interval := b.set(nil)
|
||||
if interval != time.Second*(1<<i) {
|
||||
t.Fatalf("backoff.set(nil)=%v; want %v", interval, time.Second*(1<<i))
|
||||
}
|
||||
expected := n.Add(interval)
|
||||
until := b.until()
|
||||
if !fuzzyTimeEquals(expected, until, time.Millisecond) {
|
||||
t.Fatalf("backoff.until()=%v; want %v (+ 0-250ms)", expected, until)
|
||||
}
|
||||
|
||||
// reset notBefore
|
||||
b.notBefore = time.Time{}
|
||||
}
|
||||
|
||||
// Test that multiplier doesn't go above maxMultiplier
|
||||
b.multiplier = maxMultiplier
|
||||
b.notBefore = time.Time{}
|
||||
interval := b.set(nil)
|
||||
if b.multiplier > maxMultiplier {
|
||||
t.Fatalf("backoff.multiplier=%v; want %v", b.multiplier, maxMultiplier)
|
||||
}
|
||||
if interval > time.Second*(1<<(maxMultiplier-1)) {
|
||||
t.Fatalf("backoff.set(nil)=%v; want %v", interval, 1<<(maxMultiplier-1)*time.Second)
|
||||
}
|
||||
|
||||
// Test decreaseMultiplier properly decreases the multiplier
|
||||
b.multiplier = 1
|
||||
b.notBefore = time.Time{}
|
||||
b.decreaseMultiplier()
|
||||
if b.multiplier != 0 {
|
||||
t.Fatalf("backoff.multiplier=%v; want %v", b.multiplier, 0)
|
||||
}
|
||||
|
||||
// Test decreaseMultiplier doesn't reduce multiplier below 0
|
||||
b.decreaseMultiplier()
|
||||
if b.multiplier != 0 {
|
||||
t.Fatalf("backoff.multiplier=%v; want %v", b.multiplier, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBackoffOverride(t *testing.T) {
|
||||
b := backoff{}
|
||||
for _, tc := range []struct {
|
||||
notBefore time.Time
|
||||
override time.Duration
|
||||
expectedInterval time.Duration
|
||||
}{
|
||||
{
|
||||
notBefore: time.Now().Add(time.Hour),
|
||||
override: time.Second * 1800,
|
||||
expectedInterval: time.Hour,
|
||||
},
|
||||
{
|
||||
notBefore: time.Now().Add(time.Hour),
|
||||
override: time.Second * 7200,
|
||||
expectedInterval: 2 * time.Hour,
|
||||
},
|
||||
{
|
||||
notBefore: time.Time{},
|
||||
override: time.Second * 7200,
|
||||
expectedInterval: 2 * time.Hour,
|
||||
},
|
||||
} {
|
||||
b.multiplier = 0
|
||||
b.notBefore = tc.notBefore
|
||||
interval := b.set(&tc.override)
|
||||
if !fuzzyDurationEquals(tc.expectedInterval, interval, testLeeway) {
|
||||
t.Fatalf("backoff.set(%v)=%v; want %v", tc.override, interval, tc.expectedInterval)
|
||||
}
|
||||
}
|
||||
}
|
446
vendor/github.com/google/certificate-transparency-go/jsonclient/client_test.go
generated
vendored
446
vendor/github.com/google/certificate-transparency-go/jsonclient/client_test.go
generated
vendored
@ -1,446 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package jsonclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/certificate-transparency-go/testdata"
|
||||
)
|
||||
|
||||
func publicKeyPEMToDER(key string) []byte {
|
||||
block, _ := pem.Decode([]byte(key))
|
||||
if block == nil {
|
||||
panic("failed to decode public key PEM")
|
||||
}
|
||||
if block.Type != "PUBLIC KEY" {
|
||||
panic("PEM does not have type 'PUBLIC KEY'")
|
||||
}
|
||||
return block.Bytes
|
||||
}
|
||||
|
||||
func TestNewJSONClient(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
opts Options
|
||||
errstr string
|
||||
}{
|
||||
{
|
||||
name: "invalid PublicKey",
|
||||
opts: Options{PublicKey: "bogus"},
|
||||
errstr: "no PEM block",
|
||||
},
|
||||
{
|
||||
name: "invalid PublicKeyDER",
|
||||
opts: Options{PublicKeyDER: []byte("bogus")},
|
||||
errstr: "asn1: structure error",
|
||||
},
|
||||
{
|
||||
name: "RSA PublicKey",
|
||||
opts: Options{PublicKey: testdata.RsaPublicKeyPEM},
|
||||
},
|
||||
{
|
||||
name: "RSA PublicKeyDER",
|
||||
opts: Options{PublicKeyDER: publicKeyPEMToDER(testdata.RsaPublicKeyPEM)},
|
||||
},
|
||||
{
|
||||
name: "ECDSA PublicKey",
|
||||
opts: Options{PublicKey: testdata.EcdsaPublicKeyPEM},
|
||||
},
|
||||
{
|
||||
name: "ECDSA PublicKeyDER",
|
||||
opts: Options{PublicKeyDER: publicKeyPEMToDER(testdata.EcdsaPublicKeyPEM)},
|
||||
},
|
||||
{
|
||||
name: "DSA PublicKey",
|
||||
opts: Options{PublicKey: testdata.DsaPublicKeyPEM},
|
||||
errstr: "Unsupported public key type",
|
||||
},
|
||||
{
|
||||
name: "DSA PublicKeyDER",
|
||||
opts: Options{PublicKeyDER: publicKeyPEMToDER(testdata.DsaPublicKeyPEM)},
|
||||
errstr: "Unsupported public key type",
|
||||
},
|
||||
{
|
||||
name: "PublicKey contains trailing garbage",
|
||||
opts: Options{PublicKey: testdata.RsaPublicKeyPEM + "bogus"},
|
||||
errstr: "extra data found",
|
||||
},
|
||||
{
|
||||
name: "PublicKeyDER contains trailing garbage",
|
||||
opts: Options{PublicKeyDER: append(publicKeyPEMToDER(testdata.RsaPublicKeyPEM), []byte("deadbeef")...)},
|
||||
errstr: "trailing data",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
client, err := New("http://127.0.0.1", nil, test.opts)
|
||||
if test.errstr != "" {
|
||||
if err == nil {
|
||||
t.Errorf("%v: New()=%p,nil; want error %q", test.name, client, test.errstr)
|
||||
} else if !strings.Contains(err.Error(), test.errstr) {
|
||||
t.Errorf("%v: New()=nil,%q; want error %q", test.name, err, test.errstr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("%v: New()=nil,%q; want no error", test.name, err)
|
||||
} else if client == nil {
|
||||
t.Errorf("%v: New()=nil,nil; want client", test.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type TestStruct struct {
|
||||
TreeSize int `json:"tree_size"`
|
||||
Timestamp int `json:"timestamp"`
|
||||
Data string `json:"data"`
|
||||
}
|
||||
|
||||
type TestParams struct {
|
||||
RespCode int `json:"rc"`
|
||||
}
|
||||
|
||||
func MockServer(t *testing.T, failCount int, retryAfter int) *httptest.Server {
|
||||
t.Helper()
|
||||
mu := sync.Mutex{}
|
||||
return httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
switch r.URL.Path {
|
||||
case "/struct/path":
|
||||
fmt.Fprintf(w, `{"tree_size": 11, "timestamp": 99}`)
|
||||
case "/struct/params":
|
||||
var s TestStruct
|
||||
if r.Method == http.MethodGet {
|
||||
s.TreeSize, _ = strconv.Atoi(r.FormValue("tree_size"))
|
||||
s.Timestamp, _ = strconv.Atoi(r.FormValue("timestamp"))
|
||||
s.Data = r.FormValue("data")
|
||||
} else {
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(&s)
|
||||
if err != nil {
|
||||
panic("Failed to decode: " + err.Error())
|
||||
}
|
||||
defer r.Body.Close()
|
||||
}
|
||||
fmt.Fprintf(w, `{"tree_size": %d, "timestamp": %d, "data": "%s"}`, s.TreeSize, s.Timestamp, s.Data)
|
||||
case "/error":
|
||||
var params TestParams
|
||||
if r.Method == http.MethodGet {
|
||||
params.RespCode, _ = strconv.Atoi(r.FormValue("rc"))
|
||||
} else {
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
err := decoder.Decode(¶ms)
|
||||
if err != nil {
|
||||
panic("Failed to decode: " + err.Error())
|
||||
}
|
||||
defer r.Body.Close()
|
||||
}
|
||||
http.Error(w, "error page", params.RespCode)
|
||||
case "/malformed":
|
||||
fmt.Fprintf(w, `{"tree_size": 11, "timestamp": 99`) // no closing }
|
||||
case "/retry":
|
||||
if failCount > 0 {
|
||||
failCount--
|
||||
if retryAfter != 0 {
|
||||
if retryAfter > 0 {
|
||||
w.Header().Add("Retry-After", strconv.Itoa(retryAfter))
|
||||
}
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusRequestTimeout)
|
||||
}
|
||||
} else {
|
||||
fmt.Fprintf(w, `{"tree_size": 11, "timestamp": 99}`)
|
||||
}
|
||||
case "/retry-rfc1123":
|
||||
if failCount > 0 {
|
||||
failCount--
|
||||
w.Header().Add("Retry-After", time.Now().Add(time.Duration(retryAfter)*time.Second).Format(time.RFC1123))
|
||||
w.WriteHeader(http.StatusServiceUnavailable)
|
||||
} else {
|
||||
fmt.Fprintf(w, `{"tree_size": 11, "timestamp": 99}`)
|
||||
}
|
||||
default:
|
||||
t.Fatalf("Unhandled URL path: %s", r.URL.Path)
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
func TestGetAndParse(t *testing.T) {
|
||||
rc := regexp.MustCompile
|
||||
tests := []struct {
|
||||
uri string
|
||||
params map[string]string
|
||||
status int
|
||||
result TestStruct
|
||||
errstr *regexp.Regexp
|
||||
wantBody bool
|
||||
}{
|
||||
{uri: "/short%", errstr: rc("invalid URL escape")},
|
||||
{uri: "/malformed", status: http.StatusOK, errstr: rc("unexpected EOF"), wantBody: true},
|
||||
{uri: "/error", params: map[string]string{"rc": "404"}, status: http.StatusNotFound, wantBody: true},
|
||||
{uri: "/error", params: map[string]string{"rc": "403"}, status: http.StatusForbidden, wantBody: true},
|
||||
{uri: "/struct/path", status: http.StatusOK, result: TestStruct{11, 99, ""}, wantBody: true},
|
||||
{
|
||||
uri: "/struct/params",
|
||||
status: http.StatusOK,
|
||||
params: map[string]string{"tree_size": "42", "timestamp": "88", "data": "abcd"},
|
||||
result: TestStruct{42, 88, "abcd"},
|
||||
wantBody: true,
|
||||
},
|
||||
}
|
||||
|
||||
ts := MockServer(t, -1, 0)
|
||||
defer ts.Close()
|
||||
|
||||
logClient, err := New(ts.URL, &http.Client{}, Options{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
for _, test := range tests {
|
||||
var result TestStruct
|
||||
httpRsp, body, err := logClient.GetAndParse(ctx, test.uri, test.params, &result)
|
||||
if gotBody := (body != nil); gotBody != test.wantBody {
|
||||
t.Errorf("GetAndParse(%q) got body? %v, want? %v", test.uri, gotBody, test.wantBody)
|
||||
}
|
||||
if test.errstr != nil {
|
||||
if err == nil {
|
||||
t.Errorf("GetAndParse(%q)=%+v,_,nil; want error matching %q", test.uri, result, test.errstr)
|
||||
} else if !test.errstr.MatchString(err.Error()) {
|
||||
t.Errorf("GetAndParse(%q)=nil,_,%q; want error matching %q", test.uri, err.Error(), test.errstr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if httpRsp.StatusCode != test.status {
|
||||
t.Errorf("GetAndParse('%s') got status %d; want %d", test.uri, httpRsp.StatusCode, test.status)
|
||||
}
|
||||
if test.status == http.StatusOK {
|
||||
if err != nil {
|
||||
t.Errorf("GetAndParse(%q)=nil,_,%q; want %+v", test.uri, err.Error(), result)
|
||||
}
|
||||
if !reflect.DeepEqual(result, test.result) {
|
||||
t.Errorf("GetAndParse(%q)=%+v,_,nil; want %+v", test.uri, result, test.result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestPostAndParse(t *testing.T) {
|
||||
rc := regexp.MustCompile
|
||||
tests := []struct {
|
||||
uri string
|
||||
request interface{}
|
||||
status int
|
||||
result TestStruct
|
||||
errstr *regexp.Regexp
|
||||
wantBody bool
|
||||
}{
|
||||
{uri: "/short%", errstr: rc("invalid URL escape")},
|
||||
{uri: "/struct/params", request: json.Number(`invalid`), errstr: rc("invalid number literal")},
|
||||
{uri: "/malformed", status: http.StatusOK, errstr: rc("unexpected end of JSON"), wantBody: true},
|
||||
{uri: "/error", request: TestParams{RespCode: 404}, status: http.StatusNotFound, wantBody: true},
|
||||
{uri: "/error", request: TestParams{RespCode: 403}, status: http.StatusForbidden, wantBody: true},
|
||||
{uri: "/struct/path", status: http.StatusOK, result: TestStruct{11, 99, ""}, wantBody: true},
|
||||
{
|
||||
uri: "/struct/params",
|
||||
status: http.StatusOK,
|
||||
request: TestStruct{42, 88, "abcd"},
|
||||
result: TestStruct{42, 88, "abcd"},
|
||||
wantBody: true,
|
||||
},
|
||||
}
|
||||
|
||||
ts := MockServer(t, -1, 0)
|
||||
defer ts.Close()
|
||||
|
||||
logClient, err := New(ts.URL, &http.Client{}, Options{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
ctx := context.Background()
|
||||
|
||||
for _, test := range tests {
|
||||
var result TestStruct
|
||||
httpRsp, body, err := logClient.PostAndParse(ctx, test.uri, test.request, &result)
|
||||
if gotBody := (body != nil); gotBody != test.wantBody {
|
||||
t.Errorf("GetAndParse(%q) returned body %v, wanted %v", test.uri, gotBody, test.wantBody)
|
||||
}
|
||||
if test.errstr != nil {
|
||||
if err == nil {
|
||||
t.Errorf("PostAndParse(%q)=%+v,nil; want error matching %q", test.uri, result, test.errstr)
|
||||
} else if !test.errstr.MatchString(err.Error()) {
|
||||
t.Errorf("PostAndParse(%q)=nil,%q; want error matching %q", test.uri, err.Error(), test.errstr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if httpRsp.StatusCode != test.status {
|
||||
t.Errorf("PostAndParse(%q) got status %d; want %d", test.uri, httpRsp.StatusCode, test.status)
|
||||
}
|
||||
if test.status == http.StatusOK {
|
||||
if err != nil {
|
||||
t.Errorf("PostAndParse(%q)=nil,%q; want %+v", test.uri, err.Error(), test.result)
|
||||
}
|
||||
if !reflect.DeepEqual(result, test.result) {
|
||||
t.Errorf("PostAndParse(%q)=%+v,nil; want %+v", test.uri, result, test.result)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mockBackoff is not safe for concurrent usage
|
||||
type mockBackoff struct {
|
||||
override time.Duration
|
||||
}
|
||||
|
||||
func (mb *mockBackoff) set(o *time.Duration) time.Duration {
|
||||
if o != nil {
|
||||
mb.override = *o
|
||||
}
|
||||
return 0
|
||||
}
|
||||
func (mb *mockBackoff) decreaseMultiplier() {}
|
||||
func (mb *mockBackoff) until() time.Time { return time.Time{} }
|
||||
|
||||
func TestPostAndParseWithRetry(t *testing.T) {
|
||||
tests := []struct {
|
||||
uri string
|
||||
request interface{}
|
||||
deadlineSecs int // -1 indicates no deadline
|
||||
retryAfter int // -1 indicates generate 503 with no Retry-After
|
||||
failCount int
|
||||
errstr string
|
||||
expectedBackoff time.Duration // 0 indicates no expected backoff override set
|
||||
}{
|
||||
{
|
||||
uri: "/error",
|
||||
request: TestParams{RespCode: 418},
|
||||
deadlineSecs: -1,
|
||||
retryAfter: 0,
|
||||
failCount: 0,
|
||||
errstr: "teapot",
|
||||
expectedBackoff: 0,
|
||||
},
|
||||
{
|
||||
uri: "/short%",
|
||||
request: nil,
|
||||
deadlineSecs: 0,
|
||||
retryAfter: 0,
|
||||
failCount: 0,
|
||||
errstr: "deadline exceeded",
|
||||
expectedBackoff: 0,
|
||||
},
|
||||
{
|
||||
uri: "/retry",
|
||||
request: nil,
|
||||
deadlineSecs: -1,
|
||||
retryAfter: 0,
|
||||
failCount: 1,
|
||||
errstr: "",
|
||||
expectedBackoff: 0,
|
||||
},
|
||||
{
|
||||
uri: "/retry",
|
||||
request: nil,
|
||||
deadlineSecs: -1,
|
||||
retryAfter: 5,
|
||||
failCount: 1,
|
||||
errstr: "",
|
||||
expectedBackoff: 5 * time.Second,
|
||||
},
|
||||
{
|
||||
uri: "/retry-rfc1123",
|
||||
request: nil,
|
||||
deadlineSecs: -1,
|
||||
retryAfter: 5,
|
||||
failCount: 1,
|
||||
errstr: "",
|
||||
expectedBackoff: 5 * time.Second,
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
ts := MockServer(t, test.failCount, test.retryAfter)
|
||||
defer ts.Close()
|
||||
|
||||
logClient, err := New(ts.URL, &http.Client{}, Options{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
mb := mockBackoff{}
|
||||
logClient.backoff = &mb
|
||||
ctx := context.Background()
|
||||
if test.deadlineSecs >= 0 {
|
||||
var cancel context.CancelFunc
|
||||
ctx, cancel = context.WithDeadline(context.Background(), time.Now().Add(time.Duration(test.deadlineSecs)*time.Second))
|
||||
defer cancel()
|
||||
}
|
||||
|
||||
var result TestStruct
|
||||
httpRsp, _, err := logClient.PostAndParseWithRetry(ctx, test.uri, test.request, &result)
|
||||
if test.errstr != "" {
|
||||
if err == nil {
|
||||
t.Errorf("PostAndParseWithRetry()=%+v,nil; want error %q", result, test.errstr)
|
||||
} else if !strings.Contains(err.Error(), test.errstr) {
|
||||
t.Errorf("PostAndParseWithRetry()=nil,%q; want error %q", err.Error(), test.errstr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("PostAndParseWithRetry()=nil,%q; want no error", err.Error())
|
||||
} else if httpRsp.StatusCode != http.StatusOK {
|
||||
t.Errorf("PostAndParseWithRetry() got status %d; want OK(404)", httpRsp.StatusCode)
|
||||
}
|
||||
if test.expectedBackoff > 0 && !fuzzyDurationEquals(test.expectedBackoff, mb.override, time.Second) {
|
||||
t.Errorf("Unexpected backoff override set: got: %s, wanted: %s", mb.override, test.expectedBackoff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestContextRequired(t *testing.T) {
|
||||
ts := MockServer(t, -1, 0)
|
||||
defer ts.Close()
|
||||
|
||||
logClient, err := New(ts.URL, &http.Client{}, Options{})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var result TestStruct
|
||||
_, _, err = logClient.GetAndParse(nil, "/struct/path", nil, &result)
|
||||
if err == nil {
|
||||
t.Errorf("GetAndParse() succeeded with empty Context")
|
||||
}
|
||||
_, _, err = logClient.PostAndParse(nil, "/struct/path", nil, &result)
|
||||
if err == nil {
|
||||
t.Errorf("PostAndParse() succeeded with empty Context")
|
||||
}
|
||||
_, _, err = logClient.PostAndParseWithRetry(nil, "/struct/path", nil, &result)
|
||||
if err == nil {
|
||||
t.Errorf("PostAndParseWithRetry() succeeded with empty Context")
|
||||
}
|
||||
}
|
513
vendor/github.com/google/certificate-transparency-go/serialization_test.go
generated
vendored
513
vendor/github.com/google/certificate-transparency-go/serialization_test.go
generated
vendored
@ -1,513 +0,0 @@
|
||||
// Copyright 2015 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ct
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"io/ioutil"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/certificate-transparency-go/tls"
|
||||
)
|
||||
|
||||
func dh(h string) []byte {
|
||||
r, err := hex.DecodeString(h)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
const (
|
||||
defaultSCTLogIDString string = "iamapublickeyshatwofivesixdigest"
|
||||
defaultSCTTimestamp uint64 = 1234
|
||||
defaultSCTSignatureString string = "\x04\x03\x00\x09signature"
|
||||
defaultCertifictateString string = "certificate"
|
||||
defaultPrecertString string = "precert"
|
||||
defaultPrecertIssuerHashString string = "iamapublickeyshatwofivesixdigest"
|
||||
defaultPrecertTBSString string = "tbs"
|
||||
|
||||
defaultCertificateSCTSignatureInputHexString string =
|
||||
// version, 1 byte
|
||||
"00" +
|
||||
// signature type, 1 byte
|
||||
"00" +
|
||||
// timestamp, 8 bytes
|
||||
"00000000000004d2" +
|
||||
// entry type, 2 bytes
|
||||
"0000" +
|
||||
// leaf certificate length, 3 bytes
|
||||
"00000b" +
|
||||
// leaf certificate, 11 bytes
|
||||
"6365727469666963617465" +
|
||||
// extensions length, 2 bytes
|
||||
"0000" +
|
||||
// extensions, 0 bytes
|
||||
""
|
||||
|
||||
defaultPrecertSCTSignatureInputHexString string =
|
||||
// version, 1 byte
|
||||
"00" +
|
||||
// signature type, 1 byte
|
||||
"00" +
|
||||
// timestamp, 8 bytes
|
||||
"00000000000004d2" +
|
||||
// entry type, 2 bytes
|
||||
"0001" +
|
||||
// issuer key hash, 32 bytes
|
||||
"69616d617075626c69636b657973686174776f66697665736978646967657374" +
|
||||
// tbs certificate length, 3 bytes
|
||||
"000003" +
|
||||
// tbs certificate, 3 bytes
|
||||
"746273" +
|
||||
// extensions length, 2 bytes
|
||||
"0000" +
|
||||
// extensions, 0 bytes
|
||||
""
|
||||
|
||||
defaultSTHSignedHexString string =
|
||||
// version, 1 byte
|
||||
"00" +
|
||||
// signature type, 1 byte
|
||||
"01" +
|
||||
// timestamp, 8 bytes
|
||||
"0000000000000929" +
|
||||
// tree size, 8 bytes
|
||||
"0000000000000006" +
|
||||
// root hash, 32 bytes
|
||||
"696d757374626565786163746c7974686972747974776f62797465736c6f6e67"
|
||||
|
||||
defaultSCTHexString string =
|
||||
// version, 1 byte
|
||||
"00" +
|
||||
// keyid, 32 bytes
|
||||
"69616d617075626c69636b657973686174776f66697665736978646967657374" +
|
||||
// timestamp, 8 bytes
|
||||
"00000000000004d2" +
|
||||
// extensions length, 2 bytes
|
||||
"0000" +
|
||||
// extensions, 0 bytes
|
||||
// hash algo, sig algo, 2 bytes
|
||||
"0403" +
|
||||
// signature length, 2 bytes
|
||||
"0009" +
|
||||
// signature, 9 bytes
|
||||
"7369676e6174757265"
|
||||
|
||||
defaultSCTListHexString string = "0476007400380069616d617075626c69636b657973686174776f6669766573697864696765737400000000000004d20000040300097369676e617475726500380069616d617075626c69636b657973686174776f6669766573697864696765737400000000000004d20000040300097369676e6174757265"
|
||||
)
|
||||
|
||||
func defaultSCTLogID() LogID {
|
||||
var id LogID
|
||||
copy(id.KeyID[:], defaultSCTLogIDString)
|
||||
return id
|
||||
}
|
||||
|
||||
func defaultSCTSignature() DigitallySigned {
|
||||
var ds DigitallySigned
|
||||
if _, err := tls.Unmarshal([]byte(defaultSCTSignatureString), &ds); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return ds
|
||||
}
|
||||
|
||||
func defaultSCT() SignedCertificateTimestamp {
|
||||
return SignedCertificateTimestamp{
|
||||
SCTVersion: V1,
|
||||
LogID: defaultSCTLogID(),
|
||||
Timestamp: defaultSCTTimestamp,
|
||||
Extensions: []byte{},
|
||||
Signature: defaultSCTSignature()}
|
||||
}
|
||||
|
||||
func defaultCertificate() []byte {
|
||||
return []byte(defaultCertifictateString)
|
||||
}
|
||||
|
||||
func defaultExtensions() []byte {
|
||||
return []byte{}
|
||||
}
|
||||
|
||||
func defaultCertificateSCTSignatureInput(t *testing.T) []byte {
|
||||
t.Helper()
|
||||
r, err := hex.DecodeString(defaultCertificateSCTSignatureInputHexString)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to decode defaultCertificateSCTSignatureInputHexString: %v", err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func defaultCertificateLogEntry() LogEntry {
|
||||
return LogEntry{
|
||||
Index: 1,
|
||||
Leaf: MerkleTreeLeaf{
|
||||
Version: V1,
|
||||
LeafType: TimestampedEntryLeafType,
|
||||
TimestampedEntry: &TimestampedEntry{
|
||||
Timestamp: defaultSCTTimestamp,
|
||||
EntryType: X509LogEntryType,
|
||||
X509Entry: &ASN1Cert{Data: defaultCertificate()},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func defaultPrecertSCTSignatureInput(t *testing.T) []byte {
|
||||
t.Helper()
|
||||
r, err := hex.DecodeString(defaultPrecertSCTSignatureInputHexString)
|
||||
if err != nil {
|
||||
t.Fatalf("failed to decode defaultPrecertSCTSignatureInputHexString: %v", err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func defaultPrecertTBS() []byte {
|
||||
return []byte(defaultPrecertTBSString)
|
||||
}
|
||||
|
||||
func defaultPrecertIssuerHash() [32]byte {
|
||||
var b [32]byte
|
||||
copy(b[:], []byte(defaultPrecertIssuerHashString))
|
||||
return b
|
||||
}
|
||||
|
||||
func defaultPrecertLogEntry() LogEntry {
|
||||
return LogEntry{
|
||||
Index: 1,
|
||||
Leaf: MerkleTreeLeaf{
|
||||
Version: V1,
|
||||
LeafType: TimestampedEntryLeafType,
|
||||
TimestampedEntry: &TimestampedEntry{
|
||||
Timestamp: defaultSCTTimestamp,
|
||||
EntryType: PrecertLogEntryType,
|
||||
PrecertEntry: &PreCert{
|
||||
IssuerKeyHash: defaultPrecertIssuerHash(),
|
||||
TBSCertificate: defaultPrecertTBS(),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func defaultSTH() SignedTreeHead {
|
||||
var root SHA256Hash
|
||||
copy(root[:], "imustbeexactlythirtytwobyteslong")
|
||||
return SignedTreeHead{
|
||||
TreeSize: 6,
|
||||
Timestamp: 2345,
|
||||
SHA256RootHash: root,
|
||||
TreeHeadSignature: DigitallySigned{
|
||||
Algorithm: tls.SignatureAndHashAlgorithm{
|
||||
Hash: tls.SHA256,
|
||||
Signature: tls.ECDSA},
|
||||
Signature: []byte("tree_signature"),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// Tests start here:
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
func TestSerializeV1SCTSignatureInputForCertificateKAT(t *testing.T) {
|
||||
serialized, err := SerializeSCTSignatureInput(defaultSCT(), defaultCertificateLogEntry())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to serialize SCT for signing: %v", err)
|
||||
}
|
||||
if bytes.Compare(serialized, defaultCertificateSCTSignatureInput(t)) != 0 {
|
||||
t.Fatalf("Serialized certificate signature input doesn't match expected answer:\n%v\n%v", serialized, defaultCertificateSCTSignatureInput(t))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerializeV1SCTSignatureInputForPrecertKAT(t *testing.T) {
|
||||
serialized, err := SerializeSCTSignatureInput(defaultSCT(), defaultPrecertLogEntry())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to serialize SCT for signing: %v", err)
|
||||
}
|
||||
if bytes.Compare(serialized, defaultPrecertSCTSignatureInput(t)) != 0 {
|
||||
t.Fatalf("Serialized precertificate signature input doesn't match expected answer:\n%v\n%v", serialized, defaultPrecertSCTSignatureInput(t))
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerializeV1SCTJSONSignature(t *testing.T) {
|
||||
entry := LogEntry{Leaf: *CreateJSONMerkleTreeLeaf("data", defaultSCT().Timestamp)}
|
||||
expected := dh(
|
||||
// version, 1 byte
|
||||
"00" +
|
||||
// signature type, 1 byte
|
||||
"00" +
|
||||
// timestamp, 8 bytes
|
||||
"00000000000004d2" +
|
||||
// entry type, 2 bytes
|
||||
"8000" +
|
||||
// tbs certificate length, 18 bytes
|
||||
"000012" +
|
||||
// { "data": "data" }, 3 bytes
|
||||
"7b202264617461223a20226461746122207d" +
|
||||
// extensions length, 2 bytes
|
||||
"0000" +
|
||||
// extensions, 0 bytes
|
||||
"")
|
||||
serialized, err := SerializeSCTSignatureInput(defaultSCT(), entry)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to serialize SCT for signing: %v", err)
|
||||
}
|
||||
if !bytes.Equal(serialized, expected) {
|
||||
t.Fatalf("Serialized JSON signature :\n%x, want\n%x", serialized, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSerializeV1STHSignatureKAT(t *testing.T) {
|
||||
b, err := SerializeSTHSignatureInput(defaultSTH())
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to serialize defaultSTH: %v", err)
|
||||
}
|
||||
if bytes.Compare(b, mustDehex(t, defaultSTHSignedHexString)) != 0 {
|
||||
t.Fatalf("defaultSTH incorrectly serialized, expected:\n%v\ngot:\n%v", mustDehex(t, defaultSTHSignedHexString), b)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalDigitallySigned(t *testing.T) {
|
||||
b, err := tls.Marshal(
|
||||
DigitallySigned{
|
||||
Algorithm: tls.SignatureAndHashAlgorithm{
|
||||
Hash: tls.SHA512,
|
||||
Signature: tls.ECDSA},
|
||||
Signature: []byte("signature")})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to marshal DigitallySigned struct: %v", err)
|
||||
}
|
||||
if b[0] != byte(tls.SHA512) {
|
||||
t.Fatalf("Expected b[0] == SHA512, but found %v", tls.HashAlgorithm(b[0]))
|
||||
}
|
||||
if b[1] != byte(tls.ECDSA) {
|
||||
t.Fatalf("Expected b[1] == ECDSA, but found %v", tls.SignatureAlgorithm(b[1]))
|
||||
}
|
||||
if b[2] != 0x00 || b[3] != 0x09 {
|
||||
t.Fatalf("Found incorrect length bytes, expected (0x00, 0x09) found %v", b[2:3])
|
||||
}
|
||||
if string(b[4:]) != "signature" {
|
||||
t.Fatalf("Found incorrect signature bytes, expected %v, found %v", []byte("signature"), b[4:])
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalDigitallySigned(t *testing.T) {
|
||||
var ds DigitallySigned
|
||||
if _, err := tls.Unmarshal([]byte("\x01\x02\x00\x0aSiGnAtUrE!"), &ds); err != nil {
|
||||
t.Fatalf("Failed to unmarshal DigitallySigned: %v", err)
|
||||
}
|
||||
if ds.Algorithm.Hash != tls.MD5 {
|
||||
t.Fatalf("Expected HashAlgorithm %v, but got %v", tls.MD5, ds.Algorithm.Hash)
|
||||
}
|
||||
if ds.Algorithm.Signature != tls.DSA {
|
||||
t.Fatalf("Expected SignatureAlgorithm %v, but got %v", tls.DSA, ds.Algorithm.Signature)
|
||||
}
|
||||
if string(ds.Signature) != "SiGnAtUrE!" {
|
||||
t.Fatalf("Expected Signature %v, but got %v", []byte("SiGnAtUrE!"), ds.Signature)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalUnmarshalSCTRoundTrip(t *testing.T) {
|
||||
sctIn := defaultSCT()
|
||||
b, err := tls.Marshal(sctIn)
|
||||
if err != nil {
|
||||
t.Fatalf("tls.Marshal(SCT)=nil,%v; want no error", err)
|
||||
}
|
||||
var sctOut SignedCertificateTimestamp
|
||||
if _, err := tls.Unmarshal(b, &sctOut); err != nil {
|
||||
t.Errorf("tls.Unmarshal(%s)=nil,%v; want %+v,nil", hex.EncodeToString(b), err, sctIn)
|
||||
} else if !reflect.DeepEqual(sctIn, sctOut) {
|
||||
t.Errorf("tls.Unmarshal(%s)=%v,nil; want %+v,nil", hex.EncodeToString(b), sctOut, sctIn)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalSCT(t *testing.T) {
|
||||
b, err := tls.Marshal(defaultSCT())
|
||||
if err != nil {
|
||||
t.Errorf("tls.Marshal(defaultSCT)=nil,%v; want %s", err, defaultSCTHexString)
|
||||
} else if !bytes.Equal(dh(defaultSCTHexString), b) {
|
||||
t.Errorf("tls.Marshal(defaultSCT)=%s,nil; want %s", hex.EncodeToString(b), defaultSCTHexString)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnmarshalSCT(t *testing.T) {
|
||||
want := defaultSCT()
|
||||
var got SignedCertificateTimestamp
|
||||
if _, err := tls.Unmarshal(dh(defaultSCTHexString), &got); err != nil {
|
||||
t.Errorf("tls.Unmarshal(%s)=nil,%v; want %+v,nil", defaultSCTHexString, err, want)
|
||||
} else if !reflect.DeepEqual(got, want) {
|
||||
t.Errorf("tls.Unmarshal(%s)=%+v,nil; want %+v,nil", defaultSCTHexString, got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestX509MerkleTreeLeafHash(t *testing.T) {
|
||||
certFile := "./testdata/test-cert.pem"
|
||||
sctFile := "./testdata/test-cert.proof"
|
||||
certB, err := ioutil.ReadFile(certFile)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file %s: %v", certFile, err)
|
||||
}
|
||||
certDER, _ := pem.Decode(certB)
|
||||
|
||||
sctB, err := ioutil.ReadFile(sctFile)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read file %s: %v", sctFile, err)
|
||||
}
|
||||
var sct SignedCertificateTimestamp
|
||||
if _, err := tls.Unmarshal(sctB, &sct); err != nil {
|
||||
t.Fatalf("Failed to deserialize SCT: %v", err)
|
||||
}
|
||||
|
||||
leaf := CreateX509MerkleTreeLeaf(ASN1Cert{Data: certDER.Bytes}, sct.Timestamp)
|
||||
b, err := tls.Marshal(*leaf)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to Serialize x509 leaf: %v", err)
|
||||
}
|
||||
|
||||
leafBytes := dh("00000000013ddb27ded900000002ce308202ca30820233a003020102020106300d06092a864886f70d01010505003055310b300906035504061302474231243022060355040a131b4365727469666963617465205472616e73706172656e6379204341310e300c0603550408130557616c65733110300e060355040713074572772057656e301e170d3132303630313030303030305a170d3232303630313030303030305a3052310b30090603550406130247423121301f060355040a13184365727469666963617465205472616e73706172656e6379310e300c0603550408130557616c65733110300e060355040713074572772057656e30819f300d06092a864886f70d010101050003818d0030818902818100b1fa37936111f8792da2081c3fe41925008531dc7f2c657bd9e1de4704160b4c9f19d54ada4470404c1c51341b8f1f7538dddd28d9aca48369fc5646ddcc7617f8168aae5b41d43331fca2dadfc804d57208949061f9eef902ca47ce88c644e000f06eeeccabdc9dd2f68a22ccb09dc76e0dbc73527765b1a37a8c676253dcc10203010001a381ac3081a9301d0603551d0e041604146a0d982a3b62c44b6d2ef4e9bb7a01aa9cb798e2307d0603551d230476307480145f9d880dc873e654d4f80dd8e6b0c124b447c355a159a4573055310b300906035504061302474231243022060355040a131b4365727469666963617465205472616e73706172656e6379204341310e300c0603550408130557616c65733110300e060355040713074572772057656e82010030090603551d1304023000300d06092a864886f70d010105050003818100171cd84aac414a9a030f22aac8f688b081b2709b848b4e5511406cd707fed028597a9faefc2eee2978d633aaac14ed3235197da87e0f71b8875f1ac9e78b281749ddedd007e3ecf50645f8cbf667256cd6a1647b5e13203bb8582de7d6696f656d1c60b95f456b7fcf338571908f1c69727d24c4fccd249295795814d1dac0e60000")
|
||||
if !bytes.Equal(b, leafBytes) {
|
||||
t.Errorf("CreateX509MerkleTreeLeaf(): got\n %x, want\n%x", b, sctB)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestJSONMerkleTreeLeaf(t *testing.T) {
|
||||
data := `CioaINV25GV8X4a6M6Q10avSLP9PYd5N8MwWxQvWU7E2CzZ8IgYI0KnavAUSWAoIZDc1NjMzMzMSTAgEEAMaRjBEAiBQlnp6Q3di86g8M3l5gz+9qls/Cz1+KJ+tK/jpaBtUCgIgXaJ94uLsnChA1NY7ocGwKrQwPU688hwaZ5L/DboV4mQ=2`
|
||||
timestamp := uint64(1469664866615)
|
||||
leaf := CreateJSONMerkleTreeLeaf(data, timestamp)
|
||||
b, err := tls.Marshal(*leaf)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to Serialize x509 leaf: %v", err)
|
||||
}
|
||||
leafBytes := dh("0000000001562eda313780000000c67b202264617461223a202243696f61494e563235475638583461364d365131306176534c5039505964354e384d77577851765755374532437a5a3849675949304b6e617641555357416f495a4463314e6a4d7a4d7a4d535441674545414d61526a4245416942516c6e703651336469383667384d336c35677a2b39716c735c2f437a312b4b4a2b744b5c2f6a70614274554367496758614a3934754c736e436841314e59376f6347774b72517750553638386877615a354c5c2f44626f56346d513d3222207d0000")
|
||||
|
||||
if !bytes.Equal(b, leafBytes) {
|
||||
t.Errorf("CreateJSONMerkleTreeLeaf(): got\n%x, want\n%x", b, leafBytes)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLogEntryFromLeaf(t *testing.T) {
|
||||
const (
|
||||
// Cert example taken from entry #1 in argon2018 log
|
||||
leafDER = "308204ef308202d7a00302010202070556658a503cca300d06092a864886f70d01010b0500307f310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793123302106035504030c1a4d657267652044656c617920496e7465726d6564696174652031301e170d3137303831303132343331355a170d3138303333313038333231375a3063310b3009060355040613024742310f300d06035504070c064c6f6e646f6e31283026060355040a0c1f476f6f676c65204365727469666963617465205472616e73706172656e637931193017060355040513103135303233363839393537353331363230820122300d06092a864886f70d01010105000382010f003082010a0282010100a2fb53365dfbcefea77e1d65bc40f34f7919fcae85d82d3003428199f0c893fca95ba139156fd5e9a3bd84dc6dab8e74151fde6dd25b31526c85719bbf8990f3d6b21bb7f321306f6ddc50b96e8917fa103b388a00e1e954ee0232a9f9fb2efa8c9f9196a7fe84dad1f66b5d36127c71c9dcf25a04acd7bfda7866dfb77498c63a7ae9e7d0772fe9ba938a9ff6c0209196988158e6ea055fe967dd7599ef4bd7f306ded231cca10d89b4d6de40916e615d1d4cc6032585822a650743e34735d464fc0d544d1fad8c293df22f4a55ce3fbfb55d90cdc5ab84695a5a13d46f3176f143d9d28f60dca841eac603d30cec830a62feec091c927e6c781df330f14ca10203010001a3818b30818830130603551d25040c300a06082b0601050507030130230603551d11041c301a8218666c6f776572732d746f2d7468652d776f726c642e636f6d300c0603551d130101ff04023000301f0603551d23041830168014e93c04e1802fc284132d26709ef2fd1acfaafec6301d0603551d0e041604142f3948061fe546939f5e8dbc3fe4c0a1fbaab6b7300d06092a864886f70d01010b0500038202010052a2480c754c51cfdc9f99a82a8eb7c34e5e2bdcdfdd7543fadadb578083416d34ebb87fea3c90baf97f06be5baf5c41101ad1bdd2a2f554de6a3e8cd5ff3d78354badad01032a007d2eaf03590ee5397e223b2936f0c8b59c0407079c8975ffb34eb1cfe784cf3bc45e198a601473537f1ef382e0b5311d2ddf430ade7cfd28900ec9d91c1db49a6b2fb1b9e13b94135fed978d646e048b2fa9dc36ef5821cea8ebbed38d4c2d7811e9660f23d7636b295caccdc945a010a4c364fd7e7480aa5282d28fc46ce7f4f636ef2cc57c8bb1aee5da79bc6107205d4abcd3fb09a1db023ba4e8e9f34ae36ff5b2672fc2a14af8d23d67a437b3eb507ca90f73121841ab1498ab712d18063244dc3514bfffbaf6d45acdfc5316a248589a04b79b2abbca454e2e21f9b487e21eea21565c99ebc1013b87253c91f43ac6d2d2dea7090877c2a7404bce2545662ce005dc12eb57b1efe7145af8070b5dfa86736664a644a9c0f7e7c38d715cf874b818d519927eddc69b55c781b6e0a6eef8f3e46b9e059105b7932a978704e924904dbaa9583f3dd606467f4cc41589b702f1a02d517d3cd93b55d67d0b379e2527fded951be9dfb86d473613e6d9b8399ef5174d3e03185bd3cb4ea859b465c6c49010d4119d613a60878c0e453f17cfa3ce925e10f6e0a5adb745cebe218c3c82627a120e2907eeb9ec5307664474093cbc92d65fc7"
|
||||
leafCA = "308205c8308203b0a00302010202021001300d06092a864886f70d0101050500307d310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793121301f06035504030c184d657267652044656c6179204d6f6e69746f7220526f6f74301e170d3134303731373132323633305a170d3139303731363132323633305a307f310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793123302106035504030c1a4d657267652044656c617920496e7465726d656469617465203130820222300d06092a864886f70d01010105000382020f003082020a0282020100c1e874feff9aeef303bbfa63453881faaf8dc1c22c09641daf430381f33bc157bf6c4c8a8d57b1abc792859d20f2191509c597c437b14673dea5af4bea14396dd436dc620555d7953e0ede01f7ffb44f3ff7cde64ed245634e0df0aafce9c3ac5eb63d8de1d969cac8854195403a9f9d1d4c3dceedf1351edd945743bc54ab745b204fb5259fe3edf695c2cf90b886c48ff680b744fec2691b4345242b31c36f3118b727c5de5c25ec1aa30a4c2461c5119ef6bb90d816e6e44c5b9955bfa2ed3416bf6e4a53c92fafac0d1f0b8bf3d35be0d4f61ca05d28fc662dfa588fba3ee0380470c012ded9e51bbf1e7a25efa745784c49d05eaf8dcee0527361ec913126005e972cf4b863914f8361582ed24563ff9e03c52e8a9ca3264c56c186b4ec52b7e695ce42ae17ec7ae0257131e1dbf48f2dde242e6e91ea304988135a15482b05fc091355328b39e586e8dd3a4a3a14cb97eef68f9f69728c291f2195d2cce73d4ae90845b1bfc5fae040b94fc359a29511981b9966aeb56d3a7c5e48f8eca815e5be86b3d36e6a27e0e2c4dee6e30f12a7c936b8c98cad5928aca238dfc39cf9f2c5246cbbbb280cb6f99eb49bfd1d78089539072c164c7083371746dedbc4dec1cb9439073af3f2e60f8c505f067961a8c539454fc5341158eccc78532f3e39c3187c9439fc0ff88ee957131d478df063dd50b2ad3fe7a070e905e3868b0203010001a350304e301d0603551d0e04160414e93c04e1802fc284132d26709ef2fd1acfaafec6301f0603551d23041830168014f35f7b7549e37841396a20b67c6b4c5cc93d5841300c0603551d13040530030101ff300d06092a864886f70d010105050003820201000858cbd545f2e92e09906ac39f3d55c13607a651436386c6e90f128773a0eb3f4725d8af35fb7f880436b481f2cf47801825de54f13f8f5920bf3d916e753141de5e59d2debbfc3fc226721f15a16d3b7a4618ea0551639f1d2cb7b9faad1b7e070f23a6e8197c3d7549bba6553fd5db419ce399477f6a0481b90f51c9d307d82cb05cf967828a1ace65207cf86b6d16792245dcf24b4c179f91184736e7e2fcb863a4b5c89b0ac2f368390a10594b95c856e259c77564316898cf87a6817d18585fc976d681d9d510ef2ad37e8ad0e49f5bd499c9ec7fe8f43b17dffb9b7d0dfd8300c1c5389c9ea0be4370dcbf78bd3efc2308d250b866bbca031c0c49ff77a7a5420daa1f1b6a444d366653974c2d179c3009871ee6c89140fca9efdf23bd4b88c6ebaeb9286f58f3cfc21e4874f182d1ecd6058919b03b18db7b795be9cb25fc5166a945ef8e1133cd60312a3234f4649df6166407cbb5ecc838e9e118c05dee7c896a9987655ae7e349cd8166e68d34dea3b4ae892a9f2385053271e860b542be3650503974f3bb6f2688375ab28487da6751d0f2c3a35e78efe30b19d57808ebea2c4453990ad81eb96289c0f99c5080f82092bc6123a340c63a617f3bc4adc1298d88a278a693ef93688611d3b4eded0b6d023ed9f6c2ea8836483197525b1b1bce70a90c3403b094d5f412aa1141b9965ab8314c52f772deffc1008c"
|
||||
rootCA = "308205cd308203b5a0030201020209009ed3ccb1d12ca272300d06092a864886f70d0101050500307d310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793121301f06035504030c184d657267652044656c6179204d6f6e69746f7220526f6f74301e170d3134303731373132303534335a170d3431313230323132303534335a307d310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793121301f06035504030c184d657267652044656c6179204d6f6e69746f7220526f6f7430820222300d06092a864886f70d01010105000382020f003082020a0282020100aa161cf2205ed81ac565483cda426a3db2e588fdb758b17b93ea8d68495d534a01ba4f6cd1c0fc0a128af79c066dc54c3f437e05ba275ee61dbf9cbdb2928183738139397b6189ae738fef2b9b609a6dd8e0b0d0e20b243db936c029cdc2220af2c0e1a5e4aa41a006af458957e2b1178d27156ef0cb717e16d54025d97f43e9916fb240fb85f7d579462fa0ac76c76256843750bf1ccdfeb76c8c47886477644d5ec3235628adf6a09c8488bfa5036de717908151a6b585f273dd9fb5332b9af76e8fbfa91eaf4311816dde27c5c44f2fd06cc2204d7147f77ba6b16a2a5fca470023614729538bee6b3cb07264713832aec161550eb501906802215223acc2564ad1f98bb5934924eb56d383fc7598be45c89d995281c0efb0d206d29a6d25a10a48fe235332379c5ca69e83599faa677dd20823f5c84a961255eca5d4871d54ca1df0774aa117b0f42cd6e9fda7e8a48a53923c5f94043353544e644b5a6562e5cef9fc2bd2fcfcce3323335cf7fe7c4d83c1b7f839c4790192d3ba9aa9f32093aa8ee7cbe708059d538dc663cca1b825331aa836754a0d13de63bf65b6e2044dcdf041f1a0c5a9c3c38fe74cf576d451c23eaa519db32ef9e039bd848a194c3b5e41a55642dc283ddbd73d1dd97ae6951de18ad89d005007fae7e88bc7a3cce8b7ccc49603a0db67c76d58a28d4b77aa7460801e34377d0c5e4606c2e25b0203010001a350304e301d0603551d0e04160414f35f7b7549e37841396a20b67c6b4c5cc93d5841301f0603551d23041830168014f35f7b7549e37841396a20b67c6b4c5cc93d5841300c0603551d13040530030101ff300d06092a864886f70d01010505000382020100771cfea34579a97520d8c2423d68ecd07891f8c7f1c38bf3cd30ea9d3637bfc5d373532ec7656558bef4950646750c6fe085c52d9ffc09e66ebfa2b067de7727cb381d2b25db58b9c2197fd5eb53e020f429b86a3b1f37a07a761a66a5b3ecd797c46695a37ff2d47c54126be6bd28a2a103357227c6b73f7f689b09b48927e6e9a52267a728a115d4bcbb477533dc28f3fc57da735a3ec54fbc36990b17febb7e46b324208c1fa7425a0cba48bdc0381ea8285215261c3c483f2fa6d1da0dba4949107189f32d728a7ff395d43430af3b8ce4be5075bcf67d66661941dc8be37340f8f9282b2d2aadd69065932ad49769f8bc7fc9e5f6e79ff392420ba78de3172778e2b67e4df18440dd561e5a7844c8efa06c0e5f5b8695fa069114a00518fb4c19f9d7855831b5eeebced14b8598daffa49f2dcf505bff6417d84b28e83599d4e0371ef64b2d82ffa068a31044f7322fee2f654ec357c9c121f3458a509728c37f5673412ad0d5e76aa6b4eb1582181a8be404d3dc35e71edd83ee388087d6147c4d86f1cacacface0104df1f4b100c2ceb1be4d1851c4f31e7c4409262185878f23cceb30790143f0d5bd80d2c0ed4260aaa312597d950aaf3c8bcfc812d9a56e8d160dd772a494743710a7e478a046d8a5d505ee6b8cc37fec09dfd4cb57c6c4d8e8ef2a22e1d9e50957852633138d722253e51ba77b0069d38812207a"
|
||||
noExts = "0000"
|
||||
// Precert example taken from entry #2 in argon2018 log
|
||||
issuerKeyHash = "e37689003073a0c649cc656de946c03174d25c566fe3c3805b846f5236943798"
|
||||
precertTBS = "0002db308202d7a0030201020207055667377e8bcc300d06092a864886f70d01010b0500307f310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793123302106035504030c1a4d657267652044656c617920496e7465726d6564696174652031301e170d3137303831303134343331365a170d3138303432363134323430315a3063310b3009060355040613024742310f300d06035504070c064c6f6e646f6e31283026060355040a0c1f476f6f676c65204365727469666963617465205472616e73706172656e637931193017060355040513103135303233373631393632313337303830820122300d06092a864886f70d01010105000382010f003082010a0282010100dea100ff02f31ae6f76f9c26525afcdd0ef6eef780d72b4b1c0ff14fc7ac021852d6f34af20713d05fea2c2e1a4b488b3849c2511cf30fcd2e61d9e7392557498a4ff600c8fdc912f05c8a583a5f2b6a3d3320c6cc10b7eed502de392d11b3c4d57fa6e3ddc69d3f73305bb6441a0359bd526272784523ae5319cffd2993abba54d26c4c1b760c8660b65161a349e415207a6fbb20d02ce13054e6ffa7776bccfd26c3e4220e0e504f102f352260aaa9864411f7eeae8f6071c9ba54b83d11af43ab58dcb6a7d9053654b98b165fb84a27c78361d957c70a064f45bf4501ef744302e497839a34222e94b3018e587c70c130208976d9f80cf6741a95abfa6b810203010001a3818b30818830130603551d25040c300a06082b0601050507030130230603551d11041c301a8218666c6f776572732d746f2d7468652d776f726c642e636f6d300c0603551d130101ff04023000301f0603551d23041830168014e93c04e1802fc284132d26709ef2fd1acfaafec6301d0603551d0e04160414df25c220250d548e08341c26cadc5effc177841c"
|
||||
precertDER = "30820504308202eca0030201020207055667377e8bcc300d06092a864886f70d01010b0500307f310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793123302106035504030c1a4d657267652044656c617920496e7465726d6564696174652031301e170d3137303831303134343331365a170d3138303432363134323430315a3063310b3009060355040613024742310f300d06035504070c064c6f6e646f6e31283026060355040a0c1f476f6f676c65204365727469666963617465205472616e73706172656e637931193017060355040513103135303233373631393632313337303830820122300d06092a864886f70d01010105000382010f003082010a0282010100dea100ff02f31ae6f76f9c26525afcdd0ef6eef780d72b4b1c0ff14fc7ac021852d6f34af20713d05fea2c2e1a4b488b3849c2511cf30fcd2e61d9e7392557498a4ff600c8fdc912f05c8a583a5f2b6a3d3320c6cc10b7eed502de392d11b3c4d57fa6e3ddc69d3f73305bb6441a0359bd526272784523ae5319cffd2993abba54d26c4c1b760c8660b65161a349e415207a6fbb20d02ce13054e6ffa7776bccfd26c3e4220e0e504f102f352260aaa9864411f7eeae8f6071c9ba54b83d11af43ab58dcb6a7d9053654b98b165fb84a27c78361d957c70a064f45bf4501ef744302e497839a34222e94b3018e587c70c130208976d9f80cf6741a95abfa6b810203010001a381a030819d30130603551d25040c300a06082b0601050507030130230603551d11041c301a8218666c6f776572732d746f2d7468652d776f726c642e636f6d300c0603551d130101ff04023000301f0603551d23041830168014e93c04e1802fc284132d26709ef2fd1acfaafec6301d0603551d0e04160414df25c220250d548e08341c26cadc5effc177841c3013060a2b06010401d6790204030101ff04020500300d06092a864886f70d01010b05000382020100ae9ca16ec19bb469d08628b1296f50e3e15b362e2b18c691b11eef3af9ce655bf74e0c21c84f6091132851ba78465c3ae97a1409ee7505395d4e7e0318189029a12bf1c3ba2b6f3231c7aac13dbbfaade8d56f0fbe91d32440ad0ab816184c72392154275ead8418cc62e4e2b08de1b14acb6b27c0f36fa586feb875666f46d232a32ef022440d52cdd8bd31a42de55bfa77de8742816f086830b07eedbde545af5a2b9dd17bd49ded508589a0673f6e0d55f210818422093fd10939f0c81521ca654958e6e01b76ef8c7380bdb331e67d44ccb18a83ed04d97d463c37c7cbc592768e2373e198a1d64be3bd22d1833994706797461d05a85e779cd6e2b4b2b14e81d1eca454f29780c47a7366041ace1a48319eff3f1f04bbd471d5125774ef050e47bf664a98101b7be3337bb786b760a92be46488c6a15f72972a4b7c932c736311f0ac1d40920580329657f00e26cfb6d3b1db1eb7a95952fbcbfcbaf9d17587f03aeb9c3b403d1dccad895316658d35fe385fc5a62b60db36e3f07c4798314936aeb3f40094aee9ec1350ea8f68d1aeb41b211ecd0c9e29c5fa2d6576bcb2ad5ec8cc936e1f5a127afa0de3ae490b914adaa733f18ed9348d497e10ba4aa3008f84deec6976292dc0d3c2aa523602188916dd468b47f3d571e71fe51cd293c805d1280a53ab9f519a616d889303be461354edfc29dc3cc85d8570264cf4"
|
||||
precertCA = "308205c8308203b0a00302010202021001300d06092a864886f70d0101050500307d310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793121301f06035504030c184d657267652044656c6179204d6f6e69746f7220526f6f74301e170d3134303731373132323633305a170d3139303731363132323633305a307f310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793123302106035504030c1a4d657267652044656c617920496e7465726d656469617465203130820222300d06092a864886f70d01010105000382020f003082020a0282020100c1e874feff9aeef303bbfa63453881faaf8dc1c22c09641daf430381f33bc157bf6c4c8a8d57b1abc792859d20f2191509c597c437b14673dea5af4bea14396dd436dc620555d7953e0ede01f7ffb44f3ff7cde64ed245634e0df0aafce9c3ac5eb63d8de1d969cac8854195403a9f9d1d4c3dceedf1351edd945743bc54ab745b204fb5259fe3edf695c2cf90b886c48ff680b744fec2691b4345242b31c36f3118b727c5de5c25ec1aa30a4c2461c5119ef6bb90d816e6e44c5b9955bfa2ed3416bf6e4a53c92fafac0d1f0b8bf3d35be0d4f61ca05d28fc662dfa588fba3ee0380470c012ded9e51bbf1e7a25efa745784c49d05eaf8dcee0527361ec913126005e972cf4b863914f8361582ed24563ff9e03c52e8a9ca3264c56c186b4ec52b7e695ce42ae17ec7ae0257131e1dbf48f2dde242e6e91ea304988135a15482b05fc091355328b39e586e8dd3a4a3a14cb97eef68f9f69728c291f2195d2cce73d4ae90845b1bfc5fae040b94fc359a29511981b9966aeb56d3a7c5e48f8eca815e5be86b3d36e6a27e0e2c4dee6e30f12a7c936b8c98cad5928aca238dfc39cf9f2c5246cbbbb280cb6f99eb49bfd1d78089539072c164c7083371746dedbc4dec1cb9439073af3f2e60f8c505f067961a8c539454fc5341158eccc78532f3e39c3187c9439fc0ff88ee957131d478df063dd50b2ad3fe7a070e905e3868b0203010001a350304e301d0603551d0e04160414e93c04e1802fc284132d26709ef2fd1acfaafec6301f0603551d23041830168014f35f7b7549e37841396a20b67c6b4c5cc93d5841300c0603551d13040530030101ff300d06092a864886f70d010105050003820201000858cbd545f2e92e09906ac39f3d55c13607a651436386c6e90f128773a0eb3f4725d8af35fb7f880436b481f2cf47801825de54f13f8f5920bf3d916e753141de5e59d2debbfc3fc226721f15a16d3b7a4618ea0551639f1d2cb7b9faad1b7e070f23a6e8197c3d7549bba6553fd5db419ce399477f6a0481b90f51c9d307d82cb05cf967828a1ace65207cf86b6d16792245dcf24b4c179f91184736e7e2fcb863a4b5c89b0ac2f368390a10594b95c856e259c77564316898cf87a6817d18585fc976d681d9d510ef2ad37e8ad0e49f5bd499c9ec7fe8f43b17dffb9b7d0dfd8300c1c5389c9ea0be4370dcbf78bd3efc2308d250b866bbca031c0c49ff77a7a5420daa1f1b6a444d366653974c2d179c3009871ee6c89140fca9efdf23bd4b88c6ebaeb9286f58f3cfc21e4874f182d1ecd6058919b03b18db7b795be9cb25fc5166a945ef8e1133cd60312a3234f4649df6166407cbb5ecc838e9e118c05dee7c896a9987655ae7e349cd8166e68d34dea3b4ae892a9f2385053271e860b542be3650503974f3bb6f2688375ab28487da6751d0f2c3a35e78efe30b19d57808ebea2c4453990ad81eb96289c0f99c5080f82092bc6123a340c63a617f3bc4adc1298d88a278a693ef93688611d3b4eded0b6d023ed9f6c2ea8836483197525b1b1bce70a90c3403b094d5f412aa1141b9965ab8314c52f772deffc1008c"
|
||||
precertRoot = "308205cd308203b5a0030201020209009ed3ccb1d12ca272300d06092a864886f70d0101050500307d310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793121301f06035504030c184d657267652044656c6179204d6f6e69746f7220526f6f74301e170d3134303731373132303534335a170d3431313230323132303534335a307d310b3009060355040613024742310f300d06035504080c064c6f6e646f6e31173015060355040a0c0e476f6f676c6520554b204c74642e3121301f060355040b0c184365727469666963617465205472616e73706172656e63793121301f06035504030c184d657267652044656c6179204d6f6e69746f7220526f6f7430820222300d06092a864886f70d01010105000382020f003082020a0282020100aa161cf2205ed81ac565483cda426a3db2e588fdb758b17b93ea8d68495d534a01ba4f6cd1c0fc0a128af79c066dc54c3f437e05ba275ee61dbf9cbdb2928183738139397b6189ae738fef2b9b609a6dd8e0b0d0e20b243db936c029cdc2220af2c0e1a5e4aa41a006af458957e2b1178d27156ef0cb717e16d54025d97f43e9916fb240fb85f7d579462fa0ac76c76256843750bf1ccdfeb76c8c47886477644d5ec3235628adf6a09c8488bfa5036de717908151a6b585f273dd9fb5332b9af76e8fbfa91eaf4311816dde27c5c44f2fd06cc2204d7147f77ba6b16a2a5fca470023614729538bee6b3cb07264713832aec161550eb501906802215223acc2564ad1f98bb5934924eb56d383fc7598be45c89d995281c0efb0d206d29a6d25a10a48fe235332379c5ca69e83599faa677dd20823f5c84a961255eca5d4871d54ca1df0774aa117b0f42cd6e9fda7e8a48a53923c5f94043353544e644b5a6562e5cef9fc2bd2fcfcce3323335cf7fe7c4d83c1b7f839c4790192d3ba9aa9f32093aa8ee7cbe708059d538dc663cca1b825331aa836754a0d13de63bf65b6e2044dcdf041f1a0c5a9c3c38fe74cf576d451c23eaa519db32ef9e039bd848a194c3b5e41a55642dc283ddbd73d1dd97ae6951de18ad89d005007fae7e88bc7a3cce8b7ccc49603a0db67c76d58a28d4b77aa7460801e34377d0c5e4606c2e25b0203010001a350304e301d0603551d0e04160414f35f7b7549e37841396a20b67c6b4c5cc93d5841301f0603551d23041830168014f35f7b7549e37841396a20b67c6b4c5cc93d5841300c0603551d13040530030101ff300d06092a864886f70d01010505000382020100771cfea34579a97520d8c2423d68ecd07891f8c7f1c38bf3cd30ea9d3637bfc5d373532ec7656558bef4950646750c6fe085c52d9ffc09e66ebfa2b067de7727cb381d2b25db58b9c2197fd5eb53e020f429b86a3b1f37a07a761a66a5b3ecd797c46695a37ff2d47c54126be6bd28a2a103357227c6b73f7f689b09b48927e6e9a52267a728a115d4bcbb477533dc28f3fc57da735a3ec54fbc36990b17febb7e46b324208c1fa7425a0cba48bdc0381ea8285215261c3c483f2fa6d1da0dba4949107189f32d728a7ff395d43430af3b8ce4be5075bcf67d66661941dc8be37340f8f9282b2d2aadd69065932ad49769f8bc7fc9e5f6e79ff392420ba78de3172778e2b67e4df18440dd561e5a7844c8efa06c0e5f5b8695fa069114a00518fb4c19f9d7855831b5eeebced14b8598daffa49f2dcf505bff6417d84b28e83599d4e0371ef64b2d82ffa068a31044f7322fee2f654ec357c9c121f3458a509728c37f5673412ad0d5e76aa6b4eb1582181a8be404d3dc35e71edd83ee388087d6147c4d86f1cacacface0104df1f4b100c2ceb1be4d1851c4f31e7c4409262185878f23cceb30790143f0d5bd80d2c0ed4260aaa312597d950aaf3c8bcfc812d9a56e8d160dd772a494743710a7e478a046d8a5d505ee6b8cc37fec09dfd4cb57c6c4d8e8ef2a22e1d9e50957852633138d722253e51ba77b0069d38812207a"
|
||||
)
|
||||
var tests = []struct {
|
||||
leaf LeafEntry
|
||||
wantCert bool
|
||||
wantPrecert bool
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
leaf: LeafEntry{},
|
||||
wantErr: "failed to unmarshal",
|
||||
},
|
||||
{
|
||||
leaf: LeafEntry{
|
||||
// {version + leaf_type + timestamp + entry_type + len + cert + exts}
|
||||
LeafInput: dh("00" + "00" + "0000015dcc2b99c8" + "0000" + "0004f3" + leafDER + noExts),
|
||||
ExtraData: dh("000ba3" + "0005cc" + leafCA + "0005d1" + rootCA),
|
||||
},
|
||||
wantCert: true,
|
||||
},
|
||||
{
|
||||
leaf: LeafEntry{
|
||||
LeafInput: dh("00" + "00" + "0000015dcc2b99c8" + "0000" + "0004f3" + leafDER + noExts + "ff"),
|
||||
ExtraData: dh("000ba3" + "0005cc" + leafCA + "0005d1" + rootCA),
|
||||
},
|
||||
wantErr: "trailing data",
|
||||
},
|
||||
{
|
||||
leaf: LeafEntry{
|
||||
LeafInput: dh("00" + "00" + "0000015dcc2b99c8" + "0000" + "0004f3" + leafDER + noExts),
|
||||
ExtraData: dh("000ba3" + "0005cc" + leafCA + "0005d1" + rootCA + "00"),
|
||||
},
|
||||
wantErr: "trailing data",
|
||||
},
|
||||
{
|
||||
leaf: LeafEntry{
|
||||
LeafInput: dh("00" + "00" + "0000015dcc2b99c8" + "0000" + "0004f3" + leafDER + noExts),
|
||||
},
|
||||
wantErr: "failed to unmarshal",
|
||||
},
|
||||
{
|
||||
leaf: LeafEntry{
|
||||
LeafInput: dh("00" + "00" + "0000015dcc2b99c8" + "8000" + "0004f3" + leafDER + noExts),
|
||||
},
|
||||
wantErr: "unknown entry type",
|
||||
},
|
||||
{
|
||||
leaf: LeafEntry{
|
||||
// version + leaf_type + timestamp + entry_type + key_hash + tbs + exts
|
||||
LeafInput: dh("00" + "00" + "0000015dcc997890" + "0001" + issuerKeyHash + precertTBS + noExts),
|
||||
ExtraData: dh("000508" + precertDER +
|
||||
("000ba3" + "0005cc" + precertCA + "0005d1" + precertRoot)),
|
||||
},
|
||||
wantPrecert: true,
|
||||
},
|
||||
{
|
||||
leaf: LeafEntry{
|
||||
LeafInput: dh("00" + "00" + "0000015dcc997890" + "0001" + issuerKeyHash + precertTBS + noExts),
|
||||
ExtraData: dh("000508" + precertDER +
|
||||
("000ba3" + "0005cc" + precertCA + "0005d1" + precertRoot) + "ff"),
|
||||
},
|
||||
wantErr: "trailing data",
|
||||
},
|
||||
{
|
||||
leaf: LeafEntry{
|
||||
LeafInput: dh("00" + "00" + "0000015dcc997890" + "0001" + issuerKeyHash + precertTBS + noExts + "ff"),
|
||||
ExtraData: dh("000508" + precertDER +
|
||||
("000ba3" + "0005cc" + precertCA + "0005d1" + precertRoot)),
|
||||
},
|
||||
wantErr: "trailing data",
|
||||
},
|
||||
{
|
||||
leaf: LeafEntry{
|
||||
LeafInput: dh("00" + "00" + "0000015dcc997890" + "0001" + issuerKeyHash + precertTBS + noExts),
|
||||
},
|
||||
wantErr: "failed to unmarshal",
|
||||
},
|
||||
}
|
||||
for i, test := range tests {
|
||||
got, err := LogEntryFromLeaf(int64(i), &test.leaf)
|
||||
if err != nil {
|
||||
if test.wantErr == "" {
|
||||
t.Errorf("LogEntryFromLeaf(%d) = _, %v; want _, nil", i, err)
|
||||
} else if !strings.Contains(err.Error(), test.wantErr) {
|
||||
t.Errorf("LogEntryFromLeaf(%d) = _, %v; want _, err containing %q", i, err, test.wantErr)
|
||||
}
|
||||
} else if test.wantErr != "" {
|
||||
t.Errorf("LogEntryFromLeaf(%d) = _, nil; want _, err containing %q", i, test.wantErr)
|
||||
}
|
||||
if gotCert := (got != nil && got.X509Cert != nil); gotCert != test.wantCert {
|
||||
t.Errorf("LogEntryFromLeaf(%d).X509Cert = %v; want %v", i, gotCert, test.wantCert)
|
||||
}
|
||||
if gotPrecert := (got != nil && got.Precert != nil); gotPrecert != test.wantPrecert {
|
||||
t.Errorf("LogEntryFromLeaf(%d).Precert = %v; want %v", i, gotPrecert, test.wantPrecert)
|
||||
}
|
||||
}
|
||||
}
|
493
vendor/github.com/google/certificate-transparency-go/signatures_test.go
generated
vendored
493
vendor/github.com/google/certificate-transparency-go/signatures_test.go
generated
vendored
@ -1,493 +0,0 @@
|
||||
// Copyright 2015 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ct
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"crypto/rsa"
|
||||
"encoding/hex"
|
||||
mrand "math/rand"
|
||||
"testing"
|
||||
|
||||
"github.com/google/certificate-transparency-go/tls"
|
||||
)
|
||||
|
||||
const (
|
||||
sigTestDERCertString = "308202ca30820233a003020102020102300d06092a864886f70d01010505003055310b300" +
|
||||
"906035504061302474231243022060355040a131b4365727469666963617465205472616e" +
|
||||
"73706172656e6379204341310e300c0603550408130557616c65733110300e06035504071" +
|
||||
"3074572772057656e301e170d3132303630313030303030305a170d323230363031303030" +
|
||||
"3030305a3052310b30090603550406130247423121301f060355040a13184365727469666" +
|
||||
"963617465205472616e73706172656e6379310e300c0603550408130557616c6573311030" +
|
||||
"0e060355040713074572772057656e30819f300d06092a864886f70d010101050003818d0" +
|
||||
"030818902818100b8742267898b99ba6bfd6e6f7ada8e54337f58feb7227c46248437ba5f" +
|
||||
"89b007cbe1ecb4545b38ed23fddbf6b9742cafb638157f68184776a1b38ab39318ddd7344" +
|
||||
"89b4d750117cd83a220a7b52f295d1e18571469a581c23c68c57d973761d9787a091fb586" +
|
||||
"4936b166535e21b427e3c6d690b2e91a87f36b7ec26f59ce53b50203010001a381ac3081a" +
|
||||
"9301d0603551d0e041604141184e1187c87956dffc31dd0521ff564efbeae8d307d060355" +
|
||||
"1d23047630748014a3b8d89ba2690dfb48bbbf87c1039ddce56256c6a159a4573055310b3" +
|
||||
"00906035504061302474231243022060355040a131b436572746966696361746520547261" +
|
||||
"6e73706172656e6379204341310e300c0603550408130557616c65733110300e060355040" +
|
||||
"713074572772057656e82010030090603551d1304023000300d06092a864886f70d010105" +
|
||||
"050003818100292ecf6e46c7a0bcd69051739277710385363341c0a9049637279707ae23c" +
|
||||
"c5128a4bdea0d480ed0206b39e3a77a2b0c49b0271f4140ab75c1de57aba498e09459b479" +
|
||||
"cf92a4d5d5dd5cbe3f0a11e25f04078df88fc388b61b867a8de46216c0e17c31fc7d8003e" +
|
||||
"cc37be22292f84242ab87fb08bd4dfa3c1b9ce4d3ee6667da"
|
||||
|
||||
sigTestSCTTimestamp = 1348589665525
|
||||
|
||||
sigTestCertSCTSignatureEC = "0403" + "0048" +
|
||||
"3046022100d3f7690e7ee80d9988a54a3821056393e9eb0c686ad67fbae3686c888fb1a3c" +
|
||||
"e022100f9a51c6065bbba7ad7116a31bea1c31dbed6a921e1df02e4b403757fae3254ae"
|
||||
|
||||
sigTestEC256PrivateKeyPEM = "-----BEGIN EC PRIVATE KEY-----\n" +
|
||||
"MHcCAQEEIG8QAquNnarN6Ik2cMIZtPBugh9wNRe0e309MCmDfBGuoAoGCCqGSM49\n" +
|
||||
"AwEHoUQDQgAES0AfBkjr7b8b19p5Gk8plSAN16wWXZyhYsH6FMCEUK60t7pem/ck\n" +
|
||||
"oPX8hupuaiJzJS0ZQ0SEoJGlFxkUFwft5g==\n" +
|
||||
"-----END EC PRIVATE KEY-----\n"
|
||||
|
||||
sigTestEC256PublicKeyPEM = "-----BEGIN PUBLIC KEY-----\n" +
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAES0AfBkjr7b8b19p5Gk8plSAN16wW\n" +
|
||||
"XZyhYsH6FMCEUK60t7pem/ckoPX8hupuaiJzJS0ZQ0SEoJGlFxkUFwft5g==\n" +
|
||||
"-----END PUBLIC KEY-----\n"
|
||||
|
||||
sigTestEC256PublicKey2PEM = "-----BEGIN PUBLIC KEY-----\n" +
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHT\n" +
|
||||
"DM0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA==\n" +
|
||||
"-----END PUBLIC KEY-----\n"
|
||||
|
||||
sigTestRSAPrivateKeyPEM = "-----BEGIN RSA PRIVATE KEY-----\n" +
|
||||
"MIIEpAIBAAKCAQEAxy7llbig9kL0wo5AyV1FhmJLvWTWxzAMwGdhG1h1CqQpaWut\n" +
|
||||
"XGI9WKRDJSZ/9dr9vgvqdRX2QsnUdJbJ3cz5Z1ie/RdT/mSVO7ZEqvJS93PIHnqu\n" +
|
||||
"FZXxNnIerGnQ7guC+Zm9BlQ2DIhYpnvVRRVyD/D8KT92R7qOu3JACduoMrF1synk\n" +
|
||||
"nL8rb8lZvCej8tbhJ38yibMWTmkxsFS+a29Xqk8pkhgwIwvUZqcMaqZo+4/iCuKL\n" +
|
||||
"bVc85V98SvbcnmsX3gqeQnyRtxlctlclcbvHmJt5U+3yF1UtcuiyZf1gjcAqnOgv\n" +
|
||||
"ZZYzsodXi0KGV7NRQhTPvwH0C8In2qL+v4qWAQIDAQABAoIBAQCdyqsaNw9cx6I6\n" +
|
||||
"1pLAcuF3GjvCKDZ1ybzwV3V4QlVGPtKHr0PBIhpTNJ30ulE4pWnKuoncg695LYbf\n" +
|
||||
"be0xhwY1NuGMwoRJzcjjavtvKVVMry5j5vAuLYDPjwx5rcJUMk5qCb7TWrcOqp0A\n" +
|
||||
"Fq3XcqvPsSsyShIbtNEJ8fKFXLwcm07bGDgOacrXieP/nL2Hh6joeAJLgnKAOtU5\n" +
|
||||
"qw6fdweYGThfhdCwaBq0WSaxj6nMG3Q40bHurvdOAtU1GF2a27BGsnfKFyKlvk8+\n" +
|
||||
"K7tCc4oXo4WWEUuOwu6SmB1kYIZLf258B0PFQJwN8OA3Mbek+F4Bm3DzWe1aLS5L\n" +
|
||||
"wpOYxrq5AoGBAO0sGq+ic+9K81FvBBUYXiFtt9rv3nU9jZhjqpfvdqRs2KXt8ldz\n" +
|
||||
"2M+JCRFHt8rLDEutK/NZuZcq3wAXS3EeMIp33QZ7Yuj5LeG9eD0asX8yq51Toua3\n" +
|
||||
"gRDbiR00Vz/3BINM8JufN/sPLoUiuAV5mlOTktZ8+z7ixO4ravMB1Z9HAoGBANb+\n" +
|
||||
"w+1Hre8+4JEnl3yRh1UNDmbhCc2tRxCD4QJyb9qaOl2IK1QXuDcwD8owdenwOrAi\n" +
|
||||
"I5yKx7y4oKNfdSrP2wlAGS/GAEL5f+JhLtv2cNoKNxMXNRgYfJAQeMKBjINdECia\n" +
|
||||
"G89lbPVCm+F3guzrO70giA4617GFSEA31rRC1BR3AoGBAKcQLiwRrsCcdxChtqp1\n" +
|
||||
"Y7kAZEXgOT80gI0bh4tGrrfbxC/9kHtxqwNlb/GwJxK+PIcCELd2OHj3ReX2grnH\n" +
|
||||
"nkGrdRGf0GhzPZKJuCyypN0IgEJuK42BLXUGb2sW926jPZaPl9zHJtO+OfKmJiIV\n" +
|
||||
"KlQ8224i04fUjQuHoepTHHr5AoGAS8AZ4lmWFCywTRSJEG/qIfJmt6LkpF5AIraE\n" +
|
||||
"qisN9BTRKbFXqtpsoq1BcvjeIt3sn7B3oalYNMtMdiOlEb+Iqlq2RRnbb72e7HFX\n" +
|
||||
"ZFMRchGVVBmiMGo4QT48fjPNAV/h2Jxr3ggbetLMP4WvULCVLM7wgSsEYlzWlyHV\n" +
|
||||
"eU/uj4MCgYADGpY3Q3ueB23eTTnAMtESwmAQvjTBOPKVpaV/ohHb8BdzAjwcgEUA\n" +
|
||||
"wB1be/bHCrLbW09Pi3HVp0I0x0mBAYoUP2NRYKCYlhs28cu+ygB4nsy+YZPg00+E\n" +
|
||||
"ByqqrQ0zuN82ytXzRFHmh2Hb2O+HOj6aJjgVuj/rR7aifIt8scSAhg==\n" +
|
||||
"-----END RSA PRIVATE KEY-----\n"
|
||||
|
||||
sigTestRSAPublicKeyPEM = "-----BEGIN PUBLIC KEY-----\n" +
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxy7llbig9kL0wo5AyV1F\n" +
|
||||
"hmJLvWTWxzAMwGdhG1h1CqQpaWutXGI9WKRDJSZ/9dr9vgvqdRX2QsnUdJbJ3cz5\n" +
|
||||
"Z1ie/RdT/mSVO7ZEqvJS93PIHnquFZXxNnIerGnQ7guC+Zm9BlQ2DIhYpnvVRRVy\n" +
|
||||
"D/D8KT92R7qOu3JACduoMrF1synknL8rb8lZvCej8tbhJ38yibMWTmkxsFS+a29X\n" +
|
||||
"qk8pkhgwIwvUZqcMaqZo+4/iCuKLbVc85V98SvbcnmsX3gqeQnyRtxlctlclcbvH\n" +
|
||||
"mJt5U+3yF1UtcuiyZf1gjcAqnOgvZZYzsodXi0KGV7NRQhTPvwH0C8In2qL+v4qW\n" +
|
||||
"AQIDAQAB\n" +
|
||||
"-----END PUBLIC KEY-----\n"
|
||||
|
||||
sigTestCertSCTSignatureRSA = "0401" + "0100" +
|
||||
"6bc1fecfe9052036e31278cd7eded90d000b127f2b657831baf5ecb31ee3" +
|
||||
"c17497abd9562df6319928a36df0ab1a1a917b3f4530e1ca0000ae6c4a0c" +
|
||||
"0efada7df83beb95da8eea98f1a27c70afa1ccaa7a0245e1db785b1c0d9f" +
|
||||
"ee307e926e14bed1eac0d01c34939e659360432a9552c02b89c3ef3c44aa" +
|
||||
"22fc31f2444522975ee83989dd7af1ab05b91bbf0985ca4d04245b68a683" +
|
||||
"01d300f0c976ce13d58618dad1b49c0ec5cdc4352016823fc88c479ef214" +
|
||||
"76c5f19923af207dbb1b2cff72d4e1e5ee77dd420b85d0f9dcc30a0f617c" +
|
||||
"2d3c916eb77f167323500d1b53dc4253321a106e441af343cf2f68630873" +
|
||||
"abd43ca52629c586107eb7eb85f2c3ee"
|
||||
|
||||
sigTestCertSCTSignatureUnsupportedSignatureAlgorithm = "0402" + "0000"
|
||||
|
||||
sigTestCertSCTSignatureUnsupportedHashAlgorithm = "0303" + "0000"
|
||||
|
||||
// Some time in September 2012.
|
||||
sigTestDefaultSTHTimestamp = 1348589667204
|
||||
|
||||
sigTestDefaultTreeSize = 42
|
||||
|
||||
// *Some* hash that we pretend is a valid root hash.
|
||||
sigTestDefaultRootHash = "18041bd4665083001fba8c5411d2d748e8abbfdcdfd9218cb02b68a78e7d4c23"
|
||||
|
||||
sigTestDefaultSTHSerialized = "000100000139fe354384000000000000002a18041bd4665083001fba8c5411d2d748e8abb" +
|
||||
"fdcdfd9218cb02b68a78e7d4c23"
|
||||
|
||||
sigTestDefaultSTHSignature = "0403" + "0048" +
|
||||
"3046022100befd8060563763a5e49ba53e6443c13f7624fd6403178113736e16012aca983" +
|
||||
"e022100f572568dbfe9a86490eb915c4ee16ad5ecd708fed35ed4e5cd1b2c3f087b4130"
|
||||
|
||||
sigTestKeyIDEC = "b69d879e3f2c4402556dcda2f6b2e02ff6b6df4789c53000e14f4b125ae847aa"
|
||||
|
||||
sigTestKeyIDRSA = "b853f84c71a7aa5f23905ba5340f183af927c330c7ce590ba1524981c4ec4358"
|
||||
)
|
||||
|
||||
func mustDehex(t *testing.T, h string) []byte {
|
||||
t.Helper()
|
||||
r, err := hex.DecodeString(h)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to decode hex string (%s): %v", h, err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func sigTestSCTWithSignature(t *testing.T, sig, keyID string) SignedCertificateTimestamp {
|
||||
t.Helper()
|
||||
var ds DigitallySigned
|
||||
if _, err := tls.Unmarshal(mustDehex(t, sig), &ds); err != nil {
|
||||
t.Fatalf("Failed to unmarshal sigTestCertSCTSignatureEC: %v", err)
|
||||
}
|
||||
var id LogID
|
||||
copy(id.KeyID[:], mustDehex(t, keyID))
|
||||
return SignedCertificateTimestamp{
|
||||
SCTVersion: V1,
|
||||
LogID: id,
|
||||
Timestamp: sigTestSCTTimestamp,
|
||||
Signature: ds,
|
||||
}
|
||||
}
|
||||
|
||||
func sigTestSCTEC(t *testing.T) SignedCertificateTimestamp {
|
||||
t.Helper()
|
||||
return sigTestSCTWithSignature(t, sigTestCertSCTSignatureEC, sigTestKeyIDEC)
|
||||
}
|
||||
|
||||
func sigTestSCTRSA(t *testing.T) SignedCertificateTimestamp {
|
||||
t.Helper()
|
||||
return sigTestSCTWithSignature(t, sigTestCertSCTSignatureRSA, sigTestKeyIDEC)
|
||||
}
|
||||
|
||||
func sigTestECPublicKey(t *testing.T) crypto.PublicKey {
|
||||
t.Helper()
|
||||
pk, _, _, err := PublicKeyFromPEM([]byte(sigTestEC256PublicKeyPEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse sigTestEC256PublicKey: %v", err)
|
||||
}
|
||||
return pk
|
||||
}
|
||||
|
||||
func sigTestECPublicKey2(t *testing.T) crypto.PublicKey {
|
||||
t.Helper()
|
||||
pk, _, _, err := PublicKeyFromPEM([]byte(sigTestEC256PublicKey2PEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse sigTestEC256PublicKey2: %v", err)
|
||||
}
|
||||
return pk
|
||||
}
|
||||
|
||||
func sigTestRSAPublicKey(t *testing.T) crypto.PublicKey {
|
||||
t.Helper()
|
||||
pk, _, _, err := PublicKeyFromPEM([]byte(sigTestRSAPublicKeyPEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse sigTestRSAPublicKey: %v", err)
|
||||
}
|
||||
return pk
|
||||
}
|
||||
|
||||
func sigTestCertLogEntry(t *testing.T) LogEntry {
|
||||
t.Helper()
|
||||
return LogEntry{
|
||||
Index: 0,
|
||||
Leaf: MerkleTreeLeaf{
|
||||
Version: V1,
|
||||
LeafType: TimestampedEntryLeafType,
|
||||
TimestampedEntry: &TimestampedEntry{
|
||||
Timestamp: sigTestSCTTimestamp,
|
||||
EntryType: X509LogEntryType,
|
||||
X509Entry: &ASN1Cert{Data: mustDehex(t, sigTestDERCertString)},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func sigTestDefaultSTH(t *testing.T) SignedTreeHead {
|
||||
t.Helper()
|
||||
var ds DigitallySigned
|
||||
if _, err := tls.Unmarshal(mustDehex(t, sigTestDefaultSTHSignature), &ds); err != nil {
|
||||
t.Fatalf("Failed to unmarshal sigTestCertSCTSignatureEC: %v", err)
|
||||
}
|
||||
var rootHash SHA256Hash
|
||||
copy(rootHash[:], mustDehex(t, sigTestDefaultRootHash))
|
||||
return SignedTreeHead{
|
||||
Version: V1,
|
||||
Timestamp: sigTestDefaultSTHTimestamp,
|
||||
TreeSize: sigTestDefaultTreeSize,
|
||||
SHA256RootHash: rootHash,
|
||||
TreeHeadSignature: ds,
|
||||
}
|
||||
}
|
||||
|
||||
func mustCreateSignatureVerifier(t *testing.T, pk crypto.PublicKey) SignatureVerifier {
|
||||
t.Helper()
|
||||
sv, err := NewSignatureVerifier(pk)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create SignatureVerifier: %v", err)
|
||||
}
|
||||
return *sv
|
||||
}
|
||||
|
||||
func corruptByteAt(b []byte, pos int) {
|
||||
b[pos] ^= byte(mrand.Intn(255) + 1)
|
||||
}
|
||||
|
||||
func corruptBytes(b []byte) {
|
||||
corruptByteAt(b, mrand.Intn(len(b)))
|
||||
}
|
||||
|
||||
func expectVerifySCTToFail(t *testing.T, sv SignatureVerifier, sct SignedCertificateTimestamp, msg string) {
|
||||
t.Helper()
|
||||
if err := sv.VerifySCTSignature(sct, sigTestCertLogEntry(t)); err == nil {
|
||||
t.Fatal(msg)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureEC(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
if err := v.VerifySCTSignature(sigTestSCTEC(t), sigTestCertLogEntry(t)); err != nil {
|
||||
t.Fatalf("Failed to verify signature on SCT: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureRSA(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestRSAPublicKey(t))
|
||||
if err := v.VerifySCTSignature(sigTestSCTRSA(t), sigTestCertLogEntry(t)); err != nil {
|
||||
t.Fatalf("Failed to verify signature on SCT: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureFailsForMismatchedSignatureAlgorithm(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
expectVerifySCTToFail(t, v, sigTestSCTRSA(t), "Successfully verified with mismatched signature algorithm")
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureFailsForUnknownSignatureAlgorithm(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
expectVerifySCTToFail(t, v, sigTestSCTWithSignature(t, sigTestCertSCTSignatureUnsupportedSignatureAlgorithm, sigTestKeyIDEC),
|
||||
"Successfully verified signature with unsupported signature algorithm")
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureFailsForUnknownHashAlgorithm(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
expectVerifySCTToFail(t, v, sigTestSCTWithSignature(t, sigTestCertSCTSignatureUnsupportedHashAlgorithm, sigTestKeyIDEC),
|
||||
"Successfully verified signature with unsupported hash algorithm")
|
||||
}
|
||||
|
||||
func testVerifySCTSignatureFailsForIncorrectLeafBytes(t *testing.T, sct SignedCertificateTimestamp, sv SignatureVerifier) {
|
||||
t.Helper()
|
||||
entry := sigTestCertLogEntry(t)
|
||||
for i := range entry.Leaf.TimestampedEntry.X509Entry.Data {
|
||||
old := entry.Leaf.TimestampedEntry.X509Entry.Data[i]
|
||||
corruptByteAt(entry.Leaf.TimestampedEntry.X509Entry.Data, i)
|
||||
if err := sv.VerifySCTSignature(sct, entry); err == nil {
|
||||
t.Fatalf("Incorrectly verfied signature over corrupted leaf data, uncovered byte at %d?", i)
|
||||
}
|
||||
entry.Leaf.TimestampedEntry.X509Entry.Data[i] = old
|
||||
}
|
||||
// Ensure we were only corrupting one byte at a time, should be correct again now.
|
||||
if err := sv.VerifySCTSignature(sct, entry); err != nil {
|
||||
t.Fatalf("Input data appears to still be corrupt, bug? %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func testVerifySCTSignatureFailsForIncorrectSignature(t *testing.T, sct SignedCertificateTimestamp, sv SignatureVerifier) {
|
||||
t.Helper()
|
||||
corruptBytes(sct.Signature.Signature)
|
||||
expectVerifySCTToFail(t, sv, sct, "Incorrectly verified corrupt signature")
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureECFailsForIncorrectLeafBytes(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
testVerifySCTSignatureFailsForIncorrectLeafBytes(t, sigTestSCTEC(t), v)
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureECFailsForIncorrectTimestamp(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
sct := sigTestSCTEC(t)
|
||||
sct.Timestamp++
|
||||
expectVerifySCTToFail(t, v, sct, "Incorrectly verified signature with incorrect SCT timestamp.")
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureECFailsForIncorrectVersion(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
sct := sigTestSCTEC(t)
|
||||
sct.SCTVersion++
|
||||
expectVerifySCTToFail(t, v, sct, "Incorrectly verified signature with incorrect SCT Version.")
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureECFailsForIncorrectSignature(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
testVerifySCTSignatureFailsForIncorrectSignature(t, sigTestSCTEC(t), v)
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureRSAFailsForIncorrectLeafBytes(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestRSAPublicKey(t))
|
||||
testVerifySCTSignatureFailsForIncorrectLeafBytes(t, sigTestSCTRSA(t), v)
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureRSAFailsForIncorrectSignature(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestRSAPublicKey(t))
|
||||
testVerifySCTSignatureFailsForIncorrectSignature(t, sigTestSCTRSA(t), v)
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureFailsForSignatureCreatedWithDifferentAlgorithm(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestRSAPublicKey(t))
|
||||
testVerifySCTSignatureFailsForIncorrectSignature(t, sigTestSCTEC(t), v)
|
||||
}
|
||||
|
||||
func TestVerifySCTSignatureFailsForSignatureCreatedWithDifferentKey(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey2(t))
|
||||
testVerifySCTSignatureFailsForIncorrectSignature(t, sigTestSCTEC(t), v)
|
||||
}
|
||||
|
||||
func expectVerifySTHToPass(t *testing.T, v SignatureVerifier, sth SignedTreeHead) {
|
||||
t.Helper()
|
||||
if err := v.VerifySTHSignature(sth); err != nil {
|
||||
t.Fatalf("Incorrectly failed to verify STH signature: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func expectVerifySTHToFail(t *testing.T, v SignatureVerifier, sth SignedTreeHead) {
|
||||
t.Helper()
|
||||
if err := v.VerifySTHSignature(sth); err == nil {
|
||||
t.Fatal("Incorrectly verified STH signature")
|
||||
}
|
||||
}
|
||||
|
||||
func TestVerifyValidSTH(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
sth := sigTestDefaultSTH(t)
|
||||
expectVerifySTHToPass(t, v, sth)
|
||||
}
|
||||
|
||||
func TestVerifySTHCatchesCorruptSignature(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
sth := sigTestDefaultSTH(t)
|
||||
corruptBytes(sth.TreeHeadSignature.Signature)
|
||||
expectVerifySTHToFail(t, v, sth)
|
||||
}
|
||||
|
||||
func TestVerifySTHCatchesCorruptRootHash(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
sth := sigTestDefaultSTH(t)
|
||||
for i := range sth.SHA256RootHash {
|
||||
old := sth.SHA256RootHash[i]
|
||||
corruptByteAt(sth.SHA256RootHash[:], i)
|
||||
expectVerifySTHToFail(t, v, sth)
|
||||
sth.SHA256RootHash[i] = old
|
||||
}
|
||||
// ensure we were only testing one corrupt byte at a time - should be correct again now.
|
||||
expectVerifySTHToPass(t, v, sth)
|
||||
}
|
||||
|
||||
func TestVerifySTHCatchesCorruptTimestamp(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
sth := sigTestDefaultSTH(t)
|
||||
sth.Timestamp++
|
||||
expectVerifySTHToFail(t, v, sth)
|
||||
}
|
||||
|
||||
func TestVerifySTHCatchesCorruptVersion(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
sth := sigTestDefaultSTH(t)
|
||||
sth.Version++
|
||||
expectVerifySTHToFail(t, v, sth)
|
||||
}
|
||||
|
||||
func TestVerifySTHCatchesCorruptTreeSize(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey(t))
|
||||
sth := sigTestDefaultSTH(t)
|
||||
sth.TreeSize++
|
||||
expectVerifySTHToFail(t, v, sth)
|
||||
}
|
||||
|
||||
func TestVerifySTHFailsToVerifyForKeyWithDifferentAlgorithm(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestRSAPublicKey(t))
|
||||
sth := sigTestDefaultSTH(t)
|
||||
expectVerifySTHToFail(t, v, sth)
|
||||
}
|
||||
|
||||
func TestVerifySTHFailsToVerifyForDifferentKey(t *testing.T) {
|
||||
v := mustCreateSignatureVerifier(t, sigTestECPublicKey2(t))
|
||||
sth := sigTestDefaultSTH(t)
|
||||
expectVerifySTHToFail(t, v, sth)
|
||||
}
|
||||
|
||||
func TestNewSignatureVerifierFailsWithUnsupportedKeyType(t *testing.T) {
|
||||
var k dsa.PrivateKey
|
||||
if err := dsa.GenerateParameters(&k.Parameters, rand.Reader, dsa.L1024N160); err != nil {
|
||||
t.Fatalf("Failed to generate DSA key parameters: %v", err)
|
||||
}
|
||||
if err := dsa.GenerateKey(&k, rand.Reader); err != nil {
|
||||
t.Fatalf("Failed to generate DSA key: %v", err)
|
||||
}
|
||||
if _, err := NewSignatureVerifier(k); err == nil {
|
||||
t.Fatal("Creating a SignatureVerifier with a DSA key unexpectedly succeeded")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewSignatureVerifierFailsWithBadKeyParametersForEC(t *testing.T) {
|
||||
k, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate ECDSA key on P224: %v", err)
|
||||
}
|
||||
if _, err := NewSignatureVerifier(k); err == nil {
|
||||
t.Fatal("Incorrectly created new SignatureVerifier with EC P224 key.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewSignatureVerifierFailsWithBadKeyParametersForRSA(t *testing.T) {
|
||||
k, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate 1024 bit RSA key: %v", err)
|
||||
}
|
||||
if _, err := NewSignatureVerifier(k); err == nil {
|
||||
t.Fatal("Incorrectly created new SignatureVerifier with 1024 bit RSA key.")
|
||||
}
|
||||
}
|
||||
|
||||
func TestWillAllowNonCompliantECKeyWithOverride(t *testing.T) {
|
||||
AllowVerificationWithNonCompliantKeys = true
|
||||
k, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate EC key on P224: %v", err)
|
||||
}
|
||||
if _, err := NewSignatureVerifier(k.Public()); err != nil {
|
||||
t.Fatalf("Incorrectly disallowed P224 EC key with override set: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWillAllowNonCompliantRSAKeyWithOverride(t *testing.T) {
|
||||
AllowVerificationWithNonCompliantKeys = true
|
||||
k, err := rsa.GenerateKey(rand.Reader, 1024)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to generate 1024 bit RSA key: %v", err)
|
||||
}
|
||||
if _, err := NewSignatureVerifier(k.Public()); err != nil {
|
||||
t.Fatalf("Incorrectly disallowed 1024 bit RSA key with override set: %v", err)
|
||||
}
|
||||
}
|
30
vendor/github.com/google/certificate-transparency-go/testdata/argon.cfg
generated
vendored
30
vendor/github.com/google/certificate-transparency-go/testdata/argon.cfg
generated
vendored
@ -1,30 +0,0 @@
|
||||
shard {
|
||||
uri: "https://ct.googleapis.com/logs/argon2017"
|
||||
public_key_der:"0Y0\023\006\007*\206H\316=\002\001\006\010*\206H\316=\003\001\007\003B\000\004Tm|\211\335\352\235\360\272_\364m`z7O\002%\277\034\366o\205\256\257\025\337in\355\333\251\232)\227\362\231v\036\3463F\036'\364\276p\335Y\327\272\317\376\320r\216\260W\017\2357\211b\243"
|
||||
not_after_start:<seconds:1483228800>
|
||||
not_after_limit:<seconds:1514764800>
|
||||
}
|
||||
shard {
|
||||
uri: "https://ct.googleapis.com/logs/argon2018"
|
||||
public_key_der:"0Y0\023\006\007*\206H\316=\002\001\006\010*\206H\316=\003\001\007\003B\000\004\322\000U\005\255\325G\264\031\273\315\225\373)\327X=x$\315\316F\235\3732\324qN`\002%^Y>\327\324\003\270mChh~\350\240e\013>nqY\2227\276\251\350\361\243+\344\331\rUh"
|
||||
not_after_start:<seconds:1514764800>
|
||||
not_after_limit:<seconds:1546300800>
|
||||
}
|
||||
shard {
|
||||
uri: "https://ct.googleapis.com/logs/argon2019"
|
||||
public_key_der:"0Y0\023\006\007*\206H\316=\002\001\006\010*\206H\316=\003\001\007\003B\000\004#s\020\233\341\363^\366\230ki\225\226\020x\316I\333\264\004\374q,Z\222`h%\300J\032\241\260a-\033\207\024\251\272\360\0013Y\035\0050\351B\025\347U\327*\370\264\242\272E\311F\221\207V"
|
||||
not_after_start:<seconds:1546300800>
|
||||
not_after_limit:<seconds:1577836800>
|
||||
}
|
||||
shard {
|
||||
uri: "https://ct.googleapis.com/logs/argon2020"
|
||||
public_key_der:"0Y0\023\006\007*\206H\316=\002\001\006\010*\206H\316=\003\001\007\003B\000\004\351<v\247\\\212c\2155\344\334\210b\367k\223~\236\263K\200s\\\300\340\364>LdX\373vcQ2\030c\325\262\273\355\352\377^;$n/5R\213\2645\232\255\234\025\250i \352P\030\314"
|
||||
not_after_start:<seconds:1577836800>
|
||||
not_after_limit:<seconds:1609459200>
|
||||
}
|
||||
shard {
|
||||
uri: "https://ct.googleapis.com/logs/argon2021"
|
||||
public_key_der:"0Y0\023\006\007*\206H\316=\002\001\006\010*\206H\316=\003\001\007\003B\000\004M\340fd\352\363d\2528\305\211-\307\330\010\331\310Dq\355\334\303\373[\257\234d\241\tf\204\035|h\247\354\304?\214\234\202\340\030\331t\024\351\264y\201\242\224Ub\363\234\013D\203\241+\311q+"
|
||||
not_after_start:<seconds:1609459200>
|
||||
not_after_limit:<seconds:1640995200>
|
||||
}
|
409
vendor/github.com/google/certificate-transparency-go/testdata/certs.go
generated
vendored
409
vendor/github.com/google/certificate-transparency-go/testdata/certs.go
generated
vendored
@ -1,409 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
)
|
||||
|
||||
const (
|
||||
// CACertPEM is a CA cert:
|
||||
// Certificate:
|
||||
// Data:
|
||||
// Version: 3 (0x2)
|
||||
// Serial Number: 0 (0x0)
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// Issuer: C=GB, O=Certificate Transparency CA, ST=Wales, L=Erw Wen
|
||||
// Validity
|
||||
// Not Before: Jun 1 00:00:00 2012 GMT
|
||||
// Not After : Jun 1 00:00:00 2022 GMT
|
||||
// Subject: C=GB, O=Certificate Transparency CA, ST=Wales, L=Erw Wen
|
||||
// Subject Public Key Info:
|
||||
// Public Key Algorithm: rsaEncryption
|
||||
// Public-Key: (1024 bit)
|
||||
// Modulus:
|
||||
// 00:d5:8a:68:53:62:10:a2:71:19:93:6e:77:83:21:
|
||||
// 18:1c:2a:40:13:c6:d0:7b:8c:76:eb:91:57:d3:d0:
|
||||
// fb:4b:3b:51:6e:ce:cb:d1:c9:8d:91:c5:2f:74:3f:
|
||||
// ab:63:5d:55:09:9c:d1:3a:ba:f3:1a:e5:41:44:24:
|
||||
// 51:a7:4c:78:16:f2:24:3c:f8:48:cf:28:31:cc:e6:
|
||||
// 7b:a0:4a:5a:23:81:9f:3c:ba:37:e6:24:d9:c3:bd:
|
||||
// b2:99:b8:39:dd:fe:26:31:d2:cb:3a:84:fc:7b:b2:
|
||||
// b5:c5:2f:cf:c1:4f:ff:40:6f:5c:d4:46:69:cb:b2:
|
||||
// f7:cf:df:86:fb:6a:b9:d1:b1
|
||||
// Exponent: 65537 (0x10001)
|
||||
// X509v3 extensions:
|
||||
// X509v3 Subject Key Identifier:
|
||||
// 5F:9D:88:0D:C8:73:E6:54:D4:F8:0D:D8:E6:B0:C1:24:B4:47:C3:55
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:5F:9D:88:0D:C8:73:E6:54:D4:F8:0D:D8:E6:B0:C1:24:B4:47:C3:55
|
||||
// DirName:/C=GB/O=Certificate Transparency CA/ST=Wales/L=Erw Wen
|
||||
// serial:00
|
||||
//
|
||||
// X509v3 Basic Constraints:
|
||||
// CA:TRUE
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// 06:08:cc:4a:6d:64:f2:20:5e:14:6c:04:b2:76:f9:2b:0e:fa:
|
||||
// 94:a5:da:f2:3a:fc:38:06:60:6d:39:90:d0:a1:ea:23:3d:40:
|
||||
// 29:57:69:46:3b:04:66:61:e7:fa:1d:17:99:15:20:9a:ea:2e:
|
||||
// 0a:77:51:76:41:12:27:d7:c0:03:07:c7:47:0e:61:58:4f:d7:
|
||||
// 33:42:24:72:7f:51:d6:90:bc:47:a9:df:35:4d:b0:f6:eb:25:
|
||||
// 95:5d:e1:89:3c:4d:d5:20:2b:24:a2:f3:e4:40:d2:74:b5:4e:
|
||||
// 1b:d3:76:26:9c:a9:62:89:b7:6e:ca:a4:10:90:e1:4f:3b:0a:
|
||||
// 94:2e
|
||||
CACertPEM = "-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC0DCCAjmgAwIBAgIBADANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk\n" +
|
||||
"MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX\n" +
|
||||
"YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw\n" +
|
||||
"MDAwMDBaMFUxCzAJBgNVBAYTAkdCMSQwIgYDVQQKExtDZXJ0aWZpY2F0ZSBUcmFu\n" +
|
||||
"c3BhcmVuY3kgQ0ExDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGf\n" +
|
||||
"MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVimhTYhCicRmTbneDIRgcKkATxtB7\n" +
|
||||
"jHbrkVfT0PtLO1FuzsvRyY2RxS90P6tjXVUJnNE6uvMa5UFEJFGnTHgW8iQ8+EjP\n" +
|
||||
"KDHM5nugSlojgZ88ujfmJNnDvbKZuDnd/iYx0ss6hPx7srXFL8/BT/9Ab1zURmnL\n" +
|
||||
"svfP34b7arnRsQIDAQABo4GvMIGsMB0GA1UdDgQWBBRfnYgNyHPmVNT4DdjmsMEk\n" +
|
||||
"tEfDVTB9BgNVHSMEdjB0gBRfnYgNyHPmVNT4DdjmsMEktEfDVaFZpFcwVTELMAkG\n" +
|
||||
"A1UEBhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRyYW5zcGFyZW5jeSBDQTEO\n" +
|
||||
"MAwGA1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW6CAQAwDAYDVR0TBAUwAwEB\n" +
|
||||
"/zANBgkqhkiG9w0BAQUFAAOBgQAGCMxKbWTyIF4UbASydvkrDvqUpdryOvw4BmBt\n" +
|
||||
"OZDQoeojPUApV2lGOwRmYef6HReZFSCa6i4Kd1F2QRIn18ADB8dHDmFYT9czQiRy\n" +
|
||||
"f1HWkLxHqd81TbD26yWVXeGJPE3VICskovPkQNJ0tU4b03YmnKliibduyqQQkOFP\n" +
|
||||
"OwqULg==\n" +
|
||||
"-----END CERTIFICATE-----"
|
||||
|
||||
// TestCertPEM is a leaf certificate signed by CACertPEM.
|
||||
// Certificate:
|
||||
// Data:
|
||||
// Version: 3 (0x2)
|
||||
// Serial Number: 6 (0x6)
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// Issuer: C=GB, O=Certificate Transparency CA, ST=Wales, L=Erw Wen
|
||||
// Validity
|
||||
// Not Before: Jun 1 00:00:00 2012 GMT
|
||||
// Not After : Jun 1 00:00:00 2022 GMT
|
||||
// Subject: C=GB, O=Certificate Transparency, ST=Wales, L=Erw Wen
|
||||
// Subject Public Key Info:
|
||||
// Public Key Algorithm: rsaEncryption
|
||||
// Public-Key: (1024 bit)
|
||||
// Modulus:
|
||||
// 00:b1:fa:37:93:61:11:f8:79:2d:a2:08:1c:3f:e4:
|
||||
// 19:25:00:85:31:dc:7f:2c:65:7b:d9:e1:de:47:04:
|
||||
// 16:0b:4c:9f:19:d5:4a:da:44:70:40:4c:1c:51:34:
|
||||
// 1b:8f:1f:75:38:dd:dd:28:d9:ac:a4:83:69:fc:56:
|
||||
// 46:dd:cc:76:17:f8:16:8a:ae:5b:41:d4:33:31:fc:
|
||||
// a2:da:df:c8:04:d5:72:08:94:90:61:f9:ee:f9:02:
|
||||
// ca:47:ce:88:c6:44:e0:00:f0:6e:ee:cc:ab:dc:9d:
|
||||
// d2:f6:8a:22:cc:b0:9d:c7:6e:0d:bc:73:52:77:65:
|
||||
// b1:a3:7a:8c:67:62:53:dc:c1
|
||||
// Exponent: 65537 (0x10001)
|
||||
// X509v3 extensions:
|
||||
// X509v3 Subject Key Identifier:
|
||||
// 6A:0D:98:2A:3B:62:C4:4B:6D:2E:F4:E9:BB:7A:01:AA:9C:B7:98:E2
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:5F:9D:88:0D:C8:73:E6:54:D4:F8:0D:D8:E6:B0:C1:24:B4:47:C3:55
|
||||
// DirName:/C=GB/O=Certificate Transparency CA/ST=Wales/L=Erw Wen
|
||||
// serial:00
|
||||
//
|
||||
// X509v3 Basic Constraints:
|
||||
// CA:FALSE
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// 17:1c:d8:4a:ac:41:4a:9a:03:0f:22:aa:c8:f6:88:b0:81:b2:
|
||||
// 70:9b:84:8b:4e:55:11:40:6c:d7:07:fe:d0:28:59:7a:9f:ae:
|
||||
// fc:2e:ee:29:78:d6:33:aa:ac:14:ed:32:35:19:7d:a8:7e:0f:
|
||||
// 71:b8:87:5f:1a:c9:e7:8b:28:17:49:dd:ed:d0:07:e3:ec:f5:
|
||||
// 06:45:f8:cb:f6:67:25:6c:d6:a1:64:7b:5e:13:20:3b:b8:58:
|
||||
// 2d:e7:d6:69:6f:65:6d:1c:60:b9:5f:45:6b:7f:cf:33:85:71:
|
||||
// 90:8f:1c:69:72:7d:24:c4:fc:cd:24:92:95:79:58:14:d1:da:
|
||||
// c0:e6
|
||||
TestCertPEM = "-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIICyjCCAjOgAwIBAgIBBjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk\n" +
|
||||
"MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX\n" +
|
||||
"YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw\n" +
|
||||
"MDAwMDBaMFIxCzAJBgNVBAYTAkdCMSEwHwYDVQQKExhDZXJ0aWZpY2F0ZSBUcmFu\n" +
|
||||
"c3BhcmVuY3kxDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGfMA0G\n" +
|
||||
"CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCx+jeTYRH4eS2iCBw/5BklAIUx3H8sZXvZ\n" +
|
||||
"4d5HBBYLTJ8Z1UraRHBATBxRNBuPH3U43d0o2aykg2n8VkbdzHYX+BaKrltB1DMx\n" +
|
||||
"/KLa38gE1XIIlJBh+e75AspHzojGROAA8G7uzKvcndL2iiLMsJ3Hbg28c1J3ZbGj\n" +
|
||||
"eoxnYlPcwQIDAQABo4GsMIGpMB0GA1UdDgQWBBRqDZgqO2LES20u9Om7egGqnLeY\n" +
|
||||
"4jB9BgNVHSMEdjB0gBRfnYgNyHPmVNT4DdjmsMEktEfDVaFZpFcwVTELMAkGA1UE\n" +
|
||||
"BhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRyYW5zcGFyZW5jeSBDQTEOMAwG\n" +
|
||||
"A1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW6CAQAwCQYDVR0TBAIwADANBgkq\n" +
|
||||
"hkiG9w0BAQUFAAOBgQAXHNhKrEFKmgMPIqrI9oiwgbJwm4SLTlURQGzXB/7QKFl6\n" +
|
||||
"n678Lu4peNYzqqwU7TI1GX2ofg9xuIdfGsnniygXSd3t0Afj7PUGRfjL9mclbNah\n" +
|
||||
"ZHteEyA7uFgt59Zpb2VtHGC5X0Vrf88zhXGQjxxpcn0kxPzNJJKVeVgU0drA5g==\n" +
|
||||
"-----END CERTIFICATE-----\n"
|
||||
|
||||
// TestPreCertPEM is a pre-certificate signed by CACertPEM.
|
||||
// Certificate:
|
||||
// Data:
|
||||
// Version: 3 (0x2)
|
||||
// Serial Number: 7 (0x7)
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// Issuer: C=GB, O=Certificate Transparency CA, ST=Wales, L=Erw Wen
|
||||
// Validity
|
||||
// Not Before: Jun 1 00:00:00 2012 GMT
|
||||
// Not After : Jun 1 00:00:00 2022 GMT
|
||||
// Subject: C=GB, O=Certificate Transparency, ST=Wales, L=Erw Wen
|
||||
// Subject Public Key Info:
|
||||
// Public Key Algorithm: rsaEncryption
|
||||
// Public-Key: (1024 bit)
|
||||
// Modulus:
|
||||
// 00:be:ef:98:e7:c2:68:77:ae:38:5f:75:32:5a:0c:
|
||||
// 1d:32:9b:ed:f1:8f:aa:f4:d7:96:bf:04:7e:b7:e1:
|
||||
// ce:15:c9:5b:a2:f8:0e:e4:58:bd:7d:b8:6f:8a:4b:
|
||||
// 25:21:91:a7:9b:d7:00:c3:8e:9c:03:89:b4:5c:d4:
|
||||
// dc:9a:12:0a:b2:1e:0c:b4:1c:d0:e7:28:05:a4:10:
|
||||
// cd:9c:5b:db:5d:49:27:72:6d:af:17:10:f6:01:87:
|
||||
// 37:7e:a2:5b:1a:1e:39:ee:d0:b8:81:19:dc:15:4d:
|
||||
// c6:8f:7d:a8:e3:0c:af:15:8a:33:e6:c9:50:9f:4a:
|
||||
// 05:b0:14:09:ff:5d:d8:7e:b5
|
||||
// Exponent: 65537 (0x10001)
|
||||
// X509v3 extensions:
|
||||
// X509v3 Subject Key Identifier:
|
||||
// 20:31:54:1A:F2:5C:05:FF:D8:65:8B:68:43:79:4F:5E:90:36:F7:B4
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:5F:9D:88:0D:C8:73:E6:54:D4:F8:0D:D8:E6:B0:C1:24:B4:47:C3:55
|
||||
// DirName:/C=GB/O=Certificate Transparency CA/ST=Wales/L=Erw Wen
|
||||
// serial:00
|
||||
//
|
||||
// X509v3 Basic Constraints:
|
||||
// CA:FALSE
|
||||
// 1.3.6.1.4.1.11129.2.4.3: critical
|
||||
// ..
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// 02:a1:c3:9e:01:5a:f5:4d:ff:02:3c:33:60:87:5f:ff:34:37:
|
||||
// 55:2f:1f:09:01:bd:c2:54:31:5f:33:72:b7:23:fb:15:fb:ce:
|
||||
// cc:4d:f4:71:a0:ce:4d:8c:54:65:5d:84:87:97:fb:28:1e:3d:
|
||||
// fa:bb:46:2d:2c:68:4b:05:6f:ea:7b:63:b4:70:ff:16:6e:32:
|
||||
// d4:46:06:35:b3:d2:bc:6d:a8:24:9b:26:30:e7:1f:c3:4f:08:
|
||||
// f2:3d:d4:ee:22:8f:8f:74:f6:3d:78:63:11:dd:0a:58:11:40:
|
||||
// 5f:90:6c:ca:2c:2d:3e:eb:fc:81:99:64:eb:d8:cf:7c:08:86:
|
||||
// 3f:be
|
||||
TestPreCertPEM = "-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIC3zCCAkigAwIBAgIBBzANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk\n" +
|
||||
"MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX\n" +
|
||||
"YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw\n" +
|
||||
"MDAwMDBaMFIxCzAJBgNVBAYTAkdCMSEwHwYDVQQKExhDZXJ0aWZpY2F0ZSBUcmFu\n" +
|
||||
"c3BhcmVuY3kxDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGfMA0G\n" +
|
||||
"CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+75jnwmh3rjhfdTJaDB0ym+3xj6r015a/\n" +
|
||||
"BH634c4VyVui+A7kWL19uG+KSyUhkaeb1wDDjpwDibRc1NyaEgqyHgy0HNDnKAWk\n" +
|
||||
"EM2cW9tdSSdyba8XEPYBhzd+olsaHjnu0LiBGdwVTcaPfajjDK8VijPmyVCfSgWw\n" +
|
||||
"FAn/Xdh+tQIDAQABo4HBMIG+MB0GA1UdDgQWBBQgMVQa8lwF/9hli2hDeU9ekDb3\n" +
|
||||
"tDB9BgNVHSMEdjB0gBRfnYgNyHPmVNT4DdjmsMEktEfDVaFZpFcwVTELMAkGA1UE\n" +
|
||||
"BhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRyYW5zcGFyZW5jeSBDQTEOMAwG\n" +
|
||||
"A1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW6CAQAwCQYDVR0TBAIwADATBgor\n" +
|
||||
"BgEEAdZ5AgQDAQH/BAIFADANBgkqhkiG9w0BAQUFAAOBgQACocOeAVr1Tf8CPDNg\n" +
|
||||
"h1//NDdVLx8JAb3CVDFfM3K3I/sV+87MTfRxoM5NjFRlXYSHl/soHj36u0YtLGhL\n" +
|
||||
"BW/qe2O0cP8WbjLURgY1s9K8bagkmyYw5x/DTwjyPdTuIo+PdPY9eGMR3QpYEUBf\n" +
|
||||
"kGzKLC0+6/yBmWTr2M98CIY/vg==\n" +
|
||||
"-----END CERTIFICATE-----\n"
|
||||
|
||||
// TestEmbeddedCertPEM is a certificate containing an embedded SCT that
|
||||
// corresponds to TestPreCertProof.
|
||||
// Certificate:
|
||||
// Data:
|
||||
// Version: 3 (0x2)
|
||||
// Serial Number: 7 (0x7)
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// Issuer: C = GB, O = Certificate Transparency CA, ST = Wales, L = Erw Wen
|
||||
// Validity
|
||||
// Not Before: Jun 1 00:00:00 2012 GMT
|
||||
// Not After : Jun 1 00:00:00 2022 GMT
|
||||
// Subject: C = GB, O = Certificate Transparency, ST = Wales, L = Erw Wen
|
||||
// Subject Public Key Info:
|
||||
// Public Key Algorithm: rsaEncryption
|
||||
// Public-Key: (1024 bit)
|
||||
// Modulus:
|
||||
// 00:be:ef:98:e7:c2:68:77:ae:38:5f:75:32:5a:0c:
|
||||
// 1d:32:9b:ed:f1:8f:aa:f4:d7:96:bf:04:7e:b7:e1:
|
||||
// ce:15:c9:5b:a2:f8:0e:e4:58:bd:7d:b8:6f:8a:4b:
|
||||
// 25:21:91:a7:9b:d7:00:c3:8e:9c:03:89:b4:5c:d4:
|
||||
// dc:9a:12:0a:b2:1e:0c:b4:1c:d0:e7:28:05:a4:10:
|
||||
// cd:9c:5b:db:5d:49:27:72:6d:af:17:10:f6:01:87:
|
||||
// 37:7e:a2:5b:1a:1e:39:ee:d0:b8:81:19:dc:15:4d:
|
||||
// c6:8f:7d:a8:e3:0c:af:15:8a:33:e6:c9:50:9f:4a:
|
||||
// 05:b0:14:09:ff:5d:d8:7e:b5
|
||||
// Exponent: 65537 (0x10001)
|
||||
// X509v3 extensions:
|
||||
// X509v3 Subject Key Identifier:
|
||||
// 20:31:54:1A:F2:5C:05:FF:D8:65:8B:68:43:79:4F:5E:90:36:F7:B4
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:5F:9D:88:0D:C8:73:E6:54:D4:F8:0D:D8:E6:B0:C1:24:B4:47:C3:55
|
||||
// DirName:/C=GB/O=Certificate Transparency CA/ST=Wales/L=Erw Wen
|
||||
// serial:00
|
||||
//
|
||||
// X509v3 Basic Constraints:
|
||||
// CA:FALSE
|
||||
// CT Precertificate SCTs:
|
||||
// Signed Certificate Timestamp:
|
||||
// Version : v1 (0x0)
|
||||
// Log ID : DF:1C:2E:C1:15:00:94:52:47:A9:61:68:32:5D:DC:5C:
|
||||
// 79:59:E8:F7:C6:D3:88:FC:00:2E:0B:BD:3F:74:D7:64
|
||||
// Timestamp : Apr 5 17:04:16.275 2013 GMT
|
||||
// Extensions: none
|
||||
// Signature : ecdsa-with-SHA256
|
||||
// 30:45:02:20:48:2F:67:51:AF:35:DB:A6:54:36:BE:1F:
|
||||
// D6:64:0F:3D:BF:9A:41:42:94:95:92:45:30:28:8F:A3:
|
||||
// E5:E2:3E:06:02:21:00:E4:ED:C0:DB:3A:C5:72:B1:E2:
|
||||
// F5:E8:AB:6A:68:06:53:98:7D:CF:41:02:7D:FE:FF:A1:
|
||||
// 05:51:9D:89:ED:BF:08
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// 8a:0c:4b:ef:09:9d:47:92:79:af:a0:a2:8e:68:9f:91:e1:c4:
|
||||
// 42:1b:e2:d2:69:a2:ea:6c:a4:e8:21:5d:de:dd:ca:15:04:a1:
|
||||
// 1e:7c:87:c4:b7:7e:80:f0:e9:79:03:52:68:f2:7c:a2:0e:16:
|
||||
// 68:04:ae:55:6f:31:69:81:f9:6a:39:4a:b7:ab:fd:3e:25:5a:
|
||||
// c0:04:45:13:fe:76:57:0c:67:95:ab:e4:70:31:33:d3:03:f8:
|
||||
// 9f:3a:fa:6b:bc:fc:51:73:19:df:d9:5b:93:42:41:21:1f:63:
|
||||
// 40:35:c3:d0:78:30:7a:68:c6:07:5a:2e:20:c8:9f:36:b8:91:
|
||||
// 0c:a0
|
||||
TestEmbeddedCertPEM = "-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIDWTCCAsKgAwIBAgIBBzANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk\n" +
|
||||
"MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX\n" +
|
||||
"YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw\n" +
|
||||
"MDAwMDBaMFIxCzAJBgNVBAYTAkdCMSEwHwYDVQQKExhDZXJ0aWZpY2F0ZSBUcmFu\n" +
|
||||
"c3BhcmVuY3kxDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGfMA0G\n" +
|
||||
"CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+75jnwmh3rjhfdTJaDB0ym+3xj6r015a/\n" +
|
||||
"BH634c4VyVui+A7kWL19uG+KSyUhkaeb1wDDjpwDibRc1NyaEgqyHgy0HNDnKAWk\n" +
|
||||
"EM2cW9tdSSdyba8XEPYBhzd+olsaHjnu0LiBGdwVTcaPfajjDK8VijPmyVCfSgWw\n" +
|
||||
"FAn/Xdh+tQIDAQABo4IBOjCCATYwHQYDVR0OBBYEFCAxVBryXAX/2GWLaEN5T16Q\n" +
|
||||
"Nve0MH0GA1UdIwR2MHSAFF+diA3Ic+ZU1PgN2OawwSS0R8NVoVmkVzBVMQswCQYD\n" +
|
||||
"VQQGEwJHQjEkMCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4w\n" +
|
||||
"DAYDVQQIEwVXYWxlczEQMA4GA1UEBxMHRXJ3IFdlboIBADAJBgNVHRMEAjAAMIGK\n" +
|
||||
"BgorBgEEAdZ5AgQCBHwEegB4AHYA3xwuwRUAlFJHqWFoMl3cXHlZ6PfG04j8AC4L\n" +
|
||||
"vT9012QAAAE92yffkwAABAMARzBFAiBIL2dRrzXbplQ2vh/WZA89v5pBQpSVkkUw\n" +
|
||||
"KI+j5eI+BgIhAOTtwNs6xXKx4vXoq2poBlOYfc9BAn3+/6EFUZ2J7b8IMA0GCSqG\n" +
|
||||
"SIb3DQEBBQUAA4GBAIoMS+8JnUeSea+goo5on5HhxEIb4tJpoupspOghXd7dyhUE\n" +
|
||||
"oR58h8S3foDw6XkDUmjyfKIOFmgErlVvMWmB+Wo5Srer/T4lWsAERRP+dlcMZ5Wr\n" +
|
||||
"5HAxM9MD+J86+mu8/FFzGd/ZW5NCQSEfY0A1w9B4MHpoxgdaLiDInza4kQyg\n" +
|
||||
"-----END CERTIFICATE-----\n"
|
||||
|
||||
// TestInvalidEmbeddedCertPEM is a certificate that contains an SCT that is
|
||||
// not for the corresponding pre-certificate. The SCT embedded corresponds
|
||||
// to TestInvalidProof.
|
||||
// Certificate:
|
||||
// Data:
|
||||
// Version: 3 (0x2)
|
||||
// Serial Number: 7 (0x7)
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// Issuer: C = GB, O = Certificate Transparency CA, ST = Wales, L = Erw Wen
|
||||
// Validity
|
||||
// Not Before: Jun 1 00:00:00 2012 GMT
|
||||
// Not After : Jun 1 00:00:00 2022 GMT
|
||||
// Subject: C = GB, O = Certificate Transparency, ST = Wales, L = Erw Wen
|
||||
// Subject Public Key Info:
|
||||
// Public Key Algorithm: rsaEncryption
|
||||
// Public-Key: (1024 bit)
|
||||
// Modulus:
|
||||
// 00:be:ef:98:e7:c2:68:77:ae:38:5f:75:32:5a:0c:
|
||||
// 1d:32:9b:ed:f1:8f:aa:f4:d7:96:bf:04:7e:b7:e1:
|
||||
// ce:15:c9:5b:a2:f8:0e:e4:58:bd:7d:b8:6f:8a:4b:
|
||||
// 25:21:91:a7:9b:d7:00:c3:8e:9c:03:89:b4:5c:d4:
|
||||
// dc:9a:12:0a:b2:1e:0c:b4:1c:d0:e7:28:05:a4:10:
|
||||
// cd:9c:5b:db:5d:49:27:72:6d:af:17:10:f6:01:87:
|
||||
// 37:7e:a2:5b:1a:1e:39:ee:d0:b8:81:19:dc:15:4d:
|
||||
// c6:8f:7d:a8:e3:0c:af:15:8a:33:e6:c9:50:9f:4a:
|
||||
// 05:b0:14:09:ff:5d:d8:7e:b5
|
||||
// Exponent: 65537 (0x10001)
|
||||
// X509v3 extensions:
|
||||
// X509v3 Subject Key Identifier:
|
||||
// 20:31:54:1A:F2:5C:05:FF:D8:65:8B:68:43:79:4F:5E:90:36:F7:B4
|
||||
// X509v3 Authority Key Identifier:
|
||||
// keyid:5F:9D:88:0D:C8:73:E6:54:D4:F8:0D:D8:E6:B0:C1:24:B4:47:C3:55
|
||||
// DirName:/C=GB/O=Certificate Transparency CA/ST=Wales/L=Erw Wen
|
||||
// serial:00
|
||||
//
|
||||
// X509v3 Basic Constraints:
|
||||
// CA:FALSE
|
||||
// CT Precertificate SCTs:
|
||||
// Signed Certificate Timestamp:
|
||||
// Version : v1 (0x0)
|
||||
// Log ID : DF:1C:2E:C1:15:00:94:52:47:A9:61:68:32:5D:DC:5C:
|
||||
// 79:59:E8:F7:C6:D3:88:FC:00:2E:0B:BD:3F:74:D7:64
|
||||
// Timestamp : Apr 5 17:04:17.060 2013 GMT
|
||||
// Extensions: none
|
||||
// Signature : ecdsa-with-SHA256
|
||||
// 30:45:02:21:00:A6:D3:45:17:F3:39:2D:9E:C5:D2:57:
|
||||
// AD:F1:C5:97:DC:45:BD:4C:D3:B7:38:56:C6:16:A9:FB:
|
||||
// 99:E5:AE:75:A8:02:20:5E:26:C8:D1:C7:E2:22:FE:8C:
|
||||
// DA:29:BA:EB:04:A8:34:EE:97:D3:4F:D8:17:18:F1:AA:
|
||||
// E0:CD:66:F4:B8:A9:3F
|
||||
// Signature Algorithm: sha1WithRSAEncryption
|
||||
// af:28:89:06:38:b0:12:6f:dd:64:5d:d0:62:80:f8:10:6c:ec:
|
||||
// 49:4c:f8:22:86:0a:29:d4:f1:7e:6a:a5:7c:5a:58:b2:96:cc:
|
||||
// 90:c6:db:f1:22:10:4b:7f:4a:76:d6:fd:df:f2:1a:41:3a:9e:
|
||||
// e7:88:7e:32:a3:c7:a2:07:3c:e6:af:ae:01:b4:1a:a2:3d:ce:
|
||||
// 98:f3:ab:5e:c7:5c:e7:59:fa:7c:cc:ab:4f:fa:7a:a7:3e:7d:
|
||||
// 98:38:77:c6:d0:f1:de:cd:dd:37:49:00:59:b7:91:90:b2:7f:
|
||||
// 85:94:2b:7c:c8:b2:3c:bf:90:30:68:5d:21:43:c4:95:a5:39:
|
||||
// 6d:9f
|
||||
TestInvalidEmbeddedCertPEM = "-----BEGIN CERTIFICATE-----\n" +
|
||||
"MIIDWTCCAsKgAwIBAgIBBzANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk\n" +
|
||||
"MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX\n" +
|
||||
"YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw\n" +
|
||||
"MDAwMDBaMFIxCzAJBgNVBAYTAkdCMSEwHwYDVQQKExhDZXJ0aWZpY2F0ZSBUcmFu\n" +
|
||||
"c3BhcmVuY3kxDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGfMA0G\n" +
|
||||
"CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+75jnwmh3rjhfdTJaDB0ym+3xj6r015a/\n" +
|
||||
"BH634c4VyVui+A7kWL19uG+KSyUhkaeb1wDDjpwDibRc1NyaEgqyHgy0HNDnKAWk\n" +
|
||||
"EM2cW9tdSSdyba8XEPYBhzd+olsaHjnu0LiBGdwVTcaPfajjDK8VijPmyVCfSgWw\n" +
|
||||
"FAn/Xdh+tQIDAQABo4IBOjCCATYwHQYDVR0OBBYEFCAxVBryXAX/2GWLaEN5T16Q\n" +
|
||||
"Nve0MH0GA1UdIwR2MHSAFF+diA3Ic+ZU1PgN2OawwSS0R8NVoVmkVzBVMQswCQYD\n" +
|
||||
"VQQGEwJHQjEkMCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4w\n" +
|
||||
"DAYDVQQIEwVXYWxlczEQMA4GA1UEBxMHRXJ3IFdlboIBADAJBgNVHRMEAjAAMIGK\n" +
|
||||
"BgorBgEEAdZ5AgQCBHwEegB4AHYA3xwuwRUAlFJHqWFoMl3cXHlZ6PfG04j8AC4L\n" +
|
||||
"vT9012QAAAE92yfipAAABAMARzBFAiEAptNFF/M5LZ7F0let8cWX3EW9TNO3OFbG\n" +
|
||||
"Fqn7meWudagCIF4myNHH4iL+jNopuusEqDTul9NP2BcY8argzWb0uKk/MA0GCSqG\n" +
|
||||
"SIb3DQEBBQUAA4GBAK8oiQY4sBJv3WRd0GKA+BBs7ElM+CKGCinU8X5qpXxaWLKW\n" +
|
||||
"zJDG2/EiEEt/SnbW/d/yGkE6nueIfjKjx6IHPOavrgG0GqI9zpjzq17HXOdZ+nzM\n" +
|
||||
"q0/6eqc+fZg4d8bQ8d7N3TdJAFm3kZCyf4WUK3zIsjy/kDBoXSFDxJWlOW2f\n" +
|
||||
"-----END CERTIFICATE-----\n"
|
||||
)
|
||||
|
||||
var (
|
||||
// TestCertProof is a TLS-encoded ct.SignedCertificateTimestamp corresponding
|
||||
// to TestCertPEM.
|
||||
TestCertProof = dh("00df1c2ec11500945247a96168325ddc5c7959e8f7c6d388fc002e0bbd3f74d7" +
|
||||
"640000013ddb27ded900000403004730450220606e10ae5c2d5a1b0aed49dc49" +
|
||||
"37f48de71a4e9784e9c208dfbfe9ef536cf7f2022100beb29c72d7d06d61d06b" +
|
||||
"db38a069469aa86fe12e18bb7cc45689a2c0187ef5a5")
|
||||
|
||||
// TestPreCertProof is a TLS-encoded ct.SignedCertificateTimestamp
|
||||
// corresponding to TestPreCertPEM
|
||||
TestPreCertProof = dh("00df1c2ec11500945247a96168325ddc5c7959e8f7c6d388fc002e0bbd3f74d7" +
|
||||
"640000013ddb27df9300000403004730450220482f6751af35dba65436be1fd6" +
|
||||
"640f3dbf9a41429495924530288fa3e5e23e06022100e4edc0db3ac572b1e2f5" +
|
||||
"e8ab6a680653987dcf41027dfeffa105519d89edbf08")
|
||||
|
||||
// TestInvalidProof is a TLS-encoded ct.SignedCertificateTimestamp
|
||||
// corresponding to the invalid SCT embedded in TestInvalidEmbeddedCertPEM.
|
||||
TestInvalidProof = dh("00df1c2ec11500945247a96168325ddc5c7959e8f7c6d388fc002e0bbd3f74d7" +
|
||||
"640000013ddb27e2a40000040300473045022100a6d34517f3392d9ec5d257ad" +
|
||||
"f1c597dc45bd4cd3b73856c616a9fb99e5ae75a802205e26c8d1c7e222fe8cda" +
|
||||
"29baeb04a834ee97d34fd81718f1aae0cd66f4b8a93f")
|
||||
|
||||
// TestCertB64LeafHash is the base64-encoded leaf hash of TestCertPEM with
|
||||
// TestCertProof as the corresponding SCT.
|
||||
TestCertB64LeafHash = "BKZLZGMbAnDW0gQWjNJNCyS2IgweWn76YW3tFlu3AuY="
|
||||
|
||||
// TestPreCertB64LeafHash is the base64-encoded leaf hash of TestPreCertPEM
|
||||
// with TestPreCertProof as the corresponding SCT.
|
||||
TestPreCertB64LeafHash = "mbk+d5FDW3oNZJCbOi828rqC3hf+qhigTWVGcXEZq1U="
|
||||
)
|
||||
|
||||
func dh(h string) []byte {
|
||||
r, err := hex.DecodeString(h)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return r
|
||||
}
|
15
vendor/github.com/google/certificate-transparency-go/testdata/gossip-root.cert
generated
vendored
15
vendor/github.com/google/certificate-transparency-go/testdata/gossip-root.cert
generated
vendored
@ -1,15 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICQTCCAeegAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP
|
||||
MA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds
|
||||
ZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4
|
||||
MDIyNTA4MTA1M1oXDTI4MDIyMzA4MTA1M1owaTELMAkGA1UEBhMCR0IxDzANBgNV
|
||||
BAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK
|
||||
BgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49
|
||||
AgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH
|
||||
ccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijfTB7MB0GA1UdDgQWBBRq
|
||||
6hoXslGgHhrCVJMu4jrYlksyZjAfBgNVHSMEGDAWgBRq6hoXslGgHhrCVJMu4jrY
|
||||
lksyZjASBgNVHRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwICBDAVBgNVHSUE
|
||||
DjAMBgorBgEEAdZ5AgQGMAoGCCqGSM49BAMCA0gAMEUCIQCQCnWTIOlC6LqkcdH0
|
||||
fWZeNo5E3AaZBb9Tkv76ET2fJAIgOeGJvfiiOIlDV41/bIOg5eTHb/fxg80TCQBe
|
||||
6ia6ZS8=
|
||||
-----END CERTIFICATE-----
|
8
vendor/github.com/google/certificate-transparency-go/testdata/gossiper.privkey.pem
generated
vendored
8
vendor/github.com/google/certificate-transparency-go/testdata/gossiper.privkey.pem
generated
vendored
@ -1,8 +0,0 @@
|
||||
-----BEGIN EC PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-CBC,559BE893ECD7A88C
|
||||
|
||||
UOwSw+WlSv5LLiBZSCnR12FX13Hk1a3vavdpUde4W4qawQgJSMqLa3it8Lfadtnm
|
||||
GfGVqN+gF5KFiNWxgMs2qRcbdQ03ZlMmoH8Z8jPQHXvKseJvME8tZQWPvJ15rbXh
|
||||
G9Lcx7NYlm0miHPy3ras8ci58HSDqz9Z7yOdgHzPpiU=
|
||||
-----END EC PRIVATE KEY-----
|
221
vendor/github.com/google/certificate-transparency-go/testdata/keys.go
generated
vendored
221
vendor/github.com/google/certificate-transparency-go/testdata/keys.go
generated
vendored
@ -1,221 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package testdata holds data and utility functions needed for various Go tests.
|
||||
package testdata
|
||||
|
||||
import "encoding/hex"
|
||||
|
||||
// Hashes of text string 'abcd' with various algorithms; check with either "<alg>sum input" or "openssl dgst -<alg> input"
|
||||
const (
|
||||
// AbcdMD5 is 'abcd' hashed with MD5
|
||||
AbcdMD5 = "e2fc714c4727ee9395f324cd2e7f331f"
|
||||
// AbcdSHA1 is 'abcd' hashed with SHA1
|
||||
AbcdSHA1 = "81fe8bfe87576c3ecb22426f8e57847382917acf"
|
||||
// AbcdSHA224 is 'abcd' hashed with SHA224
|
||||
AbcdSHA224 = "a76654d8e3550e9a2d67a0eeb6c67b220e5885eddd3fde135806e601"
|
||||
// AbcdSHA256 is 'abcd' hashed with SHA256
|
||||
AbcdSHA256 = "88d4266fd4e6338d13b845fcf289579d209c897823b9217da3e161936f031589"
|
||||
// AbcdSHA384 is 'abcd' hashed with SHA384
|
||||
AbcdSHA384 = "1165b3406ff0b52a3d24721f785462ca2276c9f454a116c2b2ba20171a7905ea5a026682eb659c4d5f115c363aa3c79b"
|
||||
// AbcdSHA512 is 'abcd' hashed with SHA512
|
||||
AbcdSHA512 = "d8022f2060ad6efd297ab73dcc5355c9b214054b0d1776a136a669d26a7d3b14f73aa0d0ebff19ee333368f0164b6419a96da49e3e481753e7e96b716bdccb6f"
|
||||
)
|
||||
|
||||
const (
|
||||
// LogPublicKeyB64 is an ECDSA key copied from test/testdata/ct-server-key-public.pem
|
||||
LogPublicKeyB64 = "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmXg8sUUzwBYaWrRb+V0IopzQ6o3UyEJ04r5ZrRXGdpYM8K+hB0pXrGRLI0eeWz+3skXrS0IO83AhA3GpRL6s6w=="
|
||||
|
||||
// LogPublicKeyPEM is an ECDSA key copied from test/testdata/ct-server-key-public.pem
|
||||
LogPublicKeyPEM = "-----BEGIN PUBLIC KEY-----\n" +
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEmXg8sUUzwBYaWrRb+V0IopzQ6o3U\n" +
|
||||
"yEJ04r5ZrRXGdpYM8K+hB0pXrGRLI0eeWz+3skXrS0IO83AhA3GpRL6s6w==\n" +
|
||||
"-----END PUBLIC KEY-----\n"
|
||||
|
||||
// RsaPrivateKeyPEM was generated with:
|
||||
// openssl genpkey -algorithm RSA -out rsa.privkey.pem -pkeyopt rsa_keygen_bits:2048
|
||||
RsaPrivateKeyPEM = "-----BEGIN PRIVATE KEY-----\n" +
|
||||
"MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDP8SJM5SBIbFpF\n" +
|
||||
"dRAUEERo35E4iFXfT5SVAzBIqATkCpf3LfdFZgssPeliBdTtgdvT/CWC2m6aVXYZ\n" +
|
||||
"eScAJOauTpGDyJ7OXj7Yhx1q6u28NuQleU3UQK5QYb7VOjeIse7oTh+THf5IK5T5\n" +
|
||||
"esyh+ioybEYBXXMQetHc4YbXAq06crNT2BP+AxQ4z27xu4X5CKLwwVMa2xwMCFDC\n" +
|
||||
"Y7mxQzEhFv8+HbOtM0IQMSSyh6+o0w4Yzt6i/TUOytZb1D7WHOEMpVTd1CMbXjN0\n" +
|
||||
"tFZvoO0V+n0OV3oT1E5AvwujVguUJblQiapbL890/nZbBtP3xMoFLLhc7sX7N2vR\n" +
|
||||
"1wLWsjOVAgMBAAECggEBAL+frUZDV86l20JqsFhs7T3f2MnKCahyg7AWciZif69O\n" +
|
||||
"e+BTQa14bg9lNm8YhLIim1vs3vyJIqei3eR3mxMs7k/vI3XYKVBv1WZgjSF8QXzS\n" +
|
||||
"8Mf/01MoD/sPOHby4T5dCpaVd89xMmV7lBubqHwUN1KkKJcVcPXc2Qy94C6/zrcu\n" +
|
||||
"Vb7Q91ugTvvhyalWEN02M3tzHEn4cXrnMLWPmTgxb7YtTMRIbJFx2um7/W9G5D+1\n" +
|
||||
"ZtKMjwt+P/yXynx3Sa555MjjJ1/LUyMSbQZoLE0SGOigz1VQnP8nFlpvXUHzktiA\n" +
|
||||
"IBPBBQSsEoS8H3z6WThwY72O795/i2l5mf7EUUAa2/kCgYEA+W7tJPg69KWHKn6E\n" +
|
||||
"gGZKIDTxvp3vRxjLedp7D7cu6bVPCBVIHrPQdmp/mneY6x7Air0a9gCVbh32iCrm\n" +
|
||||
"UrSBCio4i6jtqtna2T1Gc0z63K3UrVQPR0Z6Swq1XDOI6/I23ibxPr12/XXWWYlA\n" +
|
||||
"wkPwvewJVrjtMoP1dkAKVbyzImcCgYEA1WqS0xg7BL4iNGFPrrSme2blZOgga83x\n" +
|
||||
"CtY9dnWAs0IvdxsuItCDaFVJm3oU18ohirEMzqZvbRlwMlUawpd75hCNWyVF4cRo\n" +
|
||||
"+l1RvzOlC/7QXX/E+Kv7sTEUYH7hJyS46QhOtC1/ndAyObk9c2VNJmERfMwIHNm9\n" +
|
||||
"BfSN8yrq1KMCgYEA94fCZPbGIvSFj4EgYv+fvhhscvrucsLDYniTuUPTlXAtLttX\n" +
|
||||
"x8gwLuN/ID5hjarl7oi90bVAlZe8iOLx0M96YykFFmuc9/jcOsuZN2EEbq0/KocJ\n" +
|
||||
"5nSldgT5d7dYwLWNB6bjr5x8Egm3nwEbN+4OYZt0pRA9q+zSUfg5iV4K8y8CgYA7\n" +
|
||||
"S9YposTbJ3zXcuYx022iQc+gvsIrUdgUO7xuCm3M4KnRfRLPh4HLXk8KTNw3rKiv\n" +
|
||||
"IUw+qo2xEW1T/sNlp7M8FANCfNOyy+CjF4ScDFxiPdVk9RgkQ5y1+b4ApaAnQRPD\n" +
|
||||
"Y5SCiVW44lziHu7M/it2a2fxdbsXUQQtAGrkUltW4wKBgAPZyEGi4V2wryOswmkC\n" +
|
||||
"I29TbC6ChnUOvqJfSfz536eIi41D1Ua2Y/VlAK1ud7K8ilr/M4VoRjHqbPivR1Uk\n" +
|
||||
"RU7nO3cWRBuDBjgZWeAq5WFIMPbm9gRlaTECI6EFtAOI1GcHOsOBecd3PBiQNXvj\n" +
|
||||
"YyGD1wSrHQwDcnxtP1rqEQDV\n" +
|
||||
"-----END PRIVATE KEY-----\n"
|
||||
|
||||
// RsaPublicKeyPEM was generated from above with:
|
||||
// openssl rsa -pubout -in rsa.privkey.pem -out rsa.pubkey.pem
|
||||
RsaPublicKeyPEM = "-----BEGIN PUBLIC KEY-----\n" +
|
||||
"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz/EiTOUgSGxaRXUQFBBE\n" +
|
||||
"aN+ROIhV30+UlQMwSKgE5AqX9y33RWYLLD3pYgXU7YHb0/wlgtpumlV2GXknACTm\n" +
|
||||
"rk6Rg8iezl4+2IcdaurtvDbkJXlN1ECuUGG+1To3iLHu6E4fkx3+SCuU+XrMofoq\n" +
|
||||
"MmxGAV1zEHrR3OGG1wKtOnKzU9gT/gMUOM9u8buF+Qii8MFTGtscDAhQwmO5sUMx\n" +
|
||||
"IRb/Ph2zrTNCEDEksoevqNMOGM7eov01DsrWW9Q+1hzhDKVU3dQjG14zdLRWb6Dt\n" +
|
||||
"Ffp9Dld6E9ROQL8Lo1YLlCW5UImqWy/PdP52WwbT98TKBSy4XO7F+zdr0dcC1rIz\n" +
|
||||
"lQIDAQAB\n" +
|
||||
"-----END PUBLIC KEY-----\n"
|
||||
|
||||
// RsaSignedAbcdHex was generated with:
|
||||
// echo -n "abcd" > sign.input
|
||||
// openssl sha256 -sign rsa.privkey.pem -out sign.rsa sign.input
|
||||
// Verify with:
|
||||
// openssl sha256 -verify rsa.pubkey.pem -signature sign.rsa sign.input
|
||||
RsaSignedAbcdHex = "4692f17adad62324a38a786d9b05eb7facf95c277729bc23e8d4f4fe25c0ac0e" +
|
||||
"9115f14ffd4dc6c00e6b2717677e96ed4da9e2226745db5c2d14ec8b4f96959e" +
|
||||
"a43ca73e3ab801d4e76b0c0599c741b9701dd0c22b20cc7a294fccce97d2eda2" +
|
||||
"72448830a19b0b1075f962d3bcf65922f81f4747dde1a2883ffce12941927af6" +
|
||||
"25549ea7b4f745a95f5558822af434cc7471ea5a21cce656a7667d29bff3e6f2" +
|
||||
"fb3d48bbee1a60116f0dd429d5691b008482e9ec42538bcf2692e1a685e836c8" +
|
||||
"49316fb3c49b58bd5a0c33f0256b09d59af08a018fe64cd31051cb9e9a1d3fde" +
|
||||
"e186bd80bfe304abbbec2ac18d3bee09465cb69f2638728aba4b9886a252768a"
|
||||
|
||||
// DsaPrivateKeyPEM was generated with:
|
||||
// openssl dsaparam -out dsa.param.pem 2048; openssl gendsa dsa.param.pem -out dsa.privkey.pem
|
||||
DsaPrivateKeyPEM = "-----BEGIN DSA PRIVATE KEY-----\n" +
|
||||
"MIIDVwIBAAKCAQEA3Q72qQc0ZM2eUjvZ/XOROQTbhmjzuZdzY7kd+82n54NPeqVz\n" +
|
||||
"+FWmk26INd7pUNbn/TjniN5+pC2pK+p9alFLE19bOvsY4x7Ugwrpd9sQIea3W4Q7\n" +
|
||||
"H9PaEW+BooFzT/feC9TmnU0ynwoNhZB33Cr3k3PFt/69lmyrkd91wTpXrstrQurU\n" +
|
||||
"h4baL5l6t2/JT3TxpKx6xe19hWqqFsBLu/j+kE2o2Aw1TVLHg4/74TJLfqAkWnCI\n" +
|
||||
"u9QL0uGQnW80kRfJnT+tUJXrXMpg1HxK7CsDEW5xsAWF370Is0UPaP7jRru6FiSN\n" +
|
||||
"ObcVhSqCIs+QJIWie9cRtwniwhoi4z6AfGeEYQIhAOkSzAsWja1fwB486/LCW+zv\n" +
|
||||
"DJKiCGLTalimfawzHQHFAoIBAQDJvCujEZ/WeQFLlP/0zS+2DjqdaxnKj1xuXfoL\n" +
|
||||
"LOocvMw06dnrQNmDu/nBQiYSfzf7zjwpnx+AVjBQssK0jXs0l7gw52FyCIztDejT\n" +
|
||||
"/ybMVudwKUGudxAEjOclOSQ7XVpPd4p3UMy+E6pkJ8VRiuNFDibYTD+O3XhFTj2l\n" +
|
||||
"6LqV/KcB2fWV1fUqfxax2vpcwe4clTJbJXUgJC3mYmUXv1U6z0hliDz2WMhbOyea\n" +
|
||||
"1fs31zYvIMyk2wJFJl7+EbXb8BgYcQt1FE4c14fuFnincAW0So+xBZ5DtiTja4lm\n" +
|
||||
"DE0OAI2hhLslSQ7rGwWt2zIKSFLtsWf78CP1wigJvWcUVhazAoIBAFAhxgtOaV8G\n" +
|
||||
"FJxs6A3TtXEmmrq3i5/w3/8l7skWamcHvcwrvw37g5KQY+N+85JZszHPjmUzEq/o\n" +
|
||||
"NOLjF6zq7+oRtWbOR3Mvc2hHsHg86tE/HAkBIu2G73c9UuskzGSMec4F6TyWKHvC\n" +
|
||||
"26F2cvu9aA42v/8q1d/QQs3+LrtARGhyFCqnBVNSZmZj5ngR0kLGUfs/LQklpGFe\n" +
|
||||
"VciXK57RxHSPo15lnKiHW9kCte7tGEg9Eber8paMz67dQDuj1yRkS5H7JXqRZjIP\n" +
|
||||
"UrICWGGk1vluQsuoyI/Nu8/tL7Im24xZH6XHBm4F+aijl9XlAJiKXfkCLIaxYSdc\n" +
|
||||
"4PXquTwtRLICIQCijrpD+UhidGFLPZCCLzBC239PrP7PabSVurWXHh5iYw==\n" +
|
||||
"-----END DSA PRIVATE KEY-----\n"
|
||||
|
||||
// DsaPrivateKeyPKCS8PEM is a copy of the private key above, encoded in PKCS#8 format.
|
||||
// Generated from above with:
|
||||
// openssl pkcs8 -topk8 -nocrypt -in dsa.privkey.pem -out dsa.privkey.pkcs8.pem
|
||||
DsaPrivateKeyPKCS8PEM = "-----BEGIN PRIVATE KEY-----\n" +
|
||||
"MIICZgIBADCCAjoGByqGSM44BAEwggItAoIBAQDdDvapBzRkzZ5SO9n9c5E5BNuG\n" +
|
||||
"aPO5l3NjuR37zafng096pXP4VaaTbog13ulQ1uf9OOeI3n6kLakr6n1qUUsTX1s6\n" +
|
||||
"+xjjHtSDCul32xAh5rdbhDsf09oRb4GigXNP994L1OadTTKfCg2FkHfcKveTc8W3\n" +
|
||||
"/r2WbKuR33XBOleuy2tC6tSHhtovmXq3b8lPdPGkrHrF7X2FaqoWwEu7+P6QTajY\n" +
|
||||
"DDVNUseDj/vhMkt+oCRacIi71AvS4ZCdbzSRF8mdP61QletcymDUfErsKwMRbnGw\n" +
|
||||
"BYXfvQizRQ9o/uNGu7oWJI05txWFKoIiz5AkhaJ71xG3CeLCGiLjPoB8Z4RhAiEA\n" +
|
||||
"6RLMCxaNrV/AHjzr8sJb7O8MkqIIYtNqWKZ9rDMdAcUCggEBAMm8K6MRn9Z5AUuU\n" +
|
||||
"//TNL7YOOp1rGcqPXG5d+gss6hy8zDTp2etA2YO7+cFCJhJ/N/vOPCmfH4BWMFCy\n" +
|
||||
"wrSNezSXuDDnYXIIjO0N6NP/JsxW53ApQa53EASM5yU5JDtdWk93indQzL4TqmQn\n" +
|
||||
"xVGK40UOJthMP47deEVOPaXoupX8pwHZ9ZXV9Sp/FrHa+lzB7hyVMlsldSAkLeZi\n" +
|
||||
"ZRe/VTrPSGWIPPZYyFs7J5rV+zfXNi8gzKTbAkUmXv4RtdvwGBhxC3UUThzXh+4W\n" +
|
||||
"eKdwBbRKj7EFnkO2JONriWYMTQ4AjaGEuyVJDusbBa3bMgpIUu2xZ/vwI/XCKAm9\n" +
|
||||
"ZxRWFrMEIwIhAKKOukP5SGJ0YUs9kIIvMELbf0+s/s9ptJW6tZceHmJj\n" +
|
||||
"-----END PRIVATE KEY-----\n"
|
||||
|
||||
// DsaPublicKeyPEM was generated from above with:
|
||||
// openssl dsa -in dsa.privkey.pem -pubout -out dsa.pubkey.pem
|
||||
DsaPublicKeyPEM = "-----BEGIN PUBLIC KEY-----\n" +
|
||||
"MIIDRzCCAjoGByqGSM44BAEwggItAoIBAQDdDvapBzRkzZ5SO9n9c5E5BNuGaPO5\n" +
|
||||
"l3NjuR37zafng096pXP4VaaTbog13ulQ1uf9OOeI3n6kLakr6n1qUUsTX1s6+xjj\n" +
|
||||
"HtSDCul32xAh5rdbhDsf09oRb4GigXNP994L1OadTTKfCg2FkHfcKveTc8W3/r2W\n" +
|
||||
"bKuR33XBOleuy2tC6tSHhtovmXq3b8lPdPGkrHrF7X2FaqoWwEu7+P6QTajYDDVN\n" +
|
||||
"UseDj/vhMkt+oCRacIi71AvS4ZCdbzSRF8mdP61QletcymDUfErsKwMRbnGwBYXf\n" +
|
||||
"vQizRQ9o/uNGu7oWJI05txWFKoIiz5AkhaJ71xG3CeLCGiLjPoB8Z4RhAiEA6RLM\n" +
|
||||
"CxaNrV/AHjzr8sJb7O8MkqIIYtNqWKZ9rDMdAcUCggEBAMm8K6MRn9Z5AUuU//TN\n" +
|
||||
"L7YOOp1rGcqPXG5d+gss6hy8zDTp2etA2YO7+cFCJhJ/N/vOPCmfH4BWMFCywrSN\n" +
|
||||
"ezSXuDDnYXIIjO0N6NP/JsxW53ApQa53EASM5yU5JDtdWk93indQzL4TqmQnxVGK\n" +
|
||||
"40UOJthMP47deEVOPaXoupX8pwHZ9ZXV9Sp/FrHa+lzB7hyVMlsldSAkLeZiZRe/\n" +
|
||||
"VTrPSGWIPPZYyFs7J5rV+zfXNi8gzKTbAkUmXv4RtdvwGBhxC3UUThzXh+4WeKdw\n" +
|
||||
"BbRKj7EFnkO2JONriWYMTQ4AjaGEuyVJDusbBa3bMgpIUu2xZ/vwI/XCKAm9ZxRW\n" +
|
||||
"FrMDggEFAAKCAQBQIcYLTmlfBhScbOgN07VxJpq6t4uf8N//Je7JFmpnB73MK78N\n" +
|
||||
"+4OSkGPjfvOSWbMxz45lMxKv6DTi4xes6u/qEbVmzkdzL3NoR7B4POrRPxwJASLt\n" +
|
||||
"hu93PVLrJMxkjHnOBek8lih7wtuhdnL7vWgONr//KtXf0ELN/i67QERochQqpwVT\n" +
|
||||
"UmZmY+Z4EdJCxlH7Py0JJaRhXlXIlyue0cR0j6NeZZyoh1vZArXu7RhIPRG3q/KW\n" +
|
||||
"jM+u3UA7o9ckZEuR+yV6kWYyD1KyAlhhpNb5bkLLqMiPzbvP7S+yJtuMWR+lxwZu\n" +
|
||||
"Bfmoo5fV5QCYil35AiyGsWEnXOD16rk8LUSy\n" +
|
||||
"-----END PUBLIC KEY-----\n"
|
||||
|
||||
// DsaSignedAbcdHex was generated with:
|
||||
// echo -n "abcd" > sign.input
|
||||
// openssl dgst -dss1 -sign dsa.privkey.pem -out sign.dsa sign.input
|
||||
// Note that this includes randomization so will give different results each time.
|
||||
// Verify with:
|
||||
// openssl dgst -dss1 -verify dsa.pubkey.pem -signature sign.dsa sign.input
|
||||
DsaSignedAbcdHex = "3045022100c287211dec54eab597ed5264f6fdf57faf651909914c533d42f0e3" +
|
||||
"2809e9141402205f34cc4b8ca12ebdf025bf36bbe1ff7d807d4cfe951ac1329a" +
|
||||
"35a39f5e971f10"
|
||||
|
||||
// EcdsaPrivateKeyPEM was generated with:
|
||||
// openssl ecparam -genkey -name prime256v1 -noout -out ecdsa.privkey.pem
|
||||
EcdsaPrivateKeyPEM = "-----BEGIN EC PRIVATE KEY-----\n" +
|
||||
"MHcCAQEEIHg0hg3vLqLVI7wv2y0cCk+kmwuwoKsMZqzqbjqP1AtjoAoGCCqGSM49\n" +
|
||||
"AwEHoUQDQgAEjHs6Rw7KFt8Wd2ZcioZi7eZY5nodUXMnCWUhZzsGVsPaexqUyPSr\n" +
|
||||
"9cQgrCe7MPRLJ524AO6rREqfs7FKt85++A==\n" +
|
||||
"-----END EC PRIVATE KEY-----\n"
|
||||
|
||||
// EcdsaPrivateKeyPKCS8PEM is a copy of the private key above, encoded in PKCS#8 format.
|
||||
// Generated from above with:
|
||||
// openssl pkcs8 -topk8 -nocrypt -in ecdsa.privkey.pem -out ecdsa.privkey.pkcs8.pem
|
||||
EcdsaPrivateKeyPKCS8PEM = "-----BEGIN PRIVATE KEY-----\n" +
|
||||
"MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgeDSGDe8uotUjvC/b\n" +
|
||||
"LRwKT6SbC7CgqwxmrOpuOo/UC2OhRANCAASMezpHDsoW3xZ3ZlyKhmLt5ljmeh1R\n" +
|
||||
"cycJZSFnOwZWw9p7GpTI9Kv1xCCsJ7sw9EsnnbgA7qtESp+zsUq3zn74\n" +
|
||||
"-----END PRIVATE KEY-----\n"
|
||||
|
||||
// EcdsaPublicKeyPEM was generated from above with:
|
||||
// openssl ec -in ecdsa.privkey.pem -pubout -out ecdsa.pubkey.pem
|
||||
EcdsaPublicKeyPEM = "-----BEGIN PUBLIC KEY-----\n" +
|
||||
"MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjHs6Rw7KFt8Wd2ZcioZi7eZY5nod\n" +
|
||||
"UXMnCWUhZzsGVsPaexqUyPSr9cQgrCe7MPRLJ524AO6rREqfs7FKt85++A==\n" +
|
||||
"-----END PUBLIC KEY-----\n"
|
||||
|
||||
// EcdsaSignedAbcdHex was generated with:
|
||||
// echo -n "abcd" > sign.input
|
||||
// openssl dgst -sha256 -sign ecdsa.privkey.pem -out sign.ecdsa sign.input
|
||||
// Note that this includes randomization so will give different results each time.
|
||||
// Verify with:
|
||||
// openssl dgst -sha256 -verify ecdsa.pubkey.pem -signature sign.ecdsa sign.input
|
||||
EcdsaSignedAbcdHex = "304502202e0204dadf2baa35e426b66ab8cd32a9ba33421187645a9110512e3e" +
|
||||
"d1b8007b022100ae83f5f993ab3af6f46bb09b4f15d07cc582b03e1353879ada" +
|
||||
"ce68796fe537e5"
|
||||
)
|
||||
|
||||
// FromHex decodes a hex string to a byte array, and panics on error; only suitable for
|
||||
// use in test code.
|
||||
func FromHex(hexdata string) []byte {
|
||||
data, err := hex.DecodeString(hexdata)
|
||||
if err != nil {
|
||||
panic("non hex data: " + err.Error())
|
||||
}
|
||||
return data
|
||||
}
|
60
vendor/github.com/google/certificate-transparency-go/testdata/test-cert.pem
generated
vendored
60
vendor/github.com/google/certificate-transparency-go/testdata/test-cert.pem
generated
vendored
@ -1,60 +0,0 @@
|
||||
Certificate:
|
||||
Data:
|
||||
Version: 3 (0x2)
|
||||
Serial Number: 6 (0x6)
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
Issuer: C=GB, O=Certificate Transparency CA, ST=Wales, L=Erw Wen
|
||||
Validity
|
||||
Not Before: Jun 1 00:00:00 2012 GMT
|
||||
Not After : Jun 1 00:00:00 2022 GMT
|
||||
Subject: C=GB, O=Certificate Transparency, ST=Wales, L=Erw Wen
|
||||
Subject Public Key Info:
|
||||
Public Key Algorithm: rsaEncryption
|
||||
Public-Key: (1024 bit)
|
||||
Modulus:
|
||||
00:b1:fa:37:93:61:11:f8:79:2d:a2:08:1c:3f:e4:
|
||||
19:25:00:85:31:dc:7f:2c:65:7b:d9:e1:de:47:04:
|
||||
16:0b:4c:9f:19:d5:4a:da:44:70:40:4c:1c:51:34:
|
||||
1b:8f:1f:75:38:dd:dd:28:d9:ac:a4:83:69:fc:56:
|
||||
46:dd:cc:76:17:f8:16:8a:ae:5b:41:d4:33:31:fc:
|
||||
a2:da:df:c8:04:d5:72:08:94:90:61:f9:ee:f9:02:
|
||||
ca:47:ce:88:c6:44:e0:00:f0:6e:ee:cc:ab:dc:9d:
|
||||
d2:f6:8a:22:cc:b0:9d:c7:6e:0d:bc:73:52:77:65:
|
||||
b1:a3:7a:8c:67:62:53:dc:c1
|
||||
Exponent: 65537 (0x10001)
|
||||
X509v3 extensions:
|
||||
X509v3 Subject Key Identifier:
|
||||
6A:0D:98:2A:3B:62:C4:4B:6D:2E:F4:E9:BB:7A:01:AA:9C:B7:98:E2
|
||||
X509v3 Authority Key Identifier:
|
||||
keyid:5F:9D:88:0D:C8:73:E6:54:D4:F8:0D:D8:E6:B0:C1:24:B4:47:C3:55
|
||||
DirName:/C=GB/O=Certificate Transparency CA/ST=Wales/L=Erw Wen
|
||||
serial:00
|
||||
|
||||
X509v3 Basic Constraints:
|
||||
CA:FALSE
|
||||
Signature Algorithm: sha1WithRSAEncryption
|
||||
17:1c:d8:4a:ac:41:4a:9a:03:0f:22:aa:c8:f6:88:b0:81:b2:
|
||||
70:9b:84:8b:4e:55:11:40:6c:d7:07:fe:d0:28:59:7a:9f:ae:
|
||||
fc:2e:ee:29:78:d6:33:aa:ac:14:ed:32:35:19:7d:a8:7e:0f:
|
||||
71:b8:87:5f:1a:c9:e7:8b:28:17:49:dd:ed:d0:07:e3:ec:f5:
|
||||
06:45:f8:cb:f6:67:25:6c:d6:a1:64:7b:5e:13:20:3b:b8:58:
|
||||
2d:e7:d6:69:6f:65:6d:1c:60:b9:5f:45:6b:7f:cf:33:85:71:
|
||||
90:8f:1c:69:72:7d:24:c4:fc:cd:24:92:95:79:58:14:d1:da:
|
||||
c0:e6
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIICyjCCAjOgAwIBAgIBBjANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk
|
||||
MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX
|
||||
YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw
|
||||
MDAwMDBaMFIxCzAJBgNVBAYTAkdCMSEwHwYDVQQKExhDZXJ0aWZpY2F0ZSBUcmFu
|
||||
c3BhcmVuY3kxDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGfMA0G
|
||||
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCx+jeTYRH4eS2iCBw/5BklAIUx3H8sZXvZ
|
||||
4d5HBBYLTJ8Z1UraRHBATBxRNBuPH3U43d0o2aykg2n8VkbdzHYX+BaKrltB1DMx
|
||||
/KLa38gE1XIIlJBh+e75AspHzojGROAA8G7uzKvcndL2iiLMsJ3Hbg28c1J3ZbGj
|
||||
eoxnYlPcwQIDAQABo4GsMIGpMB0GA1UdDgQWBBRqDZgqO2LES20u9Om7egGqnLeY
|
||||
4jB9BgNVHSMEdjB0gBRfnYgNyHPmVNT4DdjmsMEktEfDVaFZpFcwVTELMAkGA1UE
|
||||
BhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRyYW5zcGFyZW5jeSBDQTEOMAwG
|
||||
A1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW6CAQAwCQYDVR0TBAIwADANBgkq
|
||||
hkiG9w0BAQUFAAOBgQAXHNhKrEFKmgMPIqrI9oiwgbJwm4SLTlURQGzXB/7QKFl6
|
||||
n678Lu4peNYzqqwU7TI1GX2ofg9xuIdfGsnniygXSd3t0Afj7PUGRfjL9mclbNah
|
||||
ZHteEyA7uFgt59Zpb2VtHGC5X0Vrf88zhXGQjxxpcn0kxPzNJJKVeVgU0drA5g==
|
||||
-----END CERTIFICATE-----
|
BIN
vendor/github.com/google/certificate-transparency-go/testdata/test-cert.proof
generated
vendored
BIN
vendor/github.com/google/certificate-transparency-go/testdata/test-cert.proof
generated
vendored
Binary file not shown.
65
vendor/github.com/google/certificate-transparency-go/tls/hash_test.go
generated
vendored
65
vendor/github.com/google/certificate-transparency-go/tls/hash_test.go
generated
vendored
@ -1,65 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tls
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/certificate-transparency-go/testdata"
|
||||
)
|
||||
|
||||
func TestGenerateHash(t *testing.T) {
|
||||
var tests = []struct {
|
||||
in string // hex encoded
|
||||
algo HashAlgorithm
|
||||
want string // hex encoded
|
||||
errstr string
|
||||
}{
|
||||
// Empty hash values
|
||||
{"", MD5, "d41d8cd98f00b204e9800998ecf8427e", ""},
|
||||
{"", SHA1, "da39a3ee5e6b4b0d3255bfef95601890afd80709", ""},
|
||||
{"", SHA224, "d14a028c2a3a2bc9476102bb288234c415a2b01f828ea62ac5b3e42f", ""},
|
||||
{"", SHA256, "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", ""},
|
||||
{"", SHA384, "38b060a751ac96384cd9327eb1b1e36a21fdb71114be07434c0cc7bf63f6e1da274edebfe76f65fbd51ad2f14898b95b", ""},
|
||||
{"", SHA512, "cf83e1357eefb8bdf1542850d66d8007d620e4050b5715dc83f4a921d36ce9ce47d0d13c5d85f2b0ff8318d2877eec2f63b931bd47417a81a538327af927da3e", ""},
|
||||
{"", 999, "", "unsupported"},
|
||||
|
||||
// Hashes of "abcd".
|
||||
{"61626364", MD5, testdata.AbcdMD5, ""},
|
||||
{"61626364", SHA1, testdata.AbcdSHA1, ""},
|
||||
{"61626364", SHA224, testdata.AbcdSHA224, ""},
|
||||
{"61626364", SHA256, testdata.AbcdSHA256, ""},
|
||||
{"61626364", SHA384, testdata.AbcdSHA384, ""},
|
||||
{"61626364", SHA512, testdata.AbcdSHA512, ""},
|
||||
}
|
||||
for _, test := range tests {
|
||||
got, _, err := generateHash(test.algo, testdata.FromHex(test.in))
|
||||
if test.errstr != "" {
|
||||
if err == nil {
|
||||
t.Errorf("generateHash(%s)=%s,nil; want error %q", test.in, hex.EncodeToString(got), test.errstr)
|
||||
} else if !strings.Contains(err.Error(), test.errstr) {
|
||||
t.Errorf("generateHash(%s)=nil,%q; want error %q", test.in, test.errstr, err.Error())
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("generateHash(%s)=nil,%q; want %s", test.in, err, test.want)
|
||||
} else if hex.EncodeToString(got) != test.want {
|
||||
t.Errorf("generateHash(%s)=%s,nil; want %s", test.in, hex.EncodeToString(got), test.want)
|
||||
}
|
||||
}
|
||||
}
|
160
vendor/github.com/google/certificate-transparency-go/tls/signature_test.go
generated
vendored
160
vendor/github.com/google/certificate-transparency-go/tls/signature_test.go
generated
vendored
@ -1,160 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tls_test
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"encoding/pem"
|
||||
mathrand "math/rand"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/certificate-transparency-go/testdata"
|
||||
"github.com/google/certificate-transparency-go/tls"
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
)
|
||||
|
||||
func TestVerifySignature(t *testing.T) {
|
||||
var tests = []struct {
|
||||
pubKey crypto.PublicKey
|
||||
in string // hex encoded
|
||||
hashAlgo tls.HashAlgorithm
|
||||
sigAlgo tls.SignatureAlgorithm
|
||||
errstr string
|
||||
sig string // hex encoded
|
||||
}{
|
||||
{PEM2PK(testdata.RsaPublicKeyPEM), "61626364", 99, tls.ECDSA, "unsupported Algorithm.Hash", "1234"},
|
||||
{PEM2PK(testdata.RsaPublicKeyPEM), "61626364", tls.SHA256, 99, "unsupported Algorithm.Signature", "1234"},
|
||||
|
||||
{PEM2PK(testdata.RsaPublicKeyPEM), "61626364", tls.SHA256, tls.DSA, "cannot verify DSA", "1234"},
|
||||
{PEM2PK(testdata.RsaPublicKeyPEM), "61626364", tls.SHA256, tls.ECDSA, "cannot verify ECDSA", "1234"},
|
||||
{PEM2PK(testdata.RsaPublicKeyPEM), "61626364", tls.SHA256, tls.RSA, "verification error", "1234"},
|
||||
{PEM2PK(testdata.RsaPublicKeyPEM), "61626364", tls.SHA256, tls.ECDSA, "cannot verify ECDSA", "1234"},
|
||||
|
||||
{PEM2PK(testdata.DsaPublicKeyPEM), "61626364", tls.SHA1, tls.RSA, "cannot verify RSA", "1234"},
|
||||
{PEM2PK(testdata.DsaPublicKeyPEM), "61626364", tls.SHA1, tls.ECDSA, "cannot verify ECDSA", "1234"},
|
||||
{PEM2PK(testdata.DsaPublicKeyPEM), "61626364", tls.SHA1, tls.DSA, "failed to unmarshal DSA signature", "1234"},
|
||||
{PEM2PK(testdata.DsaPublicKeyPEM), "61626364", tls.SHA1, tls.DSA, "failed to verify DSA signature", "3006020101020101eeff"},
|
||||
{PEM2PK(testdata.DsaPublicKeyPEM), "61626364", tls.SHA1, tls.DSA, "zero or negative values", "3006020100020181"},
|
||||
|
||||
{PEM2PK(testdata.EcdsaPublicKeyPEM), "61626364", tls.SHA256, tls.RSA, "cannot verify RSA", "1234"},
|
||||
{PEM2PK(testdata.EcdsaPublicKeyPEM), "61626364", tls.SHA256, tls.DSA, "cannot verify DSA", "1234"},
|
||||
{PEM2PK(testdata.EcdsaPublicKeyPEM), "61626364", tls.SHA256, tls.ECDSA, "failed to unmarshal ECDSA signature", "1234"},
|
||||
{PEM2PK(testdata.EcdsaPublicKeyPEM), "61626364", tls.SHA256, tls.ECDSA, "failed to verify ECDSA signature", "3006020101020101eeff"},
|
||||
{PEM2PK(testdata.EcdsaPublicKeyPEM), "61626364", tls.SHA256, tls.ECDSA, "zero or negative values", "3006020100020181"},
|
||||
|
||||
{PEM2PK(testdata.RsaPublicKeyPEM), "61626364", tls.SHA256, tls.RSA, "", testdata.RsaSignedAbcdHex},
|
||||
{PEM2PK(testdata.DsaPublicKeyPEM), "61626364", tls.SHA1, tls.DSA, "", testdata.DsaSignedAbcdHex},
|
||||
{PEM2PK(testdata.EcdsaPublicKeyPEM), "61626364", tls.SHA256, tls.ECDSA, "", testdata.EcdsaSignedAbcdHex},
|
||||
}
|
||||
for _, test := range tests {
|
||||
algo := tls.SignatureAndHashAlgorithm{Hash: test.hashAlgo, Signature: test.sigAlgo}
|
||||
signed := tls.DigitallySigned{Algorithm: algo, Signature: testdata.FromHex(test.sig)}
|
||||
|
||||
err := tls.VerifySignature(test.pubKey, testdata.FromHex(test.in), signed)
|
||||
if test.errstr != "" {
|
||||
if err == nil {
|
||||
t.Errorf("VerifySignature(%s)=nil; want %q", test.in, test.errstr)
|
||||
} else if !strings.Contains(err.Error(), test.errstr) {
|
||||
t.Errorf("VerifySignature(%s)=%q; want %q", test.in, err.Error(), test.errstr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("VerifySignature(%s)=%q; want nil", test.in, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateSignatureVerifySignatureRoundTrip(t *testing.T) {
|
||||
var tests = []struct {
|
||||
privKey crypto.PrivateKey
|
||||
pubKey crypto.PublicKey
|
||||
hashAlgo tls.HashAlgorithm
|
||||
}{
|
||||
{PEM2PrivKey(testdata.RsaPrivateKeyPEM), PEM2PK(testdata.RsaPublicKeyPEM), tls.SHA256},
|
||||
{PEM2PrivKey(testdata.EcdsaPrivateKeyPKCS8PEM), PEM2PK(testdata.EcdsaPublicKeyPEM), tls.SHA256},
|
||||
}
|
||||
seed := time.Now().UnixNano()
|
||||
r := mathrand.New(mathrand.NewSource(seed))
|
||||
for _, test := range tests {
|
||||
for j := 0; j < 1; j++ {
|
||||
dataLen := 10 + r.Intn(100)
|
||||
data := make([]byte, dataLen)
|
||||
_, _ = r.Read(data)
|
||||
sig, err := tls.CreateSignature(test.privKey, test.hashAlgo, data)
|
||||
if err != nil {
|
||||
t.Errorf("CreateSignature(%T, %v) failed with: %q", test.privKey, test.hashAlgo, err.Error())
|
||||
continue
|
||||
}
|
||||
|
||||
if err := tls.VerifySignature(test.pubKey, data, sig); err != nil {
|
||||
t.Errorf("VerifySignature(%T, %v) failed with: %q", test.pubKey, test.hashAlgo, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateSignatureFailures(t *testing.T) {
|
||||
var tests = []struct {
|
||||
privKey crypto.PrivateKey
|
||||
hashAlgo tls.HashAlgorithm
|
||||
in string // hex encoded
|
||||
errstr string
|
||||
}{
|
||||
{PEM2PrivKey(testdata.EcdsaPrivateKeyPKCS8PEM), 99, "abcd", "unsupported Algorithm.Hash"},
|
||||
{nil, tls.SHA256, "abcd", "unsupported private key type"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if sig, err := tls.CreateSignature(test.privKey, test.hashAlgo, testdata.FromHex(test.in)); err == nil {
|
||||
t.Errorf("CreateSignature(%T, %v)=%v,nil; want error %q", test.privKey, test.hashAlgo, sig, test.errstr)
|
||||
} else if !strings.Contains(err.Error(), test.errstr) {
|
||||
t.Errorf("CreateSignature(%T, %v)=nil,%q; want error %q", test.privKey, test.hashAlgo, err.Error(), test.errstr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func PEM2PK(s string) crypto.PublicKey {
|
||||
p, _ := pem.Decode([]byte(s))
|
||||
if p == nil {
|
||||
panic("no PEM block found in " + s)
|
||||
}
|
||||
pubKey, _ := x509.ParsePKIXPublicKey(p.Bytes)
|
||||
if pubKey == nil {
|
||||
panic("public key not parsed from " + s)
|
||||
}
|
||||
return pubKey
|
||||
}
|
||||
func PEM2PrivKey(s string) crypto.PrivateKey {
|
||||
p, _ := pem.Decode([]byte(s))
|
||||
if p == nil {
|
||||
panic("no PEM block found in " + s)
|
||||
}
|
||||
|
||||
// Try various different private key formats one after another.
|
||||
if rsaPrivKey, err := x509.ParsePKCS1PrivateKey(p.Bytes); err == nil {
|
||||
return *rsaPrivKey
|
||||
}
|
||||
if pkcs8Key, err := x509.ParsePKCS8PrivateKey(p.Bytes); err == nil {
|
||||
if reflect.TypeOf(pkcs8Key).Kind() == reflect.Ptr {
|
||||
pkcs8Key = reflect.ValueOf(pkcs8Key).Elem().Interface()
|
||||
}
|
||||
return pkcs8Key
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
355
vendor/github.com/google/certificate-transparency-go/tls/tls_test.go
generated
vendored
355
vendor/github.com/google/certificate-transparency-go/tls/tls_test.go
generated
vendored
@ -1,355 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tls
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type testStruct struct {
|
||||
Data []byte `tls:"minlen:2,maxlen:4"`
|
||||
IntVal uint16
|
||||
Other [4]byte
|
||||
Enum Enum `tls:"size:2"`
|
||||
}
|
||||
|
||||
type testVariant struct {
|
||||
Which Enum `tls:"size:1"`
|
||||
Val16 *uint16 `tls:"selector:Which,val:0"`
|
||||
Val32 *uint32 `tls:"selector:Which,val:1"`
|
||||
}
|
||||
|
||||
type testTwoVariants struct {
|
||||
Which Enum `tls:"size:1"`
|
||||
Val16 *uint16 `tls:"selector:Which,val:0"`
|
||||
Val32 *uint32 `tls:"selector:Which,val:1"`
|
||||
Second Enum `tls:"size:1"`
|
||||
Second16 *uint16 `tls:"selector:Second,val:0"`
|
||||
Second32 *uint32 `tls:"selector:Second,val:1"`
|
||||
}
|
||||
|
||||
// Check that library users can define their own Enum types.
|
||||
type aliasEnum Enum
|
||||
type testAliasEnum struct {
|
||||
Val aliasEnum `tls:"size:1"`
|
||||
Val16 *uint16 `tls:"selector:Val,val:1"`
|
||||
Val32 *uint32 `tls:"selector:Val,val:2"`
|
||||
}
|
||||
|
||||
type testNonByteSlice struct {
|
||||
Vals []uint16 `tls:"minlen:2,maxlen:6"`
|
||||
}
|
||||
|
||||
type testSliceOfStructs struct {
|
||||
Vals []testVariant `tls:"minlen:0,maxlen:100"`
|
||||
}
|
||||
|
||||
type testInnerType struct {
|
||||
Val []byte `tls:"minlen:0,maxlen:65535"`
|
||||
}
|
||||
|
||||
type testSliceOfSlices struct {
|
||||
Inners []testInnerType `tls:"minlen:0,maxlen:65535"`
|
||||
}
|
||||
|
||||
func TestMarshalUnmarshalRoundTrip(t *testing.T) {
|
||||
thing := testStruct{Data: []byte{0x01, 0x02, 0x03}, IntVal: 42, Other: [4]byte{1, 2, 3, 4}, Enum: 17}
|
||||
data, err := Marshal(thing)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to Marshal(%+v): %s", thing, err.Error())
|
||||
}
|
||||
var other testStruct
|
||||
rest, err := Unmarshal(data, &other)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to Unmarshal(%s)", hex.EncodeToString(data))
|
||||
}
|
||||
if len(rest) > 0 {
|
||||
t.Errorf("Data left over after Unmarshal(%s): %s", hex.EncodeToString(data), hex.EncodeToString(rest))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFieldTagToFieldInfo(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tag string
|
||||
want *fieldInfo
|
||||
errstr string
|
||||
}{
|
||||
{"", nil, ""},
|
||||
{"bogus", nil, ""},
|
||||
{"also,bogus", nil, ""},
|
||||
{"also,bogus:99", nil, ""},
|
||||
{"maxval:1xyz", nil, ""},
|
||||
{"maxval:1", &fieldInfo{count: 1, countSet: true}, ""},
|
||||
{"maxval:255", &fieldInfo{count: 1, countSet: true}, ""},
|
||||
{"maxval:256", &fieldInfo{count: 2, countSet: true}, ""},
|
||||
{"maxval:65535", &fieldInfo{count: 2, countSet: true}, ""},
|
||||
{"maxval:65536", &fieldInfo{count: 3, countSet: true}, ""},
|
||||
{"maxval:16777215", &fieldInfo{count: 3, countSet: true}, ""},
|
||||
{"maxval:16777216", &fieldInfo{count: 4, countSet: true}, ""},
|
||||
{"maxval:16777216", &fieldInfo{count: 4, countSet: true}, ""},
|
||||
{"maxval:4294967295", &fieldInfo{count: 4, countSet: true}, ""},
|
||||
{"maxval:4294967296", &fieldInfo{count: 5, countSet: true}, ""},
|
||||
{"maxval:1099511627775", &fieldInfo{count: 5, countSet: true}, ""},
|
||||
{"maxval:1099511627776", &fieldInfo{count: 6, countSet: true}, ""},
|
||||
{"maxval:281474976710655", &fieldInfo{count: 6, countSet: true}, ""},
|
||||
{"maxval:281474976710656", &fieldInfo{count: 7, countSet: true}, ""},
|
||||
{"maxval:72057594037927935", &fieldInfo{count: 7, countSet: true}, ""},
|
||||
{"maxval:72057594037927936", &fieldInfo{count: 8, countSet: true}, ""},
|
||||
{"minlen:1x", nil, ""},
|
||||
{"maxlen:1x", nil, ""},
|
||||
{"maxlen:1", &fieldInfo{count: 1, countSet: true, maxlen: 1}, ""},
|
||||
{"maxlen:255", &fieldInfo{count: 1, countSet: true, maxlen: 255}, ""},
|
||||
{"maxlen:65535", &fieldInfo{count: 2, countSet: true, maxlen: 65535}, ""},
|
||||
{"minlen:65530,maxlen:65535", &fieldInfo{count: 2, countSet: true, minlen: 65530, maxlen: 65535}, ""},
|
||||
{"maxlen:65535,minlen:65530", &fieldInfo{count: 2, countSet: true, minlen: 65530, maxlen: 65535}, ""},
|
||||
{"minlen:65536,maxlen:65535", nil, "inverted"},
|
||||
{"maxlen:16777215", &fieldInfo{count: 3, countSet: true, maxlen: 16777215}, ""},
|
||||
{"maxlen:281474976710655", &fieldInfo{count: 6, countSet: true, maxlen: 281474976710655}, ""},
|
||||
{"maxlen:72057594037927936", &fieldInfo{count: 8, countSet: true, maxlen: 72057594037927936}, ""},
|
||||
{"size:0", nil, "unknown size"},
|
||||
{"size:1", &fieldInfo{count: 1, countSet: true}, ""},
|
||||
{"size:2", &fieldInfo{count: 2, countSet: true}, ""},
|
||||
{"size:3", &fieldInfo{count: 3, countSet: true}, ""},
|
||||
{"size:4", &fieldInfo{count: 4, countSet: true}, ""},
|
||||
{"size:5", &fieldInfo{count: 5, countSet: true}, ""},
|
||||
{"size:6", &fieldInfo{count: 6, countSet: true}, ""},
|
||||
{"size:7", &fieldInfo{count: 7, countSet: true}, ""},
|
||||
{"size:8", &fieldInfo{count: 8, countSet: true}, ""},
|
||||
{"size:9", nil, "too large"},
|
||||
{"size:1x", nil, ""},
|
||||
{"size:1,val:9", nil, "selector value"},
|
||||
{"selector:Bob,val:x9", &fieldInfo{selector: "Bob"}, ""},
|
||||
{"selector:Fred,val:1", &fieldInfo{selector: "Fred", val: 1}, ""},
|
||||
{"val:9,selector:Fred,val:1", &fieldInfo{selector: "Fred", val: 1}, ""},
|
||||
}
|
||||
for _, test := range tests {
|
||||
got, err := fieldTagToFieldInfo(test.tag, "")
|
||||
if test.errstr != "" {
|
||||
if err == nil {
|
||||
t.Errorf("fieldTagToFieldInfo('%v')=%+v,nil; want error %q", test.tag, got, test.errstr)
|
||||
} else if !strings.Contains(err.Error(), test.errstr) {
|
||||
t.Errorf("fieldTagToFieldInfo('%v')=nil,%q; want error %q", test.tag, err.Error(), test.errstr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("fieldTagToFieldInfo('%v')=nil,%q; want %+v", test.tag, err.Error(), test.want)
|
||||
} else if !reflect.DeepEqual(got, test.want) {
|
||||
t.Errorf("fieldTagToFieldInfo('%v')=%+v,nil; want %+v", test.tag, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Can't take the address of a numeric constant so use helper functions
|
||||
func newByte(n byte) *byte { return &n }
|
||||
func newUint8(n uint8) *uint8 { return &n }
|
||||
func newUint16(n uint16) *uint16 { return &n }
|
||||
func newUint24(n Uint24) *Uint24 { return &n }
|
||||
func newUint32(n uint32) *uint32 { return &n }
|
||||
func newUint64(n uint64) *uint64 { return &n }
|
||||
func newInt16(n int16) *int16 { return &n }
|
||||
func newEnum(n Enum) *Enum { return &n }
|
||||
|
||||
func TestUnmarshalMarshalWithParamsRoundTrip(t *testing.T) {
|
||||
var tests = []struct {
|
||||
data string // hex encoded
|
||||
params string
|
||||
item interface{}
|
||||
}{
|
||||
{"00", "", newUint8(0)},
|
||||
{"03", "", newByte(3)},
|
||||
{"0101", "", newUint16(0x0101)},
|
||||
{"010203", "", newUint24(0x010203)},
|
||||
{"000000", "", newUint24(0x00)},
|
||||
{"00000009", "", newUint32(0x09)},
|
||||
{"0000000901020304", "", newUint64(0x0901020304)},
|
||||
{"030405", "", &[3]byte{3, 4, 5}},
|
||||
{"03", "", &[1]byte{3}},
|
||||
{"0001", "size:2", newEnum(1)},
|
||||
{"0100000001", "size:5", newEnum(0x100000001)},
|
||||
{"12", "maxval:18", newEnum(18)},
|
||||
// Note that maxval is just used to give enum size; it's not policed
|
||||
{"20", "maxval:18", newEnum(32)},
|
||||
{"020a0b", "minlen:1,maxlen:5", &[]byte{0xa, 0xb}},
|
||||
{"020a0b0101010203040011", "", &testStruct{Data: []byte{0xa, 0xb}, IntVal: 0x101, Other: [4]byte{1, 2, 3, 4}, Enum: 17}},
|
||||
{"000102", "", &testVariant{Which: 0, Val16: newUint16(0x0102)}},
|
||||
{"0101020304", "", &testVariant{Which: 1, Val32: newUint32(0x01020304)}},
|
||||
{"0001020104030201", "", &testTwoVariants{Which: 0, Val16: newUint16(0x0102), Second: 1, Second32: newUint32(0x04030201)}},
|
||||
{"06010102020303", "", &testNonByteSlice{Vals: []uint16{0x101, 0x202, 0x303}}},
|
||||
{"00", "", &testSliceOfStructs{Vals: []testVariant{}}},
|
||||
{"080001020101020304", "",
|
||||
&testSliceOfStructs{
|
||||
Vals: []testVariant{
|
||||
{Which: 0, Val16: newUint16(0x0102)},
|
||||
{Which: 1, Val32: newUint32(0x01020304)},
|
||||
},
|
||||
},
|
||||
},
|
||||
{"000a00030102030003040506", "",
|
||||
&testSliceOfSlices{
|
||||
Inners: []testInnerType{
|
||||
{Val: []byte{1, 2, 3}},
|
||||
{Val: []byte{4, 5, 6}},
|
||||
},
|
||||
},
|
||||
},
|
||||
{"011011", "", &testAliasEnum{Val: 1, Val16: newUint16(0x1011)}},
|
||||
{"0403", "", &SignatureAndHashAlgorithm{Hash: SHA256, Signature: ECDSA}},
|
||||
{"04030003010203", "",
|
||||
&DigitallySigned{
|
||||
Algorithm: SignatureAndHashAlgorithm{Hash: SHA256, Signature: ECDSA},
|
||||
Signature: []byte{1, 2, 3},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
inVal := reflect.ValueOf(test.item).Elem()
|
||||
pv := reflect.New(reflect.TypeOf(test.item).Elem())
|
||||
val := pv.Interface()
|
||||
inData, _ := hex.DecodeString(test.data)
|
||||
if _, err := UnmarshalWithParams(inData, val, test.params); err != nil {
|
||||
t.Errorf("Unmarshal(%s)=nil,%q; want %+v", test.data, err.Error(), inVal)
|
||||
} else if !reflect.DeepEqual(val, test.item) {
|
||||
t.Errorf("Unmarshal(%s)=%+v,nil; want %+v", test.data, reflect.ValueOf(val).Elem(), inVal)
|
||||
}
|
||||
|
||||
if data, err := MarshalWithParams(inVal.Interface(), test.params); err != nil {
|
||||
t.Errorf("Marshal(%+v)=nil,%q; want %s", inVal, err.Error(), test.data)
|
||||
} else if !bytes.Equal(data, inData) {
|
||||
t.Errorf("Marshal(%+v)=%s,nil; want %s", inVal, hex.EncodeToString(data), test.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type testInvalidFieldTag struct {
|
||||
Data []byte `tls:"minlen:3,maxlen:2"`
|
||||
}
|
||||
|
||||
type testDuplicateSelectorVal struct {
|
||||
Which Enum `tls:"size:1"`
|
||||
Val *uint16 `tls:"selector:Which,val:0"`
|
||||
DupVal *uint32 `tls:"selector:Which"` // implicit val:0
|
||||
}
|
||||
|
||||
type testMissingSelector struct {
|
||||
Val *uint16 `tls:"selector:Missing,val:0"`
|
||||
}
|
||||
|
||||
type testChoiceNotPointer struct {
|
||||
Which Enum `tls:"size:1"`
|
||||
Val uint16 `tls:"selector:Which,val:0"`
|
||||
}
|
||||
|
||||
type nonEnumAlias uint16
|
||||
|
||||
func newNonEnumAlias(n nonEnumAlias) *nonEnumAlias { return &n }
|
||||
|
||||
func TestUnmarshalWithParamsFailures(t *testing.T) {
|
||||
var tests = []struct {
|
||||
data string // hex encoded
|
||||
params string
|
||||
item interface{}
|
||||
errstr string
|
||||
}{
|
||||
{"", "", newUint8(0), "truncated"},
|
||||
{"0x01", "", newUint16(0x0101), "truncated"},
|
||||
{"0103", "", newUint24(0x010203), "truncated"},
|
||||
{"00", "", newUint24(0x00), "truncated"},
|
||||
{"000009", "", newUint32(0x09), "truncated"},
|
||||
{"00000901020304", "", newUint64(0x0901020304), "truncated"},
|
||||
{"0102", "", newInt16(0x0102), "unsupported type"}, // TLS encoding only supports unsigned integers
|
||||
{"0607", "", &[3]byte{6, 7, 8}, "truncated array"},
|
||||
{"01010202", "", &[3]uint16{0x101, 0x202}, "unsupported array"},
|
||||
{"01", "", newEnum(1), "no field size"},
|
||||
{"00", "size:2", newEnum(0), "truncated"},
|
||||
{"00", "size:9", newEnum(0), "too large"},
|
||||
{"020a0b", "minlen:4,maxlen:8", &[]byte{0x0a, 0x0b}, "too small"},
|
||||
{"040a0b0c0d", "minlen:1,maxlen:3", &[]byte{0x0a, 0x0b, 0x0c, 0x0d}, "too large"},
|
||||
{"020a0b", "minlen:8,maxlen:6", &[]byte{0x0a, 0x0b}, "inverted"},
|
||||
{"020a", "minlen:0,maxlen:6", &[]byte{0x0a, 0x0b}, "truncated"},
|
||||
{"02", "minlen:0,maxlen:6", &[]byte{0x0a, 0x0b}, "truncated"},
|
||||
{"0001", "minlen:0,maxlen:256", &[]byte{0x0a, 0x0b}, "truncated"},
|
||||
{"020a", "minlen:0", &[]byte{0x0a, 0x0b}, "unknown size"},
|
||||
{"020a", "", &[]byte{0x0a, 0x0b}, "no field size information"},
|
||||
{"020a0b", "", &testInvalidFieldTag{}, "range inverted"},
|
||||
{"020a0b01010102030400", "",
|
||||
&testStruct{Data: []byte{0xa, 0xb}, IntVal: 0x101, Other: [4]byte{1, 2, 3, 4}, Enum: 17}, "truncated"},
|
||||
{"010102", "", &testVariant{Which: 1, Val32: newUint32(0x01020304)}, "truncated"},
|
||||
{"092122", "", &testVariant{Which: 0, Val16: newUint16(0x2122)}, "unhandled value for selector"},
|
||||
{"0001020304", "", &testDuplicateSelectorVal{Which: 0, Val: newUint16(0x0102)}, "duplicate selector value"},
|
||||
{"0102", "", &testMissingSelector{Val: newUint16(1)}, "selector not seen"},
|
||||
{"000007", "", &testChoiceNotPointer{Which: 0, Val: 7}, "choice field not a pointer type"},
|
||||
{"05010102020303", "", &testNonByteSlice{Vals: []uint16{0x101, 0x202, 0x303}}, "truncated"},
|
||||
{"0101", "size:2", newNonEnumAlias(0x0102), "unsupported type"},
|
||||
{"0403010203", "",
|
||||
&DigitallySigned{
|
||||
Algorithm: SignatureAndHashAlgorithm{Hash: SHA256, Signature: ECDSA},
|
||||
Signature: []byte{1, 2, 3}}, "truncated"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
pv := reflect.New(reflect.TypeOf(test.item).Elem())
|
||||
val := pv.Interface()
|
||||
in, _ := hex.DecodeString(test.data)
|
||||
if _, err := UnmarshalWithParams(in, val, test.params); err == nil {
|
||||
t.Errorf("Unmarshal(%s)=%+v,nil; want error %q", test.data, reflect.ValueOf(val).Elem(), test.errstr)
|
||||
} else if !strings.Contains(err.Error(), test.errstr) {
|
||||
t.Errorf("Unmarshal(%s)=nil,%q; want error %q", test.data, err.Error(), test.errstr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMarshalWithParamsFailures(t *testing.T) {
|
||||
var tests = []struct {
|
||||
item interface{}
|
||||
params string
|
||||
errstr string
|
||||
}{
|
||||
{Uint24(0x1000000), "", "overflow"},
|
||||
{int16(0x0102), "", "unsupported type"}, // All TLS ints are unsigned
|
||||
{Enum(1), "", "field tag missing"},
|
||||
{Enum(256), "size:1", "too large"},
|
||||
{Enum(256), "maxval:255", "too large"},
|
||||
{Enum(2), "", "field tag missing"},
|
||||
{Enum(256), "size:9", "too large"},
|
||||
{[]byte{0xa, 0xb, 0xc, 0xd}, "minlen:1,maxlen:3", "too large"},
|
||||
{[]byte{0xa, 0xb, 0xc, 0xd}, "minlen:6,maxlen:13", "too small"},
|
||||
{[]byte{0xa, 0xb, 0xc, 0xd}, "minlen:6,maxlen:3", "inverted"},
|
||||
{[]byte{0xa, 0xb, 0xc, 0xd}, "minlen:6", "unknown size"},
|
||||
{[]byte{0xa, 0xb, 0xc, 0xd}, "", "field tag missing"},
|
||||
{[3]uint16{0x101, 0x202}, "", "unsupported array"},
|
||||
{testInvalidFieldTag{}, "", "inverted"},
|
||||
{testStruct{Data: []byte{0xa}, IntVal: 0x101, Other: [4]byte{1, 2, 3, 4}, Enum: 17}, "", "too small"},
|
||||
{testVariant{Which: 0, Val32: newUint32(0x01020304)}, "", "chosen field is nil"},
|
||||
{testVariant{Which: 0, Val16: newUint16(11), Val32: newUint32(0x01020304)}, "", "unchosen field is non-nil"},
|
||||
{testVariant{Which: 3}, "", "unhandled value for selector"},
|
||||
{testMissingSelector{Val: newUint16(1)}, "", "selector not seen"},
|
||||
{testChoiceNotPointer{Which: 0, Val: 7}, "", "choice field not a pointer"},
|
||||
{testDuplicateSelectorVal{Which: 0, Val: newUint16(1)}, "", "duplicate selector value"},
|
||||
{testNonByteSlice{Vals: []uint16{1, 2, 3, 4}}, "", "too large"},
|
||||
{testSliceOfStructs{[]testVariant{{Which: 3}}}, "", "unhandled value for selector"},
|
||||
{nonEnumAlias(0x0102), "", "unsupported type"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if data, err := MarshalWithParams(test.item, test.params); err == nil {
|
||||
t.Errorf("Marshal(%+v)=%x,nil; want error %q", test.item, data, test.errstr)
|
||||
} else if !strings.Contains(err.Error(), test.errstr) {
|
||||
t.Errorf("Marshal(%+v)=nil,%q; want error %q", test.item, err.Error(), test.errstr)
|
||||
}
|
||||
}
|
||||
}
|
100
vendor/github.com/google/certificate-transparency-go/tls/types_test.go
generated
vendored
100
vendor/github.com/google/certificate-transparency-go/tls/types_test.go
generated
vendored
@ -1,100 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package tls
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHashAlgorithmString(t *testing.T) {
|
||||
var tests = []struct {
|
||||
algo HashAlgorithm
|
||||
want string
|
||||
}{
|
||||
{None, "None"},
|
||||
{MD5, "MD5"},
|
||||
{SHA1, "SHA1"},
|
||||
{SHA224, "SHA224"},
|
||||
{SHA256, "SHA256"},
|
||||
{SHA384, "SHA384"},
|
||||
{SHA512, "SHA512"},
|
||||
{99, "UNKNOWN(99)"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if got := test.algo.String(); got != test.want {
|
||||
t.Errorf("%v.String()=%q; want %q", test.algo, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignatureAlgorithmString(t *testing.T) {
|
||||
var tests = []struct {
|
||||
algo SignatureAlgorithm
|
||||
want string
|
||||
}{
|
||||
{Anonymous, "Anonymous"},
|
||||
{RSA, "RSA"},
|
||||
{DSA, "DSA"},
|
||||
{ECDSA, "ECDSA"},
|
||||
{99, "UNKNOWN(99)"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if got := test.algo.String(); got != test.want {
|
||||
t.Errorf("%v.String()=%q; want %q", test.algo, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDigitallySignedString(t *testing.T) {
|
||||
var tests = []struct {
|
||||
ds DigitallySigned
|
||||
want string
|
||||
}{
|
||||
{
|
||||
ds: DigitallySigned{Algorithm: SignatureAndHashAlgorithm{Hash: SHA1, Signature: RSA}, Signature: []byte{0x01, 0x02}},
|
||||
want: "Signature: HashAlgo=SHA1 SignAlgo=RSA Value=0102",
|
||||
},
|
||||
{
|
||||
ds: DigitallySigned{Algorithm: SignatureAndHashAlgorithm{Hash: 99, Signature: 99}, Signature: []byte{0x03, 0x04}},
|
||||
want: "Signature: HashAlgo=UNKNOWN(99) SignAlgo=UNKNOWN(99) Value=0304",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
if got := test.ds.String(); got != test.want {
|
||||
t.Errorf("%v.String()=%q; want %q", test.ds, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSignatureAlgorithm(t *testing.T) {
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
key crypto.PublicKey
|
||||
want SignatureAlgorithm
|
||||
}{
|
||||
{name: "ECDSA", key: new(ecdsa.PublicKey), want: ECDSA},
|
||||
{name: "RSA", key: new(rsa.PublicKey), want: RSA},
|
||||
{name: "DSA", key: new(dsa.PublicKey), want: DSA},
|
||||
{name: "Other", key: "foo", want: Anonymous},
|
||||
} {
|
||||
if got := SignatureAlgorithmFromPubKey(test.key); got != test.want {
|
||||
t.Errorf("%v: SignatureAlgorithm() = %v, want %v", test.name, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
131
vendor/github.com/google/certificate-transparency-go/types_test.go
generated
vendored
131
vendor/github.com/google/certificate-transparency-go/types_test.go
generated
vendored
@ -1,131 +0,0 @@
|
||||
// Copyright 2015 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package ct
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/certificate-transparency-go/tls"
|
||||
)
|
||||
|
||||
const (
|
||||
CertEntry = "000000000149a6e03abe00000006513082064d30820535a003020102020c6a5d4161f5c9b68043270b0c300d06092a864886f70d0101050500305e310b300906035504061302424531193017060355040a1310476c6f62616c5369676e206e762d7361313430320603550403132b476c6f62616c5369676e20457874656e6465642056616c69646174696f6e204341202d2047322054455354301e170d3134313131333031353830315a170d3136313131333031353830315a3082011331183016060355040f0c0f427573696e65737320456e74697479311230100603550405130936363636363636363631133011060b2b0601040182373c0201031302444531293027060b2b0601040182373c02010113186576206a7572697364696374696f6e206c6f63616c69747931263024060b2b0601040182373c02010213156576206a7572697364696374696f6e207374617465310b3009060355040613024a50310a300806035504080c0153310a300806035504070c014c311530130603550409130c657620616464726573732033310c300a060355040b0c034f5531310c300a060355040b0c034f5532310a3008060355040a0c014f3117301506035504030c0e637372636e2e73736c32342e6a7030820122300d06092a864886f70d01010105000382010f003082010a02820101008db9f0d6b359466dffe95ba43dc1a5680eedc8f3cabbc573a236a109bf6e58df816c7bb8156147ab526eceaffd0576e6e1c09ea33433e114d7e5038c697298c7957f01a7e1142320847cf234995bbe42798340cb99e6a7e2cfa950277aef6e02f4d96ddceb0af9541171b0f8f1aa4f0d02453e6e654b25a13f2aff4357cae8177d3bd21855686591a2309d9ff5dead8240304e22eafcc5508587e6b6ad1d00b53c28e5b936269afbf214b73edbdc8a48a86c1c23f3dce55fcce60502c0908bca9bdb22c16c0b34d11b4fd27e9d7bcb56c5ec0fc4d52500fb06b0af5c4112e421022b78b31030cb73e9fd92ffc65919fd8f35e604fcaf025b9c77e3e5dff749a70203010001a38202523082024e300e0603551d0f0101ff0404030205a0304c0603551d2004453043304106092b06010401a03201013034303206082b06010505070201162668747470733a2f2f7777772e676c6f62616c7369676e2e636f6d2f7265706f7369746f72792f30480603551d1f0441303f303da03ba0398637687474703a2f2f63726c2e676c6f62616c7369676e2e636f6d2f67732f67736f7267616e697a6174696f6e76616c63617467322e63726c30819c06082b0601050507010104818f30818c304a06082b06010505073002863e687474703a2f2f7365637572652e676c6f62616c7369676e2e636f6d2f6361636572742f67736f7267616e697a6174696f6e76616c63617467322e637274303e06082b060105050730018632687474703a2f2f6f637370322e676c6f62616c7369676e2e636f6d2f67736f7267616e697a6174696f6e76616c6361746732301d0603551d250416301406082b0601050507030106082b0601050507030230190603551d1104123010820e637372636e2e73736c32342e6a70301d0603551d0e041604147f834b2903e35efff651619083a2efd69a6d70f4301f0603551d23041830168014ab30a406d972d0029ab2c7d3f4241be2fca5320230818a060a2b06010401d679020402047c047a0078007600b0cc83e5a5f97d6baf7c09cc284904872ac7e88b132c6350b7c6fd26e16c6c7700000149a6dc346b00000403004730450220469f4dc0553b7832bd56633c3b9d53faaec84df414b7a05ab1b2d544d146ac3e022100ee899419fd4f95544798f7883fe093692feb4c90e84d651600f7019166a43701300d06092a864886f70d010105050003820101007dcd3e228d68cdc0734c7629fd7d40cd742d0ed1d0d9f49a643af12dcdbc61394638b7c519bb7cae530ccdc3a5037d5cdd8a4d2c01abdc834daf1993f7a22ee2c223377a94da4e68ac69a0b50d2d473ec77651e001c5f71a23cc2defe7616fd6c6491aa7f9a2bb16b930ce3f8cc37cf6a47bfb04fd4eff7db8433cc6fdb05146a4a31fe65211875f2c51129bf0729ce2dc7ce1a5afc6eaa1eb3a36296cb9e091375edfc408c727f6d54bba408da60b46c496a364c504adf47ee0496a9260fe223c8b23c14832635c3dff0dba8a0c8cdd957a77f18443b7782a9b6c7636b7d66df426350b959537e911888e45b2c0b218e50d03fdcfa7f758e8e60dd1a1996bc00000"
|
||||
PrecertEntry = "00000000014b4981f0c800013760e2790f33a498f9b6c149fecfca3993954b536fbf36ad45d0a8415b79337d00047a30820476a00302010202100532298c396a3e25fcaa1977e827b5f3300d06092a864886f70d01010b0500306d310b300906035504061302555331163014060355040a130d47656f547275737420496e632e311f301d060355040b1316464f52205445535420505552504f534553204f4e4c59312530230603550403131c47656f54727573742045562053534c2054455354204341202d204734301e170d3135303230323030303030305a170d3136303232373233353935395a3081c331133011060b2b0601040182373c02010313024742311b3019060b2b0601040182373c020102140a43616c69666f726e6961311e301c060b2b0601040182373c0201010c0d4d6f756e7461696e2056696577310b30090603550406130247423113301106035504080c0a43616c69666f726e69613116301406035504070c0d4d6f756e7461696e2056696577311d301b060355040a0c1453796d616e74656320436f72706f726174696f6e3116301406035504030c0d736466656473662e747275737430820122300d06092a864886f70d01010105000382010f003082010a0282010100b19d97def39ff829c65ea099a3257298b33ff675451fdc5641a222347aee4a56201f4c1a406f2f19815d86dec1a611768e7d556c8e33a7f1b4c78db19cceae540e97ae1f0660b2ee4f8cff2045b84a9da228349744406eceaed0b08d46fdab3543b3d86ea708627a61a529b793a76adc6b776bc8d5b3d4fe21e2c4aa92cfd33b45e7412068e0683a2beffad1df2fc320b8ddbf02ffb603d2cf74798277fd9656b5acd45659b0e5d761e02dcf95c53095555a931ad5bfa9b4967c045d5f12de2d6b537cd93af2ad8b45e5540bd43279876d13e376fb649778e10dfa56165b901bd37e9dee4e46027b4c0732ca7ed64491862abaf6a24a4aaed8f49a0922ca4fb50203010001a38201d1308201cd30470603551d110440303e820d6b6a61736468662e7472757374820b73736466732e7472757374820d736466656473662e747275737482117777772e736466656473662e747275737430090603551d1304023000300e0603551d0f0101ff0404030205a0302b0603551d1f042430223020a01ea01c861a687474703a2f2f676d2e73796d63622e636f6d2f676d2e63726c3081a00603551d2004819830819530819206092b06010401f0220106308184303f06082b06010505070201163368747470733a2f2f7777772e67656f74727573742e636f6d2f7265736f75726365732f7265706f7369746f72792f6c6567616c304106082b0601050507020230350c3368747470733a2f2f7777772e67656f74727573742e636f6d2f7265736f75726365732f7265706f7369746f72792f6c6567616c301d0603551d250416301406082b0601050507030106082b06010505070302301f0603551d23041830168014b1699461abe6cb0c4ce759af5a498b1833c1e147305706082b06010505070101044b3049301f06082b060105050730018613687474703a2f2f676d2e73796d63642e636f6d302606082b06010505073002861a687474703a2f2f676d2e73796d63622e636f6d2f676d2e6372740000"
|
||||
)
|
||||
|
||||
func TestUnmarshalMerkleTreeLeaf(t *testing.T) {
|
||||
var tests = []struct {
|
||||
in string // hex string
|
||||
want LogEntryType
|
||||
errstr string
|
||||
}{
|
||||
{CertEntry, X509LogEntryType, ""},
|
||||
{PrecertEntry, PrecertLogEntryType, ""},
|
||||
{"001234", 0, "LeafType: unhandled value"},
|
||||
}
|
||||
for _, test := range tests {
|
||||
inData, _ := hex.DecodeString(test.in)
|
||||
var got MerkleTreeLeaf
|
||||
_, err := tls.Unmarshal(inData, &got)
|
||||
if test.errstr != "" {
|
||||
if err == nil {
|
||||
t.Errorf("tls.Unmarshal(%s, &MerkleTreeLeaf)=%+v,nil; want error %q", test.in, got, test.errstr)
|
||||
} else if !strings.Contains(err.Error(), test.errstr) {
|
||||
t.Errorf("tls.Unmarshal(%s, &MerkleTreeLeaf)=nil,%q; want error %q", test.in, err.Error(), test.errstr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err != nil {
|
||||
t.Errorf("tls.Unmarshal(%s, &MerkleTreeLeaf)=nil,%q; want type %v", test.in, err.Error(), test.want)
|
||||
continue
|
||||
}
|
||||
if got.Version != V1 {
|
||||
t.Errorf("tls.Unmarshal(%s, &MerkleTreeLeaf)=version=%v,nil; want version 1", test.in, got.Version)
|
||||
}
|
||||
if got.LeafType != TimestampedEntryLeafType {
|
||||
t.Errorf("tls.Unmarshal(%s, &MerkleTreeLeaf)=LeafType=%v,nil; want LeafType=%v", test.in, got.LeafType, TimestampedEntryLeafType)
|
||||
}
|
||||
if got.TimestampedEntry.EntryType != test.want {
|
||||
t.Errorf("tls.Unmarshal(%s, &MerkleTreeLeaf)=EntryType=%v,nil; want LeafType=%v", test.in, got.TimestampedEntry.EntryType, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
validRootHash = "708981e91d1487c2a9ea901ab5a8d053c1348585afcdb5e107bf60c0c1d20fc0"
|
||||
longRootHash = "708981e91d1487c2a9ea901ab5a8d053c1348585afcdb5e107bf60c0c1d20fc000"
|
||||
shortRootHash = "708981e91d1487c2a9ea901ab5a8d053c1348585afcdb5e107bf60c0c1d20f"
|
||||
|
||||
validSignature = "040300473045022007fb5ae3cea8f076b534a01a9a19e60625c6cc70704c6c1a7c88b30d8f67d4af022100840d37b8f2f9ce134e74eefda6a0c2ad034d591b785cdc4973c4c4f5d03f0439"
|
||||
longSignature = "040300473045022007fb5ae3cea8f076b534a01a9a19e60625c6cc70704c6c1a7c88b30d8f67d4af022100840d37b8f2f9ce134e74eefda6a0c2ad034d591b785cdc4973c4c4f5d03f043900"
|
||||
)
|
||||
|
||||
func mustHexDecode(s string) []byte {
|
||||
h, err := hex.DecodeString(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return h
|
||||
}
|
||||
|
||||
func TestToSignedTreeHead(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
rootHash string
|
||||
signature string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
desc: "success",
|
||||
rootHash: validRootHash,
|
||||
signature: validSignature,
|
||||
},
|
||||
{
|
||||
desc: "root hash too long",
|
||||
rootHash: longRootHash,
|
||||
signature: validSignature,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
desc: "root hash too short",
|
||||
rootHash: shortRootHash,
|
||||
signature: validSignature,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
desc: "signature trailing data",
|
||||
rootHash: validRootHash,
|
||||
signature: longSignature,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.desc, func(t *testing.T) {
|
||||
sthResponse := &GetSTHResponse{
|
||||
TreeSize: 278437663,
|
||||
Timestamp: 1527076172068,
|
||||
SHA256RootHash: mustHexDecode(test.rootHash),
|
||||
TreeHeadSignature: mustHexDecode(test.signature),
|
||||
}
|
||||
sth, err := sthResponse.ToSignedTreeHead()
|
||||
if gotErr := (err != nil); gotErr != test.wantErr {
|
||||
t.Errorf("GetSTHResponse.ToSignedTreeHead() = %+v, %v, want err? %t", sth, err, test.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
192
vendor/github.com/google/certificate-transparency-go/x509/error_test.go
generated
vendored
192
vendor/github.com/google/certificate-transparency-go/x509/error_test.go
generated
vendored
@ -1,192 +0,0 @@
|
||||
package x509_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
)
|
||||
|
||||
func TestErrors(t *testing.T) {
|
||||
var tests = []struct {
|
||||
errs []x509.Error
|
||||
want string
|
||||
wantVerbose string
|
||||
wantFatal bool
|
||||
}{
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{Summary: "Error", Field: "a.b.c"},
|
||||
},
|
||||
want: "Error",
|
||||
wantVerbose: "Error (a.b.c)",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{
|
||||
Summary: "Error",
|
||||
Field: "a.b.c",
|
||||
SpecRef: "RFC5280 s4.1.2.2",
|
||||
SpecText: "The serial number MUST be a positive integer",
|
||||
Category: x509.MalformedCertificate,
|
||||
},
|
||||
},
|
||||
want: "Error",
|
||||
wantVerbose: "Error (a.b.c: Certificate does not comply with MUST clause in spec: RFC5280 s4.1.2.2, 'The serial number MUST be a positive integer')",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{
|
||||
Summary: "Error",
|
||||
Field: "a.b.c",
|
||||
SpecRef: "RFC5280 s4.1.2.2",
|
||||
SpecText: "The serial number MUST be a positive integer",
|
||||
},
|
||||
},
|
||||
want: "Error",
|
||||
wantVerbose: "Error (a.b.c: RFC5280 s4.1.2.2, 'The serial number MUST be a positive integer')",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{
|
||||
Summary: "Error",
|
||||
Field: "a.b.c",
|
||||
SpecRef: "RFC5280 s4.1.2.2",
|
||||
Category: x509.MalformedCertificate,
|
||||
},
|
||||
},
|
||||
want: "Error",
|
||||
wantVerbose: "Error (a.b.c: Certificate does not comply with MUST clause in spec: RFC5280 s4.1.2.2)",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{
|
||||
Summary: "Error",
|
||||
Field: "a.b.c",
|
||||
SpecText: "The serial number MUST be a positive integer",
|
||||
Category: x509.MalformedCertificate,
|
||||
},
|
||||
},
|
||||
want: "Error",
|
||||
wantVerbose: "Error (a.b.c: Certificate does not comply with MUST clause in spec: 'The serial number MUST be a positive integer')",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{
|
||||
Summary: "Error",
|
||||
Field: "a.b.c",
|
||||
SpecRef: "RFC5280 s4.1.2.2",
|
||||
},
|
||||
},
|
||||
want: "Error",
|
||||
wantVerbose: "Error (a.b.c: RFC5280 s4.1.2.2)",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{
|
||||
Summary: "Error",
|
||||
Field: "a.b.c",
|
||||
SpecText: "The serial number MUST be a positive integer",
|
||||
},
|
||||
},
|
||||
want: "Error",
|
||||
wantVerbose: "Error (a.b.c: 'The serial number MUST be a positive integer')",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{
|
||||
Summary: "Error",
|
||||
Field: "a.b.c",
|
||||
Category: x509.MalformedCertificate,
|
||||
},
|
||||
},
|
||||
want: "Error",
|
||||
wantVerbose: "Error (a.b.c: Certificate does not comply with MUST clause in spec)",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{Summary: "Error"},
|
||||
},
|
||||
want: "Error",
|
||||
wantVerbose: "Error",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{Summary: "Error\nwith newline", Field: "x", Category: x509.InvalidASN1DER},
|
||||
},
|
||||
want: "Error\nwith newline",
|
||||
wantVerbose: "Error\nwith newline (x: Invalid ASN.1 distinguished encoding)",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{Summary: "Error1", Field: "a.b.c"},
|
||||
{Summary: "Error2", Field: "a.b.c.d"},
|
||||
{Summary: "Error3", Field: "x.y.z"},
|
||||
},
|
||||
want: "Errors:\n Error1\n Error2\n Error3",
|
||||
wantVerbose: "Errors:\n Error1 (a.b.c)\n Error2 (a.b.c.d)\n Error3 (x.y.z)",
|
||||
},
|
||||
{
|
||||
errs: []x509.Error{
|
||||
{Summary: "Error1", Field: "a.b.c"},
|
||||
{Summary: "Error2", Field: "a.b.c.d", Fatal: true},
|
||||
{Summary: "Error3", Field: "x.y.z"},
|
||||
},
|
||||
want: "Errors:\n Error1\n Error2\n Error3",
|
||||
wantVerbose: "Errors:\n Error1 (a.b.c)\n Error2 (a.b.c.d)\n Error3 (x.y.z)",
|
||||
wantFatal: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
errs := x509.Errors{Errs: test.errs}
|
||||
if got := errs.Error(); got != test.want {
|
||||
t.Errorf("Errors(%+v).Error()=%q; want %q", test.errs, got, test.want)
|
||||
}
|
||||
if got := errs.VerboseError(); got != test.wantVerbose {
|
||||
t.Errorf("Errors(%+v).VerboseError()=%q; want %q", test.errs, got, test.wantVerbose)
|
||||
}
|
||||
if got := errs.Fatal(); got != test.wantFatal {
|
||||
t.Errorf("Errors(%+v).Fatal()=%v; want %v", test.errs, got, test.wantFatal)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorsAppend(t *testing.T) {
|
||||
var errs x509.Errors
|
||||
if got, want := errs.Error(), ""; got != want {
|
||||
t.Errorf("Errors().Error()=%q; want %q", got, want)
|
||||
}
|
||||
if got, want := errs.Empty(), true; got != want {
|
||||
t.Errorf("Errors().Empty()=%t; want %t", got, want)
|
||||
}
|
||||
errs.Errs = append(errs.Errs, x509.Error{
|
||||
Summary: "Error",
|
||||
Field: "a.b.c",
|
||||
SpecRef: "RFC5280 s4.1.2.2"})
|
||||
if got, want := errs.VerboseError(), "Error (a.b.c: RFC5280 s4.1.2.2)"; got != want {
|
||||
t.Errorf("Errors(%+v).Error=%q; want %q", errs, got, want)
|
||||
}
|
||||
if got, want := errs.Empty(), false; got != want {
|
||||
t.Errorf("Errors().Empty()=%t; want %t", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestErrorsFilter(t *testing.T) {
|
||||
var errs x509.Errors
|
||||
id := x509.ErrMaxID + 2
|
||||
errs.AddID(id, "arg1", 2, "arg3")
|
||||
baseErr := errs.Error()
|
||||
|
||||
errs.AddID(x509.ErrMaxID + 1)
|
||||
if got, want := errs.Error(), fmt.Sprintf("Errors:\n %s\n E%03d: Unknown error ID %v: args []", baseErr, x509.ErrMaxID+1, x509.ErrMaxID+1); got != want {
|
||||
t.Errorf("Errors(%+v).Error=%q; want %q", errs, got, want)
|
||||
}
|
||||
|
||||
errList := fmt.Sprintf("%d, %d", x509.ErrMaxID+1, x509.ErrMaxID+1)
|
||||
filter := x509.ErrorFilter(errList)
|
||||
errs2 := errs.Filter(filter)
|
||||
if got, want := errs2.Error(), baseErr; got != want {
|
||||
t.Errorf("Errors(%+v).Error=%q; want %q", errs, got, want)
|
||||
}
|
||||
}
|
13
vendor/github.com/google/certificate-transparency-go/x509/errors_test.go
generated
vendored
13
vendor/github.com/google/certificate-transparency-go/x509/errors_test.go
generated
vendored
@ -1,13 +0,0 @@
|
||||
package x509
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestTemplateIDs(t *testing.T) {
|
||||
for id, template := range idToError {
|
||||
if template.ID != id {
|
||||
t.Errorf("idToError[%v].id=%v; want %v", id, template.ID, id)
|
||||
}
|
||||
}
|
||||
}
|
135
vendor/github.com/google/certificate-transparency-go/x509/example_test.go
generated
vendored
135
vendor/github.com/google/certificate-transparency-go/x509/example_test.go
generated
vendored
@ -1,135 +0,0 @@
|
||||
// Copyright 2014 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509_test
|
||||
|
||||
import (
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
)
|
||||
|
||||
func ExampleCertificate_Verify() {
|
||||
// Verifying with a custom list of root certificates.
|
||||
|
||||
const rootPEM = `
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEBDCCAuygAwIBAgIDAjppMA0GCSqGSIb3DQEBBQUAMEIxCzAJBgNVBAYTAlVT
|
||||
MRYwFAYDVQQKEw1HZW9UcnVzdCBJbmMuMRswGQYDVQQDExJHZW9UcnVzdCBHbG9i
|
||||
YWwgQ0EwHhcNMTMwNDA1MTUxNTU1WhcNMTUwNDA0MTUxNTU1WjBJMQswCQYDVQQG
|
||||
EwJVUzETMBEGA1UEChMKR29vZ2xlIEluYzElMCMGA1UEAxMcR29vZ2xlIEludGVy
|
||||
bmV0IEF1dGhvcml0eSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB
|
||||
AJwqBHdc2FCROgajguDYUEi8iT/xGXAaiEZ+4I/F8YnOIe5a/mENtzJEiaB0C1NP
|
||||
VaTOgmKV7utZX8bhBYASxF6UP7xbSDj0U/ck5vuR6RXEz/RTDfRK/J9U3n2+oGtv
|
||||
h8DQUB8oMANA2ghzUWx//zo8pzcGjr1LEQTrfSTe5vn8MXH7lNVg8y5Kr0LSy+rE
|
||||
ahqyzFPdFUuLH8gZYR/Nnag+YyuENWllhMgZxUYi+FOVvuOAShDGKuy6lyARxzmZ
|
||||
EASg8GF6lSWMTlJ14rbtCMoU/M4iarNOz0YDl5cDfsCx3nuvRTPPuj5xt970JSXC
|
||||
DTWJnZ37DhF5iR43xa+OcmkCAwEAAaOB+zCB+DAfBgNVHSMEGDAWgBTAephojYn7
|
||||
qwVkDBF9qn1luMrMTjAdBgNVHQ4EFgQUSt0GFhu89mi1dvWBtrtiGrpagS8wEgYD
|
||||
VR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAQYwOgYDVR0fBDMwMTAvoC2g
|
||||
K4YpaHR0cDovL2NybC5nZW90cnVzdC5jb20vY3Jscy9ndGdsb2JhbC5jcmwwPQYI
|
||||
KwYBBQUHAQEEMTAvMC0GCCsGAQUFBzABhiFodHRwOi8vZ3RnbG9iYWwtb2NzcC5n
|
||||
ZW90cnVzdC5jb20wFwYDVR0gBBAwDjAMBgorBgEEAdZ5AgUBMA0GCSqGSIb3DQEB
|
||||
BQUAA4IBAQA21waAESetKhSbOHezI6B1WLuxfoNCunLaHtiONgaX4PCVOzf9G0JY
|
||||
/iLIa704XtE7JW4S615ndkZAkNoUyHgN7ZVm2o6Gb4ChulYylYbc3GrKBIxbf/a/
|
||||
zG+FA1jDaFETzf3I93k9mTXwVqO94FntT0QJo544evZG0R0SnU++0ED8Vf4GXjza
|
||||
HFa9llF7b1cq26KqltyMdMKVvvBulRP/F/A8rLIQjcxz++iPAsbw+zOzlTvjwsto
|
||||
WHPbqCRiOwY1nQ2pM714A5AuTHhdUDqB1O6gyHA43LL5Z/qHQF1hwFGPa4NrzQU6
|
||||
yuGnBXj8ytqU0CwIPX4WecigUCAkVDNx
|
||||
-----END CERTIFICATE-----`
|
||||
|
||||
const certPEM = `
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDujCCAqKgAwIBAgIIE31FZVaPXTUwDQYJKoZIhvcNAQEFBQAwSTELMAkGA1UE
|
||||
BhMCVVMxEzARBgNVBAoTCkdvb2dsZSBJbmMxJTAjBgNVBAMTHEdvb2dsZSBJbnRl
|
||||
cm5ldCBBdXRob3JpdHkgRzIwHhcNMTQwMTI5MTMyNzQzWhcNMTQwNTI5MDAwMDAw
|
||||
WjBpMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2FsaWZvcm5pYTEWMBQGA1UEBwwN
|
||||
TW91bnRhaW4gVmlldzETMBEGA1UECgwKR29vZ2xlIEluYzEYMBYGA1UEAwwPbWFp
|
||||
bC5nb29nbGUuY29tMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfRrObuSW5T7q
|
||||
5CnSEqefEmtH4CCv6+5EckuriNr1CjfVvqzwfAhopXkLrq45EQm8vkmf7W96XJhC
|
||||
7ZM0dYi1/qOCAU8wggFLMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAa
|
||||
BgNVHREEEzARgg9tYWlsLmdvb2dsZS5jb20wCwYDVR0PBAQDAgeAMGgGCCsGAQUF
|
||||
BwEBBFwwWjArBggrBgEFBQcwAoYfaHR0cDovL3BraS5nb29nbGUuY29tL0dJQUcy
|
||||
LmNydDArBggrBgEFBQcwAYYfaHR0cDovL2NsaWVudHMxLmdvb2dsZS5jb20vb2Nz
|
||||
cDAdBgNVHQ4EFgQUiJxtimAuTfwb+aUtBn5UYKreKvMwDAYDVR0TAQH/BAIwADAf
|
||||
BgNVHSMEGDAWgBRK3QYWG7z2aLV29YG2u2IaulqBLzAXBgNVHSAEEDAOMAwGCisG
|
||||
AQQB1nkCBQEwMAYDVR0fBCkwJzAloCOgIYYfaHR0cDovL3BraS5nb29nbGUuY29t
|
||||
L0dJQUcyLmNybDANBgkqhkiG9w0BAQUFAAOCAQEAH6RYHxHdcGpMpFE3oxDoFnP+
|
||||
gtuBCHan2yE2GRbJ2Cw8Lw0MmuKqHlf9RSeYfd3BXeKkj1qO6TVKwCh+0HdZk283
|
||||
TZZyzmEOyclm3UGFYe82P/iDFt+CeQ3NpmBg+GoaVCuWAARJN/KfglbLyyYygcQq
|
||||
0SgeDh8dRKUiaW3HQSoYvTvdTuqzwK4CXsr3b5/dAOY8uMuG/IAR3FgwTbZ1dtoW
|
||||
RvOTa8hYiU6A475WuZKyEHcwnGYe57u2I2KbMgcKjPniocj4QzgYsVAVKW3IwaOh
|
||||
yE+vPxsiUkvQHdO2fojCkY8jg70jxM+gu59tPDNbw3Uh/2Ij310FgTHsnGQMyA==
|
||||
-----END CERTIFICATE-----`
|
||||
|
||||
// First, create the set of root certificates. For this example we only
|
||||
// have one. It's also possible to omit this in order to use the
|
||||
// default root set of the current operating system.
|
||||
roots := x509.NewCertPool()
|
||||
ok := roots.AppendCertsFromPEM([]byte(rootPEM))
|
||||
if !ok {
|
||||
panic("failed to parse root certificate")
|
||||
}
|
||||
|
||||
block, _ := pem.Decode([]byte(certPEM))
|
||||
if block == nil {
|
||||
panic("failed to parse certificate PEM")
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
panic("failed to parse certificate: " + err.Error())
|
||||
}
|
||||
|
||||
opts := x509.VerifyOptions{
|
||||
DNSName: "mail.google.com",
|
||||
Roots: roots,
|
||||
}
|
||||
|
||||
if _, err := cert.Verify(opts); err != nil {
|
||||
panic("failed to verify certificate: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func ExampleParsePKIXPublicKey() {
|
||||
const pubPEM = `
|
||||
-----BEGIN PUBLIC KEY-----
|
||||
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAlRuRnThUjU8/prwYxbty
|
||||
WPT9pURI3lbsKMiB6Fn/VHOKE13p4D8xgOCADpdRagdT6n4etr9atzDKUSvpMtR3
|
||||
CP5noNc97WiNCggBjVWhs7szEe8ugyqF23XwpHQ6uV1LKH50m92MbOWfCtjU9p/x
|
||||
qhNpQQ1AZhqNy5Gevap5k8XzRmjSldNAFZMY7Yv3Gi+nyCwGwpVtBUwhuLzgNFK/
|
||||
yDtw2WcWmUU7NuC8Q6MWvPebxVtCfVp/iQU6q60yyt6aGOBkhAX0LpKAEhKidixY
|
||||
nP9PNVBvxgu3XZ4P36gZV6+ummKdBVnc3NqwBLu5+CcdRdusmHPHd5pHf4/38Z3/
|
||||
6qU2a/fPvWzceVTEgZ47QjFMTCTmCwNt29cvi7zZeQzjtwQgn4ipN9NibRH/Ax/q
|
||||
TbIzHfrJ1xa2RteWSdFjwtxi9C20HUkjXSeI4YlzQMH0fPX6KCE7aVePTOnB69I/
|
||||
a9/q96DiXZajwlpq3wFctrs1oXqBp5DVrCIj8hU2wNgB7LtQ1mCtsYz//heai0K9
|
||||
PhE4X6hiE0YmeAZjR0uHl8M/5aW9xCoJ72+12kKpWAa0SFRWLy6FejNYCYpkupVJ
|
||||
yecLk/4L1W0l6jQQZnWErXZYe0PNFcmwGXy1Rep83kfBRNKRy5tvocalLlwXLdUk
|
||||
AIU+2GKjyT3iMuzZxxFxPFMCAwEAAQ==
|
||||
-----END PUBLIC KEY-----`
|
||||
|
||||
block, _ := pem.Decode([]byte(pubPEM))
|
||||
if block == nil {
|
||||
panic("failed to parse PEM block containing the public key")
|
||||
}
|
||||
|
||||
pub, err := x509.ParsePKIXPublicKey(block.Bytes)
|
||||
if err != nil {
|
||||
panic("failed to parse DER encoded public key: " + err.Error())
|
||||
}
|
||||
|
||||
switch pub := pub.(type) {
|
||||
case *rsa.PublicKey:
|
||||
fmt.Println("pub is of type RSA:", pub)
|
||||
case *dsa.PublicKey:
|
||||
fmt.Println("pub is of type DSA:", pub)
|
||||
case *ecdsa.PublicKey:
|
||||
fmt.Println("pub is of type ECDSA:", pub)
|
||||
default:
|
||||
panic("unknown type of public key")
|
||||
}
|
||||
}
|
2126
vendor/github.com/google/certificate-transparency-go/x509/name_constraints_test.go
generated
vendored
2126
vendor/github.com/google/certificate-transparency-go/x509/name_constraints_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
267
vendor/github.com/google/certificate-transparency-go/x509/names_test.go
generated
vendored
267
vendor/github.com/google/certificate-transparency-go/x509/names_test.go
generated
vendored
@ -1,267 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"net"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/google/certificate-transparency-go/asn1"
|
||||
"github.com/google/certificate-transparency-go/x509/pkix"
|
||||
)
|
||||
|
||||
func TestParseGeneralNames(t *testing.T) {
|
||||
var tests = []struct {
|
||||
data string // as hex
|
||||
want GeneralNames
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
data: ("3012" +
|
||||
("8210" + "7777772e676f6f676c652e636f2e756b")),
|
||||
want: GeneralNames{
|
||||
DNSNames: []string{"www.google.co.uk"},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("3024" +
|
||||
("8210" + "7777772e676f6f676c652e636f2e756b") +
|
||||
("8610" + "7777772e676f6f676c652e636f2e756b")),
|
||||
want: GeneralNames{
|
||||
DNSNames: []string{"www.google.co.uk"},
|
||||
URIs: []string{"www.google.co.uk"},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: "0a0101",
|
||||
wantErr: "failed to parse GeneralNames sequence",
|
||||
},
|
||||
{
|
||||
data: "0a",
|
||||
wantErr: "failed to parse GeneralNames:",
|
||||
},
|
||||
{
|
||||
data: "03000a0101",
|
||||
wantErr: "trailing data",
|
||||
},
|
||||
{
|
||||
data: ("3005" + ("8703" + "010203")),
|
||||
wantErr: "invalid IP length",
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
inData := fromHex(test.data)
|
||||
var got GeneralNames
|
||||
err := parseGeneralNames(inData, &got)
|
||||
if err != nil {
|
||||
if test.wantErr == "" {
|
||||
t.Errorf("parseGeneralNames(%s)=%v; want nil", test.data, err)
|
||||
} else if !strings.Contains(err.Error(), test.wantErr) {
|
||||
t.Errorf("parseGeneralNames(%s)=%v; want %q", test.data, err, test.wantErr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.wantErr != "" {
|
||||
t.Errorf("parseGeneralNames(%s)=%+v,nil; want %q", test.data, got, test.wantErr)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(got, test.want) {
|
||||
t.Errorf("parseGeneralNames(%s)=%+v; want %+v", test.data, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseGeneralName(t *testing.T) {
|
||||
var tests = []struct {
|
||||
data string // as hex
|
||||
withMask bool
|
||||
want GeneralNames
|
||||
wantErr string
|
||||
}{
|
||||
{
|
||||
data: ("a008" +
|
||||
("0603" + "551d0e") + // OID: subject-key-id
|
||||
("0a01" + "01")), // enum=1
|
||||
want: GeneralNames{
|
||||
OtherNames: []OtherName{
|
||||
{
|
||||
TypeID: OIDExtensionSubjectKeyId,
|
||||
Value: asn1.RawValue{
|
||||
Class: asn1.ClassUniversal,
|
||||
Tag: asn1.TagEnum,
|
||||
IsCompound: false,
|
||||
Bytes: fromHex("01"),
|
||||
FullBytes: fromHex("0a0101"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("8008" +
|
||||
("0603" + "551d0e") + // OID: subject-key-id
|
||||
("0a01" + "01")), // enum=1
|
||||
wantErr: "not compound",
|
||||
},
|
||||
{
|
||||
data: ("a005" +
|
||||
("0603" + "551d0e")), // OID: subject-key-id
|
||||
wantErr: "sequence truncated",
|
||||
},
|
||||
{
|
||||
data: ("8110" + "77777740676f6f676c652e636f2e756b"),
|
||||
want: GeneralNames{
|
||||
EmailAddresses: []string{"www@google.co.uk"},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("8210" + "7777772e676f6f676c652e636f2e756b"),
|
||||
want: GeneralNames{
|
||||
DNSNames: []string{"www.google.co.uk"},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("844b" +
|
||||
("3049" +
|
||||
("310b" +
|
||||
("3009" +
|
||||
("0603" + "550406") +
|
||||
("1302" + "5553"))) + // "US"
|
||||
("3113" +
|
||||
("3011" +
|
||||
("0603" + "55040a") +
|
||||
("130a" + "476f6f676c6520496e63"))) + // "Google Inc"
|
||||
("3125" +
|
||||
("3023" +
|
||||
("0603" + "550403") +
|
||||
("131c" + "476f6f676c6520496e7465726e657420417574686f72697479204732"))))), // "GoogleInternet Authority G2"
|
||||
want: GeneralNames{
|
||||
DirectoryNames: []pkix.Name{
|
||||
{
|
||||
Country: []string{"US"},
|
||||
Organization: []string{"Google Inc"},
|
||||
CommonName: "Google Internet Authority G2",
|
||||
Names: []pkix.AttributeTypeAndValue{
|
||||
{Type: pkix.OIDCountry, Value: "US"},
|
||||
{Type: pkix.OIDOrganization, Value: "Google Inc"},
|
||||
{Type: pkix.OIDCommonName, Value: "Google Internet Authority G2"},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("8410" + "7777772e676f6f676c652e636f2e756b"),
|
||||
wantErr: "failed to unmarshal GeneralNames.directoryName",
|
||||
},
|
||||
{
|
||||
data: ("8610" + "7777772e676f6f676c652e636f2e756b"),
|
||||
want: GeneralNames{
|
||||
URIs: []string{"www.google.co.uk"},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("8704" + "01020304"),
|
||||
want: GeneralNames{
|
||||
IPNets: []net.IPNet{{IP: net.IP{1, 2, 3, 4}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("8708" + "01020304ffffff00"),
|
||||
withMask: true,
|
||||
want: GeneralNames{
|
||||
IPNets: []net.IPNet{{IP: net.IP{1, 2, 3, 4}, Mask: net.IPMask{0xff, 0xff, 0xff, 0x00}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("8710" + "01020304111213142122232431323334"),
|
||||
want: GeneralNames{
|
||||
IPNets: []net.IPNet{{IP: net.IP{1, 2, 3, 4, 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, 0x24, 0x31, 0x32, 0x33, 0x34}}},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("8703" + "010203"),
|
||||
wantErr: "invalid IP length",
|
||||
},
|
||||
{
|
||||
data: ("8707" + "01020304ffffff"),
|
||||
withMask: true,
|
||||
wantErr: "invalid IP/mask length",
|
||||
},
|
||||
{
|
||||
data: ("8803" + "551d0e"), // OID: subject-key-id
|
||||
want: GeneralNames{
|
||||
RegisteredIDs: []asn1.ObjectIdentifier{OIDExtensionSubjectKeyId},
|
||||
},
|
||||
},
|
||||
{
|
||||
data: ("8803" + "551d8e"),
|
||||
wantErr: "syntax error",
|
||||
},
|
||||
{
|
||||
data: ("9003" + "551d8e"),
|
||||
wantErr: "unknown tag",
|
||||
},
|
||||
{
|
||||
data: ("8803"),
|
||||
wantErr: "data truncated",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
inData := fromHex(test.data)
|
||||
var got GeneralNames
|
||||
_, err := parseGeneralName(inData, &got, test.withMask)
|
||||
if err != nil {
|
||||
if test.wantErr == "" {
|
||||
t.Errorf("parseGeneralName(%s)=%v; want nil", test.data, err)
|
||||
} else if !strings.Contains(err.Error(), test.wantErr) {
|
||||
t.Errorf("parseGeneralName(%s)=%v; want %q", test.data, err, test.wantErr)
|
||||
}
|
||||
continue
|
||||
}
|
||||
if test.wantErr != "" {
|
||||
t.Errorf("parseGeneralName(%s)=%+v,nil; want %q", test.data, got, test.wantErr)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(got, test.want) {
|
||||
t.Errorf("parseGeneralName(%s)=%+v; want %+v", test.data, got, test.want)
|
||||
}
|
||||
if got.Empty() {
|
||||
t.Errorf("parseGeneralName(%s).Empty(%+v)=true; want false", test.data, got)
|
||||
}
|
||||
if gotLen, wantLen := got.Len(), 1; gotLen != wantLen {
|
||||
t.Errorf("parseGeneralName(%s).Len(%+v)=%d; want %d", test.data, got, gotLen, wantLen)
|
||||
}
|
||||
if !bytes.Equal(inData, fromHex(test.data)) {
|
||||
t.Errorf("parseGeneralName(%s) modified data to %x", test.data, inData)
|
||||
}
|
||||
|
||||
// Wrap the GeneralName up in a SEQUENCE and check that we get the same result using parseGeneralNames.
|
||||
if test.withMask {
|
||||
continue
|
||||
}
|
||||
seqData := append([]byte{0x30, byte(len(inData))}, inData...)
|
||||
var gotSeq GeneralNames
|
||||
err = parseGeneralNames(seqData, &gotSeq)
|
||||
if err != nil {
|
||||
t.Errorf("parseGeneralNames(%x)=%v; want nil", seqData, err)
|
||||
continue
|
||||
}
|
||||
if !reflect.DeepEqual(gotSeq, test.want) {
|
||||
t.Errorf("parseGeneralNames(%x)=%+v; want %+v", seqData, gotSeq, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func fromHex(s string) []byte {
|
||||
d, _ := hex.DecodeString(s)
|
||||
return d
|
||||
}
|
247
vendor/github.com/google/certificate-transparency-go/x509/pem_decrypt_test.go
generated
vendored
247
vendor/github.com/google/certificate-transparency-go/x509/pem_decrypt_test.go
generated
vendored
@ -1,247 +0,0 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestDecrypt(t *testing.T) {
|
||||
for i, data := range testData {
|
||||
t.Logf("test %v. %v", i, data.kind)
|
||||
block, rest := pem.Decode(data.pemData)
|
||||
if len(rest) > 0 {
|
||||
t.Error("extra data")
|
||||
}
|
||||
der, err := DecryptPEMBlock(block, data.password)
|
||||
if err != nil {
|
||||
t.Error("decrypt failed: ", err)
|
||||
continue
|
||||
}
|
||||
if _, err := ParsePKCS1PrivateKey(der); err != nil {
|
||||
t.Error("invalid private key: ", err)
|
||||
}
|
||||
plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
|
||||
if err != nil {
|
||||
t.Fatal("cannot decode test DER data: ", err)
|
||||
}
|
||||
if !bytes.Equal(der, plainDER) {
|
||||
t.Error("data mismatch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestEncrypt(t *testing.T) {
|
||||
for i, data := range testData {
|
||||
t.Logf("test %v. %v", i, data.kind)
|
||||
plainDER, err := base64.StdEncoding.DecodeString(data.plainDER)
|
||||
if err != nil {
|
||||
t.Fatal("cannot decode test DER data: ", err)
|
||||
}
|
||||
password := []byte("kremvax1")
|
||||
block, err := EncryptPEMBlock(rand.Reader, "RSA PRIVATE KEY", plainDER, password, data.kind)
|
||||
if err != nil {
|
||||
t.Error("encrypt: ", err)
|
||||
continue
|
||||
}
|
||||
if !IsEncryptedPEMBlock(block) {
|
||||
t.Error("PEM block does not appear to be encrypted")
|
||||
}
|
||||
if block.Type != "RSA PRIVATE KEY" {
|
||||
t.Errorf("unexpected block type; got %q want %q", block.Type, "RSA PRIVATE KEY")
|
||||
}
|
||||
if block.Headers["Proc-Type"] != "4,ENCRYPTED" {
|
||||
t.Errorf("block does not have correct Proc-Type header")
|
||||
}
|
||||
der, err := DecryptPEMBlock(block, password)
|
||||
if err != nil {
|
||||
t.Error("decrypt: ", err)
|
||||
continue
|
||||
}
|
||||
if !bytes.Equal(der, plainDER) {
|
||||
t.Errorf("data mismatch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var testData = []struct {
|
||||
kind PEMCipher
|
||||
password []byte
|
||||
pemData []byte
|
||||
plainDER string
|
||||
}{
|
||||
{
|
||||
kind: PEMCipherDES,
|
||||
password: []byte("asdf"),
|
||||
pemData: []byte(`
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-CBC,34F09A4FC8DE22B5
|
||||
|
||||
WXxy8kbZdiZvANtKvhmPBLV7eVFj2A5z6oAxvI9KGyhG0ZK0skfnt00C24vfU7m5
|
||||
ICXeoqP67lzJ18xCzQfHjDaBNs53DSDT+Iz4e8QUep1xQ30+8QKX2NA2coee3nwc
|
||||
6oM1cuvhNUDemBH2i3dKgMVkfaga0zQiiOq6HJyGSncCMSruQ7F9iWEfRbFcxFCx
|
||||
qtHb1kirfGKEtgWTF+ynyco6+2gMXNu70L7nJcnxnV/RLFkHt7AUU1yrclxz7eZz
|
||||
XOH9VfTjb52q/I8Suozq9coVQwg4tXfIoYUdT//O+mB7zJb9HI9Ps77b9TxDE6Gm
|
||||
4C9brwZ3zg2vqXcwwV6QRZMtyll9rOpxkbw6NPlpfBqkc3xS51bbxivbO/Nve4KD
|
||||
r12ymjFNF4stXCfJnNqKoZ50BHmEEUDu5Wb0fpVn82XrGw7CYc4iug==
|
||||
-----END RSA PRIVATE KEY-----`),
|
||||
plainDER: `
|
||||
MIIBPAIBAAJBAPASZe+tCPU6p80AjHhDkVsLYa51D35e/YGa8QcZyooeZM8EHozo
|
||||
KD0fNiKI+53bHdy07N+81VQ8/ejPcRoXPlsCAwEAAQJBAMTxIuSq27VpR+zZ7WJf
|
||||
c6fvv1OBvpMZ0/d1pxL/KnOAgq2rD5hDtk9b0LGhTPgQAmrrMTKuSeGoIuYE+gKQ
|
||||
QvkCIQD+GC1m+/do+QRurr0uo46Kx1LzLeSCrjBk34wiOp2+dwIhAPHfTLRXS2fv
|
||||
7rljm0bYa4+eDZpz+E8RcXEgzhhvcQQ9AiAI5eHZJGOyml3MXnQjiPi55WcDOw0w
|
||||
glcRgT6QCEtz2wIhANSyqaFtosIkHKqrDUGfz/bb5tqMYTAnBruVPaf/WEOBAiEA
|
||||
9xORWeRG1tRpso4+dYy4KdDkuLPIO01KY6neYGm3BCM=`,
|
||||
},
|
||||
{
|
||||
kind: PEMCipher3DES,
|
||||
password: []byte("asdf"),
|
||||
pemData: []byte(`
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: DES-EDE3-CBC,C1F4A6A03682C2C7
|
||||
|
||||
0JqVdBEH6iqM7drTkj+e2W/bE3LqakaiWhb9WUVonFkhyu8ca/QzebY3b5gCvAZQ
|
||||
YwBvDcT/GHospKqPx+cxDHJNsUASDZws6bz8ZXWJGwZGExKzr0+Qx5fgXn44Ms3x
|
||||
8g1ENFuTXtxo+KoNK0zuAMAqp66Llcds3Fjl4XR18QaD0CrVNAfOdgATWZm5GJxk
|
||||
Fgx5f84nT+/ovvreG+xeOzWgvtKo0UUZVrhGOgfKLpa57adumcJ6SkUuBtEFpZFB
|
||||
ldw5w7WC7d13x2LsRkwo8ZrDKgIV+Y9GNvhuCCkTzNP0V3gNeJpd201HZHR+9n3w
|
||||
3z0VjR/MGqsfcy1ziEWMNOO53At3zlG6zP05aHMnMcZoVXadEK6L1gz++inSSDCq
|
||||
gI0UJP4e3JVB7AkgYymYAwiYALAkoEIuanxoc50njJk=
|
||||
-----END RSA PRIVATE KEY-----`),
|
||||
plainDER: `
|
||||
MIIBOwIBAAJBANOCXKdoNS/iP/MAbl9cf1/SF3P+Ns7ZeNL27CfmDh0O6Zduaax5
|
||||
NBiumd2PmjkaCu7lQ5JOibHfWn+xJsc3kw0CAwEAAQJANX/W8d1Q/sCqzkuAn4xl
|
||||
B5a7qfJWaLHndu1QRLNTRJPn0Ee7OKJ4H0QKOhQM6vpjRrz+P2u9thn6wUxoPsef
|
||||
QQIhAP/jCkfejFcy4v15beqKzwz08/tslVjF+Yq41eJGejmxAiEA05pMoqfkyjcx
|
||||
fyvGhpoOyoCp71vSGUfR2I9CR65oKh0CIC1Msjs66LlfJtQctRq6bCEtFCxEcsP+
|
||||
eEjYo/Sk6WphAiEAxpgWPMJeU/shFT28gS+tmhjPZLpEoT1qkVlC14u0b3ECIQDX
|
||||
tZZZxCtPAm7shftEib0VU77Lk8MsXJcx2C4voRsjEw==`,
|
||||
},
|
||||
{
|
||||
kind: PEMCipherAES128,
|
||||
password: []byte("asdf"),
|
||||
pemData: []byte(`
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,D4492E793FC835CC038A728ED174F78A
|
||||
|
||||
EyfQSzXSjv6BaNH+NHdXRlkHdimpF9izWlugVJAPApgXrq5YldPe2aGIOFXyJ+QE
|
||||
ZIG20DYqaPzJRjTEbPNZ6Es0S2JJ5yCpKxwJuDkgJZKtF39Q2i36JeGbSZQIuWJE
|
||||
GZbBpf1jDH/pr0iGonuAdl2PCCZUiy+8eLsD2tyviHUkFLOB+ykYoJ5t8ngZ/B6D
|
||||
33U43LLb7+9zD4y3Q9OVHqBFGyHcxCY9+9Qh4ZnFp7DTf6RY5TNEvE3s4g6aDpBs
|
||||
3NbvRVvYTgs8K9EPk4K+5R+P2kD8J8KvEIGxVa1vz8QoCJ/jr7Ka2rvNgPCex5/E
|
||||
080LzLHPCrXKdlr/f50yhNWq08ZxMWQFkui+FDHPDUaEELKAXV8/5PDxw80Rtybo
|
||||
AVYoCVIbZXZCuCO81op8UcOgEpTtyU5Lgh3Mw5scQL0=
|
||||
-----END RSA PRIVATE KEY-----`),
|
||||
plainDER: `
|
||||
MIIBOgIBAAJBAMBlj5FxYtqbcy8wY89d/S7n0+r5MzD9F63BA/Lpl78vQKtdJ5dT
|
||||
cDGh/rBt1ufRrNp0WihcmZi7Mpl/3jHjiWECAwEAAQJABNOHYnKhtDIqFYj1OAJ3
|
||||
k3GlU0OlERmIOoeY/cL2V4lgwllPBEs7r134AY4wMmZSBUj8UR/O4SNO668ElKPE
|
||||
cQIhAOuqY7/115x5KCdGDMWi+jNaMxIvI4ETGwV40ykGzqlzAiEA0P9oEC3m9tHB
|
||||
kbpjSTxaNkrXxDgdEOZz8X0uOUUwHNsCIAwzcSCiGLyYJTULUmP1ESERfW1mlV78
|
||||
XzzESaJpIM/zAiBQkSTcl9VhcJreQqvjn5BnPZLP4ZHS4gPwJAGdsj5J4QIhAOVR
|
||||
B3WlRNTXR2WsJ5JdByezg9xzdXzULqmga0OE339a`,
|
||||
},
|
||||
{
|
||||
kind: PEMCipherAES192,
|
||||
password: []byte("asdf"),
|
||||
pemData: []byte(`
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-192-CBC,E2C9FB02BCA23ADE1829F8D8BC5F5369
|
||||
|
||||
cqVslvHqDDM6qwU6YjezCRifXmKsrgEev7ng6Qs7UmDJOpHDgJQZI9fwMFUhIyn5
|
||||
FbCu1SHkLMW52Ld3CuEqMnzWMlhPrW8tFvUOrMWPYSisv7nNq88HobZEJcUNL2MM
|
||||
Y15XmHW6IJwPqhKyLHpWXyOCVEh4ODND2nV15PCoi18oTa475baxSk7+1qH7GuIs
|
||||
Rb7tshNTMqHbCpyo9Rn3UxeFIf9efdl8YLiMoIqc7J8E5e9VlbeQSdLMQOgDAQJG
|
||||
ReUtTw8exmKsY4gsSjhkg5uiw7/ZB1Ihto0qnfQJgjGc680qGkT1d6JfvOfeYAk6
|
||||
xn5RqS/h8rYAYm64KnepfC9vIujo4NqpaREDmaLdX5MJPQ+SlytITQvgUsUq3q/t
|
||||
Ss85xjQEZH3hzwjQqdJvmA4hYP6SUjxYpBM+02xZ1Xw=
|
||||
-----END RSA PRIVATE KEY-----`),
|
||||
plainDER: `
|
||||
MIIBOwIBAAJBAMGcRrZiNNmtF20zyS6MQ7pdGx17aFDl+lTl+qnLuJRUCMUG05xs
|
||||
OmxmL/O1Qlf+bnqR8Bgg65SfKg21SYuLhiMCAwEAAQJBAL94uuHyO4wux2VC+qpj
|
||||
IzPykjdU7XRcDHbbvksf4xokSeUFjjD3PB0Qa83M94y89ZfdILIqS9x5EgSB4/lX
|
||||
qNkCIQD6cCIqLfzq/lYbZbQgAAjpBXeQVYsbvVtJrPrXJAlVVQIhAMXpDKMeFPMn
|
||||
J0g2rbx1gngx0qOa5r5iMU5w/noN4W2XAiBjf+WzCG5yFvazD+dOx3TC0A8+4x3P
|
||||
uZ3pWbaXf5PNuQIgAcdXarvhelH2w2piY1g3BPeFqhzBSCK/yLGxR82KIh8CIQDD
|
||||
+qGKsd09NhQ/G27y/DARzOYtml1NvdmCQAgsDIIOLA==`,
|
||||
},
|
||||
{
|
||||
kind: PEMCipherAES256,
|
||||
password: []byte("asdf"),
|
||||
pemData: []byte(`
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-256-CBC,8E7ED5CD731902CE938957A886A5FFBD
|
||||
|
||||
4Mxr+KIzRVwoOP0wwq6caSkvW0iS+GE2h2Ov/u+n9ZTMwL83PRnmjfjzBgfRZLVf
|
||||
JFPXxUK26kMNpIdssNnqGOds+DhB+oSrsNKoxgxSl5OBoYv9eJTVYm7qOyAFIsjr
|
||||
DRKAcjYCmzfesr7PVTowwy0RtHmYwyXMGDlAzzZrEvaiySFFmMyKKvtoavwaFoc7
|
||||
Pz3RZScwIuubzTGJ1x8EzdffYOsdCa9Mtgpp3L136+23dOd6L/qK2EG2fzrJSHs/
|
||||
2XugkleBFSMKzEp9mxXKRfa++uidQvMZTFLDK9w5YjrRvMBo/l2BoZIsq0jAIE1N
|
||||
sv5Z/KwlX+3MDEpPQpUwGPlGGdLnjI3UZ+cjgqBcoMiNc6HfgbBgYJSU6aDSHuCk
|
||||
clCwByxWkBNgJ2GrkwNrF26v+bGJJJNR4SKouY1jQf0=
|
||||
-----END RSA PRIVATE KEY-----`),
|
||||
plainDER: `
|
||||
MIIBOgIBAAJBAKy3GFkstoCHIEeUU/qO8207m8WSrjksR+p9B4tf1w5k+2O1V/GY
|
||||
AQ5WFCApItcOkQe/I0yZZJk/PmCqMzSxrc8CAwEAAQJAOCAz0F7AW9oNelVQSP8F
|
||||
Sfzx7O1yom+qWyAQQJF/gFR11gpf9xpVnnyu1WxIRnDUh1LZwUsjwlDYb7MB74id
|
||||
oQIhANPcOiLwOPT4sIUpRM5HG6BF1BI7L77VpyGVk8xNP7X/AiEA0LMHZtk4I+lJ
|
||||
nClgYp4Yh2JZ1Znbu7IoQMCEJCjwKDECIGd8Dzm5tViTkUW6Hs3Tlf73nNs65duF
|
||||
aRnSglss8I3pAiEAonEnKruawgD8RavDFR+fUgmQiPz4FnGGeVgfwpGG1JECIBYq
|
||||
PXHYtPqxQIbD2pScR5qum7iGUh11lEUPkmt+2uqS`,
|
||||
},
|
||||
{
|
||||
// generated with:
|
||||
// openssl genrsa -aes128 -passout pass:asdf -out server.orig.key 128
|
||||
kind: PEMCipherAES128,
|
||||
password: []byte("asdf"),
|
||||
pemData: []byte(`
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7
|
||||
|
||||
6ei/MlytjE0FFgZOGQ+jrwomKfpl8kdefeE0NSt/DMRrw8OacHAzBNi3pPEa0eX3
|
||||
eND9l7C9meCirWovjj9QWVHrXyugFuDIqgdhQ8iHTgCfF3lrmcttVrbIfMDw+smD
|
||||
hTP8O1mS/MHl92NE0nhv0w==
|
||||
-----END RSA PRIVATE KEY-----`),
|
||||
plainDER: `
|
||||
MGMCAQACEQC6ssxmYuauuHGOCDAI54RdAgMBAAECEQCWIn6Yv2O+kBcDF7STctKB
|
||||
AgkA8SEfu/2i3g0CCQDGNlXbBHX7kQIIK3Ww5o0cYbECCQDCimPb0dYGsQIIeQ7A
|
||||
jryIst8=`,
|
||||
},
|
||||
}
|
||||
|
||||
const incompleteBlockPEM = `
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
Proc-Type: 4,ENCRYPTED
|
||||
DEK-Info: AES-128-CBC,74611ABC2571AF11B1BF9B69E62C89E7
|
||||
|
||||
6L8yXK2MTQUWBk4ZD6OvCiYp+mXyR1594TQ1K38MxGvDw5pwcDME2Lek8RrR5fd40P2XsL2Z4KKt
|
||||
ai+OP1BZUetfK6AW4MiqB2FDyIdOAJ8XeWuZy21Wtsh8wPD6yYOFM/w7WZL8weX3Y0TSeG/T
|
||||
-----END RSA PRIVATE KEY-----`
|
||||
|
||||
func TestIncompleteBlock(t *testing.T) {
|
||||
// incompleteBlockPEM contains ciphertext that is not a multiple of the
|
||||
// block size. This previously panicked. See #11215.
|
||||
block, _ := pem.Decode([]byte(incompleteBlockPEM))
|
||||
_, err := DecryptPEMBlock(block, []byte("foo"))
|
||||
if err == nil {
|
||||
t.Fatal("Bad PEM data decrypted successfully")
|
||||
}
|
||||
const expectedSubstr = "block size"
|
||||
if e := err.Error(); !strings.Contains(e, expectedSubstr) {
|
||||
t.Fatalf("Expected error containing %q but got: %q", expectedSubstr, e)
|
||||
}
|
||||
}
|
109
vendor/github.com/google/certificate-transparency-go/x509/pkcs8_test.go
generated
vendored
109
vendor/github.com/google/certificate-transparency-go/x509/pkcs8_test.go
generated
vendored
@ -1,109 +0,0 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"encoding/hex"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// Generated using:
|
||||
// openssl genrsa 1024 | openssl pkcs8 -topk8 -nocrypt
|
||||
var pkcs8RSAPrivateKeyHex = `30820278020100300d06092a864886f70d0101010500048202623082025e02010002818100cfb1b5bf9685ffa97b4f99df4ff122b70e59ac9b992f3bc2b3dde17d53c1a34928719b02e8fd17839499bfbd515bd6ef99c7a1c47a239718fe36bfd824c0d96060084b5f67f0273443007a24dfaf5634f7772c9346e10eb294c2306671a5a5e719ae24b4de467291bc571014b0e02dec04534d66a9bb171d644b66b091780e8d020301000102818100b595778383c4afdbab95d2bfed12b3f93bb0a73a7ad952f44d7185fd9ec6c34de8f03a48770f2009c8580bcd275e9632714e9a5e3f32f29dc55474b2329ff0ebc08b3ffcb35bc96e6516b483df80a4a59cceb71918cbabf91564e64a39d7e35dce21cb3031824fdbc845dba6458852ec16af5dddf51a8397a8797ae0337b1439024100ea0eb1b914158c70db39031dd8904d6f18f408c85fbbc592d7d20dee7986969efbda081fdf8bc40e1b1336d6b638110c836bfdc3f314560d2e49cd4fbde1e20b024100e32a4e793b574c9c4a94c8803db5152141e72d03de64e54ef2c8ed104988ca780cd11397bc359630d01b97ebd87067c5451ba777cf045ca23f5912f1031308c702406dfcdbbd5a57c9f85abc4edf9e9e29153507b07ce0a7ef6f52e60dcfebe1b8341babd8b789a837485da6c8d55b29bbb142ace3c24a1f5b54b454d01b51e2ad03024100bd6a2b60dee01e1b3bfcef6a2f09ed027c273cdbbaf6ba55a80f6dcc64e4509ee560f84b4f3e076bd03b11e42fe71a3fdd2dffe7e0902c8584f8cad877cdc945024100aa512fa4ada69881f1d8bb8ad6614f192b83200aef5edf4811313d5ef30a86cbd0a90f7b025c71ea06ec6b34db6306c86b1040670fd8654ad7291d066d06d031`
|
||||
|
||||
// Generated using:
|
||||
// openssl ecparam -genkey -name secp224r1 | openssl pkcs8 -topk8 -nocrypt
|
||||
var pkcs8P224PrivateKeyHex = `3078020100301006072a8648ce3d020106052b810400210461305f020101041cca3d72b3e88fed2684576dad9b80a9180363a5424986900e3abcab3fa13c033a0004f8f2a6372872a4e61263ed893afb919576a4cacfecd6c081a2cbc76873cf4ba8530703c6042b3a00e2205087e87d2435d2e339e25702fae1`
|
||||
|
||||
// Generated using:
|
||||
// openssl ecparam -genkey -name secp256r1 | openssl pkcs8 -topk8 -nocrypt
|
||||
var pkcs8P256PrivateKeyHex = `308187020100301306072a8648ce3d020106082a8648ce3d030107046d306b0201010420dad6b2f49ca774c36d8ae9517e935226f667c929498f0343d2424d0b9b591b43a14403420004b9c9b90095476afe7b860d8bd43568cab7bcb2eed7b8bf2fa0ce1762dd20b04193f859d2d782b1e4cbfd48492f1f533113a6804903f292258513837f07fda735`
|
||||
|
||||
// Generated using:
|
||||
// openssl ecparam -genkey -name secp384r1 | openssl pkcs8 -topk8 -nocrypt
|
||||
var pkcs8P384PrivateKeyHex = `3081b6020100301006072a8648ce3d020106052b8104002204819e30819b02010104309bf832f6aaaeacb78ce47ffb15e6fd0fd48683ae79df6eca39bfb8e33829ac94aa29d08911568684c2264a08a4ceb679a164036200049070ad4ed993c7770d700e9f6dc2baa83f63dd165b5507f98e8ff29b5d2e78ccbe05c8ddc955dbf0f7497e8222cfa49314fe4e269459f8e880147f70d785e530f2939e4bf9f838325bb1a80ad4cf59272ae0e5efe9a9dc33d874492596304bd3`
|
||||
|
||||
// Generated using:
|
||||
// openssl ecparam -genkey -name secp521r1 | openssl pkcs8 -topk8 -nocrypt
|
||||
//
|
||||
// Note that OpenSSL will truncate the private key if it can (i.e. it emits it
|
||||
// like an integer, even though it's an OCTET STRING field). Thus if you
|
||||
// regenerate this you may, randomly, find that it's a byte shorter than
|
||||
// expected and the Go test will fail to recreate it exactly.
|
||||
var pkcs8P521PrivateKeyHex = `3081ee020100301006072a8648ce3d020106052b810400230481d63081d3020101044200cfe0b87113a205cf291bb9a8cd1a74ac6c7b2ebb8199aaa9a5010d8b8012276fa3c22ac913369fa61beec2a3b8b4516bc049bde4fb3b745ac11b56ab23ac52e361a1818903818600040138f75acdd03fbafa4f047a8e4b272ba9d555c667962b76f6f232911a5786a0964e5edea6bd21a6f8725720958de049c6e3e6661c1c91b227cebee916c0319ed6ca003db0a3206d372229baf9dd25d868bf81140a518114803ce40c1855074d68c4e9dab9e65efba7064c703b400f1767f217dac82715ac1f6d88c74baf47a7971de4ea`
|
||||
|
||||
func TestPKCS8(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
keyHex string
|
||||
keyType reflect.Type
|
||||
curve elliptic.Curve
|
||||
}{
|
||||
{
|
||||
name: "RSA private key",
|
||||
keyHex: pkcs8RSAPrivateKeyHex,
|
||||
keyType: reflect.TypeOf(&rsa.PrivateKey{}),
|
||||
},
|
||||
{
|
||||
name: "P-224 private key",
|
||||
keyHex: pkcs8P224PrivateKeyHex,
|
||||
keyType: reflect.TypeOf(&ecdsa.PrivateKey{}),
|
||||
curve: elliptic.P224(),
|
||||
},
|
||||
{
|
||||
name: "P-256 private key",
|
||||
keyHex: pkcs8P256PrivateKeyHex,
|
||||
keyType: reflect.TypeOf(&ecdsa.PrivateKey{}),
|
||||
curve: elliptic.P256(),
|
||||
},
|
||||
{
|
||||
name: "P-384 private key",
|
||||
keyHex: pkcs8P384PrivateKeyHex,
|
||||
keyType: reflect.TypeOf(&ecdsa.PrivateKey{}),
|
||||
curve: elliptic.P384(),
|
||||
},
|
||||
{
|
||||
name: "P-521 private key",
|
||||
keyHex: pkcs8P521PrivateKeyHex,
|
||||
keyType: reflect.TypeOf(&ecdsa.PrivateKey{}),
|
||||
curve: elliptic.P521(),
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
derBytes, err := hex.DecodeString(test.keyHex)
|
||||
if err != nil {
|
||||
t.Errorf("%s: failed to decode hex: %s", test.name, err)
|
||||
continue
|
||||
}
|
||||
privKey, err := ParsePKCS8PrivateKey(derBytes)
|
||||
if err != nil {
|
||||
t.Errorf("%s: failed to decode PKCS#8: %s", test.name, err)
|
||||
continue
|
||||
}
|
||||
if reflect.TypeOf(privKey) != test.keyType {
|
||||
t.Errorf("%s: decoded PKCS#8 returned unexpected key type: %T", test.name, privKey)
|
||||
continue
|
||||
}
|
||||
if ecKey, isEC := privKey.(*ecdsa.PrivateKey); isEC && ecKey.Curve != test.curve {
|
||||
t.Errorf("%s: decoded PKCS#8 returned unexpected curve %#v", test.name, ecKey.Curve)
|
||||
continue
|
||||
}
|
||||
reserialised, err := MarshalPKCS8PrivateKey(privKey)
|
||||
if err != nil {
|
||||
t.Errorf("%s: failed to marshal into PKCS#8: %s", test.name, err)
|
||||
continue
|
||||
}
|
||||
if !bytes.Equal(derBytes, reserialised) {
|
||||
t.Errorf("%s: marshalled PKCS#8 didn't match original: got %x, want %x", test.name, reserialised, derBytes)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
2123
vendor/github.com/google/certificate-transparency-go/x509/revoked_test.go
generated
vendored
2123
vendor/github.com/google/certificate-transparency-go/x509/revoked_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
80
vendor/github.com/google/certificate-transparency-go/x509/root_darwin_test.go
generated
vendored
80
vendor/github.com/google/certificate-transparency-go/x509/root_darwin_test.go
generated
vendored
@ -1,80 +0,0 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestSystemRoots(t *testing.T) {
|
||||
switch runtime.GOARCH {
|
||||
case "arm", "arm64":
|
||||
t.Skipf("skipping on %s/%s, no system root", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "darwin":
|
||||
t.Skipf("skipping on %s/%s until cgo part of golang.org/issue/16532 has been implemented.", runtime.GOOS, runtime.GOARCH)
|
||||
}
|
||||
|
||||
t0 := time.Now()
|
||||
sysRoots := systemRootsPool() // actual system roots
|
||||
sysRootsDuration := time.Since(t0)
|
||||
|
||||
t1 := time.Now()
|
||||
execRoots, err := execSecurityRoots() // non-cgo roots
|
||||
execSysRootsDuration := time.Since(t1)
|
||||
|
||||
if err != nil {
|
||||
t.Fatalf("failed to read system roots: %v", err)
|
||||
}
|
||||
|
||||
t.Logf(" cgo sys roots: %v", sysRootsDuration)
|
||||
t.Logf("non-cgo sys roots: %v", execSysRootsDuration)
|
||||
|
||||
for _, tt := range []*CertPool{sysRoots, execRoots} {
|
||||
if tt == nil {
|
||||
t.Fatal("no system roots")
|
||||
}
|
||||
// On Mavericks, there are 212 bundled certs, at least
|
||||
// there was at one point in time on one machine.
|
||||
// (Maybe it was a corp laptop with extra certs?)
|
||||
// Other OS X users report
|
||||
// 135, 142, 145... Let's try requiring at least 100,
|
||||
// since this is just a sanity check.
|
||||
t.Logf("got %d roots", len(tt.certs))
|
||||
if want, have := 100, len(tt.certs); have < want {
|
||||
t.Fatalf("want at least %d system roots, have %d", want, have)
|
||||
}
|
||||
}
|
||||
|
||||
// Check that the two cert pools are roughly the same;
|
||||
// |A∩B| > max(|A|, |B|) / 2 should be a reasonably robust check.
|
||||
|
||||
isect := make(map[string]bool, len(sysRoots.certs))
|
||||
for _, c := range sysRoots.certs {
|
||||
isect[string(c.Raw)] = true
|
||||
}
|
||||
|
||||
have := 0
|
||||
for _, c := range execRoots.certs {
|
||||
if isect[string(c.Raw)] {
|
||||
have++
|
||||
}
|
||||
}
|
||||
|
||||
var want int
|
||||
if nsys, nexec := len(sysRoots.certs), len(execRoots.certs); nsys > nexec {
|
||||
want = nsys / 2
|
||||
} else {
|
||||
want = nexec / 2
|
||||
}
|
||||
|
||||
if have < want {
|
||||
t.Errorf("insufficient overlap between cgo and non-cgo roots; want at least %d, have %d", want, have)
|
||||
}
|
||||
}
|
127
vendor/github.com/google/certificate-transparency-go/x509/root_unix_test.go
generated
vendored
127
vendor/github.com/google/certificate-transparency-go/x509/root_unix_test.go
generated
vendored
@ -1,127 +0,0 @@
|
||||
// Copyright 2017 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build dragonfly freebsd linux netbsd openbsd solaris
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
const (
|
||||
testDir = "testdata"
|
||||
testDirCN = "test-dir"
|
||||
testFile = "test-file.crt"
|
||||
testFileCN = "test-file"
|
||||
testMissing = "missing"
|
||||
)
|
||||
|
||||
func TestEnvVars(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
fileEnv string
|
||||
dirEnv string
|
||||
files []string
|
||||
dirs []string
|
||||
cns []string
|
||||
}{
|
||||
{
|
||||
// Environment variables override the default locations preventing fall through.
|
||||
name: "override-defaults",
|
||||
fileEnv: testMissing,
|
||||
dirEnv: testMissing,
|
||||
files: []string{testFile},
|
||||
dirs: []string{testDir},
|
||||
cns: nil,
|
||||
},
|
||||
{
|
||||
// File environment overrides default file locations.
|
||||
name: "file",
|
||||
fileEnv: testFile,
|
||||
dirEnv: "",
|
||||
files: nil,
|
||||
dirs: nil,
|
||||
cns: []string{testFileCN},
|
||||
},
|
||||
{
|
||||
// Directory environment overrides default directory locations.
|
||||
name: "dir",
|
||||
fileEnv: "",
|
||||
dirEnv: testDir,
|
||||
files: nil,
|
||||
dirs: nil,
|
||||
cns: []string{testDirCN},
|
||||
},
|
||||
{
|
||||
// File & directory environment overrides both default locations.
|
||||
name: "file+dir",
|
||||
fileEnv: testFile,
|
||||
dirEnv: testDir,
|
||||
files: nil,
|
||||
dirs: nil,
|
||||
cns: []string{testFileCN, testDirCN},
|
||||
},
|
||||
{
|
||||
// Environment variable empty / unset uses default locations.
|
||||
name: "empty-fall-through",
|
||||
fileEnv: "",
|
||||
dirEnv: "",
|
||||
files: []string{testFile},
|
||||
dirs: []string{testDir},
|
||||
cns: []string{testFileCN, testDirCN},
|
||||
},
|
||||
}
|
||||
|
||||
// Save old settings so we can restore before the test ends.
|
||||
origCertFiles, origCertDirectories := certFiles, certDirectories
|
||||
origFile, origDir := os.Getenv(certFileEnv), os.Getenv(certDirEnv)
|
||||
defer func() {
|
||||
certFiles = origCertFiles
|
||||
certDirectories = origCertDirectories
|
||||
os.Setenv(certFileEnv, origFile)
|
||||
os.Setenv(certDirEnv, origDir)
|
||||
}()
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if err := os.Setenv(certFileEnv, tc.fileEnv); err != nil {
|
||||
t.Fatalf("setenv %q failed: %v", certFileEnv, err)
|
||||
}
|
||||
if err := os.Setenv(certDirEnv, tc.dirEnv); err != nil {
|
||||
t.Fatalf("setenv %q failed: %v", certDirEnv, err)
|
||||
}
|
||||
|
||||
certFiles, certDirectories = tc.files, tc.dirs
|
||||
|
||||
r, err := loadSystemRoots()
|
||||
if err != nil {
|
||||
t.Fatal("unexpected failure:", err)
|
||||
}
|
||||
|
||||
if r == nil {
|
||||
if tc.cns == nil {
|
||||
// Expected nil
|
||||
return
|
||||
}
|
||||
t.Fatal("nil roots")
|
||||
}
|
||||
|
||||
// Verify that the returned certs match, otherwise report where the mismatch is.
|
||||
for i, cn := range tc.cns {
|
||||
if i >= len(r.certs) {
|
||||
t.Errorf("missing cert %v @ %v", cn, i)
|
||||
} else if r.certs[i].Subject.CommonName != cn {
|
||||
fmt.Printf("%#v\n", r.certs[0].Subject)
|
||||
t.Errorf("unexpected cert common name %q, want %q", r.certs[i].Subject.CommonName, cn)
|
||||
}
|
||||
}
|
||||
if len(r.certs) > len(tc.cns) {
|
||||
t.Errorf("got %v certs, which is more than %v wanted", len(r.certs), len(tc.cns))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
44
vendor/github.com/google/certificate-transparency-go/x509/sec1_test.go
generated
vendored
44
vendor/github.com/google/certificate-transparency-go/x509/sec1_test.go
generated
vendored
@ -1,44 +0,0 @@
|
||||
// Copyright 2012 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var ecKeyTests = []struct {
|
||||
derHex string
|
||||
shouldReserialize bool
|
||||
}{
|
||||
// Generated using:
|
||||
// openssl ecparam -genkey -name secp384r1 -outform PEM
|
||||
{"3081a40201010430bdb9839c08ee793d1157886a7a758a3c8b2a17a4df48f17ace57c72c56b4723cf21dcda21d4e1ad57ff034f19fcfd98ea00706052b81040022a16403620004feea808b5ee2429cfcce13c32160e1c960990bd050bb0fdf7222f3decd0a55008e32a6aa3c9062051c4cba92a7a3b178b24567412d43cdd2f882fa5addddd726fe3e208d2c26d733a773a597abb749714df7256ead5105fa6e7b3650de236b50", true},
|
||||
// This key was generated by GnuTLS and has illegal zero-padding of the
|
||||
// private key. See https://golang.org/issues/13699.
|
||||
{"3078020101042100f9f43a04b9bdc3ab01f53be6df80e7a7bc3eaf7b87fc24e630a4a0aa97633645a00a06082a8648ce3d030107a1440342000441a51bc318461b4c39a45048a16d4fc2a935b1ea7fe86e8c1fa219d6f2438f7c7fd62957d3442efb94b6a23eb0ea66dda663dc42f379cda6630b21b7888a5d3d", false},
|
||||
// This was generated using an old version of OpenSSL and is missing a
|
||||
// leading zero byte in the private key that should be present.
|
||||
{"3081db0201010441607b4f985774ac21e633999794542e09312073480baa69550914d6d43d8414441e61b36650567901da714f94dffb3ce0e2575c31928a0997d51df5c440e983ca17a00706052b81040023a181890381860004001661557afedd7ac8d6b70e038e576558c626eb62edda36d29c3a1310277c11f67a8c6f949e5430a37dcfb95d902c1b5b5379c389873b9dd17be3bdb088a4774a7401072f830fb9a08d93bfa50a03dd3292ea07928724ddb915d831917a338f6b0aecfbc3cf5352c4a1295d356890c41c34116d29eeb93779aab9d9d78e2613437740f6", false},
|
||||
}
|
||||
|
||||
func TestParseECPrivateKey(t *testing.T) {
|
||||
for i, test := range ecKeyTests {
|
||||
derBytes, _ := hex.DecodeString(test.derHex)
|
||||
key, err := ParseECPrivateKey(derBytes)
|
||||
if err != nil {
|
||||
t.Fatalf("#%d: failed to decode EC private key: %s", i, err)
|
||||
}
|
||||
serialized, err := MarshalECPrivateKey(key)
|
||||
if err != nil {
|
||||
t.Fatalf("#%d: failed to encode EC private key: %s", i, err)
|
||||
}
|
||||
matches := bytes.Equal(serialized, derBytes)
|
||||
if matches != test.shouldReserialize {
|
||||
t.Fatalf("#%d: when serializing key: matches=%t, should match=%t: original %x, reserialized %x", i, matches, test.shouldReserialize, serialized, derBytes)
|
||||
}
|
||||
}
|
||||
}
|
19
vendor/github.com/google/certificate-transparency-go/x509/sha2_windows_test.go
generated
vendored
19
vendor/github.com/google/certificate-transparency-go/x509/sha2_windows_test.go
generated
vendored
@ -1,19 +0,0 @@
|
||||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package x509
|
||||
|
||||
import "syscall"
|
||||
|
||||
func init() {
|
||||
v, err := syscall.GetVersion()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
if major := byte(v); major < 6 {
|
||||
// Windows XP SP2 and Windows 2003 do not support SHA2.
|
||||
// http://blogs.technet.com/b/pki/archive/2010/09/30/sha2-and-windows.aspx
|
||||
supportSHA2 = false
|
||||
}
|
||||
}
|
31
vendor/github.com/google/certificate-transparency-go/x509/testdata/test-dir.crt
generated
vendored
31
vendor/github.com/google/certificate-transparency-go/x509/testdata/test-dir.crt
generated
vendored
@ -1,31 +0,0 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIFazCCA1OgAwIBAgIJAL8a/lsnspOqMA0GCSqGSIb3DQEBCwUAMEwxCzAJBgNV
|
||||
BAYTAlVLMRMwEQYDVQQIDApUZXN0LVN0YXRlMRUwEwYDVQQKDAxHb2xhbmcgVGVz
|
||||
dHMxETAPBgNVBAMMCHRlc3QtZGlyMB4XDTE3MDIwMTIzNTAyN1oXDTI3MDEzMDIz
|
||||
NTAyN1owTDELMAkGA1UEBhMCVUsxEzARBgNVBAgMClRlc3QtU3RhdGUxFTATBgNV
|
||||
BAoMDEdvbGFuZyBUZXN0czERMA8GA1UEAwwIdGVzdC1kaXIwggIiMA0GCSqGSIb3
|
||||
DQEBAQUAA4ICDwAwggIKAoICAQDzBoi43Yn30KN13PKFHu8LA4UmgCRToTukLItM
|
||||
WK2Je45grs/axg9n3YJOXC6hmsyrkOnyBcx1xVNgSrOAll7fSjtChRIX72Xrloxu
|
||||
XewtWVIrijqz6oylbvEmbRT3O8uynu5rF82Pmdiy8oiSfdywjKuPnE0hjV1ZSCql
|
||||
MYcXqA+f0JFD8kMv4pbtxjGH8f2DkYQz+hHXLrJH4/MEYdVMQXoz/GDzLyOkrXBN
|
||||
hpMaBBqg1p0P+tRdfLXuliNzA9vbZylzpF1YZ0gvsr0S5Y6LVtv7QIRygRuLY4kF
|
||||
k+UYuFq8NrV8TykS7FVnO3tf4XcYZ7r2KV5FjYSrJtNNo85BV5c3xMD3fJ2XcOWk
|
||||
+oD1ATdgAM3aKmSOxNtNItKKxBe1mkqDH41NbWx7xMad78gDznyeT0tjEOltN2bM
|
||||
uXU1R/jgR/vq5Ec0AhXJyL/ziIcmuV2fSl/ZxT4ARD+16tgPiIx+welTf0v27/JY
|
||||
adlfkkL5XsPRrbSguISrj7JeaO/gjG3KnDVHcZvYBpDfHqRhCgrosfe26TZcTXx2
|
||||
cRxOfvBjMz1zJAg+esuUzSkerreyRhzD7RpeZTwi6sxvx82MhYMbA3w1LtgdABio
|
||||
9JRqZy3xqsIbNv7N46WO/qXL1UMRKb1UyHeW8g8btboz+B4zv1U0Nj+9qxPBbQui
|
||||
dgL9LQIDAQABo1AwTjAdBgNVHQ4EFgQUy0/0W8nwQfz2tO6AZ2jPkEiTzvUwHwYD
|
||||
VR0jBBgwFoAUy0/0W8nwQfz2tO6AZ2jPkEiTzvUwDAYDVR0TBAUwAwEB/zANBgkq
|
||||
hkiG9w0BAQsFAAOCAgEAvEVnUYsIOt87rggmLPqEueynkuQ+562M8EDHSQl82zbe
|
||||
xDCxeg3DvPgKb+RvaUdt1362z/szK10SoeMgx6+EQLoV9LiVqXwNqeYfixrhrdw3
|
||||
ppAhYYhymdkbUQCEMHypmXP1vPhAz4o8Bs+eES1M+zO6ErBiD7SqkmBElT+GixJC
|
||||
6epC9ZQFs+dw3lPlbiZSsGE85sqc3VAs0/JgpL/pb1/Eg4s0FUhZD2C2uWdSyZGc
|
||||
g0/v3aXJCp4j/9VoNhI1WXz3M45nysZIL5OQgXymLqJElQa1pZ3Wa4i/nidvT4AT
|
||||
Xlxc/qijM8set/nOqp7hVd5J0uG6qdwLRILUddZ6OpXd7ZNi1EXg+Bpc7ehzGsDt
|
||||
3UFGzYXDjxYnK2frQfjLS8stOQIqSrGthW6x0fdkVx0y8BByvd5J6+JmZl4UZfzA
|
||||
m99VxXSt4B9x6BvnY7ktzcFDOjtuLc4B/7yg9fv1eQuStA4cHGGAttsCg1X/Kx8W
|
||||
PvkkeH0UWDZ9vhH9K36703z89da6MWF+bz92B0+4HoOmlVaXRkvblsNaynJnL0LC
|
||||
Ayry7QBxuh5cMnDdRwJB3AVJIiJ1GVpb7aGvBOnx+s2lwRv9HWtghb+cbwwktx1M
|
||||
JHyBf3GZNSWTpKY7cD8V+NnBv3UuioOVVo+XAU4LF/bYUjdRpxWADJizNtZrtFo=
|
||||
-----END CERTIFICATE-----
|
1793
vendor/github.com/google/certificate-transparency-go/x509/verify_test.go
generated
vendored
1793
vendor/github.com/google/certificate-transparency-go/x509/verify_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
2429
vendor/github.com/google/certificate-transparency-go/x509/x509_test.go
generated
vendored
2429
vendor/github.com/google/certificate-transparency-go/x509/x509_test.go
generated
vendored
File diff suppressed because it is too large
Load Diff
115
vendor/github.com/google/certificate-transparency-go/x509util/files.go
generated
vendored
115
vendor/github.com/google/certificate-transparency-go/x509util/files.go
generated
vendored
@ -1,115 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package x509util
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
)
|
||||
|
||||
// ReadPossiblePEMFile loads data from a file which may be in DER format
|
||||
// or may be in PEM format (with the given blockname).
|
||||
func ReadPossiblePEMFile(filename, blockname string) ([][]byte, error) {
|
||||
data, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%s: failed to read data: %v", filename, err)
|
||||
}
|
||||
return dePEM(data, blockname), nil
|
||||
}
|
||||
|
||||
// ReadPossiblePEMURL attempts to determine if the given target is a local file or a
|
||||
// URL, and return the file contents regardless. It also copes with either PEM or DER
|
||||
// format data.
|
||||
func ReadPossiblePEMURL(target, blockname string) ([][]byte, error) {
|
||||
if !strings.HasPrefix(target, "http://") && !strings.HasPrefix(target, "https://") {
|
||||
// Assume it's a filename
|
||||
return ReadPossiblePEMFile(target, blockname)
|
||||
}
|
||||
|
||||
rsp, err := http.Get(target)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to http.Get(%q): %v", target, err)
|
||||
}
|
||||
data, err := ioutil.ReadAll(rsp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to ioutil.ReadAll(%q): %v", target, err)
|
||||
}
|
||||
return dePEM(data, blockname), nil
|
||||
}
|
||||
|
||||
func dePEM(data []byte, blockname string) [][]byte {
|
||||
var results [][]byte
|
||||
if strings.Contains(string(data), "BEGIN "+blockname) {
|
||||
rest := data
|
||||
for {
|
||||
var block *pem.Block
|
||||
block, rest = pem.Decode(rest)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
if block.Type == blockname {
|
||||
results = append(results, block.Bytes)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
results = append(results, data)
|
||||
}
|
||||
return results
|
||||
}
|
||||
|
||||
// ReadFileOrURL returns the data from a target which may be either a filename
|
||||
// or an HTTP(S) URL.
|
||||
func ReadFileOrURL(target string, client *http.Client) ([]byte, error) {
|
||||
u, err := url.Parse(target)
|
||||
if err != nil || (u.Scheme != "http" && u.Scheme != "https") {
|
||||
return ioutil.ReadFile(target)
|
||||
}
|
||||
|
||||
rsp, err := client.Get(u.String())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to http.Get(%q): %v", target, err)
|
||||
}
|
||||
return ioutil.ReadAll(rsp.Body)
|
||||
}
|
||||
|
||||
// GetIssuer attempts to retrieve the issuer for a certificate, by examining
|
||||
// the cert's Authority Information Access extension (if present) for the
|
||||
// issuer's URL and retrieving from there.
|
||||
func GetIssuer(cert *x509.Certificate, client *http.Client) (*x509.Certificate, error) {
|
||||
if len(cert.IssuingCertificateURL) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
issuerURL := cert.IssuingCertificateURL[0]
|
||||
rsp, err := client.Get(issuerURL)
|
||||
if err != nil || rsp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("failed to get issuer from %q: %v", issuerURL, err)
|
||||
}
|
||||
defer rsp.Body.Close()
|
||||
body, err := ioutil.ReadAll(rsp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read issuer from %q: %v", issuerURL, err)
|
||||
}
|
||||
issuers, err := x509.ParseCertificates(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse issuer cert: %v", err)
|
||||
}
|
||||
return issuers[0], nil
|
||||
}
|
26
vendor/github.com/google/certificate-transparency-go/x509util/fuzz.go
generated
vendored
26
vendor/github.com/google/certificate-transparency-go/x509util/fuzz.go
generated
vendored
@ -1,26 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package x509util
|
||||
|
||||
import "github.com/google/certificate-transparency-go/x509"
|
||||
|
||||
// Fuzz is a go-fuzz (https://github.com/dvyukov/go-fuzz) entrypoint
|
||||
// for fuzzing the parsing of X509 certificates.
|
||||
func Fuzz(data []byte) int {
|
||||
if _, err := x509.ParseCertificate(data); err == nil {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
169
vendor/github.com/google/certificate-transparency-go/x509util/revoked.go
generated
vendored
169
vendor/github.com/google/certificate-transparency-go/x509util/revoked.go
generated
vendored
@ -1,169 +0,0 @@
|
||||
// Copyright 2017 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package x509util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
"github.com/google/certificate-transparency-go/x509/pkix"
|
||||
)
|
||||
|
||||
// RevocationReasonToString generates a string describing a revocation reason code.
|
||||
func RevocationReasonToString(reason x509.RevocationReasonCode) string {
|
||||
switch reason {
|
||||
case x509.Unspecified:
|
||||
return "Unspecified"
|
||||
case x509.KeyCompromise:
|
||||
return "Key Compromise"
|
||||
case x509.CACompromise:
|
||||
return "CA Compromise"
|
||||
case x509.AffiliationChanged:
|
||||
return "Affiliation Changed"
|
||||
case x509.Superseded:
|
||||
return "Superseded"
|
||||
case x509.CessationOfOperation:
|
||||
return "Cessation Of Operation"
|
||||
case x509.CertificateHold:
|
||||
return "Certificate Hold"
|
||||
case x509.RemoveFromCRL:
|
||||
return "Remove From CRL"
|
||||
case x509.PrivilegeWithdrawn:
|
||||
return "Privilege Withdrawn"
|
||||
case x509.AACompromise:
|
||||
return "AA Compromise"
|
||||
default:
|
||||
return strconv.Itoa(int(reason))
|
||||
}
|
||||
}
|
||||
|
||||
// CRLToString generates a string describing the given certificate revocation list.
|
||||
// The output roughly resembles that from openssl crl -text.
|
||||
func CRLToString(crl *x509.CertificateList) string {
|
||||
var result bytes.Buffer
|
||||
var showCritical = func(critical bool) {
|
||||
if critical {
|
||||
result.WriteString(" critical")
|
||||
}
|
||||
result.WriteString("\n")
|
||||
}
|
||||
result.WriteString("Certificate Revocation List (CRL):\n")
|
||||
result.WriteString(fmt.Sprintf(" Version: %d (%#x)\n", crl.TBSCertList.Version+1, crl.TBSCertList.Version))
|
||||
result.WriteString(fmt.Sprintf(" Signature Algorithm: %v\n", x509.SignatureAlgorithmFromAI(crl.TBSCertList.Signature)))
|
||||
var issuer pkix.Name
|
||||
issuer.FillFromRDNSequence(&crl.TBSCertList.Issuer)
|
||||
result.WriteString(fmt.Sprintf(" Issuer: %v\n", NameToString(issuer)))
|
||||
result.WriteString(fmt.Sprintf(" Last Update: %v\n", crl.TBSCertList.ThisUpdate))
|
||||
result.WriteString(fmt.Sprintf(" Next Update: %v\n", crl.TBSCertList.NextUpdate))
|
||||
|
||||
if len(crl.TBSCertList.Extensions) > 0 {
|
||||
result.WriteString(" CRL extensions:\n")
|
||||
}
|
||||
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionAuthorityKeyId, crl.TBSCertList.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Authority Key Identifier:"))
|
||||
showCritical(critical)
|
||||
result.WriteString(fmt.Sprintf(" keyid:%v\n", hex.EncodeToString(crl.TBSCertList.AuthorityKeyID)))
|
||||
}
|
||||
count, critical = OIDInExtensions(x509.OIDExtensionIssuerAltName, crl.TBSCertList.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Issuer Alt Name:"))
|
||||
showCritical(critical)
|
||||
result.WriteString(fmt.Sprintf(" %s\n", GeneralNamesToString(&crl.TBSCertList.IssuerAltNames)))
|
||||
}
|
||||
count, critical = OIDInExtensions(x509.OIDExtensionCRLNumber, crl.TBSCertList.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 CRLNumber:"))
|
||||
showCritical(critical)
|
||||
result.WriteString(fmt.Sprintf(" %d\n", crl.TBSCertList.CRLNumber))
|
||||
}
|
||||
count, critical = OIDInExtensions(x509.OIDExtensionDeltaCRLIndicator, crl.TBSCertList.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Delta CRL Indicator:"))
|
||||
showCritical(critical)
|
||||
result.WriteString(fmt.Sprintf(" %d\n", crl.TBSCertList.BaseCRLNumber))
|
||||
}
|
||||
count, critical = OIDInExtensions(x509.OIDExtensionIssuingDistributionPoint, crl.TBSCertList.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Issuing Distribution Point:"))
|
||||
showCritical(critical)
|
||||
result.WriteString(fmt.Sprintf(" %s\n", GeneralNamesToString(&crl.TBSCertList.IssuingDPFullNames)))
|
||||
}
|
||||
count, critical = OIDInExtensions(x509.OIDExtensionFreshestCRL, crl.TBSCertList.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Freshest CRL:"))
|
||||
showCritical(critical)
|
||||
result.WriteString(fmt.Sprintf(" Full Name:\n"))
|
||||
var buf bytes.Buffer
|
||||
for _, pt := range crl.TBSCertList.FreshestCRLDistributionPoint {
|
||||
commaAppend(&buf, "URI:"+pt)
|
||||
}
|
||||
result.WriteString(fmt.Sprintf(" %v\n", buf.String()))
|
||||
}
|
||||
count, critical = OIDInExtensions(x509.OIDExtensionAuthorityInfoAccess, crl.TBSCertList.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" Authority Information Access:"))
|
||||
showCritical(critical)
|
||||
var issuerBuf bytes.Buffer
|
||||
for _, issuer := range crl.TBSCertList.IssuingCertificateURL {
|
||||
commaAppend(&issuerBuf, "URI:"+issuer)
|
||||
}
|
||||
if issuerBuf.Len() > 0 {
|
||||
result.WriteString(fmt.Sprintf(" CA Issuers - %v\n", issuerBuf.String()))
|
||||
}
|
||||
var ocspBuf bytes.Buffer
|
||||
for _, ocsp := range crl.TBSCertList.OCSPServer {
|
||||
commaAppend(&ocspBuf, "URI:"+ocsp)
|
||||
}
|
||||
if ocspBuf.Len() > 0 {
|
||||
result.WriteString(fmt.Sprintf(" OCSP - %v\n", ocspBuf.String()))
|
||||
}
|
||||
// TODO(drysdale): Display other GeneralName types
|
||||
}
|
||||
|
||||
result.WriteString("\n")
|
||||
result.WriteString("Revoked Certificates:\n")
|
||||
for _, c := range crl.TBSCertList.RevokedCertificates {
|
||||
result.WriteString(fmt.Sprintf(" Serial Number: %d (%#[1]x)\n", c.SerialNumber))
|
||||
result.WriteString(fmt.Sprintf(" Revocation Date : %v\n", c.RevocationTime))
|
||||
count, critical = OIDInExtensions(x509.OIDExtensionCRLReasons, c.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 CRL Reason Code:"))
|
||||
showCritical(critical)
|
||||
result.WriteString(fmt.Sprintf(" %s\n", RevocationReasonToString(c.RevocationReason)))
|
||||
}
|
||||
count, critical = OIDInExtensions(x509.OIDExtensionInvalidityDate, c.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" Invalidity Date:"))
|
||||
showCritical(critical)
|
||||
result.WriteString(fmt.Sprintf(" %s\n", c.InvalidityDate))
|
||||
}
|
||||
count, critical = OIDInExtensions(x509.OIDExtensionCertificateIssuer, c.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" Issuer:"))
|
||||
showCritical(critical)
|
||||
result.WriteString(fmt.Sprintf(" %s\n", GeneralNamesToString(&c.Issuer)))
|
||||
}
|
||||
}
|
||||
result.WriteString(fmt.Sprintf(" Signature Algorithm: %v\n", x509.SignatureAlgorithmFromAI(crl.SignatureAlgorithm)))
|
||||
appendHexData(&result, crl.SignatureValue.Bytes, 18, " ")
|
||||
result.WriteString("\n")
|
||||
|
||||
return result.String()
|
||||
}
|
773
vendor/github.com/google/certificate-transparency-go/x509util/x509util.go
generated
vendored
773
vendor/github.com/google/certificate-transparency-go/x509util/x509util.go
generated
vendored
@ -1,773 +0,0 @@
|
||||
// Copyright 2016 Google Inc. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Package x509util includes utility code for working with X.509
|
||||
// certificates from the x509 package.
|
||||
package x509util
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
|
||||
ct "github.com/google/certificate-transparency-go"
|
||||
"github.com/google/certificate-transparency-go/asn1"
|
||||
"github.com/google/certificate-transparency-go/gossip/minimal/x509ext"
|
||||
"github.com/google/certificate-transparency-go/tls"
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
"github.com/google/certificate-transparency-go/x509/pkix"
|
||||
)
|
||||
|
||||
// OIDForStandardExtension indicates whether oid identifies a standard extension.
|
||||
// Standard extensions are listed in RFC 5280 (and other RFCs).
|
||||
func OIDForStandardExtension(oid asn1.ObjectIdentifier) bool {
|
||||
if oid.Equal(x509.OIDExtensionSubjectKeyId) ||
|
||||
oid.Equal(x509.OIDExtensionKeyUsage) ||
|
||||
oid.Equal(x509.OIDExtensionExtendedKeyUsage) ||
|
||||
oid.Equal(x509.OIDExtensionAuthorityKeyId) ||
|
||||
oid.Equal(x509.OIDExtensionBasicConstraints) ||
|
||||
oid.Equal(x509.OIDExtensionSubjectAltName) ||
|
||||
oid.Equal(x509.OIDExtensionCertificatePolicies) ||
|
||||
oid.Equal(x509.OIDExtensionNameConstraints) ||
|
||||
oid.Equal(x509.OIDExtensionCRLDistributionPoints) ||
|
||||
oid.Equal(x509.OIDExtensionIssuerAltName) ||
|
||||
oid.Equal(x509.OIDExtensionSubjectDirectoryAttributes) ||
|
||||
oid.Equal(x509.OIDExtensionInhibitAnyPolicy) ||
|
||||
oid.Equal(x509.OIDExtensionPolicyConstraints) ||
|
||||
oid.Equal(x509.OIDExtensionPolicyMappings) ||
|
||||
oid.Equal(x509.OIDExtensionFreshestCRL) ||
|
||||
oid.Equal(x509.OIDExtensionSubjectInfoAccess) ||
|
||||
oid.Equal(x509.OIDExtensionAuthorityInfoAccess) ||
|
||||
oid.Equal(x509.OIDExtensionCTPoison) ||
|
||||
oid.Equal(x509.OIDExtensionCTSCT) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// OIDInExtensions checks whether the extension identified by oid is present in extensions
|
||||
// and returns how many times it occurs together with an indication of whether any of them
|
||||
// are marked critical.
|
||||
func OIDInExtensions(oid asn1.ObjectIdentifier, extensions []pkix.Extension) (int, bool) {
|
||||
count := 0
|
||||
critical := false
|
||||
for _, ext := range extensions {
|
||||
if ext.Id.Equal(oid) {
|
||||
count++
|
||||
if ext.Critical {
|
||||
critical = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return count, critical
|
||||
}
|
||||
|
||||
// String formatting for various X.509/ASN.1 types
|
||||
func bitStringToString(b asn1.BitString) string {
|
||||
result := hex.EncodeToString(b.Bytes)
|
||||
bitsLeft := b.BitLength % 8
|
||||
if bitsLeft != 0 {
|
||||
result += " (" + strconv.Itoa(8-bitsLeft) + " unused bits)"
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func publicKeyAlgorithmToString(algo x509.PublicKeyAlgorithm) string {
|
||||
// Use OpenSSL-compatible strings for the algorithms.
|
||||
switch algo {
|
||||
case x509.RSA:
|
||||
return "rsaEncryption"
|
||||
case x509.DSA:
|
||||
return "dsaEncryption"
|
||||
case x509.ECDSA:
|
||||
return "id-ecPublicKey"
|
||||
default:
|
||||
return strconv.Itoa(int(algo))
|
||||
}
|
||||
}
|
||||
|
||||
// appendHexData adds a hex dump of binary data to buf, with line breaks
|
||||
// after each set of count bytes, and with each new line prefixed with the
|
||||
// given prefix.
|
||||
func appendHexData(buf *bytes.Buffer, data []byte, count int, prefix string) {
|
||||
for ii, byte := range data {
|
||||
if ii%count == 0 {
|
||||
if ii > 0 {
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
buf.WriteString(prefix)
|
||||
}
|
||||
buf.WriteString(fmt.Sprintf("%02x:", byte))
|
||||
}
|
||||
}
|
||||
|
||||
func curveOIDToString(oid asn1.ObjectIdentifier) (t string, bitlen int) {
|
||||
switch {
|
||||
case oid.Equal(x509.OIDNamedCurveP224):
|
||||
return "secp224r1", 224
|
||||
case oid.Equal(x509.OIDNamedCurveP256):
|
||||
return "prime256v1", 256
|
||||
case oid.Equal(x509.OIDNamedCurveP384):
|
||||
return "secp384r1", 384
|
||||
case oid.Equal(x509.OIDNamedCurveP521):
|
||||
return "secp521r1", 521
|
||||
}
|
||||
return fmt.Sprintf("%v", oid), -1
|
||||
}
|
||||
|
||||
func publicKeyToString(algo x509.PublicKeyAlgorithm, pub interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
switch pub := pub.(type) {
|
||||
case *rsa.PublicKey:
|
||||
bitlen := pub.N.BitLen()
|
||||
buf.WriteString(fmt.Sprintf(" Public Key: (%d bit)\n", bitlen))
|
||||
buf.WriteString(" Modulus:\n")
|
||||
data := pub.N.Bytes()
|
||||
appendHexData(&buf, data, 15, " ")
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString(fmt.Sprintf(" Exponent: %d (0x%x)", pub.E, pub.E))
|
||||
case *dsa.PublicKey:
|
||||
buf.WriteString(" pub:\n")
|
||||
appendHexData(&buf, pub.Y.Bytes(), 15, " ")
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString(" P:\n")
|
||||
appendHexData(&buf, pub.P.Bytes(), 15, " ")
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString(" Q:\n")
|
||||
appendHexData(&buf, pub.Q.Bytes(), 15, " ")
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString(" G:\n")
|
||||
appendHexData(&buf, pub.G.Bytes(), 15, " ")
|
||||
case *ecdsa.PublicKey:
|
||||
data := elliptic.Marshal(pub.Curve, pub.X, pub.Y)
|
||||
oid, ok := x509.OIDFromNamedCurve(pub.Curve)
|
||||
if !ok {
|
||||
return " <unsupported elliptic curve>"
|
||||
}
|
||||
oidname, bitlen := curveOIDToString(oid)
|
||||
buf.WriteString(fmt.Sprintf(" Public Key: (%d bit)\n", bitlen))
|
||||
buf.WriteString(" pub:\n")
|
||||
appendHexData(&buf, data, 15, " ")
|
||||
buf.WriteString("\n")
|
||||
buf.WriteString(fmt.Sprintf(" ASN1 OID: %s", oidname))
|
||||
default:
|
||||
buf.WriteString(fmt.Sprintf("%v", pub))
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func commaAppend(buf *bytes.Buffer, s string) {
|
||||
if buf.Len() > 0 {
|
||||
buf.WriteString(", ")
|
||||
}
|
||||
buf.WriteString(s)
|
||||
}
|
||||
|
||||
func keyUsageToString(k x509.KeyUsage) string {
|
||||
var buf bytes.Buffer
|
||||
if k&x509.KeyUsageDigitalSignature != 0 {
|
||||
commaAppend(&buf, "Digital Signature")
|
||||
}
|
||||
if k&x509.KeyUsageContentCommitment != 0 {
|
||||
commaAppend(&buf, "Content Commitment")
|
||||
}
|
||||
if k&x509.KeyUsageKeyEncipherment != 0 {
|
||||
commaAppend(&buf, "Key Encipherment")
|
||||
}
|
||||
if k&x509.KeyUsageDataEncipherment != 0 {
|
||||
commaAppend(&buf, "Data Encipherment")
|
||||
}
|
||||
if k&x509.KeyUsageKeyAgreement != 0 {
|
||||
commaAppend(&buf, "Key Agreement")
|
||||
}
|
||||
if k&x509.KeyUsageCertSign != 0 {
|
||||
commaAppend(&buf, "Certificate Signing")
|
||||
}
|
||||
if k&x509.KeyUsageCRLSign != 0 {
|
||||
commaAppend(&buf, "CRL Signing")
|
||||
}
|
||||
if k&x509.KeyUsageEncipherOnly != 0 {
|
||||
commaAppend(&buf, "Encipher Only")
|
||||
}
|
||||
if k&x509.KeyUsageDecipherOnly != 0 {
|
||||
commaAppend(&buf, "Decipher Only")
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
func extKeyUsageToString(u x509.ExtKeyUsage) string {
|
||||
switch u {
|
||||
case x509.ExtKeyUsageAny:
|
||||
return "Any"
|
||||
case x509.ExtKeyUsageServerAuth:
|
||||
return "TLS Web server authentication"
|
||||
case x509.ExtKeyUsageClientAuth:
|
||||
return "TLS Web client authentication"
|
||||
case x509.ExtKeyUsageCodeSigning:
|
||||
return "Signing of executable code"
|
||||
case x509.ExtKeyUsageEmailProtection:
|
||||
return "Email protection"
|
||||
case x509.ExtKeyUsageIPSECEndSystem:
|
||||
return "IPSEC end system"
|
||||
case x509.ExtKeyUsageIPSECTunnel:
|
||||
return "IPSEC tunnel"
|
||||
case x509.ExtKeyUsageIPSECUser:
|
||||
return "IPSEC user"
|
||||
case x509.ExtKeyUsageTimeStamping:
|
||||
return "Time stamping"
|
||||
case x509.ExtKeyUsageOCSPSigning:
|
||||
return "OCSP signing"
|
||||
case x509.ExtKeyUsageMicrosoftServerGatedCrypto:
|
||||
return "Microsoft server gated cryptography"
|
||||
case x509.ExtKeyUsageNetscapeServerGatedCrypto:
|
||||
return "Netscape server gated cryptography"
|
||||
case x509.ExtKeyUsageCertificateTransparency:
|
||||
return "Certificate transparency"
|
||||
default:
|
||||
return "Unknown"
|
||||
}
|
||||
}
|
||||
|
||||
func attributeOIDToString(oid asn1.ObjectIdentifier) string {
|
||||
switch {
|
||||
case oid.Equal(pkix.OIDCountry):
|
||||
return "Country"
|
||||
case oid.Equal(pkix.OIDOrganization):
|
||||
return "Organization"
|
||||
case oid.Equal(pkix.OIDOrganizationalUnit):
|
||||
return "OrganizationalUnit"
|
||||
case oid.Equal(pkix.OIDCommonName):
|
||||
return "CommonName"
|
||||
case oid.Equal(pkix.OIDSerialNumber):
|
||||
return "SerialNumber"
|
||||
case oid.Equal(pkix.OIDLocality):
|
||||
return "Locality"
|
||||
case oid.Equal(pkix.OIDProvince):
|
||||
return "Province"
|
||||
case oid.Equal(pkix.OIDStreetAddress):
|
||||
return "StreetAddress"
|
||||
case oid.Equal(pkix.OIDPostalCode):
|
||||
return "PostalCode"
|
||||
case oid.Equal(pkix.OIDPseudonym):
|
||||
return "Pseudonym"
|
||||
case oid.Equal(pkix.OIDTitle):
|
||||
return "Title"
|
||||
case oid.Equal(pkix.OIDDnQualifier):
|
||||
return "DnQualifier"
|
||||
case oid.Equal(pkix.OIDName):
|
||||
return "Name"
|
||||
case oid.Equal(pkix.OIDSurname):
|
||||
return "Surname"
|
||||
case oid.Equal(pkix.OIDGivenName):
|
||||
return "GivenName"
|
||||
case oid.Equal(pkix.OIDInitials):
|
||||
return "Initials"
|
||||
case oid.Equal(pkix.OIDGenerationQualifier):
|
||||
return "GenerationQualifier"
|
||||
default:
|
||||
return oid.String()
|
||||
}
|
||||
}
|
||||
|
||||
// NameToString creates a string description of a pkix.Name object.
|
||||
func NameToString(name pkix.Name) string {
|
||||
var result bytes.Buffer
|
||||
addSingle := func(prefix, item string) {
|
||||
if len(item) == 0 {
|
||||
return
|
||||
}
|
||||
commaAppend(&result, prefix)
|
||||
result.WriteString(item)
|
||||
}
|
||||
addList := func(prefix string, items []string) {
|
||||
for _, item := range items {
|
||||
addSingle(prefix, item)
|
||||
}
|
||||
}
|
||||
addList("C=", name.Country)
|
||||
addList("O=", name.Organization)
|
||||
addList("OU=", name.OrganizationalUnit)
|
||||
addList("L=", name.Locality)
|
||||
addList("ST=", name.Province)
|
||||
addList("streetAddress=", name.StreetAddress)
|
||||
addList("postalCode=", name.PostalCode)
|
||||
addSingle("serialNumber=", name.SerialNumber)
|
||||
addSingle("CN=", name.CommonName)
|
||||
for _, atv := range name.Names {
|
||||
value, ok := atv.Value.(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
t := atv.Type
|
||||
// All of the defined attribute OIDs are of the form 2.5.4.N, and OIDAttribute is
|
||||
// the 2.5.4 prefix ('id-at' in RFC 5280).
|
||||
if len(t) == 4 && t[0] == pkix.OIDAttribute[0] && t[1] == pkix.OIDAttribute[1] && t[2] == pkix.OIDAttribute[2] {
|
||||
// OID is 'id-at N', so check the final value to figure out which attribute.
|
||||
switch t[3] {
|
||||
case pkix.OIDCommonName[3], pkix.OIDSerialNumber[3], pkix.OIDCountry[3], pkix.OIDLocality[3], pkix.OIDProvince[3],
|
||||
pkix.OIDStreetAddress[3], pkix.OIDOrganization[3], pkix.OIDOrganizationalUnit[3], pkix.OIDPostalCode[3]:
|
||||
continue // covered by explicit fields
|
||||
case pkix.OIDPseudonym[3]:
|
||||
addSingle("pseudonym=", value)
|
||||
continue
|
||||
case pkix.OIDTitle[3]:
|
||||
addSingle("title=", value)
|
||||
continue
|
||||
case pkix.OIDDnQualifier[3]:
|
||||
addSingle("dnQualifier=", value)
|
||||
continue
|
||||
case pkix.OIDName[3]:
|
||||
addSingle("name=", value)
|
||||
continue
|
||||
case pkix.OIDSurname[3]:
|
||||
addSingle("surname=", value)
|
||||
continue
|
||||
case pkix.OIDGivenName[3]:
|
||||
addSingle("givenName=", value)
|
||||
continue
|
||||
case pkix.OIDInitials[3]:
|
||||
addSingle("initials=", value)
|
||||
continue
|
||||
case pkix.OIDGenerationQualifier[3]:
|
||||
addSingle("generationQualifier=", value)
|
||||
continue
|
||||
}
|
||||
}
|
||||
addSingle(t.String()+"=", value)
|
||||
}
|
||||
return result.String()
|
||||
}
|
||||
|
||||
// OtherNameToString creates a string description of an x509.OtherName object.
|
||||
func OtherNameToString(other x509.OtherName) string {
|
||||
return fmt.Sprintf("%v=%v", other.TypeID, hex.EncodeToString(other.Value.Bytes))
|
||||
}
|
||||
|
||||
// GeneralNamesToString creates a string description of an x509.GeneralNames object.
|
||||
func GeneralNamesToString(gname *x509.GeneralNames) string {
|
||||
var buf bytes.Buffer
|
||||
for _, name := range gname.DNSNames {
|
||||
commaAppend(&buf, "DNS:"+name)
|
||||
}
|
||||
for _, email := range gname.EmailAddresses {
|
||||
commaAppend(&buf, "email:"+email)
|
||||
}
|
||||
for _, name := range gname.DirectoryNames {
|
||||
commaAppend(&buf, "DirName:"+NameToString(name))
|
||||
}
|
||||
for _, uri := range gname.URIs {
|
||||
commaAppend(&buf, "URI:"+uri)
|
||||
}
|
||||
for _, ip := range gname.IPNets {
|
||||
if ip.Mask == nil {
|
||||
commaAppend(&buf, "IP Address:"+ip.IP.String())
|
||||
} else {
|
||||
commaAppend(&buf, "IP Address:"+ip.IP.String()+"/"+ip.Mask.String())
|
||||
}
|
||||
}
|
||||
for _, id := range gname.RegisteredIDs {
|
||||
commaAppend(&buf, "Registered ID:"+id.String())
|
||||
}
|
||||
for _, other := range gname.OtherNames {
|
||||
commaAppend(&buf, "othername:"+OtherNameToString(other))
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// CertificateToString generates a string describing the given certificate.
|
||||
// The output roughly resembles that from openssl x509 -text.
|
||||
func CertificateToString(cert *x509.Certificate) string {
|
||||
var result bytes.Buffer
|
||||
result.WriteString(fmt.Sprintf("Certificate:\n"))
|
||||
result.WriteString(fmt.Sprintf(" Data:\n"))
|
||||
result.WriteString(fmt.Sprintf(" Version: %d (%#x)\n", cert.Version, cert.Version-1))
|
||||
result.WriteString(fmt.Sprintf(" Serial Number: %d (%#[1]x)\n", cert.SerialNumber))
|
||||
result.WriteString(fmt.Sprintf(" Signature Algorithm: %v\n", cert.SignatureAlgorithm))
|
||||
result.WriteString(fmt.Sprintf(" Issuer: %v\n", NameToString(cert.Issuer)))
|
||||
result.WriteString(fmt.Sprintf(" Validity:\n"))
|
||||
result.WriteString(fmt.Sprintf(" Not Before: %v\n", cert.NotBefore))
|
||||
result.WriteString(fmt.Sprintf(" Not After : %v\n", cert.NotAfter))
|
||||
result.WriteString(fmt.Sprintf(" Subject: %v\n", NameToString(cert.Subject)))
|
||||
result.WriteString(fmt.Sprintf(" Subject Public Key Info:\n"))
|
||||
result.WriteString(fmt.Sprintf(" Public Key Algorithm: %v\n", publicKeyAlgorithmToString(cert.PublicKeyAlgorithm)))
|
||||
result.WriteString(fmt.Sprintf("%v\n", publicKeyToString(cert.PublicKeyAlgorithm, cert.PublicKey)))
|
||||
|
||||
if len(cert.Extensions) > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 extensions:\n"))
|
||||
}
|
||||
// First display the extensions that are already cracked out
|
||||
showAuthKeyID(&result, cert)
|
||||
showSubjectKeyID(&result, cert)
|
||||
showKeyUsage(&result, cert)
|
||||
showExtendedKeyUsage(&result, cert)
|
||||
showBasicConstraints(&result, cert)
|
||||
showSubjectAltName(&result, cert)
|
||||
showNameConstraints(&result, cert)
|
||||
showCertPolicies(&result, cert)
|
||||
showCRLDPs(&result, cert)
|
||||
showAuthInfoAccess(&result, cert)
|
||||
showCTPoison(&result, cert)
|
||||
showCTSCT(&result, cert)
|
||||
showCTLogSTHInfo(&result, cert)
|
||||
|
||||
showUnhandledExtensions(&result, cert)
|
||||
showSignature(&result, cert)
|
||||
|
||||
return result.String()
|
||||
}
|
||||
|
||||
func showCritical(result *bytes.Buffer, critical bool) {
|
||||
if critical {
|
||||
result.WriteString(" critical")
|
||||
}
|
||||
result.WriteString("\n")
|
||||
}
|
||||
|
||||
func showAuthKeyID(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionAuthorityKeyId, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Authority Key Identifier:"))
|
||||
showCritical(result, critical)
|
||||
result.WriteString(fmt.Sprintf(" keyid:%v\n", hex.EncodeToString(cert.AuthorityKeyId)))
|
||||
}
|
||||
}
|
||||
|
||||
func showSubjectKeyID(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionSubjectKeyId, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Subject Key Identifier:"))
|
||||
showCritical(result, critical)
|
||||
result.WriteString(fmt.Sprintf(" keyid:%v\n", hex.EncodeToString(cert.SubjectKeyId)))
|
||||
}
|
||||
}
|
||||
|
||||
func showKeyUsage(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionKeyUsage, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Key Usage:"))
|
||||
showCritical(result, critical)
|
||||
result.WriteString(fmt.Sprintf(" %v\n", keyUsageToString(cert.KeyUsage)))
|
||||
}
|
||||
}
|
||||
|
||||
func showExtendedKeyUsage(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionExtendedKeyUsage, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Extended Key Usage:"))
|
||||
showCritical(result, critical)
|
||||
var usages bytes.Buffer
|
||||
for _, usage := range cert.ExtKeyUsage {
|
||||
commaAppend(&usages, extKeyUsageToString(usage))
|
||||
}
|
||||
for _, oid := range cert.UnknownExtKeyUsage {
|
||||
commaAppend(&usages, oid.String())
|
||||
}
|
||||
result.WriteString(fmt.Sprintf(" %v\n", usages.String()))
|
||||
}
|
||||
}
|
||||
|
||||
func showBasicConstraints(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionBasicConstraints, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Basic Constraints:"))
|
||||
showCritical(result, critical)
|
||||
result.WriteString(fmt.Sprintf(" CA:%t", cert.IsCA))
|
||||
if cert.MaxPathLen > 0 || cert.MaxPathLenZero {
|
||||
result.WriteString(fmt.Sprintf(", pathlen:%d", cert.MaxPathLen))
|
||||
}
|
||||
result.WriteString(fmt.Sprintf("\n"))
|
||||
}
|
||||
}
|
||||
|
||||
func showSubjectAltName(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionSubjectAltName, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Subject Alternative Name:"))
|
||||
showCritical(result, critical)
|
||||
var buf bytes.Buffer
|
||||
for _, name := range cert.DNSNames {
|
||||
commaAppend(&buf, "DNS:"+name)
|
||||
}
|
||||
for _, email := range cert.EmailAddresses {
|
||||
commaAppend(&buf, "email:"+email)
|
||||
}
|
||||
for _, ip := range cert.IPAddresses {
|
||||
commaAppend(&buf, "IP Address:"+ip.String())
|
||||
}
|
||||
|
||||
result.WriteString(fmt.Sprintf(" %v\n", buf.String()))
|
||||
// TODO(drysdale): include other name forms
|
||||
}
|
||||
}
|
||||
|
||||
func showNameConstraints(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionNameConstraints, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Name Constraints:"))
|
||||
showCritical(result, critical)
|
||||
if len(cert.PermittedDNSDomains) > 0 {
|
||||
result.WriteString(fmt.Sprintf(" Permitted:\n"))
|
||||
var buf bytes.Buffer
|
||||
for _, name := range cert.PermittedDNSDomains {
|
||||
commaAppend(&buf, "DNS:"+name)
|
||||
}
|
||||
result.WriteString(fmt.Sprintf(" %v\n", buf.String()))
|
||||
}
|
||||
// TODO(drysdale): include other name forms
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func showCertPolicies(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionCertificatePolicies, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 Certificate Policies:"))
|
||||
showCritical(result, critical)
|
||||
for _, oid := range cert.PolicyIdentifiers {
|
||||
result.WriteString(fmt.Sprintf(" Policy: %v\n", oid.String()))
|
||||
// TODO(drysdale): Display any qualifiers associated with the policy
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func showCRLDPs(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionCRLDistributionPoints, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" X509v3 CRL Distribution Points:"))
|
||||
showCritical(result, critical)
|
||||
result.WriteString(fmt.Sprintf(" Full Name:\n"))
|
||||
var buf bytes.Buffer
|
||||
for _, pt := range cert.CRLDistributionPoints {
|
||||
commaAppend(&buf, "URI:"+pt)
|
||||
}
|
||||
result.WriteString(fmt.Sprintf(" %v\n", buf.String()))
|
||||
// TODO(drysdale): Display other GeneralNames types, plus issuer/reasons/relative-name
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func showAuthInfoAccess(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionAuthorityInfoAccess, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" Authority Information Access:"))
|
||||
showCritical(result, critical)
|
||||
var issuerBuf bytes.Buffer
|
||||
for _, issuer := range cert.IssuingCertificateURL {
|
||||
commaAppend(&issuerBuf, "URI:"+issuer)
|
||||
}
|
||||
if issuerBuf.Len() > 0 {
|
||||
result.WriteString(fmt.Sprintf(" CA Issuers - %v\n", issuerBuf.String()))
|
||||
}
|
||||
var ocspBuf bytes.Buffer
|
||||
for _, ocsp := range cert.OCSPServer {
|
||||
commaAppend(&ocspBuf, "URI:"+ocsp)
|
||||
}
|
||||
if ocspBuf.Len() > 0 {
|
||||
result.WriteString(fmt.Sprintf(" OCSP - %v\n", ocspBuf.String()))
|
||||
}
|
||||
// TODO(drysdale): Display other GeneralNames types
|
||||
}
|
||||
}
|
||||
|
||||
func showCTPoison(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionCTPoison, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" RFC6962 Pre-Certificate Poison:"))
|
||||
showCritical(result, critical)
|
||||
result.WriteString(" .....\n")
|
||||
}
|
||||
}
|
||||
|
||||
func showCTSCT(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509.OIDExtensionCTSCT, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" RFC6962 Certificate Transparency SCT:"))
|
||||
showCritical(result, critical)
|
||||
for i, sctData := range cert.SCTList.SCTList {
|
||||
result.WriteString(fmt.Sprintf(" SCT [%d]:\n", i))
|
||||
var sct ct.SignedCertificateTimestamp
|
||||
_, err := tls.Unmarshal(sctData.Val, &sct)
|
||||
if err != nil {
|
||||
appendHexData(result, sctData.Val, 16, " ")
|
||||
result.WriteString("\n")
|
||||
continue
|
||||
}
|
||||
result.WriteString(fmt.Sprintf(" Version: %d\n", sct.SCTVersion))
|
||||
result.WriteString(fmt.Sprintf(" LogID: %s\n", base64.StdEncoding.EncodeToString(sct.LogID.KeyID[:])))
|
||||
result.WriteString(fmt.Sprintf(" Timestamp: %d\n", sct.Timestamp))
|
||||
result.WriteString(fmt.Sprintf(" Signature: %s\n", sct.Signature.Algorithm))
|
||||
result.WriteString(fmt.Sprintf(" Signature:\n"))
|
||||
appendHexData(result, sct.Signature.Signature, 16, " ")
|
||||
result.WriteString("\n")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func showCTLogSTHInfo(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
count, critical := OIDInExtensions(x509ext.OIDExtensionCTSTH, cert.Extensions)
|
||||
if count > 0 {
|
||||
result.WriteString(fmt.Sprintf(" Certificate Transparency STH:"))
|
||||
showCritical(result, critical)
|
||||
sthInfo, err := x509ext.LogSTHInfoFromCert(cert)
|
||||
if err != nil {
|
||||
result.WriteString(fmt.Sprintf(" Failed to decode STH:\n"))
|
||||
return
|
||||
}
|
||||
result.WriteString(fmt.Sprintf(" LogURL: %s\n", string(sthInfo.LogURL)))
|
||||
result.WriteString(fmt.Sprintf(" Version: %d\n", sthInfo.Version))
|
||||
result.WriteString(fmt.Sprintf(" TreeSize: %d\n", sthInfo.TreeSize))
|
||||
result.WriteString(fmt.Sprintf(" Timestamp: %d\n", sthInfo.Timestamp))
|
||||
result.WriteString(fmt.Sprintf(" RootHash:\n"))
|
||||
appendHexData(result, sthInfo.SHA256RootHash[:], 16, " ")
|
||||
result.WriteString("\n")
|
||||
result.WriteString(fmt.Sprintf(" TreeHeadSignature: %s\n", sthInfo.TreeHeadSignature.Algorithm))
|
||||
result.WriteString(fmt.Sprintf(" TreeHeadSignature:\n"))
|
||||
appendHexData(result, sthInfo.TreeHeadSignature.Signature, 16, " ")
|
||||
result.WriteString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
func showUnhandledExtensions(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
for _, ext := range cert.Extensions {
|
||||
// Skip extensions that are already cracked out
|
||||
if oidAlreadyPrinted(ext.Id) {
|
||||
continue
|
||||
}
|
||||
result.WriteString(fmt.Sprintf(" %v:", ext.Id))
|
||||
showCritical(result, ext.Critical)
|
||||
appendHexData(result, ext.Value, 16, " ")
|
||||
result.WriteString("\n")
|
||||
}
|
||||
}
|
||||
|
||||
func showSignature(result *bytes.Buffer, cert *x509.Certificate) {
|
||||
result.WriteString(fmt.Sprintf(" Signature Algorithm: %v\n", cert.SignatureAlgorithm))
|
||||
appendHexData(result, cert.Signature, 18, " ")
|
||||
result.WriteString("\n")
|
||||
}
|
||||
|
||||
// TODO(drysdale): remove this once all standard OIDs are parsed and printed.
|
||||
func oidAlreadyPrinted(oid asn1.ObjectIdentifier) bool {
|
||||
if oid.Equal(x509.OIDExtensionSubjectKeyId) ||
|
||||
oid.Equal(x509.OIDExtensionKeyUsage) ||
|
||||
oid.Equal(x509.OIDExtensionExtendedKeyUsage) ||
|
||||
oid.Equal(x509.OIDExtensionAuthorityKeyId) ||
|
||||
oid.Equal(x509.OIDExtensionBasicConstraints) ||
|
||||
oid.Equal(x509.OIDExtensionSubjectAltName) ||
|
||||
oid.Equal(x509.OIDExtensionCertificatePolicies) ||
|
||||
oid.Equal(x509.OIDExtensionNameConstraints) ||
|
||||
oid.Equal(x509.OIDExtensionCRLDistributionPoints) ||
|
||||
oid.Equal(x509.OIDExtensionAuthorityInfoAccess) ||
|
||||
oid.Equal(x509.OIDExtensionCTPoison) ||
|
||||
oid.Equal(x509.OIDExtensionCTSCT) ||
|
||||
oid.Equal(x509ext.OIDExtensionCTSTH) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// CertificateFromPEM takes a certificate in PEM format and returns the
|
||||
// corresponding x509.Certificate object.
|
||||
func CertificateFromPEM(pemBytes []byte) (*x509.Certificate, error) {
|
||||
block, rest := pem.Decode(pemBytes)
|
||||
if len(rest) != 0 {
|
||||
return nil, errors.New("trailing data found after PEM block")
|
||||
}
|
||||
if block == nil {
|
||||
return nil, errors.New("PEM block is nil")
|
||||
}
|
||||
if block.Type != "CERTIFICATE" {
|
||||
return nil, errors.New("PEM block is not a CERTIFICATE")
|
||||
}
|
||||
return x509.ParseCertificate(block.Bytes)
|
||||
}
|
||||
|
||||
// CertificatesFromPEM parses one or more certificates from the given PEM data.
|
||||
// The PEM certificates must be concatenated. This function can be used for
|
||||
// parsing PEM-formatted certificate chains, but does not verify that the
|
||||
// resulting chain is a valid certificate chain.
|
||||
func CertificatesFromPEM(pemBytes []byte) ([]*x509.Certificate, error) {
|
||||
var chain []*x509.Certificate
|
||||
for {
|
||||
var block *pem.Block
|
||||
block, pemBytes = pem.Decode(pemBytes)
|
||||
if block == nil {
|
||||
return chain, nil
|
||||
}
|
||||
if block.Type != "CERTIFICATE" {
|
||||
return nil, fmt.Errorf("PEM block is not a CERTIFICATE")
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
return nil, errors.New("failed to parse certificate")
|
||||
}
|
||||
chain = append(chain, cert)
|
||||
}
|
||||
}
|
||||
|
||||
// ParseSCTsFromSCTList parses each of the SCTs contained within an SCT list.
|
||||
func ParseSCTsFromSCTList(sctList *x509.SignedCertificateTimestampList) ([]*ct.SignedCertificateTimestamp, error) {
|
||||
var scts []*ct.SignedCertificateTimestamp
|
||||
for i, data := range sctList.SCTList {
|
||||
sct, err := ExtractSCT(&data)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error extracting SCT number %d: %s", i, err)
|
||||
}
|
||||
scts = append(scts, sct)
|
||||
}
|
||||
return scts, nil
|
||||
}
|
||||
|
||||
// ExtractSCT deserializes an SCT from a TLS-encoded SCT.
|
||||
func ExtractSCT(sctData *x509.SerializedSCT) (*ct.SignedCertificateTimestamp, error) {
|
||||
if sctData == nil {
|
||||
return nil, errors.New("SCT is nil")
|
||||
}
|
||||
var sct ct.SignedCertificateTimestamp
|
||||
if rest, err := tls.Unmarshal(sctData.Val, &sct); err != nil {
|
||||
return nil, fmt.Errorf("error parsing SCT: %s", err)
|
||||
} else if len(rest) > 0 {
|
||||
return nil, fmt.Errorf("extra data (%d bytes) after serialized SCT", len(rest))
|
||||
}
|
||||
return &sct, nil
|
||||
}
|
||||
|
||||
var pemCertificatePrefix = []byte("-----BEGIN CERTIFICATE")
|
||||
|
||||
// ParseSCTsFromCertificate parses any SCTs that are embedded in the
|
||||
// certificate provided. The certificate bytes provided can be either DER or
|
||||
// PEM, provided the PEM data starts with the PEM block marker (i.e. has no
|
||||
// leading text).
|
||||
func ParseSCTsFromCertificate(certBytes []byte) ([]*ct.SignedCertificateTimestamp, error) {
|
||||
var cert *x509.Certificate
|
||||
var err error
|
||||
if bytes.HasPrefix(certBytes, pemCertificatePrefix) {
|
||||
cert, err = CertificateFromPEM(certBytes)
|
||||
} else {
|
||||
cert, err = x509.ParseCertificate(certBytes)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse certificate: %s", err)
|
||||
}
|
||||
return ParseSCTsFromSCTList(&cert.SCTList)
|
||||
}
|
Reference in New Issue
Block a user