chore: update vendor
This commit is contained in:
3
vendor/github.com/google/certificate-transparency-go/.gitignore
generated
vendored
3
vendor/github.com/google/certificate-transparency-go/.gitignore
generated
vendored
@ -16,9 +16,12 @@
|
||||
/data
|
||||
/dumpscts
|
||||
/etcdiscover
|
||||
/findlog
|
||||
/gossip_server
|
||||
/preloader
|
||||
/scanlog
|
||||
/sctcheck
|
||||
/sctscan
|
||||
/trillian_log_server
|
||||
/trillian_log_signer
|
||||
/trillian.json
|
||||
|
28
vendor/github.com/google/certificate-transparency-go/.travis.yml
generated
vendored
28
vendor/github.com/google/certificate-transparency-go/.travis.yml
generated
vendored
@ -1,23 +1,23 @@
|
||||
sudo: false
|
||||
sudo: true # required for CI push into Kubernetes.
|
||||
language: go
|
||||
os: linux
|
||||
go: 1.9
|
||||
|
||||
go_import_path: github.com/google/certificate-transparency-go
|
||||
|
||||
env:
|
||||
- GOFLAGS=
|
||||
- GCE_CI=${ENABLE_GCE_CI} GOFLAGS=
|
||||
- GOFLAGS=-race
|
||||
- GOFLAGS= WITH_ETCD=true
|
||||
- GOFLAGS= WITH_ETCD=true WITH_COVERAGE=true
|
||||
- GOFLAGS=-race WITH_ETCD=true
|
||||
|
||||
matrix:
|
||||
fast_finish: true
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
install:
|
||||
- |
|
||||
if [ ! -d $HOME/gopath/src/github.com/google ]; then
|
||||
mkdir -p $HOME/gopath/src/github.com/google
|
||||
ln -s $TRAVIS_BUILD_DIR $HOME/gopath/src/github.com/google/certificate-transparency-go
|
||||
fi
|
||||
- mkdir ../protoc
|
||||
- |
|
||||
(
|
||||
@ -41,9 +41,8 @@ install:
|
||||
|
||||
script:
|
||||
- set -e
|
||||
- export TRILLIAN_SQL_DRIVER=mysql
|
||||
- cd $HOME/gopath/src/github.com/google/certificate-transparency-go
|
||||
- ./scripts/presubmit.sh ${PRESUBMIT_OPTS}
|
||||
- ./scripts/presubmit.sh ${PRESUBMIT_OPTS} ${WITH_COVERAGE:+--coverage}
|
||||
- |
|
||||
# Check re-generation didn't change anything
|
||||
status=$(git status --porcelain | grep -v coverage) || :
|
||||
@ -64,3 +63,12 @@ script:
|
||||
after_success:
|
||||
- cp /tmp/coverage.txt .
|
||||
- bash <(curl -s https://codecov.io/bash)
|
||||
- |
|
||||
# Push up to GCE CI instance if we're running after a merge to master
|
||||
if [[ "${GCE_CI}" == "true" ]] && [[ $TRAVIS_PULL_REQUEST == "false" ]] && [[ $TRAVIS_BRANCH == "master" ]]; then
|
||||
. scripts/install_cloud.sh
|
||||
echo ${GCLOUD_SERVICE_KEY_CI} | base64 --decode -i > ${HOME}/gcloud-service-key.json
|
||||
gcloud auth activate-service-account --key-file ${HOME}/gcloud-service-key.json
|
||||
rm ${HOME}/gcloud-service-key.json
|
||||
. scripts/deploy_gce_ci.sh
|
||||
fi
|
||||
|
86
vendor/github.com/google/certificate-transparency-go/client/configpb/multilog.pb.go
generated
vendored
86
vendor/github.com/google/certificate-transparency-go/client/configpb/multilog.pb.go
generated
vendored
@ -1,22 +1,12 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: multilog.proto
|
||||
|
||||
/*
|
||||
Package configpb is a generated protocol buffer package.
|
||||
|
||||
It is generated from these files:
|
||||
multilog.proto
|
||||
|
||||
It has these top-level messages:
|
||||
TemporalLogConfig
|
||||
LogShardConfig
|
||||
*/
|
||||
package configpb
|
||||
|
||||
import proto "github.com/golang/protobuf/proto"
|
||||
import fmt "fmt"
|
||||
import math "math"
|
||||
import google_protobuf "github.com/golang/protobuf/ptypes/timestamp"
|
||||
import timestamp "github.com/golang/protobuf/ptypes/timestamp"
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
@ -32,13 +22,35 @@ const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
|
||||
// TemporalLogConfig is a set of LogShardConfig messages, whose
|
||||
// time limits should be contiguous.
|
||||
type TemporalLogConfig struct {
|
||||
Shard []*LogShardConfig `protobuf:"bytes,1,rep,name=shard" json:"shard,omitempty"`
|
||||
Shard []*LogShardConfig `protobuf:"bytes,1,rep,name=shard" json:"shard,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *TemporalLogConfig) Reset() { *m = TemporalLogConfig{} }
|
||||
func (m *TemporalLogConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*TemporalLogConfig) ProtoMessage() {}
|
||||
func (*TemporalLogConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
|
||||
func (m *TemporalLogConfig) Reset() { *m = TemporalLogConfig{} }
|
||||
func (m *TemporalLogConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*TemporalLogConfig) ProtoMessage() {}
|
||||
func (*TemporalLogConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_multilog_3c9b797b88da6f07, []int{0}
|
||||
}
|
||||
func (m *TemporalLogConfig) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_TemporalLogConfig.Unmarshal(m, b)
|
||||
}
|
||||
func (m *TemporalLogConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_TemporalLogConfig.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *TemporalLogConfig) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_TemporalLogConfig.Merge(dst, src)
|
||||
}
|
||||
func (m *TemporalLogConfig) XXX_Size() int {
|
||||
return xxx_messageInfo_TemporalLogConfig.Size(m)
|
||||
}
|
||||
func (m *TemporalLogConfig) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_TemporalLogConfig.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_TemporalLogConfig proto.InternalMessageInfo
|
||||
|
||||
func (m *TemporalLogConfig) GetShard() []*LogShardConfig {
|
||||
if m != nil {
|
||||
@ -56,17 +68,39 @@ type LogShardConfig struct {
|
||||
// not_after_start defines the start of the range of acceptable NotAfter
|
||||
// values, inclusive.
|
||||
// Leaving this unset implies no lower bound to the range.
|
||||
NotAfterStart *google_protobuf.Timestamp `protobuf:"bytes,3,opt,name=not_after_start,json=notAfterStart" json:"not_after_start,omitempty"`
|
||||
NotAfterStart *timestamp.Timestamp `protobuf:"bytes,3,opt,name=not_after_start,json=notAfterStart" json:"not_after_start,omitempty"`
|
||||
// not_after_limit defines the end of the range of acceptable NotAfter values,
|
||||
// exclusive.
|
||||
// Leaving this unset implies no upper bound to the range.
|
||||
NotAfterLimit *google_protobuf.Timestamp `protobuf:"bytes,4,opt,name=not_after_limit,json=notAfterLimit" json:"not_after_limit,omitempty"`
|
||||
NotAfterLimit *timestamp.Timestamp `protobuf:"bytes,4,opt,name=not_after_limit,json=notAfterLimit" json:"not_after_limit,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *LogShardConfig) Reset() { *m = LogShardConfig{} }
|
||||
func (m *LogShardConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*LogShardConfig) ProtoMessage() {}
|
||||
func (*LogShardConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
|
||||
func (m *LogShardConfig) Reset() { *m = LogShardConfig{} }
|
||||
func (m *LogShardConfig) String() string { return proto.CompactTextString(m) }
|
||||
func (*LogShardConfig) ProtoMessage() {}
|
||||
func (*LogShardConfig) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_multilog_3c9b797b88da6f07, []int{1}
|
||||
}
|
||||
func (m *LogShardConfig) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_LogShardConfig.Unmarshal(m, b)
|
||||
}
|
||||
func (m *LogShardConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_LogShardConfig.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (dst *LogShardConfig) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_LogShardConfig.Merge(dst, src)
|
||||
}
|
||||
func (m *LogShardConfig) XXX_Size() int {
|
||||
return xxx_messageInfo_LogShardConfig.Size(m)
|
||||
}
|
||||
func (m *LogShardConfig) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_LogShardConfig.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_LogShardConfig proto.InternalMessageInfo
|
||||
|
||||
func (m *LogShardConfig) GetUri() string {
|
||||
if m != nil {
|
||||
@ -82,14 +116,14 @@ func (m *LogShardConfig) GetPublicKeyDer() []byte {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *LogShardConfig) GetNotAfterStart() *google_protobuf.Timestamp {
|
||||
func (m *LogShardConfig) GetNotAfterStart() *timestamp.Timestamp {
|
||||
if m != nil {
|
||||
return m.NotAfterStart
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *LogShardConfig) GetNotAfterLimit() *google_protobuf.Timestamp {
|
||||
func (m *LogShardConfig) GetNotAfterLimit() *timestamp.Timestamp {
|
||||
if m != nil {
|
||||
return m.NotAfterLimit
|
||||
}
|
||||
@ -101,9 +135,9 @@ func init() {
|
||||
proto.RegisterType((*LogShardConfig)(nil), "configpb.LogShardConfig")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("multilog.proto", fileDescriptor0) }
|
||||
func init() { proto.RegisterFile("multilog.proto", fileDescriptor_multilog_3c9b797b88da6f07) }
|
||||
|
||||
var fileDescriptor0 = []byte{
|
||||
var fileDescriptor_multilog_3c9b797b88da6f07 = []byte{
|
||||
// 241 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x8f, 0xb1, 0x4e, 0xc3, 0x30,
|
||||
0x14, 0x45, 0x65, 0x02, 0x08, 0xdc, 0x12, 0xc0, 0x93, 0xd5, 0x85, 0xa8, 0x62, 0xc8, 0xe4, 0x4a,
|
||||
|
64
vendor/github.com/google/certificate-transparency-go/client/logclient.go
generated
vendored
64
vendor/github.com/google/certificate-transparency-go/client/logclient.go
generated
vendored
@ -19,7 +19,6 @@ package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@ -35,11 +34,19 @@ type LogClient struct {
|
||||
jsonclient.JSONClient
|
||||
}
|
||||
|
||||
// CheckLogClient is an interface that allows (just) checking of various log contents.
|
||||
type CheckLogClient interface {
|
||||
BaseURI() string
|
||||
GetSTH(context.Context) (*ct.SignedTreeHead, error)
|
||||
GetSTHConsistency(ctx context.Context, first, second uint64) ([][]byte, error)
|
||||
GetProofByHash(ctx context.Context, hash []byte, treeSize uint64) (*ct.GetProofByHashResponse, error)
|
||||
}
|
||||
|
||||
// New constructs a new LogClient instance.
|
||||
// |uri| is the base URI of the CT log instance to interact with, e.g.
|
||||
// http://ct.googleapis.com/pilot
|
||||
// https://ct.googleapis.com/pilot
|
||||
// |hc| is the underlying client to be used for HTTP requests to the CT log.
|
||||
// |opts| can be used to provide a customer logger interface and a public key
|
||||
// |opts| can be used to provide a custom logger interface and a public key
|
||||
// for signature verification.
|
||||
func New(uri string, hc *http.Client, opts jsonclient.Options) (*LogClient, error) {
|
||||
logClient, err := jsonclient.New(uri, hc, opts)
|
||||
@ -169,35 +176,16 @@ func (c *LogClient) GetSTH(ctx context.Context) (*ct.SignedTreeHead, error) {
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
sth := ct.SignedTreeHead{
|
||||
TreeSize: resp.TreeSize,
|
||||
Timestamp: resp.Timestamp,
|
||||
}
|
||||
|
||||
if len(resp.SHA256RootHash) != sha256.Size {
|
||||
return nil, RspError{
|
||||
Err: fmt.Errorf("sha256_root_hash is invalid length, expected %d got %d", sha256.Size, len(resp.SHA256RootHash)),
|
||||
StatusCode: httpRsp.StatusCode,
|
||||
Body: body,
|
||||
}
|
||||
}
|
||||
copy(sth.SHA256RootHash[:], resp.SHA256RootHash)
|
||||
|
||||
var ds ct.DigitallySigned
|
||||
if rest, err := tls.Unmarshal(resp.TreeHeadSignature, &ds); err != nil {
|
||||
return nil, RspError{Err: err, StatusCode: httpRsp.StatusCode, Body: body}
|
||||
} else if len(rest) > 0 {
|
||||
return nil, RspError{
|
||||
Err: fmt.Errorf("trailing data (%d bytes) after DigitallySigned", len(rest)),
|
||||
StatusCode: httpRsp.StatusCode,
|
||||
Body: body,
|
||||
}
|
||||
}
|
||||
sth.TreeHeadSignature = ds
|
||||
if err := c.VerifySTHSignature(sth); err != nil {
|
||||
sth, err := resp.ToSignedTreeHead()
|
||||
if err != nil {
|
||||
return nil, RspError{Err: err, StatusCode: httpRsp.StatusCode, Body: body}
|
||||
}
|
||||
return &sth, nil
|
||||
|
||||
if err := c.VerifySTHSignature(*sth); err != nil {
|
||||
return nil, RspError{Err: err, StatusCode: httpRsp.StatusCode, Body: body}
|
||||
}
|
||||
return sth, nil
|
||||
}
|
||||
|
||||
// VerifySTHSignature checks the signature in sth, returning any error encountered or nil if verification is
|
||||
@ -281,3 +269,21 @@ func (c *LogClient) GetAcceptedRoots(ctx context.Context) ([]ct.ASN1Cert, error)
|
||||
}
|
||||
return roots, nil
|
||||
}
|
||||
|
||||
// GetEntryAndProof returns a log entry and audit path for the index of a leaf.
|
||||
func (c *LogClient) GetEntryAndProof(ctx context.Context, index, treeSize uint64) (*ct.GetEntryAndProofResponse, error) {
|
||||
base10 := 10
|
||||
params := map[string]string{
|
||||
"leaf_index": strconv.FormatUint(index, base10),
|
||||
"tree_size": strconv.FormatUint(treeSize, base10),
|
||||
}
|
||||
var resp ct.GetEntryAndProofResponse
|
||||
httpRsp, body, err := c.GetAndParse(ctx, ct.GetEntryAndProofPath, params, &resp)
|
||||
if err != nil {
|
||||
if httpRsp != nil {
|
||||
return nil, RspError{Err: err, StatusCode: httpRsp.StatusCode, Body: body}
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &resp, nil
|
||||
}
|
||||
|
154
vendor/github.com/google/certificate-transparency-go/client/logclient_test.go
generated
vendored
154
vendor/github.com/google/certificate-transparency-go/client/logclient_test.go
generated
vendored
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
package client_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -32,6 +32,7 @@ import (
|
||||
"time"
|
||||
|
||||
ct "github.com/google/certificate-transparency-go"
|
||||
"github.com/google/certificate-transparency-go/client"
|
||||
"github.com/google/certificate-transparency-go/jsonclient"
|
||||
"github.com/google/certificate-transparency-go/testdata"
|
||||
"github.com/google/certificate-transparency-go/tls"
|
||||
@ -85,6 +86,15 @@ const (
|
||||
]
|
||||
}`
|
||||
GetSTHConsistencyResp = `{ "consistency": [ "IqlrapPQKtmCY1jCr8+lpCtscRyjjZAA7nyadtFPRFQ=", "ytf6K2GnSRZ3Au+YkivCb7N1DygfKyZmE4aEs9OXl\/8=" ] }`
|
||||
GetEntryAndProofResp = `{
|
||||
"leaf_input": "AAAAAAFhw8UTtQAAAAJ1MIICcTCCAhegAwIBAgIFAN6tvu8wCgYIKoZIzj0EAwIwcjELMAkGA1UEBhMCR0IxDzANBgNVBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAKBgNVBAsTA0VuZzEiMCAGA1UEAxMZRmFrZUludGVybWVkaWF0ZUF1dGhvcml0eTAgFw0xNjEyMDcxNTEzMzZaGA8wMDAxMDEwMTAwMDAwMFowVjELMAkGA1UEBhMCR0IxDzANBgNVBAgMBkxvbmRvbjEPMA0GA1UECgwGR29vZ2xlMQwwCgYDVQQLDANFbmcxFzAVBgNVBAMMDmxlYWYwMS5jc3IucGVtMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE6zdOUkWcRtWouMXtWLkwKaZwimmgJlyeL264ayNshOFGOpg2gkSliheLQYIy9C3gCFt+BzhS/EdWKCeb7WCLrKOBszCBsDAPBgNVHQ8BAf8EBQMDB/mAMIGLBgNVHQ4EgYMEgYBPRBC+90lR8pRLbTi3ID4j0WRzjoJOT3MGkKko87o8z6gEifk9zCwOiHeIgclTA0ZUTxXMRI5r+nUY0frjRCWZu4uthPlE90iJM+RyjcNTwDJGu2StvLnJ8y4t5fdnwdGssncXiBQMuM7/1eMEwAOfHgTFzJ0UBC2Umztl0hul3zAPBgNVHSMECDAGgAQBAgMEMAoGCCqGSM49BAMCA0gAMEUCIQCrwywGKvyt/BwR+e7yDs78qt4sSEVJltv7Y0W6gOI5awIgQ+IAjejYivLEfqNufFRezCBWHWhbq/HHGdNQtv6EArkAAA==",
|
||||
"extra_data": "RXh0cmEK",
|
||||
"audit_path": [
|
||||
"pMumx96PIUB3TX543ljlpQ/RgZRqitRfykupIZrXq0Q=",
|
||||
"5s2NQWkjmesu+Kqgp70TCwVLwq8obpHw/JyMGwN56pQ=",
|
||||
"7VelXijfmGFSl62BWIsG8LRmxJGBq9XP8FxmszuT2Cg="
|
||||
]
|
||||
}`
|
||||
)
|
||||
|
||||
func b64(s string) []byte {
|
||||
@ -156,11 +166,11 @@ func TestGetEntries(t *testing.T) {
|
||||
CertEntryExtraDataB64)
|
||||
})
|
||||
defer ts.Close()
|
||||
client, err := New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
leaves, err := client.GetEntries(context.Background(), 0, 1)
|
||||
leaves, err := lc.GetEntries(context.Background(), 0, 1)
|
||||
if err != nil {
|
||||
t.Errorf("GetEntries(0,1)=nil,%v; want 2 leaves,nil", err)
|
||||
} else if len(leaves) != 2 {
|
||||
@ -185,12 +195,12 @@ func TestGetEntriesErrors(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
ts := serveRspAt(t, "/ct/v1/get-entries", test.rsp)
|
||||
defer ts.Close()
|
||||
client, err := New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create client: %v", err)
|
||||
continue
|
||||
}
|
||||
got, err := client.GetEntries(ctx, test.start, test.end)
|
||||
got, err := lc.GetEntries(ctx, test.start, test.end)
|
||||
if err == nil {
|
||||
t.Errorf("GetEntries(%d, %d)=%+v, nil; want nil, %q", test.start, test.end, got, test.want)
|
||||
} else if !strings.Contains(err.Error(), test.want) {
|
||||
@ -218,12 +228,12 @@ func TestGetRawEntriesErrors(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
ts := serveRspAt(t, "/ct/v1/get-entries", test.rsp)
|
||||
defer ts.Close()
|
||||
client, err := New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create client: %v", err)
|
||||
continue
|
||||
}
|
||||
got, err := client.GetRawEntries(ctx, test.start, test.end)
|
||||
got, err := lc.GetRawEntries(ctx, test.start, test.end)
|
||||
if err == nil {
|
||||
t.Errorf("GetRawEntries(%d, %d)=%+v, nil; want nil, %q", test.start, test.end, got, test.want)
|
||||
} else if !strings.Contains(err.Error(), test.want) {
|
||||
@ -234,7 +244,7 @@ func TestGetRawEntriesErrors(t *testing.T) {
|
||||
}
|
||||
if len(test.rsp) > 0 {
|
||||
// Expect the error to include the HTTP response
|
||||
if rspErr, ok := err.(RspError); !ok {
|
||||
if rspErr, ok := err.(client.RspError); !ok {
|
||||
t.Errorf("GetRawEntries(%d, %d)=nil, .(%T); want nil, .(RspError)", test.start, test.end, err)
|
||||
} else if string(rspErr.Body) != test.rsp {
|
||||
t.Errorf("GetRawEntries(%d, %d)=nil, .Body=%q; want nil, .Body=%q", test.start, test.end, rspErr.Body, test.rsp)
|
||||
@ -251,11 +261,11 @@ func TestGetSTH(t *testing.T) {
|
||||
ValidSTHResponseSHA256RootHash,
|
||||
ValidSTHResponseTreeHeadSignature))
|
||||
defer ts.Close()
|
||||
client, err := New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
sth, err := client.GetSTH(context.Background())
|
||||
sth, err := lc.GetSTH(context.Background())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
@ -303,12 +313,12 @@ func TestGetSTHErrors(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
ts := serveRspAt(t, "/ct/v1/get-sth", test.rsp)
|
||||
defer ts.Close()
|
||||
client, err := New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create client: %v", err)
|
||||
continue
|
||||
}
|
||||
got, err := client.GetSTH(ctx)
|
||||
got, err := lc.GetSTH(ctx)
|
||||
if err == nil {
|
||||
t.Errorf("GetSTH()=%+v, nil; want nil, %q", got, test.want)
|
||||
} else if !strings.Contains(err.Error(), test.want) {
|
||||
@ -319,7 +329,7 @@ func TestGetSTHErrors(t *testing.T) {
|
||||
}
|
||||
if len(test.rsp) > 0 {
|
||||
// Expect the error to include the HTTP response
|
||||
if rspErr, ok := err.(RspError); !ok {
|
||||
if rspErr, ok := err.(client.RspError); !ok {
|
||||
t.Errorf("GetSTH()=nil, .(%T); want nil, .(RspError)", err)
|
||||
} else if string(rspErr.Body) != test.rsp {
|
||||
t.Errorf("GetSTH()=nil, .Body=%q; want nil, .Body=%q", rspErr.Body, test.rsp)
|
||||
@ -417,7 +427,7 @@ func TestAddChainRetries(t *testing.T) {
|
||||
|
||||
for i, test := range tests {
|
||||
deadline := context.Background()
|
||||
client, err := New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
@ -431,7 +441,7 @@ func TestAddChainRetries(t *testing.T) {
|
||||
currentFailures = 0
|
||||
|
||||
started := time.Now()
|
||||
sct, err := client.AddChain(deadline, chain)
|
||||
sct, err := lc.AddChain(deadline, chain)
|
||||
took := time.Since(started)
|
||||
delta := math.Abs(float64(took - test.expected))
|
||||
ratio := delta / float64(test.expected)
|
||||
@ -452,19 +462,19 @@ func TestAddChainRetries(t *testing.T) {
|
||||
func TestAddChain(t *testing.T) {
|
||||
hs := serveSCTAt(t, "/ct/v1/add-chain", testdata.TestCertProof)
|
||||
defer hs.Close()
|
||||
client, err := New(hs.URL, &http.Client{}, jsonclient.Options{PublicKey: testdata.LogPublicKeyPEM})
|
||||
lc, err := client.New(hs.URL, &http.Client{}, jsonclient.Options{PublicKey: testdata.LogPublicKeyPEM})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
|
||||
cert, err := x509util.CertificateFromPEM(testdata.TestCertPEM)
|
||||
cert, err := x509util.CertificateFromPEM([]byte(testdata.TestCertPEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse certificate from PEM: %v", err)
|
||||
}
|
||||
|
||||
// AddChain will verify the signature because the client has a public key.
|
||||
chain := []ct.ASN1Cert{{Data: cert.Raw}}
|
||||
_, err = client.AddChain(context.Background(), chain)
|
||||
_, err = lc.AddChain(context.Background(), chain)
|
||||
if err != nil {
|
||||
t.Errorf("AddChain()=nil,%v; want sct,nil", err)
|
||||
}
|
||||
@ -473,23 +483,23 @@ func TestAddChain(t *testing.T) {
|
||||
func TestAddPreChain(t *testing.T) {
|
||||
hs := serveSCTAt(t, "/ct/v1/add-pre-chain", testdata.TestPreCertProof)
|
||||
defer hs.Close()
|
||||
client, err := New(hs.URL, &http.Client{}, jsonclient.Options{PublicKey: testdata.LogPublicKeyPEM})
|
||||
lc, err := client.New(hs.URL, &http.Client{}, jsonclient.Options{PublicKey: testdata.LogPublicKeyPEM})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
|
||||
cert, err := x509util.CertificateFromPEM(testdata.TestPreCertPEM)
|
||||
cert, err := x509util.CertificateFromPEM([]byte(testdata.TestPreCertPEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse pre-certificate from PEM: %v", err)
|
||||
}
|
||||
issuer, err := x509util.CertificateFromPEM(testdata.CACertPEM)
|
||||
issuer, err := x509util.CertificateFromPEM([]byte(testdata.CACertPEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse issuer certificate from PEM: %v", err)
|
||||
}
|
||||
|
||||
// AddPreChain will verify the signature because the client has a public key.
|
||||
chain := []ct.ASN1Cert{{Data: cert.Raw}, {Data: issuer.Raw}}
|
||||
_, err = client.AddPreChain(context.Background(), chain)
|
||||
_, err = lc.AddPreChain(context.Background(), chain)
|
||||
if err != nil {
|
||||
t.Errorf("AddPreChain()=nil,%v; want sct,nil", err)
|
||||
}
|
||||
@ -498,7 +508,7 @@ func TestAddPreChain(t *testing.T) {
|
||||
func TestAddJSON(t *testing.T) {
|
||||
hs := serveRspAt(t, "/ct/v1/add-json", AddJSONResp)
|
||||
defer hs.Close()
|
||||
client, err := New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
@ -511,7 +521,7 @@ func TestAddJSON(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
sct, err := client.AddJSON(context.Background(), test.data)
|
||||
sct, err := lc.AddJSON(context.Background(), test.data)
|
||||
if test.success && err != nil {
|
||||
t.Errorf("AddJSON(%v)=nil,%v; want sct,nil", test.data, err)
|
||||
} else if !test.success && err == nil {
|
||||
@ -526,7 +536,7 @@ func TestAddJSON(t *testing.T) {
|
||||
func TestGetSTHConsistency(t *testing.T) {
|
||||
hs := serveRspAt(t, "/ct/v1/get-sth-consistency", GetSTHConsistencyResp)
|
||||
defer hs.Close()
|
||||
client, err := New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
@ -543,7 +553,7 @@ func TestGetSTHConsistency(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
proof, err := client.GetSTHConsistency(context.Background(), test.first, test.second)
|
||||
proof, err := lc.GetSTHConsistency(context.Background(), test.first, test.second)
|
||||
if err != nil {
|
||||
t.Errorf("GetSTHConsistency(%d, %d)=nil,%v; want proof,nil", test.first, test.second, err)
|
||||
} else if !reflect.DeepEqual(proof, test.proof) {
|
||||
@ -567,12 +577,12 @@ func TestGetSTHConsistencyErrors(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
ts := serveRspAt(t, "/ct/v1/get-sth-consistency", test.rsp)
|
||||
defer ts.Close()
|
||||
client, err := New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create client: %v", err)
|
||||
continue
|
||||
}
|
||||
got, err := client.GetSTHConsistency(ctx, test.first, test.second)
|
||||
got, err := lc.GetSTHConsistency(ctx, test.first, test.second)
|
||||
if err == nil {
|
||||
t.Errorf("GetSTHConsistency(%d, %d)=%+v, nil; want nil, %q", test.first, test.second, got, test.want)
|
||||
} else if !strings.Contains(err.Error(), test.want) {
|
||||
@ -583,7 +593,7 @@ func TestGetSTHConsistencyErrors(t *testing.T) {
|
||||
}
|
||||
if len(test.rsp) > 0 {
|
||||
// Expect the error to include the HTTP response
|
||||
if rspErr, ok := err.(RspError); !ok {
|
||||
if rspErr, ok := err.(client.RspError); !ok {
|
||||
t.Errorf("GetSTHConsistency(%d, %d)=nil, .(%T); want nil, .(RspError)", test.first, test.second, err)
|
||||
} else if string(rspErr.Body) != test.rsp {
|
||||
t.Errorf("GetSTHConsistency(%d, %d)=nil, .Body=%q; want nil, .Body=%q", test.first, test.second, rspErr.Body, test.rsp)
|
||||
@ -595,7 +605,7 @@ func TestGetSTHConsistencyErrors(t *testing.T) {
|
||||
func TestGetProofByHash(t *testing.T) {
|
||||
hs := serveRspAt(t, "/ct/v1/get-proof-by-hash", ProofByHashResp)
|
||||
defer hs.Close()
|
||||
client, err := New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
@ -608,7 +618,7 @@ func TestGetProofByHash(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
resp, err := client.GetProofByHash(context.Background(), test.hash, test.treesize)
|
||||
resp, err := lc.GetProofByHash(context.Background(), test.hash, test.treesize)
|
||||
if err != nil {
|
||||
t.Errorf("GetProofByHash(%v, %v)=nil,%v; want proof,nil", test.hash, test.treesize, err)
|
||||
} else if got := len(resp.AuditPath); got < 1 {
|
||||
@ -632,12 +642,12 @@ func TestGetProofByHashErrors(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
ts := serveRspAt(t, "/ct/v1/get-proof-by-hash", test.rsp)
|
||||
defer ts.Close()
|
||||
client, err := New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create client: %v", err)
|
||||
continue
|
||||
}
|
||||
got, err := client.GetProofByHash(ctx, aHash, 100)
|
||||
got, err := lc.GetProofByHash(ctx, aHash, 100)
|
||||
if err == nil {
|
||||
t.Errorf("GetProofByHash()=%+v, nil; want nil, %q", got, test.want)
|
||||
} else if !strings.Contains(err.Error(), test.want) {
|
||||
@ -648,7 +658,7 @@ func TestGetProofByHashErrors(t *testing.T) {
|
||||
}
|
||||
if len(test.rsp) > 0 {
|
||||
// Expect the error to include the HTTP response
|
||||
if rspErr, ok := err.(RspError); !ok {
|
||||
if rspErr, ok := err.(client.RspError); !ok {
|
||||
t.Errorf("GetProofByHash()=nil, .(%T); want nil, .(RspError)", err)
|
||||
} else if string(rspErr.Body) != test.rsp {
|
||||
t.Errorf("GetProofByHash()=nil, .Body=%q; want nil, .Body=%q", rspErr.Body, test.rsp)
|
||||
@ -660,12 +670,12 @@ func TestGetProofByHashErrors(t *testing.T) {
|
||||
func TestGetAcceptedRoots(t *testing.T) {
|
||||
hs := serveRspAt(t, "/ct/v1/get-roots", GetRootsResp)
|
||||
defer hs.Close()
|
||||
client, err := New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
|
||||
certs, err := client.GetAcceptedRoots(context.Background())
|
||||
certs, err := lc.GetAcceptedRoots(context.Background())
|
||||
if err != nil {
|
||||
t.Errorf("GetAcceptedRoots()=nil,%q; want roots,nil", err.Error())
|
||||
} else if len(certs) < 1 {
|
||||
@ -687,12 +697,12 @@ func TestGetAcceptedRootsErrors(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
ts := serveRspAt(t, "/ct/v1/get-roots", test.rsp)
|
||||
defer ts.Close()
|
||||
client, err := New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
lc, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create client: %v", err)
|
||||
continue
|
||||
}
|
||||
got, err := client.GetAcceptedRoots(ctx)
|
||||
got, err := lc.GetAcceptedRoots(ctx)
|
||||
if err == nil {
|
||||
t.Errorf("GetAcceptedRoots()=%+v, nil; want nil, %q", got, test.want)
|
||||
} else if !strings.Contains(err.Error(), test.want) {
|
||||
@ -703,7 +713,7 @@ func TestGetAcceptedRootsErrors(t *testing.T) {
|
||||
}
|
||||
if len(test.rsp) > 0 {
|
||||
// Expect the error to include the HTTP response
|
||||
if rspErr, ok := err.(RspError); !ok {
|
||||
if rspErr, ok := err.(client.RspError); !ok {
|
||||
t.Errorf("GetAcceptedRoots()=nil, .(%T); want nil, .(RspError)", err)
|
||||
} else if string(rspErr.Body) != test.rsp {
|
||||
t.Errorf("GetAcceptedRoots()=nil, .Body=%q; want nil, .Body=%q", rspErr.Body, test.rsp)
|
||||
@ -711,3 +721,69 @@ func TestGetAcceptedRootsErrors(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetEntryAndProof(t *testing.T) {
|
||||
hs := serveRspAt(t, "/ct/v1/get-entry-and-proof", GetEntryAndProofResp)
|
||||
defer hs.Close()
|
||||
lc, err := client.New(hs.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
index uint64
|
||||
treesize uint64
|
||||
}{
|
||||
{1000, 2000},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
resp, err := lc.GetEntryAndProof(context.Background(), test.index, test.treesize)
|
||||
if err != nil {
|
||||
t.Errorf("GetEntryAndProof(%v, %v)=nil,%v; want proof,nil", test.index, test.treesize, err)
|
||||
} else if got := len(resp.AuditPath); got < 1 {
|
||||
t.Errorf("len(GetEntryAndProof(%v, %v)): %v; want > 1", test.index, test.treesize, got)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetEntryAndProofErrors(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
var tests = []struct {
|
||||
rsp, want string
|
||||
}{
|
||||
{rsp: "", want: "EOF"},
|
||||
{rsp: "not-json", want: "invalid"},
|
||||
{rsp: `{"leaf_input": "bogus", "extra_data": "Z29vZAo=", "audit_path": ["Z29vZAo="]}`, want: "illegal base64"},
|
||||
{rsp: `{"leaf_input": "Z29vZAo=", "extra_data": "bogus", "audit_path": ["Z29vZAo="]}`, want: "illegal base64"},
|
||||
{rsp: `{"leaf_input": "Z29vZAo=", "extra_data": "Z29vZAo=", "audit_path": ["bogus"]}`, want: "illegal base64"},
|
||||
{rsp: `{"leaf_input": "Z29vZAo=", "extra_data": "Z29vZAo=", "audit_path": ["bbbb",]}`, want: "invalid"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
ts := serveRspAt(t, "/ct/v1/get-entry-and-proof", test.rsp)
|
||||
defer ts.Close()
|
||||
lc, err := client.New(ts.URL, &http.Client{}, jsonclient.Options{})
|
||||
if err != nil {
|
||||
t.Errorf("Failed to create client: %v", err)
|
||||
continue
|
||||
}
|
||||
got, err := lc.GetEntryAndProof(ctx, 99, 100)
|
||||
if err == nil {
|
||||
t.Errorf("GetEntryAndProof()=%+v, nil; want nil, %q", got, test.want)
|
||||
} else if !strings.Contains(err.Error(), test.want) {
|
||||
t.Errorf("GetEntryAndProof()=nil, %q; want nil, %q", err, test.want)
|
||||
}
|
||||
if got != nil {
|
||||
t.Errorf("GetEntryAndProof()=%+v, _; want nil, _", got)
|
||||
}
|
||||
if len(test.rsp) > 0 {
|
||||
// Expect the error to include the HTTP response
|
||||
if rspErr, ok := err.(client.RspError); !ok {
|
||||
t.Errorf("GetEntryAndProof()=nil, .(%T); want nil, .(RspError)", err)
|
||||
} else if string(rspErr.Body) != test.rsp {
|
||||
t.Errorf("GetEntryAndProof()=nil, .Body=%q; want nil, .Body=%q", rspErr.Body, test.rsp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
2
vendor/github.com/google/certificate-transparency-go/client/multilog.go
generated
vendored
2
vendor/github.com/google/certificate-transparency-go/client/multilog.go
generated
vendored
@ -23,7 +23,7 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/gogo/protobuf/proto"
|
||||
"github.com/golang/protobuf/proto"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
ct "github.com/google/certificate-transparency-go"
|
||||
"github.com/google/certificate-transparency-go/client/configpb"
|
||||
|
17
vendor/github.com/google/certificate-transparency-go/client/multilog_test.go
generated
vendored
17
vendor/github.com/google/certificate-transparency-go/client/multilog_test.go
generated
vendored
@ -12,7 +12,7 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
package client_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -26,6 +26,7 @@ import (
|
||||
"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"
|
||||
@ -200,7 +201,7 @@ func TestNewTemporalLogClient(t *testing.T) {
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
_, err := NewTemporalLogClient(test.cfg, nil)
|
||||
_, err := client.NewTemporalLogClient(test.cfg, nil)
|
||||
if err != nil {
|
||||
if test.wantErr == "" {
|
||||
t.Errorf("NewTemporalLogClient(%+v)=nil,%v; want _,nil", test.cfg, err)
|
||||
@ -313,7 +314,7 @@ func TestIndexByDate(t *testing.T) {
|
||||
{cfg: boundedCfg, when: time.Date(2015, 9, 19, 11, 00, 00, 00, time.UTC), wantErr: true},
|
||||
}
|
||||
for _, test := range tests {
|
||||
tlc, err := NewTemporalLogClient(test.cfg, nil)
|
||||
tlc, err := client.NewTemporalLogClient(test.cfg, nil)
|
||||
if err != nil {
|
||||
t.Errorf("NewTemporalLogClient(%+v)=nil, %v; want _,nil", test.cfg, err)
|
||||
continue
|
||||
@ -349,16 +350,16 @@ func TestTemporalAddChain(t *testing.T) {
|
||||
}))
|
||||
defer hs.Close()
|
||||
|
||||
cert, err := x509util.CertificateFromPEM(testdata.TestCertPEM)
|
||||
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(testdata.TestPreCertPEM)
|
||||
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(testdata.CACertPEM)
|
||||
issuer, err := x509util.CertificateFromPEM([]byte(testdata.CACertPEM))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to parse issuer certificate from PEM: %v", err)
|
||||
}
|
||||
@ -423,7 +424,7 @@ func TestTemporalAddChain(t *testing.T) {
|
||||
|
||||
ctx := context.Background()
|
||||
for _, test := range tests {
|
||||
tlc, err := NewTemporalLogClient(test.cfg, nil)
|
||||
tlc, err := client.NewTemporalLogClient(test.cfg, nil)
|
||||
if err != nil {
|
||||
t.Errorf("NewTemporalLogClient(%+v)=nil, %v; want _,nil", test.cfg, err)
|
||||
continue
|
||||
@ -464,7 +465,7 @@ func TestTemporalAddChainErrors(t *testing.T) {
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
tlc, err := NewTemporalLogClient(cfg, nil)
|
||||
tlc, err := client.NewTemporalLogClient(cfg, nil)
|
||||
if err != nil {
|
||||
t.Fatalf("NewTemporalLogClient(%+v)=nil, %v; want _,nil", cfg, err)
|
||||
}
|
||||
|
4
vendor/github.com/google/certificate-transparency-go/gometalinter.json
generated
vendored
4
vendor/github.com/google/certificate-transparency-go/gometalinter.json
generated
vendored
@ -1,7 +1,8 @@
|
||||
{
|
||||
"Linters": {
|
||||
"license": "./scripts/check_license.sh:PATH:LINE:MESSAGE",
|
||||
"forked": "./scripts/check_forked.sh:PATH:LINE:MESSAGE"
|
||||
"forked": "./scripts/check_forked.sh:PATH:LINE:MESSAGE",
|
||||
"unforked": "./scripts/check_unforked.sh:PATH:LINE:MESSAGE"
|
||||
},
|
||||
"Enable": [
|
||||
"forked",
|
||||
@ -11,6 +12,7 @@
|
||||
"golint",
|
||||
"license",
|
||||
"misspell",
|
||||
"unforked",
|
||||
"vet"
|
||||
],
|
||||
"Exclude": [
|
||||
|
7
vendor/github.com/google/certificate-transparency-go/jsonclient/client.go
generated
vendored
7
vendor/github.com/google/certificate-transparency-go/jsonclient/client.go
generated
vendored
@ -53,7 +53,7 @@ type backoffer interface {
|
||||
// JSONClient provides common functionality for interacting with a JSON server
|
||||
// that uses cryptographic signatures.
|
||||
type JSONClient struct {
|
||||
uri string // the base URI of the server. e.g. http://ct.googleapis/pilot
|
||||
uri string // the base URI of the server. e.g. https://ct.googleapis/pilot
|
||||
httpClient *http.Client // used to interact with the server via HTTP
|
||||
Verifier *ct.SignatureVerifier // nil for no verification (e.g. no public key available)
|
||||
logger Logger // interface to use for logging warnings and errors
|
||||
@ -139,6 +139,11 @@ func New(uri string, hc *http.Client, opts Options) (*JSONClient, error) {
|
||||
}, nil
|
||||
}
|
||||
|
||||
// BaseURI returns the base URI that the JSONClient makes queries to.
|
||||
func (c *JSONClient) BaseURI() string {
|
||||
return c.uri
|
||||
}
|
||||
|
||||
// GetAndParse makes a HTTP GET call to the given path, and attempta to parse
|
||||
// the response as a JSON representation of the rsp structure. Returns the
|
||||
// http.Response, the body of the response, and an error. Note that the
|
||||
|
56
vendor/github.com/google/certificate-transparency-go/serialization.go
generated
vendored
56
vendor/github.com/google/certificate-transparency-go/serialization.go
generated
vendored
@ -20,6 +20,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/certificate-transparency-go/tls"
|
||||
"github.com/google/certificate-transparency-go/x509"
|
||||
@ -189,6 +190,53 @@ func MerkleTreeLeafFromChain(chain []*x509.Certificate, etype LogEntryType, time
|
||||
return &leaf, nil
|
||||
}
|
||||
|
||||
// MerkleTreeLeafForEmbeddedSCT generates a MerkleTreeLeaf from a chain and an
|
||||
// SCT timestamp, where the leaf certificate at chain[0] is a certificate that
|
||||
// contains embedded SCTs. It is assumed that the timestamp provided is from
|
||||
// one of the SCTs embedded within the leaf certificate.
|
||||
func MerkleTreeLeafForEmbeddedSCT(chain []*x509.Certificate, timestamp uint64) (*MerkleTreeLeaf, error) {
|
||||
// For building the leaf for a certificate and SCT where the SCT is embedded
|
||||
// in the certificate, we need to build the original precertificate TBS
|
||||
// data. First, parse the leaf cert and its issuer.
|
||||
if len(chain) < 2 {
|
||||
return nil, fmt.Errorf("no issuer cert available for precert leaf building")
|
||||
}
|
||||
issuer := chain[1]
|
||||
cert := chain[0]
|
||||
|
||||
// Next, post-process the DER-encoded TBSCertificate, to remove the SCTList
|
||||
// extension.
|
||||
tbs, err := x509.RemoveSCTList(cert.RawTBSCertificate)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to remove SCT List extension: %v", err)
|
||||
}
|
||||
|
||||
return &MerkleTreeLeaf{
|
||||
Version: V1,
|
||||
LeafType: TimestampedEntryLeafType,
|
||||
TimestampedEntry: &TimestampedEntry{
|
||||
EntryType: PrecertLogEntryType,
|
||||
Timestamp: timestamp,
|
||||
PrecertEntry: &PreCert{
|
||||
IssuerKeyHash: sha256.Sum256(issuer.RawSubjectPublicKeyInfo),
|
||||
TBSCertificate: tbs,
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// LeafHashForLeaf returns the leaf hash for a Merkle tree leaf.
|
||||
func LeafHashForLeaf(leaf *MerkleTreeLeaf) ([sha256.Size]byte, error) {
|
||||
leafData, err := tls.Marshal(*leaf)
|
||||
if err != nil {
|
||||
return [sha256.Size]byte{}, fmt.Errorf("failed to tls-encode MerkleTreeLeaf: %s", err)
|
||||
}
|
||||
|
||||
data := append([]byte{TreeLeafPrefix}, leafData...)
|
||||
leafHash := sha256.Sum256(data)
|
||||
return leafHash, nil
|
||||
}
|
||||
|
||||
// IsPreIssuer indicates whether a certificate is a pre-cert issuer with the specific
|
||||
// certificate transparency extended key usage.
|
||||
func IsPreIssuer(issuer *x509.Certificate) bool {
|
||||
@ -253,3 +301,11 @@ func LogEntryFromLeaf(index int64, leafEntry *LeafEntry) (*LogEntry, error) {
|
||||
// err may hold a x509.NonFatalErrors object.
|
||||
return &entry, err
|
||||
}
|
||||
|
||||
// TimestampToTime converts a timestamp in the style of RFC 6962 (milliseconds
|
||||
// since UNIX epoch) to a Go Time.
|
||||
func TimestampToTime(ts uint64) time.Time {
|
||||
secs := int64(ts / 1000)
|
||||
msecs := int64(ts % 1000)
|
||||
return time.Unix(secs, msecs*1000000)
|
||||
}
|
||||
|
10
vendor/github.com/google/certificate-transparency-go/signatures.go
generated
vendored
10
vendor/github.com/google/certificate-transparency-go/signatures.go
generated
vendored
@ -20,6 +20,7 @@ import (
|
||||
"crypto/elliptic"
|
||||
"crypto/rsa"
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"flag"
|
||||
"fmt"
|
||||
@ -42,6 +43,15 @@ func PublicKeyFromPEM(b []byte) (crypto.PublicKey, SHA256Hash, []byte, error) {
|
||||
return k, sha256.Sum256(p.Bytes), rest, err
|
||||
}
|
||||
|
||||
// PublicKeyFromB64 parses a base64-encoded public key.
|
||||
func PublicKeyFromB64(b64PubKey string) (crypto.PublicKey, error) {
|
||||
der, err := base64.StdEncoding.DecodeString(b64PubKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error decoding public key: %s", err)
|
||||
}
|
||||
return x509.ParsePKIXPublicKey(der)
|
||||
}
|
||||
|
||||
// SignatureVerifier can verify signatures on SCTs and STHs
|
||||
type SignatureVerifier struct {
|
||||
pubKey crypto.PublicKey
|
||||
|
174
vendor/github.com/google/certificate-transparency-go/testdata/certs.go
generated
vendored
174
vendor/github.com/google/certificate-transparency-go/testdata/certs.go
generated
vendored
@ -208,6 +208,165 @@ const (
|
||||
"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 (
|
||||
@ -224,6 +383,21 @@ var (
|
||||
"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 {
|
||||
|
3
vendor/github.com/google/certificate-transparency-go/testdata/keys.go
generated
vendored
3
vendor/github.com/google/certificate-transparency-go/testdata/keys.go
generated
vendored
@ -34,6 +34,9 @@ const (
|
||||
)
|
||||
|
||||
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" +
|
||||
|
23
vendor/github.com/google/certificate-transparency-go/tls/types.go
generated
vendored
23
vendor/github.com/google/certificate-transparency-go/tls/types.go
generated
vendored
@ -14,7 +14,13 @@
|
||||
|
||||
package tls
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// DigitallySigned gives information about a signature, including the algorithm used
|
||||
// and the signature value. Defined in RFC 5246 s4.7.
|
||||
@ -94,3 +100,18 @@ func (s SignatureAlgorithm) String() string {
|
||||
return fmt.Sprintf("UNKNOWN(%d)", s)
|
||||
}
|
||||
}
|
||||
|
||||
// SignatureAlgorithmFromPubKey returns the algorithm used for this public key.
|
||||
// ECDSA, RSA, and DSA keys are supported. Other key types will return Anonymous.
|
||||
func SignatureAlgorithmFromPubKey(k crypto.PublicKey) SignatureAlgorithm {
|
||||
switch k.(type) {
|
||||
case *ecdsa.PublicKey:
|
||||
return ECDSA
|
||||
case *rsa.PublicKey:
|
||||
return RSA
|
||||
case *dsa.PublicKey:
|
||||
return DSA
|
||||
default:
|
||||
return Anonymous
|
||||
}
|
||||
}
|
||||
|
25
vendor/github.com/google/certificate-transparency-go/tls/types_test.go
generated
vendored
25
vendor/github.com/google/certificate-transparency-go/tls/types_test.go
generated
vendored
@ -14,7 +14,13 @@
|
||||
|
||||
package tls
|
||||
|
||||
import "testing"
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/dsa"
|
||||
"crypto/ecdsa"
|
||||
"crypto/rsa"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHashAlgorithmString(t *testing.T) {
|
||||
var tests = []struct {
|
||||
@ -75,3 +81,20 @@ func TestDigitallySignedString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
29
vendor/github.com/google/certificate-transparency-go/types.go
generated
vendored
29
vendor/github.com/google/certificate-transparency-go/types.go
generated
vendored
@ -54,6 +54,12 @@ func (e LogEntryType) String() string {
|
||||
}
|
||||
}
|
||||
|
||||
// RFC6962 section 2.1 requires a prefix byte on hash inputs for second preimage resistance.
|
||||
const (
|
||||
TreeLeafPrefix = byte(0x00)
|
||||
TreeNodePrefix = byte(0x01)
|
||||
)
|
||||
|
||||
// MerkleLeafType represents the MerkleLeafType enum from section 3.4:
|
||||
// enum { timestamped_entry(0), (255) } MerkleLeafType;
|
||||
type MerkleLeafType tls.Enum // tls:"maxval:255"
|
||||
@ -415,6 +421,29 @@ type GetSTHResponse struct {
|
||||
TreeHeadSignature []byte `json:"tree_head_signature"` // Log signature for this STH
|
||||
}
|
||||
|
||||
// ToSignedTreeHead creates a SignedTreeHead from the GetSTHResponse.
|
||||
func (r *GetSTHResponse) ToSignedTreeHead() (*SignedTreeHead, error) {
|
||||
sth := SignedTreeHead{
|
||||
TreeSize: r.TreeSize,
|
||||
Timestamp: r.Timestamp,
|
||||
}
|
||||
|
||||
if len(r.SHA256RootHash) != sha256.Size {
|
||||
return nil, fmt.Errorf("sha256_root_hash is invalid length, expected %d got %d", sha256.Size, len(r.SHA256RootHash))
|
||||
}
|
||||
copy(sth.SHA256RootHash[:], r.SHA256RootHash)
|
||||
|
||||
var ds DigitallySigned
|
||||
if rest, err := tls.Unmarshal(r.TreeHeadSignature, &ds); err != nil {
|
||||
return nil, fmt.Errorf("tls.Unmarshal(): %s", err)
|
||||
} else if len(rest) > 0 {
|
||||
return nil, fmt.Errorf("trailing data (%d bytes) after DigitallySigned", len(rest))
|
||||
}
|
||||
sth.TreeHeadSignature = ds
|
||||
|
||||
return &sth, nil
|
||||
}
|
||||
|
||||
// GetSTHConsistencyResponse represents the JSON response to the get-sth-consistency
|
||||
// GET method from section 4.4. (The corresponding GET request has parameters 'first' and
|
||||
// 'second'.)
|
||||
|
65
vendor/github.com/google/certificate-transparency-go/types_test.go
generated
vendored
65
vendor/github.com/google/certificate-transparency-go/types_test.go
generated
vendored
@ -64,3 +64,68 @@ func TestUnmarshalMerkleTreeLeaf(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
131
vendor/github.com/google/certificate-transparency-go/x509/name_constraints_test.go
generated
vendored
131
vendor/github.com/google/certificate-transparency-go/x509/name_constraints_test.go
generated
vendored
@ -9,6 +9,7 @@ import (
|
||||
"crypto/ecdsa"
|
||||
"crypto/elliptic"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@ -43,6 +44,7 @@ type nameConstraintsTest struct {
|
||||
roots []constraintsSpec
|
||||
intermediates [][]constraintsSpec
|
||||
leaf leafSpec
|
||||
requestedEKUs []ExtKeyUsage
|
||||
expectedError string
|
||||
noOpenSSL bool
|
||||
}
|
||||
@ -1445,6 +1447,118 @@ var nameConstraintsTests = []nameConstraintsTest{
|
||||
},
|
||||
expectedError: "\"https://example.com/test\" is excluded",
|
||||
},
|
||||
|
||||
// #75: While serverAuth in a CA certificate permits clientAuth in a leaf,
|
||||
// serverAuth in a leaf shouldn't permit clientAuth when requested in
|
||||
// VerifyOptions.
|
||||
nameConstraintsTest{
|
||||
roots: []constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
intermediates: [][]constraintsSpec{
|
||||
[]constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
},
|
||||
leaf: leafSpec{
|
||||
sans: []string{"dns:example.com"},
|
||||
ekus: []string{"serverAuth"},
|
||||
},
|
||||
requestedEKUs: []ExtKeyUsage{ExtKeyUsageClientAuth},
|
||||
expectedError: "incompatible key usage",
|
||||
},
|
||||
|
||||
// #76: However, MSSGC in a leaf should match a request for serverAuth.
|
||||
nameConstraintsTest{
|
||||
roots: []constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
intermediates: [][]constraintsSpec{
|
||||
[]constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
},
|
||||
leaf: leafSpec{
|
||||
sans: []string{"dns:example.com"},
|
||||
ekus: []string{"msSGC"},
|
||||
},
|
||||
requestedEKUs: []ExtKeyUsage{ExtKeyUsageServerAuth},
|
||||
},
|
||||
|
||||
// An invalid DNS SAN should be detected only at validation time so
|
||||
// that we can process CA certificates in the wild that have invalid SANs.
|
||||
// See https://github.com/golang/go/issues/23995
|
||||
|
||||
// #77: an invalid DNS or mail SAN will not be detected if name constaint
|
||||
// checking is not triggered.
|
||||
nameConstraintsTest{
|
||||
roots: []constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
intermediates: [][]constraintsSpec{
|
||||
[]constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
},
|
||||
leaf: leafSpec{
|
||||
sans: []string{"dns:this is invalid", "email:this @ is invalid"},
|
||||
},
|
||||
},
|
||||
|
||||
// #78: an invalid DNS SAN will be detected if any name constraint checking
|
||||
// is triggered.
|
||||
nameConstraintsTest{
|
||||
roots: []constraintsSpec{
|
||||
constraintsSpec{
|
||||
bad: []string{"uri:"},
|
||||
},
|
||||
},
|
||||
intermediates: [][]constraintsSpec{
|
||||
[]constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
},
|
||||
leaf: leafSpec{
|
||||
sans: []string{"dns:this is invalid"},
|
||||
},
|
||||
expectedError: "cannot parse dnsName",
|
||||
},
|
||||
|
||||
// #79: an invalid email SAN will be detected if any name constraint
|
||||
// checking is triggered.
|
||||
nameConstraintsTest{
|
||||
roots: []constraintsSpec{
|
||||
constraintsSpec{
|
||||
bad: []string{"uri:"},
|
||||
},
|
||||
},
|
||||
intermediates: [][]constraintsSpec{
|
||||
[]constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
},
|
||||
leaf: leafSpec{
|
||||
sans: []string{"email:this @ is invalid"},
|
||||
},
|
||||
expectedError: "cannot parse rfc822Name",
|
||||
},
|
||||
|
||||
// #80: if several EKUs are requested, satisfying any of them is sufficient.
|
||||
nameConstraintsTest{
|
||||
roots: []constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
intermediates: [][]constraintsSpec{
|
||||
[]constraintsSpec{
|
||||
constraintsSpec{},
|
||||
},
|
||||
},
|
||||
leaf: leafSpec{
|
||||
sans: []string{"dns:example.com"},
|
||||
ekus: []string{"email"},
|
||||
},
|
||||
requestedEKUs: []ExtKeyUsage{ExtKeyUsageClientAuth, ExtKeyUsageEmailProtection},
|
||||
},
|
||||
}
|
||||
|
||||
func makeConstraintsCACert(constraints constraintsSpec, name string, key *ecdsa.PrivateKey, parent *Certificate, parentKey *ecdsa.PrivateKey) (*Certificate, error) {
|
||||
@ -1513,6 +1627,13 @@ func makeConstraintsLeafCert(leaf leafSpec, key *ecdsa.PrivateKey, parent *Certi
|
||||
}
|
||||
template.IPAddresses = append(template.IPAddresses, ip)
|
||||
|
||||
case strings.HasPrefix(name, "invalidip:"):
|
||||
ipBytes, err := hex.DecodeString(name[10:])
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot parse invalid IP: %s", err)
|
||||
}
|
||||
template.IPAddresses = append(template.IPAddresses, net.IP(ipBytes))
|
||||
|
||||
case strings.HasPrefix(name, "email:"):
|
||||
template.EmailAddresses = append(template.EmailAddresses, name[6:])
|
||||
|
||||
@ -1782,6 +1903,7 @@ func TestConstraintCases(t *testing.T) {
|
||||
Roots: rootPool,
|
||||
Intermediates: intermediatePool,
|
||||
CurrentTime: time.Unix(1500, 0),
|
||||
KeyUsages: test.requestedEKUs,
|
||||
}
|
||||
_, err = leafCert.Verify(verifyOpts)
|
||||
|
||||
@ -1973,12 +2095,13 @@ func TestBadNamesInConstraints(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestBadNamesInSANs(t *testing.T) {
|
||||
// Bad names in SANs should not parse.
|
||||
// Bad names in URI and IP SANs should not parse. Bad DNS and email SANs
|
||||
// will parse and are tested in name constraint tests at the top of this
|
||||
// file.
|
||||
badNames := []string{
|
||||
"dns:foo.com.",
|
||||
"email:abc@foo.com.",
|
||||
"email:foo.com.",
|
||||
"uri:https://example.com./dsf",
|
||||
"invalidip:0102",
|
||||
"invalidip:0102030405",
|
||||
}
|
||||
|
||||
priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||||
|
119
vendor/github.com/google/certificate-transparency-go/x509/verify.go
generated
vendored
119
vendor/github.com/google/certificate-transparency-go/x509/verify.go
generated
vendored
@ -12,9 +12,12 @@ import (
|
||||
"net/url"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
|
||||
"github.com/google/certificate-transparency-go/asn1"
|
||||
)
|
||||
|
||||
type InvalidReason int
|
||||
@ -174,19 +177,29 @@ var errNotParsed = errors.New("x509: missing ASN.1 contents; use ParseCertificat
|
||||
// VerifyOptions contains parameters for Certificate.Verify. It's a structure
|
||||
// because other PKIX verification APIs have ended up needing many options.
|
||||
type VerifyOptions struct {
|
||||
DNSName string
|
||||
Intermediates *CertPool
|
||||
Roots *CertPool // if nil, the system roots are used
|
||||
CurrentTime time.Time // if zero, the current time is used
|
||||
DisableTimeChecks bool
|
||||
// KeyUsage specifies which Extended Key Usage values are acceptable.
|
||||
// An empty list means ExtKeyUsageServerAuth. Key usage is considered a
|
||||
// constraint down the chain which mirrors Windows CryptoAPI behavior,
|
||||
// but not the spec. To accept any key usage, include ExtKeyUsageAny.
|
||||
DNSName string
|
||||
Intermediates *CertPool
|
||||
Roots *CertPool // if nil, the system roots are used
|
||||
CurrentTime time.Time // if zero, the current time is used
|
||||
// Options to disable various verification checks.
|
||||
DisableTimeChecks bool
|
||||
DisableCriticalExtensionChecks bool
|
||||
DisableNameChecks bool
|
||||
DisableEKUChecks bool
|
||||
DisablePathLenChecks bool
|
||||
DisableNameConstraintChecks bool
|
||||
// KeyUsage specifies which Extended Key Usage values are acceptable. A leaf
|
||||
// certificate is accepted if it contains any of the listed values. An empty
|
||||
// list means ExtKeyUsageServerAuth. To accept any key usage, include
|
||||
// ExtKeyUsageAny.
|
||||
//
|
||||
// Certificate chains are required to nest extended key usage values,
|
||||
// irrespective of this value. This matches the Windows CryptoAPI behavior,
|
||||
// but not the spec.
|
||||
KeyUsages []ExtKeyUsage
|
||||
// MaxConstraintComparisions is the maximum number of comparisons to
|
||||
// perform when checking a given certificate's name constraints. If
|
||||
// zero, a sensible default is used. This limit prevents pathalogical
|
||||
// zero, a sensible default is used. This limit prevents pathological
|
||||
// certificates from consuming excessive amounts of CPU time when
|
||||
// validating.
|
||||
MaxConstraintComparisions int
|
||||
@ -544,11 +557,16 @@ func (c *Certificate) checkNameConstraints(count *int,
|
||||
return nil
|
||||
}
|
||||
|
||||
const (
|
||||
checkingAgainstIssuerCert = iota
|
||||
checkingAgainstLeafCert
|
||||
)
|
||||
|
||||
// ekuPermittedBy returns true iff the given extended key usage is permitted by
|
||||
// the given EKU from a certificate. Normally, this would be a simple
|
||||
// comparison plus a special case for the “any” EKU. But, in order to support
|
||||
// existing certificates, some exceptions are made.
|
||||
func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool {
|
||||
func ekuPermittedBy(eku, certEKU ExtKeyUsage, context int) bool {
|
||||
if certEKU == ExtKeyUsageAny || eku == certEKU {
|
||||
return true
|
||||
}
|
||||
@ -565,28 +583,33 @@ func ekuPermittedBy(eku, certEKU ExtKeyUsage) bool {
|
||||
eku = mapServerAuthEKUs(eku)
|
||||
certEKU = mapServerAuthEKUs(certEKU)
|
||||
|
||||
if eku == certEKU ||
|
||||
// ServerAuth in a CA permits ClientAuth in the leaf.
|
||||
(eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) ||
|
||||
if eku == certEKU {
|
||||
return true
|
||||
}
|
||||
|
||||
// If checking a requested EKU against the list in a leaf certificate there
|
||||
// are fewer exceptions.
|
||||
if context == checkingAgainstLeafCert {
|
||||
return false
|
||||
}
|
||||
|
||||
// ServerAuth in a CA permits ClientAuth in the leaf.
|
||||
return (eku == ExtKeyUsageClientAuth && certEKU == ExtKeyUsageServerAuth) ||
|
||||
// Any CA may issue an OCSP responder certificate.
|
||||
eku == ExtKeyUsageOCSPSigning ||
|
||||
// Code-signing CAs can use Microsoft's commercial and
|
||||
// kernel-mode EKUs.
|
||||
((eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
(eku == ExtKeyUsageMicrosoftCommercialCodeSigning || eku == ExtKeyUsageMicrosoftKernelCodeSigning) && certEKU == ExtKeyUsageCodeSigning
|
||||
}
|
||||
|
||||
// isValid performs validity checks on c given that it is a candidate to append
|
||||
// to the chain in currentChain.
|
||||
func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *VerifyOptions) error {
|
||||
if len(c.UnhandledCriticalExtensions) > 0 {
|
||||
if !opts.DisableCriticalExtensionChecks && len(c.UnhandledCriticalExtensions) > 0 {
|
||||
return UnhandledCriticalExtension{ID: c.UnhandledCriticalExtensions[0]}
|
||||
}
|
||||
|
||||
if len(currentChain) > 0 {
|
||||
if !opts.DisableNameChecks && len(currentChain) > 0 {
|
||||
child := currentChain[len(currentChain)-1]
|
||||
if !bytes.Equal(child.RawIssuer, c.RawSubject) {
|
||||
return CertificateInvalidError{c, NameMismatch, ""}
|
||||
@ -617,7 +640,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
|
||||
leaf = currentChain[0]
|
||||
}
|
||||
|
||||
if (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints() {
|
||||
if !opts.DisableNameConstraintChecks && (certType == intermediateCertificate || certType == rootCertificate) && c.hasNameConstraints() {
|
||||
sanExtension, ok := leaf.getSANExtension()
|
||||
if !ok {
|
||||
// This is the deprecated, legacy case of depending on
|
||||
@ -633,8 +656,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
|
||||
name := string(data)
|
||||
mailbox, ok := parseRFC2821Mailbox(name)
|
||||
if !ok {
|
||||
// This certificate should not have parsed.
|
||||
return errors.New("x509: internal error: rfc822Name SAN failed to parse")
|
||||
return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox)
|
||||
}
|
||||
|
||||
if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "email address", name, mailbox,
|
||||
@ -646,6 +668,10 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
|
||||
|
||||
case nameTypeDNS:
|
||||
name := string(data)
|
||||
if _, ok := domainToReverseLabels(name); !ok {
|
||||
return fmt.Errorf("x509: cannot parse dnsName %q", name)
|
||||
}
|
||||
|
||||
if err := c.checkNameConstraints(&comparisonCount, maxConstraintComparisons, "DNS name", name, name,
|
||||
func(parsedName, constraint interface{}) (bool, error) {
|
||||
return matchDomainConstraint(parsedName.(string), constraint.(string))
|
||||
@ -692,7 +718,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
|
||||
}
|
||||
}
|
||||
|
||||
checkEKUs := certType == intermediateCertificate
|
||||
checkEKUs := !opts.DisableEKUChecks && certType == intermediateCertificate
|
||||
|
||||
// If no extended key usages are specified, then all are acceptable.
|
||||
if checkEKUs && (len(c.ExtKeyUsage) == 0 && len(c.UnknownExtKeyUsage) == 0) {
|
||||
@ -719,7 +745,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
|
||||
|
||||
for _, caEKU := range c.ExtKeyUsage {
|
||||
comparisonCount++
|
||||
if ekuPermittedBy(eku, caEKU) {
|
||||
if ekuPermittedBy(eku, caEKU, checkingAgainstIssuerCert) {
|
||||
continue NextEKU
|
||||
}
|
||||
}
|
||||
@ -766,7 +792,7 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
|
||||
return CertificateInvalidError{c, NotAuthorizedToSign, ""}
|
||||
}
|
||||
|
||||
if c.BasicConstraintsValid && c.MaxPathLen >= 0 {
|
||||
if !opts.DisablePathLenChecks && c.BasicConstraintsValid && c.MaxPathLen >= 0 {
|
||||
numIntermediates := len(currentChain) - 1
|
||||
if numIntermediates > c.MaxPathLen {
|
||||
return CertificateInvalidError{c, TooManyIntermediates, ""}
|
||||
@ -776,6 +802,18 @@ func (c *Certificate) isValid(certType int, currentChain []*Certificate, opts *V
|
||||
return nil
|
||||
}
|
||||
|
||||
// formatOID formats an ASN.1 OBJECT IDENTIFER in the common, dotted style.
|
||||
func formatOID(oid asn1.ObjectIdentifier) string {
|
||||
ret := ""
|
||||
for i, v := range oid {
|
||||
if i > 0 {
|
||||
ret += "."
|
||||
}
|
||||
ret += strconv.Itoa(v)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
// Verify attempts to verify c by building one or more chains from c to a
|
||||
// certificate in opts.Roots, using certificates in opts.Intermediates if
|
||||
// needed. If successful, it returns one or more chains where the first
|
||||
@ -840,7 +878,7 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e
|
||||
}
|
||||
|
||||
// If no key usages are specified, then any are acceptable.
|
||||
checkEKU := len(c.ExtKeyUsage) > 0
|
||||
checkEKU := !opts.DisableEKUChecks && len(c.ExtKeyUsage) > 0
|
||||
|
||||
for _, eku := range requestedKeyUsages {
|
||||
if eku == ExtKeyUsageAny {
|
||||
@ -850,16 +888,33 @@ func (c *Certificate) Verify(opts VerifyOptions) (chains [][]*Certificate, err e
|
||||
}
|
||||
|
||||
if checkEKU {
|
||||
foundMatch := false
|
||||
NextUsage:
|
||||
for _, eku := range requestedKeyUsages {
|
||||
for _, leafEKU := range c.ExtKeyUsage {
|
||||
if ekuPermittedBy(eku, leafEKU) {
|
||||
continue NextUsage
|
||||
if ekuPermittedBy(eku, leafEKU, checkingAgainstLeafCert) {
|
||||
foundMatch = true
|
||||
break NextUsage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oid, _ := oidFromExtKeyUsage(eku)
|
||||
return nil, CertificateInvalidError{c, IncompatibleUsage, fmt.Sprintf("%#v", oid)}
|
||||
if !foundMatch {
|
||||
msg := "leaf contains the following, recognized EKUs: "
|
||||
|
||||
for i, leafEKU := range c.ExtKeyUsage {
|
||||
oid, ok := oidFromExtKeyUsage(leafEKU)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
if i > 0 {
|
||||
msg += ", "
|
||||
}
|
||||
msg += formatOID(oid)
|
||||
}
|
||||
|
||||
return nil, CertificateInvalidError{c, IncompatibleUsage, msg}
|
||||
}
|
||||
}
|
||||
|
||||
|
83
vendor/github.com/google/certificate-transparency-go/x509/verify_test.go
generated
vendored
83
vendor/github.com/google/certificate-transparency-go/x509/verify_test.go
generated
vendored
@ -19,16 +19,18 @@ import (
|
||||
var supportSHA2 = true
|
||||
|
||||
type verifyTest struct {
|
||||
leaf string
|
||||
intermediates []string
|
||||
roots []string
|
||||
currentTime int64
|
||||
dnsName string
|
||||
systemSkip bool
|
||||
keyUsages []ExtKeyUsage
|
||||
testSystemRootsError bool
|
||||
sha2 bool
|
||||
disableTimeChecks bool
|
||||
leaf string
|
||||
intermediates []string
|
||||
roots []string
|
||||
currentTime int64
|
||||
dnsName string
|
||||
systemSkip bool
|
||||
keyUsages []ExtKeyUsage
|
||||
testSystemRootsError bool
|
||||
sha2 bool
|
||||
disableTimeChecks bool
|
||||
disableCriticalExtensionChecks bool
|
||||
disableNameChecks bool
|
||||
|
||||
errorCallback func(*testing.T, int, error) bool
|
||||
expectedChains [][]string
|
||||
@ -296,7 +298,18 @@ var verifyTests = []verifyTest{
|
||||
currentTime: 1475787715,
|
||||
systemSkip: true,
|
||||
|
||||
errorCallback: expectSubjectIssuerMismatcthError,
|
||||
errorCallback: expectSubjectIssuerMismatchError,
|
||||
},
|
||||
{
|
||||
leaf: issuerSubjectMatchLeaf,
|
||||
roots: []string{issuerSubjectMatchRoot},
|
||||
currentTime: 1475787715,
|
||||
systemSkip: true,
|
||||
disableNameChecks: true,
|
||||
|
||||
expectedChains: [][]string{
|
||||
{"Leaf", "Root ca"},
|
||||
},
|
||||
},
|
||||
{
|
||||
// An X.509 v1 certificate should not be accepted as an
|
||||
@ -355,6 +368,40 @@ var verifyTests = []verifyTest{
|
||||
|
||||
errorCallback: expectUnhandledCriticalExtension,
|
||||
},
|
||||
{
|
||||
leaf: criticalExtLeafWithExt,
|
||||
dnsName: "example.com",
|
||||
intermediates: []string{criticalExtIntermediate},
|
||||
roots: []string{criticalExtRoot},
|
||||
currentTime: 1486684488,
|
||||
systemSkip: true,
|
||||
disableCriticalExtensionChecks: true,
|
||||
|
||||
expectedChains: [][]string{
|
||||
{
|
||||
"example.com",
|
||||
"Intermediate",
|
||||
"Root",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
leaf: criticalExtLeaf,
|
||||
dnsName: "example.com",
|
||||
intermediates: []string{criticalExtIntermediateWithExt},
|
||||
roots: []string{criticalExtRoot},
|
||||
currentTime: 1486684488,
|
||||
systemSkip: true,
|
||||
disableCriticalExtensionChecks: true,
|
||||
|
||||
expectedChains: [][]string{
|
||||
{
|
||||
"example.com",
|
||||
"Intermediate with Critical Extension",
|
||||
"Root",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func expectHostnameError(t *testing.T, i int, err error) (ok bool) {
|
||||
@ -414,7 +461,7 @@ func expectHashError(t *testing.T, i int, err error) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func expectSubjectIssuerMismatcthError(t *testing.T, i int, err error) (ok bool) {
|
||||
func expectSubjectIssuerMismatchError(t *testing.T, i int, err error) (ok bool) {
|
||||
if inval, ok := err.(CertificateInvalidError); !ok || inval.Reason != NameMismatch {
|
||||
t.Errorf("#%d: error was not a NameMismatch: %s", i, err)
|
||||
return false
|
||||
@ -467,11 +514,13 @@ func testVerify(t *testing.T, useSystemRoots bool) {
|
||||
}
|
||||
|
||||
opts := VerifyOptions{
|
||||
Intermediates: NewCertPool(),
|
||||
DNSName: test.dnsName,
|
||||
CurrentTime: time.Unix(test.currentTime, 0),
|
||||
KeyUsages: test.keyUsages,
|
||||
DisableTimeChecks: test.disableTimeChecks,
|
||||
Intermediates: NewCertPool(),
|
||||
DNSName: test.dnsName,
|
||||
CurrentTime: time.Unix(test.currentTime, 0),
|
||||
KeyUsages: test.keyUsages,
|
||||
DisableTimeChecks: test.disableTimeChecks,
|
||||
DisableCriticalExtensionChecks: test.disableCriticalExtensionChecks,
|
||||
DisableNameChecks: test.disableNameChecks,
|
||||
}
|
||||
|
||||
if !useSystemRoots {
|
||||
|
107
vendor/github.com/google/certificate-transparency-go/x509/x509.go
generated
vendored
107
vendor/github.com/google/certificate-transparency-go/x509/x509.go
generated
vendored
@ -737,7 +737,9 @@ type Certificate struct {
|
||||
OCSPServer []string
|
||||
IssuingCertificateURL []string
|
||||
|
||||
// Subject Alternate Name values
|
||||
// Subject Alternate Name values. (Note that these values may not be valid
|
||||
// if invalid values were contained within a parsed certificate. For
|
||||
// example, an element of DNSNames may not be a valid DNS domain name.)
|
||||
DNSNames []string
|
||||
EmailAddresses []string
|
||||
IPAddresses []net.IP
|
||||
@ -792,6 +794,20 @@ func (c *Certificate) Equal(other *Certificate) bool {
|
||||
return bytes.Equal(c.Raw, other.Raw)
|
||||
}
|
||||
|
||||
// IsPrecertificate checks whether the certificate is a precertificate, by
|
||||
// checking for the presence of the CT Poison extension.
|
||||
func (c *Certificate) IsPrecertificate() bool {
|
||||
if c == nil {
|
||||
return false
|
||||
}
|
||||
for _, ext := range c.Extensions {
|
||||
if ext.Id.Equal(OIDExtensionCTPoison) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (c *Certificate) hasSANExtension() bool {
|
||||
return oidInExtensions(OIDExtensionSubjectAltName, c.Extensions)
|
||||
}
|
||||
@ -995,6 +1011,50 @@ func (h UnhandledCriticalExtension) Error() string {
|
||||
return fmt.Sprintf("x509: unhandled critical extension (%v)", h.ID)
|
||||
}
|
||||
|
||||
// removeExtension takes a DER-encoded TBSCertificate, removes the extension
|
||||
// specified by oid (preserving the order of other extensions), and returns the
|
||||
// result still as a DER-encoded TBSCertificate. This function will fail if
|
||||
// there is not exactly 1 extension of the type specified by the oid present.
|
||||
func removeExtension(tbsData []byte, oid asn1.ObjectIdentifier) ([]byte, error) {
|
||||
var tbs tbsCertificate
|
||||
rest, err := asn1.Unmarshal(tbsData, &tbs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse TBSCertificate: %v", err)
|
||||
} else if rLen := len(rest); rLen > 0 {
|
||||
return nil, fmt.Errorf("trailing data (%d bytes) after TBSCertificate", rLen)
|
||||
}
|
||||
extAt := -1
|
||||
for i, ext := range tbs.Extensions {
|
||||
if ext.Id.Equal(oid) {
|
||||
if extAt != -1 {
|
||||
return nil, errors.New("multiple extensions of specified type present")
|
||||
}
|
||||
extAt = i
|
||||
}
|
||||
}
|
||||
if extAt == -1 {
|
||||
return nil, errors.New("no extension of specified type present")
|
||||
}
|
||||
tbs.Extensions = append(tbs.Extensions[:extAt], tbs.Extensions[extAt+1:]...)
|
||||
// Clear out the asn1.RawContent so the re-marshal operation sees the
|
||||
// updated structure (rather than just copying the out-of-date DER data).
|
||||
tbs.Raw = nil
|
||||
|
||||
data, err := asn1.Marshal(tbs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to re-marshal TBSCertificate: %v", err)
|
||||
}
|
||||
return data, nil
|
||||
}
|
||||
|
||||
// RemoveSCTList takes a DER-encoded TBSCertificate and removes the CT SCT
|
||||
// extension that contains the SCT list (preserving the order of other
|
||||
// extensions), and returns the result still as a DER-encoded TBSCertificate.
|
||||
// This function will fail if there is not exactly 1 CT SCT extension present.
|
||||
func RemoveSCTList(tbsData []byte) ([]byte, error) {
|
||||
return removeExtension(tbsData, OIDExtensionCTSCT)
|
||||
}
|
||||
|
||||
// RemoveCTPoison takes a DER-encoded TBSCertificate and removes the CT poison
|
||||
// extension (preserving the order of other extensions), and returns the result
|
||||
// still as a DER-encoded TBSCertificate. This function will fail if there is
|
||||
@ -1019,27 +1079,18 @@ func RemoveCTPoison(tbsData []byte) ([]byte, error) {
|
||||
// - The precert's AuthorityKeyId is changed to the AuthorityKeyId of the
|
||||
// intermediate.
|
||||
func BuildPrecertTBS(tbsData []byte, preIssuer *Certificate) ([]byte, error) {
|
||||
data, err := removeExtension(tbsData, OIDExtensionCTPoison)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tbs tbsCertificate
|
||||
rest, err := asn1.Unmarshal(tbsData, &tbs)
|
||||
rest, err := asn1.Unmarshal(data, &tbs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse TBSCertificate: %v", err)
|
||||
} else if rLen := len(rest); rLen > 0 {
|
||||
return nil, fmt.Errorf("trailing data (%d bytes) after TBSCertificate", rLen)
|
||||
}
|
||||
poisonAt := -1
|
||||
for i, ext := range tbs.Extensions {
|
||||
if ext.Id.Equal(OIDExtensionCTPoison) {
|
||||
if poisonAt != -1 {
|
||||
return nil, errors.New("multiple CT poison extensions present")
|
||||
}
|
||||
poisonAt = i
|
||||
}
|
||||
}
|
||||
if poisonAt == -1 {
|
||||
return nil, errors.New("no CT poison extension present")
|
||||
}
|
||||
tbs.Extensions = append(tbs.Extensions[:poisonAt], tbs.Extensions[poisonAt+1:]...)
|
||||
tbs.Raw = nil
|
||||
|
||||
if preIssuer != nil {
|
||||
// Update the precert's Issuer field. Use the RawIssuer rather than the
|
||||
@ -1092,9 +1143,13 @@ func BuildPrecertTBS(tbsData []byte, preIssuer *Certificate) ([]byte, error) {
|
||||
}
|
||||
tbs.Extensions = append(tbs.Extensions, authKeyIDExt)
|
||||
}
|
||||
|
||||
// Clear out the asn1.RawContent so the re-marshal operation sees the
|
||||
// updated structure (rather than just copying the out-of-date DER data).
|
||||
tbs.Raw = nil
|
||||
}
|
||||
|
||||
data, err := asn1.Marshal(tbs)
|
||||
data, err = asn1.Marshal(tbs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to re-marshal TBSCertificate: %v", err)
|
||||
}
|
||||
@ -1235,7 +1290,7 @@ type NonFatalErrors struct {
|
||||
Errors []error
|
||||
}
|
||||
|
||||
// Adds an error to the list of errors contained by NonFatalErrors.
|
||||
// AddError adds an error to the list of errors contained by NonFatalErrors.
|
||||
func (e *NonFatalErrors) AddError(err error) {
|
||||
e.Errors = append(e.Errors, err)
|
||||
}
|
||||
@ -1250,7 +1305,7 @@ func (e NonFatalErrors) Error() string {
|
||||
return r
|
||||
}
|
||||
|
||||
// Returns true if |e| contains at least one error
|
||||
// HasError returns true if |e| contains at least one error
|
||||
func (e *NonFatalErrors) HasError() bool {
|
||||
return len(e.Errors) > 0
|
||||
}
|
||||
@ -1337,17 +1392,9 @@ func parseSANExtension(value []byte, nfe *NonFatalErrors) (dnsNames, emailAddres
|
||||
err = forEachSAN(value, func(tag int, data []byte) error {
|
||||
switch tag {
|
||||
case nameTypeEmail:
|
||||
mailbox := string(data)
|
||||
if _, ok := parseRFC2821Mailbox(mailbox); !ok {
|
||||
return fmt.Errorf("x509: cannot parse rfc822Name %q", mailbox)
|
||||
}
|
||||
emailAddresses = append(emailAddresses, mailbox)
|
||||
emailAddresses = append(emailAddresses, string(data))
|
||||
case nameTypeDNS:
|
||||
domain := string(data)
|
||||
if _, ok := domainToReverseLabels(domain); !ok {
|
||||
return fmt.Errorf("x509: cannot parse dnsName %q", string(data))
|
||||
}
|
||||
dnsNames = append(dnsNames, domain)
|
||||
dnsNames = append(dnsNames, string(data))
|
||||
case nameTypeURI:
|
||||
uri, err := url.Parse(string(data))
|
||||
if err != nil {
|
||||
@ -1364,7 +1411,7 @@ func parseSANExtension(value []byte, nfe *NonFatalErrors) (dnsNames, emailAddres
|
||||
case net.IPv4len, net.IPv6len:
|
||||
ipAddresses = append(ipAddresses, data)
|
||||
default:
|
||||
nfe.AddError(fmt.Errorf("x509: certificate contained IP address of length %d : %v", len(data), data))
|
||||
nfe.AddError(errors.New("x509: cannot parse IP address of length " + strconv.Itoa(len(data))))
|
||||
}
|
||||
}
|
||||
|
||||
|
65
vendor/github.com/google/certificate-transparency-go/x509/x509_test.go
generated
vendored
65
vendor/github.com/google/certificate-transparency-go/x509/x509_test.go
generated
vendored
@ -1085,7 +1085,8 @@ func TestRSAPSSSelfSigned(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
const pemCertificate = `-----BEGIN CERTIFICATE-----
|
||||
const (
|
||||
pemCertificate = `-----BEGIN CERTIFICATE-----
|
||||
MIIDATCCAemgAwIBAgIRAKQkkrFx1T/dgB/Go/xBM5swDQYJKoZIhvcNAQELBQAw
|
||||
EjEQMA4GA1UEChMHQWNtZSBDbzAeFw0xNjA4MTcyMDM2MDdaFw0xNzA4MTcyMDM2
|
||||
MDdaMBIxEDAOBgNVBAoTB0FjbWUgQ28wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAw
|
||||
@ -1104,6 +1105,64 @@ fnnktsblSUV4lRCit0ymC7Ojhe+gzCCwkgs5kDzVVag+tnl/0e2DloIjASwOhpbH
|
||||
KVcg7fBd484ht/sS+l0dsB4KDOSpd8JzVDMF8OZqlaydizoJO0yWr9GbCN1+OKq5
|
||||
EhLrEqU=
|
||||
-----END CERTIFICATE-----`
|
||||
pemPrecertificate = `-----BEGIN CERTIFICATE-----
|
||||
MIIC3zCCAkigAwIBAgIBBzANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk
|
||||
MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX
|
||||
YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw
|
||||
MDAwMDBaMFIxCzAJBgNVBAYTAkdCMSEwHwYDVQQKExhDZXJ0aWZpY2F0ZSBUcmFu
|
||||
c3BhcmVuY3kxDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGfMA0G
|
||||
CSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+75jnwmh3rjhfdTJaDB0ym+3xj6r015a/
|
||||
BH634c4VyVui+A7kWL19uG+KSyUhkaeb1wDDjpwDibRc1NyaEgqyHgy0HNDnKAWk
|
||||
EM2cW9tdSSdyba8XEPYBhzd+olsaHjnu0LiBGdwVTcaPfajjDK8VijPmyVCfSgWw
|
||||
FAn/Xdh+tQIDAQABo4HBMIG+MB0GA1UdDgQWBBQgMVQa8lwF/9hli2hDeU9ekDb3
|
||||
tDB9BgNVHSMEdjB0gBRfnYgNyHPmVNT4DdjmsMEktEfDVaFZpFcwVTELMAkGA1UE
|
||||
BhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRyYW5zcGFyZW5jeSBDQTEOMAwG
|
||||
A1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW6CAQAwCQYDVR0TBAIwADATBgor
|
||||
BgEEAdZ5AgQDAQH/BAIFADANBgkqhkiG9w0BAQUFAAOBgQACocOeAVr1Tf8CPDNg
|
||||
h1//NDdVLx8JAb3CVDFfM3K3I/sV+87MTfRxoM5NjFRlXYSHl/soHj36u0YtLGhL
|
||||
BW/qe2O0cP8WbjLURgY1s9K8bagkmyYw5x/DTwjyPdTuIo+PdPY9eGMR3QpYEUBf
|
||||
kGzKLC0+6/yBmWTr2M98CIY/vg==
|
||||
-----END CERTIFICATE-----`
|
||||
)
|
||||
|
||||
func TestIsPrecertificate(t *testing.T) {
|
||||
tests := []struct {
|
||||
desc string
|
||||
certPEM string
|
||||
want bool
|
||||
}{
|
||||
{
|
||||
desc: "certificate",
|
||||
certPEM: pemCertificate,
|
||||
want: false,
|
||||
},
|
||||
{
|
||||
desc: "precertificate",
|
||||
certPEM: pemPrecertificate,
|
||||
want: true,
|
||||
},
|
||||
{
|
||||
desc: "nil",
|
||||
certPEM: "",
|
||||
want: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
var cert *Certificate
|
||||
if test.certPEM != "" {
|
||||
var err error
|
||||
cert, err = certificateFromPEM(test.certPEM)
|
||||
if err != nil {
|
||||
t.Errorf("%s: error parsing certificate: %s", test.desc, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if got := cert.IsPrecertificate(); got != test.want {
|
||||
t.Errorf("%s: c.IsPrecertificate() = %t, want %t", test.desc, got, test.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCRLCreation(t *testing.T) {
|
||||
block, _ := pem.Decode([]byte(pemPrivateKey))
|
||||
@ -1338,8 +1397,8 @@ func TestRemoveCTPoison(t *testing.T) {
|
||||
}{
|
||||
{name: "invalid-der", tbs: "01020304", errstr: "failed to parse"},
|
||||
{name: "trailing-data", tbs: tbsPoisonMiddle + "01020304", errstr: "trailing data"},
|
||||
{name: "no-poison-ext", tbs: tbsNoPoison, errstr: "no CT poison extension present"},
|
||||
{name: "two-poison-exts", tbs: tbsPoisonTwice, errstr: "multiple CT poison extensions present"},
|
||||
{name: "no-poison-ext", tbs: tbsNoPoison, errstr: "no extension of specified type present"},
|
||||
{name: "two-poison-exts", tbs: tbsPoisonTwice, errstr: "multiple extensions of specified type present"},
|
||||
{name: "poison-first", tbs: tbsPoisonFirst, want: tbsNoPoison},
|
||||
{name: "poison-last", tbs: tbsPoisonLast, want: tbsNoPoison},
|
||||
{name: "poison-middle", tbs: tbsPoisonMiddle, want: tbsNoPoison},
|
||||
|
42
vendor/github.com/google/certificate-transparency-go/x509util/files.go
generated
vendored
42
vendor/github.com/google/certificate-transparency-go/x509util/files.go
generated
vendored
@ -19,7 +19,10 @@ import (
|
||||
"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
|
||||
@ -71,3 +74,42 @@ func dePEM(data []byte, blockname string) [][]byte {
|
||||
}
|
||||
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
|
||||
}
|
||||
|
84
vendor/github.com/google/certificate-transparency-go/x509util/x509util.go
generated
vendored
84
vendor/github.com/google/certificate-transparency-go/x509util/x509util.go
generated
vendored
@ -659,12 +659,86 @@ func oidAlreadyPrinted(oid asn1.ObjectIdentifier) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// CertificateFromPEM takes a string representing a certificate in PEM format
|
||||
// and returns the corresponding x509.Certificate object.
|
||||
func CertificateFromPEM(pemBytes string) (*x509.Certificate, error) {
|
||||
block, _ := pem.Decode([]byte(pemBytes))
|
||||
// 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("failed to decode PEM")
|
||||
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 _, err := tls.Unmarshal(sctData.Val, &sct); err != nil {
|
||||
return nil, fmt.Errorf("error parsing SCT: %s", err)
|
||||
}
|
||||
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