feat: cluster addons

This commit is contained in:
Mikaël Cluseau
2018-07-07 12:22:35 +11:00
parent 6c20c29106
commit 975f002935
78 changed files with 3226 additions and 123 deletions

View File

@ -17,6 +17,8 @@
/dumpscts
/etcdiscover
/findlog
/goshawk
/gosmin
/gossip_server
/preloader
/scanlog

View File

@ -1,7 +1,7 @@
sudo: true # required for CI push into Kubernetes.
language: go
os: linux
go: 1.9
go: "1.10"
go_import_path: github.com/google/certificate-transparency-go
@ -22,8 +22,8 @@ install:
- |
(
cd ../protoc
wget https://github.com/google/protobuf/releases/download/v3.2.0/protoc-3.2.0-${TRAVIS_OS_NAME}-x86_64.zip
unzip protoc-3.2.0-${TRAVIS_OS_NAME}-x86_64.zip
wget https://github.com/google/protobuf/releases/download/v3.5.1/protoc-3.5.1-${TRAVIS_OS_NAME}-x86_64.zip
unzip protoc-3.5.1-${TRAVIS_OS_NAME}-x86_64.zip
)
- export PATH=$(pwd)/../protoc/bin:$PATH
- go get -d -t ./...

View File

@ -0,0 +1,194 @@
# CERTIFICATE-TRANSPARENCY-GO Changelog
## v1.0.19 - CTFE User Quota
Published 2018-06-01 13:51:52 +0000 UTC
CTFE now supports Trillian Log's explicit quota API; quota can be requested based on the remote user's IP, as well as per-issuing certificate in submitted chains.
Commit [8736a411b4ff214ea20687e46c2b67d66ebd83fc](https://api.github.com/repos/google/certificate-transparency-go/commits/8736a411b4ff214ea20687e46c2b67d66ebd83fc) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.19)
## v1.0.18 - Adding Migration Tool / Client Additions / K8 Config
Published 2018-06-01 14:28:20 +0000 UTC
Work on a log migration tool (Migrillian) is in progress. This is not yet ready for production use but will provide features for mirroring and migrating logs.
The `RequestLog` API allows for logging of SCTs when they are issued by CTFE.
The CT Go client now supports `GetEntryAndProof`. Utilities have been switched over to use the `glog` package.
Commit [77abf2dac5410a62c04ac1c662c6d0fa54afc2dc](https://api.github.com/repos/google/certificate-transparency-go/commits/77abf2dac5410a62c04ac1c662c6d0fa54afc2dc) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.18)
## v1.0.17 - Merkle verification / Tracing / Demo script / CORS
Published 2018-06-01 14:25:16 +0000 UTC
Now uses Merkle Tree verification from Trillian.
The CT server now supports CORS.
Request tracing added using OpenCensus. For GCE / K8 it just requires the flag to be enabled to export traces to Stackdriver. Other environments may differ.
A demo script was added that goes through setting up a simple deployment suitable for development / demo purposes. This may be useful for those new to the project.
Commit [3c3d22ce946447d047a03228ebb4a41e3e4eb15b](https://api.github.com/repos/google/certificate-transparency-go/commits/3c3d22ce946447d047a03228ebb4a41e3e4eb15b) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.17)
## v1.0.16 - Lifecycle test / Go 1.10.1
Published 2018-06-01 14:22:23 +0000 UTC
An integration test was added that goes through a create / drain queue / freeze lifecycle for a log.
Changes to `x509` were merged from Go 1.10.1.
Commit [a72423d09b410b80673fd1135ba1022d04bac6cd](https://api.github.com/repos/google/certificate-transparency-go/commits/a72423d09b410b80673fd1135ba1022d04bac6cd) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.16)
## v1.0.15 - More control of verification, grpclb, stackdriver metrics
Published 2018-06-01 14:20:32 +0000 UTC
Facilities were added to the `x509` package to control whether verification checks are applied.
Log server requests are now balanced using `gRPClb`.
For Kubernetes, metrics can be published to Stackdriver monitoring.
Commit [684d6eee6092774e54d301ccad0ed61bc8d010c1](https://api.github.com/repos/google/certificate-transparency-go/commits/684d6eee6092774e54d301ccad0ed61bc8d010c1) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.15)
## v1.0.14 - SQLite Removed, LeafHashForLeaf
Published 2018-06-01 14:15:37 +0000 UTC
Support for SQLlite was removed. This motivation was ongoing test flakiness caused by multi-user access. This database may work for an embedded scenario but is not suitable for use in a server environment.
A `LeafHashForLeaf` client API was added and is now used by the CT client and integration tests.
Commit [698cd6a661196db4b2e71437422178ffe8705006](https://api.github.com/repos/google/certificate-transparency-go/commits/698cd6a661196db4b2e71437422178ffe8705006) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.14)
## v1.0.13 - Crypto changes, util updates, sync with trillian repo, loglist verification
Published 2018-06-01 14:15:21 +0000 UTC
Some of our custom crypto package that were wrapping calls to the standard package have been removed and the base features used directly.
Updates were made to GCE ingress and health checks.
The log list utility can verify signatures.
Commit [480c3654a70c5383b9543ec784203030aedbd3a5](https://api.github.com/repos/google/certificate-transparency-go/commits/480c3654a70c5383b9543ec784203030aedbd3a5) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.13)
## v1.0.12 - Client / util updates & CTFE fixes
Published 2018-06-01 14:13:42 +0000 UTC
The CT client can now use a JSON loglist to find logs.
CTFE had a fix applied for preissued precerts.
A DNS client was added and CT client was extended to support DNS retrieval.
Commit [74c06c95e0b304a050a1c33764c8a01d653a16e3](https://api.github.com/repos/google/certificate-transparency-go/commits/74c06c95e0b304a050a1c33764c8a01d653a16e3) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.12)
## v1.0.11 - Kubernetes CI / Integration fixes
Published 2018-06-01 14:12:18 +0000 UTC
Updates to Kubernetes configs, mostly related to running a CI instance.
Commit [0856acca7e0ab7f082ae83a1fbb5d21160962efc](https://api.github.com/repos/google/certificate-transparency-go/commits/0856acca7e0ab7f082ae83a1fbb5d21160962efc) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.11)
## v1.0.10 - More scanner, x509, utility and client fixes. CTFE updates
Published 2018-06-01 14:09:47 +0000 UTC
The CT client was using the wrong protobuffer library package. To guard against this in future a check has been added to our lint config.
The `x509` and `asn1` packages have had upstream fixes applied from Go 1.10rc1.
Commit [1bec4527572c443752ad4f2830bef88be0533236](https://api.github.com/repos/google/certificate-transparency-go/commits/1bec4527572c443752ad4f2830bef88be0533236) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.10)
## v1.0.9 - Scanner, x509, utility and client fixes
Published 2018-06-01 14:11:13 +0000 UTC
The `scanner` utility now displays throughput stats.
Build instructions and README files were updated.
The `certcheck` utility can be told to ignore unknown critical X.509 extensions.
Commit [c06833528d04a94eed0c775104d1107bab9ae17c](https://api.github.com/repos/google/certificate-transparency-go/commits/c06833528d04a94eed0c775104d1107bab9ae17c) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.9)
## v1.0.8 - Client fixes, align with trillian repo
Published 2018-06-01 14:06:44 +0000 UTC
Commit [e8b02c60f294b503dbb67de0868143f5d4935e56](https://api.github.com/repos/google/certificate-transparency-go/commits/e8b02c60f294b503dbb67de0868143f5d4935e56) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.8)
## v1.0.7 - CTFE fixes
Published 2018-06-01 14:06:13 +0000 UTC
An issue was fixed with CTFE signature caching. In an unlikely set of circumstances this could lead to log mis-operation. While the chances of this are small, we recommend that versions prior to this one are not deployed.
Commit [52c0590bd3b4b80c5497005b0f47e10557425eeb](https://api.github.com/repos/google/certificate-transparency-go/commits/52c0590bd3b4b80c5497005b0f47e10557425eeb) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.7)
## v1.0.6 - crlcheck improvements / other fixes
Published 2018-06-01 14:04:22 +0000 UTC
The `crlcheck` utility has had several fixes and enhancements. Additionally the `hammer` now supports temporal logs.
Commit [3955e4a00c42e83ff17ce25003976159c5d0f0f9](https://api.github.com/repos/google/certificate-transparency-go/commits/3955e4a00c42e83ff17ce25003976159c5d0f0f9) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.6)
## v1.0.5 - X509 and asn1 fixes
Published 2018-06-01 14:02:58 +0000 UTC
This release is mostly fixes to the `x509` and `asn1` packages. Some command line utilties were also updated.
Commit [ae40d07cce12f1227c6e658e61c9dddb7646f97b](https://api.github.com/repos/google/certificate-transparency-go/commits/ae40d07cce12f1227c6e658e61c9dddb7646f97b) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.5)
## v1.0.4 - Multi log backend configs
Published 2018-06-01 14:02:07 +0000 UTC
Support was added to allow CTFE to use multiple backends, each serving a distinct set of logs. It allows for e.g. regional backend deployment with common frontend servers.
Commit [62023ed90b41fa40854957b5dec7d9d73594723f](https://api.github.com/repos/google/certificate-transparency-go/commits/62023ed90b41fa40854957b5dec7d9d73594723f) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.4)
## v1.0.3 - Hammer updates, use standard context
Published 2018-06-01 14:01:11 +0000 UTC
After the Go 1.9 migration references to anything other than the standard `context` package have been removed. This is the only one that should be used from now on.
Commit [b28beed8b9aceacc705e0ff4a11d435a310e3d97](https://api.github.com/repos/google/certificate-transparency-go/commits/b28beed8b9aceacc705e0ff4a11d435a310e3d97) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.3)
## v1.0.2 - Go 1.9
Published 2018-06-01 14:00:00 +0000 UTC
Go 1.9 is now required to build the code.
Commit [3aed33d672ee43f04b1e8a00b25ca3e2e2e74309](https://api.github.com/repos/google/certificate-transparency-go/commits/3aed33d672ee43f04b1e8a00b25ca3e2e2e74309) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.2)
## v1.0.1 - Hammer and client improvements
Published 2018-06-01 13:59:29 +0000 UTC
Commit [c28796cc21776667fb05d6300e32d9517be96515](https://api.github.com/repos/google/certificate-transparency-go/commits/c28796cc21776667fb05d6300e32d9517be96515) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0.1)
## v1.0 - First Trillian CT Release
Published 2018-06-01 13:59:00 +0000 UTC
This is the point that corresponds to the 1.0 release in the trillian repo.
Commit [abb79e468b6f3bbd48d1ab0c9e68febf80d52c4d](https://api.github.com/repos/google/certificate-transparency-go/commits/abb79e468b6f3bbd48d1ab0c9e68febf80d52c4d) Download [zip](https://api.github.com/repos/google/certificate-transparency-go/zipball/v1.0)

View File

@ -22,7 +22,7 @@ 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,proto3" json:"shard,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
@ -62,17 +62,17 @@ func (m *TemporalLogConfig) GetShard() []*LogShardConfig {
// LogShardConfig describes the acceptable date range for a single shard of a temporal
// log.
type LogShardConfig struct {
Uri string `protobuf:"bytes,1,opt,name=uri" json:"uri,omitempty"`
Uri string `protobuf:"bytes,1,opt,name=uri,proto3" json:"uri,omitempty"`
// The log's public key in DER-encoded PKIX form.
PublicKeyDer []byte `protobuf:"bytes,2,opt,name=public_key_der,json=publicKeyDer,proto3" json:"public_key_der,omitempty"`
// 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 *timestamp.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,proto3" 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 *timestamp.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,proto3" json:"not_after_limit,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`

View File

@ -0,0 +1,10 @@
steps:
- id: build_ctfe
name: gcr.io/cloud-builders/docker
args:
- build
- --file=trillian/examples/deployment/docker/ctfe/Dockerfile
- --tag=gcr.io/${PROJECT_ID}/ctfe:${TAG_NAME}
- .
images:
- gcr.io/${PROJECT_ID}/ctfe:${TAG_NAME}

View File

@ -1,4 +1,5 @@
{
"Deadline": "60s",
"Linters": {
"license": "./scripts/check_license.sh:PATH:LINE:MESSAGE",
"forked": "./scripts/check_forked.sh:PATH:LINE:MESSAGE",

View File

@ -0,0 +1,37 @@
all: ca
# The following private keys are never regenerated.
SERVER_PRIVKEYS=gossiper.privkey.pem
# Server public keys are derived from the corresponding private keys.
SERVER_PUBKEYS=$(subst .privkey,.pubkey,$(SERVER_PRIVKEYS))
# Build public keys from private keys
pubkeys: $(SERVER_PUBKEYS)
gossiper.pubkey.pem: gossiper.privkey.pem
openssl ec -in $< -pubout -out $@ -passin pass:$(GOSSIPER_PWD)
ROOT_CA_PRIVKEY=gossiper.privkey.pem
ROOT_CA_PWD=hissing-sid
ca: root-ca.cert
# Fake Root CA
root-ca.cert: gossiper.privkey.pem root-ca.cfg
openssl req -new -x509 -config root-ca.cfg -set_serial 0x0406cafe -days 3650 -extensions v3_ca -inform pem -key gossiper.privkey.pem -passin pass:$(ROOT_CA_PWD) -out $@
show-ca: root-ca.cert
openssl x509 -inform pem -in $< -text -noout
# clean removes things that regenerate exactly the same.
clean:
rm -f $(SERVER_PUBKEYS)
# distclean removes things that regenerate with changes (e.g. timestamped, randomized).
distclean: clean
rm -f $(SERVER_PUBKEYS) root-ca.cert
# The newkey target creates a fresh private key; should never be needed.
newkey: fresh.privkey.pem
fresh.privkey.pem:
openssl ecparam -genkey -name prime256v1 -noout -out $@.unencrypted
openssl ec -in $@.unencrypted -out $@ -des # Prompts for password
rm -f $@.unencrypted

View File

@ -0,0 +1,32 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
public_key: {
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
}
>
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source-2"
min_req_interval: <
seconds: 3600
>
public_key: {
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
}
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,17 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
public_key: {
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
}
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>

View File

@ -0,0 +1,8 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-CBC,559BE893ECD7A88C
UOwSw+WlSv5LLiBZSCnR12FX13Hk1a3vavdpUde4W4qawQgJSMqLa3it8Lfadtnm
GfGVqN+gF5KFiNWxgMs2qRcbdQ03ZlMmoH8Z8jPQHXvKseJvME8tZQWPvJ15rbXh
G9Lcx7NYlm0miHPy3ras8ci58HSDqz9Z7yOdgHzPpiU=
-----END EC PRIVATE KEY-----

View File

@ -0,0 +1,27 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
public_key: {
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
}
>
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source-2"
min_req_interval: <
seconds: 3600
>
public_key: {
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
}
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>

View File

@ -0,0 +1,13 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
>
dest_log: <
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>

View File

@ -0,0 +1,7 @@
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>

View File

@ -0,0 +1,13 @@
source_log: <
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>

View File

@ -0,0 +1,19 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gone.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,19 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CARTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,20 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 10
nanos: -20
>
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,22 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
public_key: {
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d"
}
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,15 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
public_key: {
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
}
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,18 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
>
dest_log: <
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,15 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"

View File

@ -0,0 +1,18 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,12 @@
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,18 @@
source_log: <
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICQTCCAeegAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP
MA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds
ZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4
MDIyNTA4MTA1M1oXDTI4MDIyMzA4MTA1M1owaTELMAkGA1UEBhMCR0IxDzANBgNV
BAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK
BgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH
ccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijfTB7MB0GA1UdDgQWBBRq
6hoXslGgHhrCVJMu4jrYlksyZjAfBgNVHSMEGDAWgBRq6hoXslGgHhrCVJMu4jrY
lksyZjASBgNVHRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwICBDAVBgNVHSUE
DjAMBgorBgEEAdZ5AgQGMAoGCCqGSM49BAMCA0gAMEUCIQCQCnWTIOlC6LqkcdH0
fWZeNo5E3AaZBb9Tkv76ET2fJAIgOeGJvfiiOIlDV41/bIOg5eTHb/fxg80TCQBe
6ia6ZS8=
-----END CERTIFICATE-----

View File

@ -0,0 +1,28 @@
# OpenSSL configuration file.
[ req ]
# Options for the `req` tool (`man req`).
default_bits = 2048
distinguished_name = req_distinguished_name
prompt = no
# SHA-1 is deprecated, so use SHA-2 instead.
default_md = sha256
# Extension to add when the -x509 option is used.
x509_extensions = v3_ca
# Try to force use of PrintableString throughout
string_mask = pkix
[ req_distinguished_name ]
C=GB
ST=London
L=London
O=Google
OU=Eng
CN=TestGossiperRoot
[ v3_ca ]
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true, pathlen:3
keyUsage = critical, keyCertSign
extendedKeyUsage = 1.3.6.1.4.1.11129.2.4.6

View File

@ -0,0 +1,22 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
public_key: {
der: "\x30\x59\x30\x13\x06\x07\x2a\x86\x48\xce\x3d\x02\x01\x06\x08\x2a\x86\x48\xce\x3d\x03\x01\x07\x03\x42\x00\x04\x07\xf8\x51\xaf\xaa\x8c\x56\x83\x90\x31\xb7\x80\xe3\xd6\x1a\xf7\x2f\x36\x06\x71\xec\xdd\x3b\xbe\x7e\x36\x6f\x0d\x1c\x1c\x60\x0b\x7f\xf5\x9f\xff\xe5\x24\x49\x34\x56\xf2\x4b\x10\x5f\xbf\x08\x1f\xf9\x0e\xcf\x35\xb5\x8a\x8a\x8b\x30\x0a\x54\xb7\xbf\x1d\x4d\xb9"
}
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013hissing-sid"
>

View File

@ -0,0 +1,19 @@
source_log: <
name: "theSourceOfAllSTHs"
url: "http://example.com/ct-source"
min_req_interval: <
seconds: 3600
>
>
dest_log: <
name: "theDestinationOfAllSTHs"
url: "http://example.com/ct-dest"
min_req_interval: <
seconds: 60
>
>
root_cert: "-----BEGIN CERTIFICATE-----\nMIICCzCCAbCgAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP\nMA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds\nZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4\nMDIyMzEzNDUyOVoXDTI4MDIyMTEzNDUyOVowaTELMAkGA1UEBhMCR0IxDzANBgNV\nBAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK\nBgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49\nAgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH\nccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijRjBEMA0GA1UdDgQGBAQR\nEhMUMA8GA1UdIwQIMAaABBESExQwEgYDVR0TAQH/BAgwBgEB/wIBAzAOBgNVHQ8B\nAf8EBAMCAgQwCgYIKoZIzj0EAwIDSQAwRgIhAICXxzQ+EulZALo8em3KujsOCpNY\n6lvLF5lqBMLS9fxwAiEAkh54N7Dq6P+3Sl/u15TA5DKhFPqgnvnB51wXGAsDhN0=\n-----END CERTIFICATE-----"
private_key: <
type_url: "type.googleapis.com/keyspb.PEMKeyFile"
value: "\n\035testdata/gossiper.privkey.pem\022\013passing-sid"
>

View File

@ -0,0 +1,91 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package x509ext holds extensions types and values for minimal gossip.
package x509ext
import (
"errors"
"fmt"
"github.com/google/certificate-transparency-go"
"github.com/google/certificate-transparency-go/asn1"
"github.com/google/certificate-transparency-go/tls"
"github.com/google/certificate-transparency-go/x509"
)
// OIDExtensionCTSTH is the OID value for an X.509 extension that holds
// a log STH value.
// TODO(drysdale): get an official OID value
var OIDExtensionCTSTH = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 5}
// OIDExtKeyUsageCTMinimalGossip is the OID value for an extended key usage
// (EKU) that indicates a leaf certificate is used for the validation of STH
// values from public CT logs.
// TODO(drysdale): get an official OID value
var OIDExtKeyUsageCTMinimalGossip = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11129, 2, 4, 6}
// LogSTHInfo is the structure that gets TLS-encoded into the X.509 extension
// identified by OIDExtensionCTSTH.
type LogSTHInfo struct {
LogURL []byte `tls:"maxlen:255"`
Version tls.Enum `tls:"maxval:255"`
TreeSize uint64
Timestamp uint64
SHA256RootHash ct.SHA256Hash
TreeHeadSignature ct.DigitallySigned
}
// LogSTHInfoFromCert retrieves the STH information embedded in a certificate.
func LogSTHInfoFromCert(cert *x509.Certificate) (*LogSTHInfo, error) {
for _, ext := range cert.Extensions {
if ext.Id.Equal(OIDExtensionCTSTH) {
var sthInfo LogSTHInfo
rest, err := tls.Unmarshal(ext.Value, &sthInfo)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal STH: %v", err)
} else if len(rest) > 0 {
return nil, fmt.Errorf("trailing data (%d bytes) after STH", len(rest))
}
return &sthInfo, nil
}
}
return nil, errors.New("no STH extension found")
}
// HasSTHInfo indicates whether a certificate has embedded STH information.
func HasSTHInfo(cert *x509.Certificate) bool {
for _, ext := range cert.Extensions {
if ext.Id.Equal(OIDExtensionCTSTH) {
return true
}
}
return false
}
// STHFromCert retrieves the STH embedded in a certificate; note the returned STH
// does not have the LogID field filled in.
func STHFromCert(cert *x509.Certificate) (*ct.SignedTreeHead, error) {
sthInfo, err := LogSTHInfoFromCert(cert)
if err != nil {
return nil, err
}
return &ct.SignedTreeHead{
Version: ct.Version(sthInfo.Version),
TreeSize: sthInfo.TreeSize,
Timestamp: sthInfo.Timestamp,
SHA256RootHash: sthInfo.SHA256RootHash,
TreeHeadSignature: sthInfo.TreeHeadSignature,
}, nil
}

View File

@ -0,0 +1,150 @@
// Copyright 2018 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package x509ext_test
import (
"encoding/hex"
"encoding/pem"
"fmt"
"strings"
"testing"
"time"
"github.com/google/certificate-transparency-go"
"github.com/google/certificate-transparency-go/gossip/minimal/x509ext"
"github.com/google/certificate-transparency-go/tls"
"github.com/google/certificate-transparency-go/x509"
"github.com/google/certificate-transparency-go/x509/pkix"
)
var (
// pilotPubKeyPEM is the public key for Google's Pilot log.
pilotPubKeyPEM = []byte(`-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfahLEimAoz2t01p3uMziiLOl/fHT
DM0YDOhBRuiBARsV4UvxG2LdNgoIGLrtCzWE0J5APC2em4JlvR8EEEFMoA==
-----END PUBLIC KEY-----`)
)
func TestSTHFromCert(t *testing.T) {
rawPubKey, _ := pem.Decode(pilotPubKeyPEM)
pubKey, _, _, err := ct.PublicKeyFromPEM(pilotPubKeyPEM)
if err != nil {
t.Fatalf("failed to decode test pubkey data: %v", err)
}
validSTH := x509ext.LogSTHInfo{
LogURL: []byte("http://ct.example.com/log"),
Version: 0,
TreeSize: 7834120,
Timestamp: 1519395540364,
SHA256RootHash: [...]byte{
0xfe, 0xc0, 0xed, 0xe1, 0xbe, 0xf1, 0xa2, 0x25, 0xc3, 0x72, 0xa6, 0x44, 0x1b, 0xa2, 0xd5, 0xdd, 0x3b, 0xbb, 0x9b, 0x7b, 0xa9, 0x79, 0xd1, 0xa7, 0x03, 0xe7, 0xfe, 0x81, 0x49, 0x75, 0x85, 0xfb,
},
TreeHeadSignature: ct.DigitallySigned{
Algorithm: tls.SignatureAndHashAlgorithm{Hash: tls.SHA256, Signature: tls.ECDSA},
Signature: dehex("220164e031604aa2a0b68887ba668cefb3e0046e455d6323c3df38b8d50108895d70220146199ee1d759a029d8b37ce8701d2ca47a387bad8ac8ef1cb84b77bc0820ed"),
},
}
sthData, err := tls.Marshal(validSTH)
if err != nil {
t.Fatalf("failed to marshal STH: %v", err)
}
var tests = []struct {
name string
cert x509.Certificate
wantErr string
}{
{
name: "ValidSTH",
cert: x509.Certificate{
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
PublicKey: pubKey,
RawSubjectPublicKeyInfo: rawPubKey.Bytes,
Subject: pkix.Name{
CommonName: "Test STH holder",
},
Extensions: []pkix.Extension{
{Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: sthData},
},
},
},
{
name: "MissingSTH",
cert: x509.Certificate{
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
Subject: pkix.Name{
CommonName: "Test STH holder",
},
},
wantErr: "no STH extension found",
},
{
name: "TrailingData",
cert: x509.Certificate{
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
Subject: pkix.Name{
CommonName: "Test STH holder",
},
Extensions: []pkix.Extension{
{Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: append(sthData, 0xff)},
},
},
wantErr: "trailing data",
},
{
name: "InvalidSTH",
cert: x509.Certificate{
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
Subject: pkix.Name{
CommonName: "Test STH holder",
},
Extensions: []pkix.Extension{
{Id: x509ext.OIDExtensionCTSTH, Critical: false, Value: []byte{0xff}},
},
},
wantErr: "failed to unmarshal",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
got, err := x509ext.STHFromCert(&test.cert)
if err != nil {
if test.wantErr == "" {
t.Errorf("STHFromCert(%+v)=nil,%v; want _,nil", test.cert, err)
} else if !strings.Contains(err.Error(), test.wantErr) {
t.Errorf("STHFromCert(%+v)=nil,%v; want nil,err containing %q", test.cert, err, test.wantErr)
}
return
}
if test.wantErr != "" {
t.Errorf("STHFromCert(%+v)=_,nil; want nil,err containing %q", test.cert, test.wantErr)
}
t.Logf("retrieved STH %+v", got)
})
}
}
func dehex(h string) []byte {
d, err := hex.DecodeString(h)
if err != nil {
panic(fmt.Sprintf("hard-coded data %q failed to decode! %v", h, err))
}
return d
}

View File

@ -22,7 +22,6 @@ import (
"crypto/sha256"
"encoding/base64"
"encoding/pem"
"flag"
"fmt"
"log"
@ -30,8 +29,10 @@ import (
"github.com/google/certificate-transparency-go/x509"
)
var allowVerificationWithNonCompliantKeys = flag.Bool("allow_verification_with_non_compliant_keys", false,
"Allow a SignatureVerifier to use keys which are technically non-compliant with RFC6962.")
// AllowVerificationWithNonCompliantKeys may be set to true in order to allow
// SignatureVerifier to use keys which are technically non-compliant with
// RFC6962.
var AllowVerificationWithNonCompliantKeys = false
// PublicKeyFromPEM parses a PEM formatted block and returns the public key contained within and any remaining unread bytes, or an error.
func PublicKeyFromPEM(b []byte) (crypto.PublicKey, SHA256Hash, []byte, error) {
@ -63,7 +64,7 @@ func NewSignatureVerifier(pk crypto.PublicKey) (*SignatureVerifier, error) {
case *rsa.PublicKey:
if pkType.N.BitLen() < 2048 {
e := fmt.Errorf("public key is RSA with < 2048 bits (size:%d)", pkType.N.BitLen())
if !(*allowVerificationWithNonCompliantKeys) {
if !AllowVerificationWithNonCompliantKeys {
return nil, e
}
log.Printf("WARNING: %v", e)
@ -72,7 +73,7 @@ func NewSignatureVerifier(pk crypto.PublicKey) (*SignatureVerifier, error) {
params := *(pkType.Params())
if params != *elliptic.P256().Params() {
e := fmt.Errorf("public is ECDSA, but not on the P256 curve")
if !(*allowVerificationWithNonCompliantKeys) {
if !AllowVerificationWithNonCompliantKeys {
return nil, e
}
log.Printf("WARNING: %v", e)

View File

@ -471,7 +471,7 @@ func TestNewSignatureVerifierFailsWithBadKeyParametersForRSA(t *testing.T) {
}
func TestWillAllowNonCompliantECKeyWithOverride(t *testing.T) {
*allowVerificationWithNonCompliantKeys = true
AllowVerificationWithNonCompliantKeys = true
k, err := ecdsa.GenerateKey(elliptic.P224(), rand.Reader)
if err != nil {
t.Fatalf("Failed to generate EC key on P224: %v", err)
@ -482,7 +482,7 @@ func TestWillAllowNonCompliantECKeyWithOverride(t *testing.T) {
}
func TestWillAllowNonCompliantRSAKeyWithOverride(t *testing.T) {
*allowVerificationWithNonCompliantKeys = true
AllowVerificationWithNonCompliantKeys = true
k, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
t.Fatalf("Failed to generate 1024 bit RSA key: %v", err)

View File

@ -0,0 +1,15 @@
-----BEGIN CERTIFICATE-----
MIICQTCCAeegAwIBAgIEBAbK/jAKBggqhkjOPQQDAjBpMQswCQYDVQQGEwJHQjEP
MA0GA1UECBMGTG9uZG9uMQ8wDQYDVQQHEwZMb25kb24xDzANBgNVBAoTBkdvb2ds
ZTEMMAoGA1UECxMDRW5nMRkwFwYDVQQDExBUZXN0R29zc2lwZXJSb290MB4XDTE4
MDIyNTA4MTA1M1oXDTI4MDIyMzA4MTA1M1owaTELMAkGA1UEBhMCR0IxDzANBgNV
BAgTBkxvbmRvbjEPMA0GA1UEBxMGTG9uZG9uMQ8wDQYDVQQKEwZHb29nbGUxDDAK
BgNVBAsTA0VuZzEZMBcGA1UEAxMQVGVzdEdvc3NpcGVyUm9vdDBZMBMGByqGSM49
AgEGCCqGSM49AwEHA0IABOqzZufPSU6hMJOIbljkjklDvQKBGYW9VenI6i7HSiyH
ccPUuh3F3fbbe2MrLtuRCjH7nqvcELPqBJsL3IVgQJijfTB7MB0GA1UdDgQWBBRq
6hoXslGgHhrCVJMu4jrYlksyZjAfBgNVHSMEGDAWgBRq6hoXslGgHhrCVJMu4jrY
lksyZjASBgNVHRMBAf8ECDAGAQH/AgEDMA4GA1UdDwEB/wQEAwICBDAVBgNVHSUE
DjAMBgorBgEEAdZ5AgQGMAoGCCqGSM49BAMCA0gAMEUCIQCQCnWTIOlC6LqkcdH0
fWZeNo5E3AaZBb9Tkv76ET2fJAIgOeGJvfiiOIlDV41/bIOg5eTHb/fxg80TCQBe
6ia6ZS8=
-----END CERTIFICATE-----

View File

@ -0,0 +1,8 @@
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-CBC,559BE893ECD7A88C
UOwSw+WlSv5LLiBZSCnR12FX13Hk1a3vavdpUde4W4qawQgJSMqLa3it8Lfadtnm
GfGVqN+gF5KFiNWxgMs2qRcbdQ03ZlMmoH8Z8jPQHXvKseJvME8tZQWPvJ15rbXh
G9Lcx7NYlm0miHPy3ras8ci58HSDqz9Z7yOdgHzPpiU=
-----END EC PRIVATE KEY-----

View File

@ -374,7 +374,27 @@ func (m *MerkleTreeLeaf) Precertificate() (*x509.Certificate, error) {
return x509.ParseTBSCertificate(m.TimestampedEntry.PrecertEntry.TBSCertificate)
}
// APIEndpoint is a string that represents one of the Certificate Transparency
// Log API endpoints.
type APIEndpoint string
// Certificate Transparency Log API endpoints; see section 4.
// WARNING: Should match the URI paths without the "/ct/v1/" prefix. If
// changing these constants, may need to change those too.
const (
AddChainStr APIEndpoint = "add-chain"
AddPreChainStr APIEndpoint = "add-pre-chain"
GetSTHStr APIEndpoint = "get-sth"
GetEntriesStr APIEndpoint = "get-entries"
GetProofByHashStr APIEndpoint = "get-proof-by-hash"
GetSTHConsistencyStr APIEndpoint = "get-sth-consistency"
GetRootsStr APIEndpoint = "get-roots"
GetEntryAndProofStr APIEndpoint = "get-entry-and-proof"
)
// URI paths for Log requests; see section 4.
// WARNING: Should match the API endpoints, with the "/ct/v1/" prefix. If
// changing these constants, may need to change those too.
const (
AddChainPath = "/ct/v1/add-chain"
AddPreChainPath = "/ct/v1/add-pre-chain"

View File

@ -0,0 +1,20 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build go1.11
package x509
import (
"syscall"
"unsafe"
)
// For Go versions >= 1.11, the ExtraPolicyPara field in
// syscall.CertChainPolicyPara is of type syscall.Pointer. See:
// https://github.com/golang/go/commit/4869ec00e87ef
func convertToPolicyParaType(p unsafe.Pointer) syscall.Pointer {
return (syscall.Pointer)(p)
}

View File

@ -0,0 +1,17 @@
// Copyright 2018 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !go1.11
package x509
import "unsafe"
// For Go versions before 1.11, the ExtraPolicyPara field in
// syscall.CertChainPolicyPara was of type uintptr. See:
// https://github.com/golang/go/commit/4869ec00e87ef
func convertToPolicyParaType(p unsafe.Pointer) uintptr {
return uintptr(p)
}

View File

@ -109,7 +109,7 @@ func checkChainSSLServerPolicy(c *Certificate, chainCtx *syscall.CertChainContex
sslPara.Size = uint32(unsafe.Sizeof(*sslPara))
para := &syscall.CertChainPolicyPara{
ExtraPolicyPara: uintptr(unsafe.Pointer(sslPara)),
ExtraPolicyPara: convertToPolicyParaType(unsafe.Pointer(sslPara)),
}
para.Size = uint32(unsafe.Sizeof(*para))

View File

@ -1446,7 +1446,7 @@ func isValidIPMask(mask []byte) bool {
return true
}
func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandled bool, err error) {
func parseNameConstraintsExtension(out *Certificate, e pkix.Extension, nfe *NonFatalErrors) (unhandled bool, err error) {
// RFC 5280, 4.2.1.10
// NameConstraints ::= SEQUENCE {
@ -1513,7 +1513,7 @@ func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandle
trimmedDomain = trimmedDomain[1:]
}
if _, ok := domainToReverseLabels(trimmedDomain); !ok {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse dnsName constraint %q", domain)
nfe.AddError(fmt.Errorf("x509: failed to parse dnsName constraint %q", domain))
}
dnsNames = append(dnsNames, domain)
@ -1550,7 +1550,7 @@ func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandle
// it specifies an exact mailbox name.
if strings.Contains(constraint, "@") {
if _, ok := parseRFC2821Mailbox(constraint); !ok {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
nfe.AddError(fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint))
}
} else {
// Otherwise it's a domain name.
@ -1559,7 +1559,7 @@ func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandle
domain = domain[1:]
}
if _, ok := domainToReverseLabels(domain); !ok {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint)
nfe.AddError(fmt.Errorf("x509: failed to parse rfc822Name constraint %q", constraint))
}
}
emails = append(emails, constraint)
@ -1583,7 +1583,7 @@ func parseNameConstraintsExtension(out *Certificate, e pkix.Extension) (unhandle
trimmedDomain = trimmedDomain[1:]
}
if _, ok := domainToReverseLabels(trimmedDomain); !ok {
return nil, nil, nil, nil, fmt.Errorf("x509: failed to parse URI constraint %q", domain)
nfe.AddError(fmt.Errorf("x509: failed to parse URI constraint %q", domain))
}
uriDomains = append(uriDomains, domain)
@ -1698,7 +1698,7 @@ func parseCertificate(in *certificate) (*Certificate, error) {
}
case OIDExtensionNameConstraints[3]:
unhandled, err = parseNameConstraintsExtension(out, e)
unhandled, err = parseNameConstraintsExtension(out, e, &nfe)
if err != nil {
return nil, err
}
@ -1834,6 +1834,8 @@ func ParseTBSCertificate(asn1Data []byte) (*Certificate, error) {
}
// ParseCertificate parses a single certificate from the given ASN.1 DER data.
// This function can return both a Certificate and an error (in which case the
// error will be of type NonFatalErrors).
func ParseCertificate(asn1Data []byte) (*Certificate, error) {
var cert certificate
rest, err := asn1.Unmarshal(asn1Data, &cert)
@ -1849,6 +1851,8 @@ func ParseCertificate(asn1Data []byte) (*Certificate, error) {
// ParseCertificates parses one or more certificates from the given ASN.1 DER
// data. The certificates must be concatenated with no intermediate padding.
// This function can return both a slice of Certificate and an error (in which
// case the error will be of type NonFatalErrors).
func ParseCertificates(asn1Data []byte) ([]*Certificate, error) {
var v []*certificate
@ -1862,15 +1866,23 @@ func ParseCertificates(asn1Data []byte) ([]*Certificate, error) {
v = append(v, cert)
}
var nfe NonFatalErrors
ret := make([]*Certificate, len(v))
for i, ci := range v {
cert, err := parseCertificate(ci)
if err != nil {
return nil, err
if errs, ok := err.(NonFatalErrors); !ok {
return nil, err
} else {
nfe.Errors = append(nfe.Errors, errs.Errors...)
}
}
ret[i] = cert
}
if nfe.HasError() {
return ret, nfe
}
return ret, nil
}

View File

@ -31,6 +31,7 @@ import (
ct "github.com/google/certificate-transparency-go"
"github.com/google/certificate-transparency-go/asn1"
"github.com/google/certificate-transparency-go/gossip/minimal/x509ext"
"github.com/google/certificate-transparency-go/tls"
"github.com/google/certificate-transparency-go/x509"
"github.com/google/certificate-transparency-go/x509/pkix"
@ -426,6 +427,7 @@ func CertificateToString(cert *x509.Certificate) string {
showAuthInfoAccess(&result, cert)
showCTPoison(&result, cert)
showCTSCT(&result, cert)
showCTLogSTHInfo(&result, cert)
showUnhandledExtensions(&result, cert)
showSignature(&result, cert)
@ -621,6 +623,30 @@ func showCTSCT(result *bytes.Buffer, cert *x509.Certificate) {
}
}
func showCTLogSTHInfo(result *bytes.Buffer, cert *x509.Certificate) {
count, critical := OIDInExtensions(x509ext.OIDExtensionCTSTH, cert.Extensions)
if count > 0 {
result.WriteString(fmt.Sprintf(" Certificate Transparency STH:"))
showCritical(result, critical)
sthInfo, err := x509ext.LogSTHInfoFromCert(cert)
if err != nil {
result.WriteString(fmt.Sprintf(" Failed to decode STH:\n"))
return
}
result.WriteString(fmt.Sprintf(" LogURL: %s\n", string(sthInfo.LogURL)))
result.WriteString(fmt.Sprintf(" Version: %d\n", sthInfo.Version))
result.WriteString(fmt.Sprintf(" TreeSize: %d\n", sthInfo.TreeSize))
result.WriteString(fmt.Sprintf(" Timestamp: %d\n", sthInfo.Timestamp))
result.WriteString(fmt.Sprintf(" RootHash:\n"))
appendHexData(result, sthInfo.SHA256RootHash[:], 16, " ")
result.WriteString("\n")
result.WriteString(fmt.Sprintf(" TreeHeadSignature: %s\n", sthInfo.TreeHeadSignature.Algorithm))
result.WriteString(fmt.Sprintf(" TreeHeadSignature:\n"))
appendHexData(result, sthInfo.TreeHeadSignature.Signature, 16, " ")
result.WriteString("\n")
}
}
func showUnhandledExtensions(result *bytes.Buffer, cert *x509.Certificate) {
for _, ext := range cert.Extensions {
// Skip extensions that are already cracked out
@ -653,7 +679,8 @@ func oidAlreadyPrinted(oid asn1.ObjectIdentifier) bool {
oid.Equal(x509.OIDExtensionCRLDistributionPoints) ||
oid.Equal(x509.OIDExtensionAuthorityInfoAccess) ||
oid.Equal(x509.OIDExtensionCTPoison) ||
oid.Equal(x509.OIDExtensionCTSCT) {
oid.Equal(x509.OIDExtensionCTSCT) ||
oid.Equal(x509ext.OIDExtensionCTSTH) {
return true
}
return false
@ -717,8 +744,10 @@ func ExtractSCT(sctData *x509.SerializedSCT) (*ct.SignedCertificateTimestamp, er
return nil, errors.New("SCT is nil")
}
var sct ct.SignedCertificateTimestamp
if _, err := tls.Unmarshal(sctData.Val, &sct); err != nil {
if rest, err := tls.Unmarshal(sctData.Val, &sct); err != nil {
return nil, fmt.Errorf("error parsing SCT: %s", err)
} else if len(rest) > 0 {
return nil, fmt.Errorf("extra data (%d bytes) after serialized SCT", len(rest))
}
return &sct, nil
}