Skip to content

Commit

Permalink
feat: Timestamp (notaryproject#978)
Browse files Browse the repository at this point in the history
Signed-off-by: Patrick Zheng <[email protected]>
  • Loading branch information
Two-Hearts authored Jul 22, 2024
1 parent 26c0b36 commit a034721
Show file tree
Hide file tree
Showing 36 changed files with 649 additions and 83 deletions.
3 changes: 3 additions & 0 deletions cmd/notation/cert/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ Example - Add a certificate to the "ca" type of a named store "acme-rockets":
Example - Add a certificate to the "signingAuthority" type of a named store "wabbit-networks":
notation cert add --type signingAuthority --store wabbit-networks wabbit-networks.pem
Example - Add a certificate to the "tsa" type of a named store "timestamp":
notation cert add --type tsa --store timestamp wabbit-networks-timestamp.pem
`,
RunE: func(cmd *cobra.Command, args []string) error {
return addCerts(opts)
Expand Down
3 changes: 3 additions & 0 deletions cmd/notation/cert/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ Example - Delete certificate "cert1.pem" with "signingAuthority" type from trust
Example - Delete all certificates with "ca" type from the trust store "acme-rockets", without prompt for confirmation:
notation cert delete --type ca --store acme-rockets -y --all
Example - Delete certificate "wabbit-networks-timestamp.pem" with "tsa" type from trust store timestamp:
notation cert delete --type tsa --store timestamp wabbit-networks-timestamp.pem -y
`,
RunE: func(cmd *cobra.Command, args []string) error {
return deleteCerts(opts)
Expand Down
3 changes: 3 additions & 0 deletions cmd/notation/cert/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ Example - List all certificate files from trust store of type "ca"
Example - List all certificate files from trust store "wabbit-networks" of type "signingAuthority"
notation cert ls --type signingAuthority --store "wabbit-networks"
Example - List all certificate files from trust store of type "tsa"
notation cert ls --type tsa
`,
RunE: func(cmd *cobra.Command, args []string) error {
return listCerts(cmd.Context(), opts)
Expand Down
3 changes: 3 additions & 0 deletions cmd/notation/cert/show.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ Example - Show details of certificate "cert1.pem" with type "ca" from trust stor
Example - Show details of certificate "cert2.pem" with type "signingAuthority" from trust store "wabbit-networks":
notation cert show --type signingAuthority --store wabbit-networks cert2.pem
Example - Show details of certificate "wabbit-networks-timestamp.pem" with type "tsa" from trust store "timestamp":
notation cert show --type tsa --store timestamp wabbit-networks-timestamp.pem
`,
RunE: func(cmd *cobra.Command, args []string) error {
return showCerts(cmd.Context(), opts)
Expand Down
80 changes: 70 additions & 10 deletions cmd/notation/sign.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,47 @@
package main

import (
"crypto/x509"
"errors"
"fmt"
"net/http"
"os"
"strings"
"time"

corex509 "github.com/notaryproject/notation-core-go/x509"
"github.com/notaryproject/notation-go"
"github.com/notaryproject/notation/cmd/notation/internal/experimental"
"github.com/notaryproject/notation/internal/cmd"
"github.com/notaryproject/notation/internal/envelope"
"github.com/notaryproject/notation/internal/httputil"
nx509 "github.com/notaryproject/notation/internal/x509"
"github.com/notaryproject/tspclient-go"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/spf13/cobra"
"golang.org/x/net/context"
)

const referrersTagSchemaDeleteError = "failed to delete dangling referrers index"

// timestampingTimeout is the timeout when requesting timestamp countersignature
// from a TSA
const timestampingTimeout = 15 * time.Second

type signOpts struct {
cmd.LoggingFlagOpts
cmd.SignerFlagOpts
SecureFlagOpts
expiry time.Duration
pluginConfig []string
userMetadata []string
reference string
allowReferrersAPI bool
forceReferrersTag bool
ociLayout bool
inputType inputType
expiry time.Duration
pluginConfig []string
userMetadata []string
reference string
allowReferrersAPI bool
forceReferrersTag bool
ociLayout bool
inputType inputType
tsaServerURL string
tsaRootCertificatePath string
}

func signCommand(opts *signOpts) *cobra.Command {
Expand Down Expand Up @@ -74,6 +87,9 @@ Example - Sign an OCI artifact stored in a registry and specify the signature ex
Example - Sign an OCI artifact and store signature using the Referrers API. If it's not supported, fallback to the Referrers tag schema
notation sign --force-referrers-tag=false <registry>/<repository>@<digest>
Example - Sign an OCI artifact with timestamping:
notation sign --timestamp-url <TSA_url> --timestamp-root-cert <TSA_root_certificate_filepath> <registry>/<repository>@<digest>
`
experimentalExamples := `
Example - [Experimental] Sign an OCI artifact referenced in an OCI layout
Expand Down Expand Up @@ -101,6 +117,16 @@ Example - [Experimental] Sign an OCI artifact identified by a tag and referenced
return experimental.CheckFlagsAndWarn(cmd, "allow-referrers-api", "oci-layout")
},
RunE: func(cmd *cobra.Command, args []string) error {
// timestamping
if cmd.Flags().Changed("timestamp-url") {
if opts.tsaServerURL == "" {
return errors.New("timestamping: tsa url cannot be empty")
}
if opts.tsaRootCertificatePath == "" {
return errors.New("timestamping: tsa root certificate path cannot be empty")
}
}

// allow-referrers-api flag is set
if cmd.Flags().Changed("allow-referrers-api") {
if opts.allowReferrersAPI {
Expand All @@ -120,9 +146,12 @@ Example - [Experimental] Sign an OCI artifact identified by a tag and referenced
cmd.SetPflagPluginConfig(command.Flags(), &opts.pluginConfig)
cmd.SetPflagUserMetadata(command.Flags(), &opts.userMetadata, cmd.PflagUserMetadataSignUsage)
cmd.SetPflagReferrersAPI(command.Flags(), &opts.allowReferrersAPI, fmt.Sprintf(cmd.PflagReferrersUsageFormat, "sign"))
command.Flags().StringVar(&opts.tsaServerURL, "timestamp-url", "", "RFC 3161 Timestamping Authority (TSA) server URL")
command.Flags().StringVar(&opts.tsaRootCertificatePath, "timestamp-root-cert", "", "filepath of timestamp authority root certificate")
cmd.SetPflagReferrersTag(command.Flags(), &opts.forceReferrersTag, "force to store signatures using the referrers tag schema")
command.Flags().BoolVar(&opts.ociLayout, "oci-layout", false, "[Experimental] sign the artifact stored as OCI image layout")
command.MarkFlagsMutuallyExclusive("oci-layout", "force-referrers-tag", "allow-referrers-api")
command.MarkFlagsRequiredTogether("timestamp-url", "timestamp-root-cert")
experimental.HideFlags(command, experimentalExamples, []string{"oci-layout"})
return command
}
Expand All @@ -140,7 +169,7 @@ func runSign(command *cobra.Command, cmdOpts *signOpts) error {
if err != nil {
return err
}
signOpts, err := prepareSigningOpts(cmdOpts)
signOpts, err := prepareSigningOpts(ctx, cmdOpts)
if err != nil {
return err
}
Expand Down Expand Up @@ -168,7 +197,7 @@ func runSign(command *cobra.Command, cmdOpts *signOpts) error {
return nil
}

func prepareSigningOpts(opts *signOpts) (notation.SignOptions, error) {
func prepareSigningOpts(ctx context.Context, opts *signOpts) (notation.SignOptions, error) {
mediaType, err := envelope.GetEnvelopeMediaType(opts.SignerFlagOpts.SignatureFormat)
if err != nil {
return notation.SignOptions{}, err
Expand All @@ -189,5 +218,36 @@ func prepareSigningOpts(opts *signOpts) (notation.SignOptions, error) {
},
UserMetadata: userMetadata,
}
if opts.tsaServerURL != "" {
// timestamping
fmt.Printf("Configured to timestamp with TSA %q\n", opts.tsaServerURL)
signOpts.Timestamper, err = tspclient.NewHTTPTimestamper(httputil.NewClient(ctx, &http.Client{Timeout: timestampingTimeout}), opts.tsaServerURL)
if err != nil {
return notation.SignOptions{}, fmt.Errorf("cannot get http timestamper for timestamping: %w", err)
}

rootCerts, err := corex509.ReadCertificateFile(opts.tsaRootCertificatePath)
if err != nil {
return notation.SignOptions{}, err
}
if len(rootCerts) == 0 {
return notation.SignOptions{}, fmt.Errorf("cannot find any certificate from %q. Expecting single x509 root certificate in PEM or DER format from the file", opts.tsaRootCertificatePath)
}
if len(rootCerts) > 1 {
return notation.SignOptions{}, fmt.Errorf("found more than one certificates from %q. Expecting single x509 root certificate in PEM or DER format from the file", opts.tsaRootCertificatePath)
}
tsaRootCert := rootCerts[0]
isRoot, err := nx509.IsRootCertificate(tsaRootCert)
if err != nil {
return notation.SignOptions{}, fmt.Errorf("failed to check root certificate with error: %w", err)
}
if !isRoot {
return notation.SignOptions{}, fmt.Errorf("certificate from %q is not a root certificate. Expecting single x509 root certificate in PEM or DER format from the file", opts.tsaRootCertificatePath)

}
rootCAs := x509.NewCertPool()
rootCAs.AddCert(tsaRootCert)
signOpts.TSARootCAs = rootCAs
}
return signOpts, nil
}
12 changes: 7 additions & 5 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,22 @@ module github.com/notaryproject/notation
go 1.22

require (
github.com/notaryproject/notation-core-go v1.0.3
github.com/notaryproject/notation-go v1.1.1
github.com/notaryproject/notation-core-go v1.0.4-0.20240716001320-f45197cbd53b
github.com/notaryproject/notation-go v1.1.1-0.20240719045753-83409204754a
github.com/notaryproject/tspclient-go v0.1.1-0.20240715235637-df25ef8d2172
github.com/opencontainers/go-digest v1.0.0
github.com/opencontainers/image-spec v1.1.0
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.1
github.com/spf13/pflag v1.0.5
golang.org/x/net v0.22.0
golang.org/x/term v0.22.0
oras.land/oras-go/v2 v2.5.0
)

require (
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect
github.com/fxamacker/cbor/v2 v2.6.0 // indirect
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.5 // indirect
github.com/go-ldap/ldap/v3 v3.4.8 // indirect
github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
Expand All @@ -25,8 +27,8 @@ require (
github.com/notaryproject/notation-plugin-framework-go v1.0.0 // indirect
github.com/veraison/go-cose v1.1.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
golang.org/x/crypto v0.23.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/crypto v0.25.0 // indirect
golang.org/x/mod v0.19.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.22.0 // indirect
)
22 changes: 12 additions & 10 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/fxamacker/cbor/v2 v2.6.0 h1:sU6J2usfADwWlYDAFhZBQ6TnLFBHxgesMrQfQgk1tWA=
github.com/fxamacker/cbor/v2 v2.6.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
github.com/go-asn1-ber/asn1-ber v1.5.5 h1:MNHlNMBDgEKD4TcKr36vQN68BA00aDfjIt3/bD50WnA=
github.com/go-asn1-ber/asn1-ber v1.5.5/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ=
Expand Down Expand Up @@ -35,12 +35,14 @@ github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh6
github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs=
github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY=
github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc=
github.com/notaryproject/notation-core-go v1.0.3 h1:FCgvULSypEFrrNgvDRdHbKAGAgbXK43n/jKD9q2WECA=
github.com/notaryproject/notation-core-go v1.0.3/go.mod h1:eDo5/LTUp23mB7w0CckJLnl+p93oGdyiKDzzggpqTH4=
github.com/notaryproject/notation-go v1.1.1 h1:EAY8ERBWhrdaG9MIumSZ9xyUHktgr6OkCByd75HR+FA=
github.com/notaryproject/notation-go v1.1.1/go.mod h1:XykI2i5jHb6cGf+bcG/cIeNfNO2u4Xoy2mkuOKHjVVI=
github.com/notaryproject/notation-core-go v1.0.4-0.20240716001320-f45197cbd53b h1:uJ4bmNieZRkPj3UgmKr3bZr8vs7UJ2MdlJMeB0oOaZw=
github.com/notaryproject/notation-core-go v1.0.4-0.20240716001320-f45197cbd53b/go.mod h1:MdxSbL9F5h63EmtXWfYMWy7hEmGmOmsfN4B6KM2WyhY=
github.com/notaryproject/notation-go v1.1.1-0.20240719045753-83409204754a h1:o3kYOcQii0dMaDKdxnr1wPlEskXHHkDZDDb3kuss+W0=
github.com/notaryproject/notation-go v1.1.1-0.20240719045753-83409204754a/go.mod h1:FwHtZC29bBvFdJu0NYM5MHxSrHJGwhkPRvEgevNo9wo=
github.com/notaryproject/notation-plugin-framework-go v1.0.0 h1:6Qzr7DGXoCgXEQN+1gTZWuJAZvxh3p8Lryjn5FaLzi4=
github.com/notaryproject/notation-plugin-framework-go v1.0.0/go.mod h1:RqWSrTOtEASCrGOEffq0n8pSg2KOgKYiWqFWczRSics=
github.com/notaryproject/tspclient-go v0.1.1-0.20240715235637-df25ef8d2172 h1:Q8UsmeFMzyFuMMq4dlbIRJUi7khEKXKUe2H2Hm3W92Y=
github.com/notaryproject/tspclient-go v0.1.1-0.20240715235637-df25ef8d2172/go.mod h1:LGyA/6Kwd2FlM0uk8Vc5il3j0CddbWSHBj/4kxQDbjs=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.1.0 h1:8SG7/vwALn54lVB/0yZ/MMwhFrPYtpEHQb2IpWsCzug=
Expand Down Expand Up @@ -73,12 +75,12 @@ golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/crypto v0.25.0 h1:ypSNr+bnYL2YhwoMt2zPxHFmbAN1KZs/njMG3hxUp30=
golang.org/x/crypto v0.25.0/go.mod h1:T+wALwcMOSE0kXgUAnPAHqTLW+XHgcELELW8VaDgm/M=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8=
golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
Expand Down
42 changes: 39 additions & 3 deletions internal/httputil/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,50 @@ import (
"oras.land/oras-go/v2/registry/remote/auth"
)

// NewAuthClient returns an *auth.Client
var userAgent = "notation/" + version.GetVersion()

// NewAuthClient returns an *auth.Client with debug log and user agent set
func NewAuthClient(ctx context.Context, httpClient *http.Client) *auth.Client {
httpClient = trace.SetHTTPDebugLog(ctx, httpClient)
client := &auth.Client{
Client: httpClient,
Cache: auth.NewCache(),
ClientID: "notation",
}
client.SetUserAgent("notation/" + version.GetVersion())
trace.SetHTTPDebugLog(ctx, client)
client.SetUserAgent(userAgent)
return client
}

// NewClient returns an *http.Client with debug log and user agent set
func NewClient(ctx context.Context, client *http.Client) *http.Client {
client = trace.SetHTTPDebugLog(ctx, client)
return SetUserAgent(client)
}

type userAgentTransport struct {
base http.RoundTripper
}

// RoundTrip returns t.Base.RoundTrip with user agent set in the request Header
func (t *userAgentTransport) RoundTrip(req *http.Request) (*http.Response, error) {
r := req.Clone(req.Context())
if r.Header == nil {
r.Header = http.Header{}
}
r.Header.Set("User-Agent", userAgent)
return t.base.RoundTrip(r)
}

// SetUserAgent sets the user agent for all out-going requests.
func SetUserAgent(client *http.Client) *http.Client {
if client == nil {
client = &http.Client{}
}
if client.Transport == nil {
client.Transport = http.DefaultTransport
}
client.Transport = &userAgentTransport{
base: client.Transport,
}
return client
}
17 changes: 17 additions & 0 deletions internal/testdata/intermediate.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICyjCCAbKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAPMQ0wCwYDVQQDDARSb290
MCAXDTIyMDYzMDE5MjAwM1oYDzMwMjExMDMxMTkyMDAzWjAYMRYwFAYDVQQDDA1J
bnRlcm1lZGlhdGUxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1JTs
aiC/7+bho43kMVyHDwCsuocYp4PvYahB59NsKDR4QbrImU5ziaQ94D0DQqthe9pm
qOW0SxN/vSRJAZFELxacrB9hc1y4MjiDYaRSt/LVx7astylBV/QRpmxWSEqp0Avu
6nMJivIa1sD0WIEchizx6jG9BI5ULr9LbJICYvMgDalQR+0JGG+rKWnf1mPZyxEu
9zEh215LCg5K56P3W5kC8fKBXSdSgTqZAvHzp6u78qet9S8gARtOEfS03A/7y7MC
U0Sn2wdQyQdci0PBsR2sTZvUw179Cr93r5aRbb3I6jXgMWHAP2vvIndb9CM9ePyY
yEy4Je7oWVVfMQ3CWQIDAQABoyYwJDASBgNVHRMBAf8ECDAGAQH/AgEBMA4GA1Ud
DwEB/wQEAwICBDANBgkqhkiG9w0BAQsFAAOCAQEALR0apUQVbWGmagLUz4Y/bRsl
mY9EJJXCiLuSxVWd3offjZfQTlGkQkCAW9FOQnm7JhEtaaHF1+AEVLo56/Gsd/hk
sXsrBagYGi72jun7QTb6j7iZ3X9zanrP3SjdkpjVnqxRfH83diSh0r68Xruq1NSK
qhUy1V+KQaXF0SSEutPqdTCoXUyxyXohVLU78uqZX/jx9Nc1XDuW9AZd+hMsLdk8
qGJqHYFvj2vOHGMTeYk8dWgMBthQeL0wdsg2AvKtAvn6FQXCN7mKCWjpFTtYsU8v
NsesS9M/i+geJjR/8/DDT3RP7S100BtCMm4XfHfmKcjXVaBh5evQVqGsa6TKLw==
-----END CERTIFICATE-----
21 changes: 21 additions & 0 deletions internal/testdata/notSelfIssued.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
-----BEGIN CERTIFICATE-----
MIIDZDCCAkygAwIBAgIBATANBgkqhkiG9w0BAQsFADBDMQswCQYDVQQGEwJVUzEJ
MAcGA1UECBMAMQkwBwYDVQQHEwAxDzANBgNVBAoTBk5vdGFyeTENMAsGA1UEAxME
dGVzdDAeFw0yNDA3MjIwNTIwMzZaFw0yNDA4MjIwNTIwMzZaMEwxCzAJBgNVBAYT
AlVTMQswCQYDVQQIEwJXQTEQMA4GA1UEBxMHU2VhdHRsZTEPMA0GA1UEChMGTm90
YXJ5MQ0wCwYDVQQDEwR0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC
AQEAp7XmYGf3p4JS/y5v6AIc/TxQvPTwIRxVmctNmDm5kG3LDUoGAAJbicTUfI/0
Un38j/PlHNKQz9hKPwV+oYotKuQrVhaA2fft+INl36tvgCAPr8yX3ToOMCLr/UlT
zQ7o9TB7IpnVT9DR9uik9MWfkz0Db5ARG1POquvSy2QM5wseEA58313YJ/7Em/Cq
FCH5s9THCfQKpb09MZ/RTEggNqU4zGADah8e1KieYeZntM/hrw7sW5oeUueKG4D4
3kvL8o7n1k6C+w8LwaOGhYXCQ51JxTE3lnmTrDdFRuKGObpNFNbLxdJPVLuHT1Nu
bwVxj5APBJQyEyja3jJ9qLQANwIDAQABo1owWDAOBgNVHQ8BAf8EBAMCAgQwEwYD
VR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBATAdBgNVHQ4EFgQU
yPScYtI4hs0+ibHaRV9BsgY734AwDQYJKoZIhvcNAQELBQADggEBABJHh3NELq1b
jcJiJX76DwDTx+FGGN96/+T5622FGg1kHeAwuxS6pQODJNrVofbrhGAqaXTDT/Tz
0b0AA5XCohmBFZQRwMh+C5QkFiIcZ9VMMBc6KTQT8DEgjI6Qo/OW2TDGOoFuAhmh
4a1ACHszuHS55Th+0TKLqeZNA6DnL9IBm0RX1FJXbqhjX52ZnRH3Zqe7uML+kxKt
LUdfnxHrpA1G2ugyAj+K7K6vth5QpezwCS1PZD2s5vlJd6clawxm5qRyyU46ow/y
7bpTSEyg6PIWWh/qv4O2t4NMa1OoRkIXx/ppsKH9XwbRg/WZ0VWlGVS6GxBtLSpG
tkyaxSRLdz0=
-----END CERTIFICATE-----
20 changes: 20 additions & 0 deletions internal/testdata/self-signed.crt
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
-----BEGIN CERTIFICATE-----
MIIDPjCCAiagAwIBAgIBeTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJVUzEL
MAkGA1UECBMCV0ExEDAOBgNVBAcTB1NlYXR0bGUxDzANBgNVBAoTBk5vdGFyeTEP
MA0GA1UEAxMGYWxwaW5lMB4XDTIzMDUwOTA0NTUxMloXDTMzMDUxMDA0NTUxMlow
TjELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAldBMRAwDgYDVQQHEwdTZWF0dGxlMQ8w
DQYDVQQKEwZOb3RhcnkxDzANBgNVBAMTBmFscGluZTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBAK5hpq1229GGLjMK6i9KZhuUO+SV7rUFnWIDiIPO5yWx
YDkl+bGroeAvJYu6MVCMQ6FMRXD9jhnG6R+sAHwY7gVgcJ1OXak87PkLp/Ii1Cr7
XkkySZeD+Br1vSQzfxs3pFG+iBCeVVkeZdsg+xqwnAlqAILXwIbTGRyJP1Xiu9nw
OeuX1YmxPl2m29Pt1EtfVCL9COsVKt5LgOVyWP/9ISWevOBqSCU9bk35HFo9VTeU
f6+ffhSMjv0Y9uwkFFOKXpcV8Sa3ArqyBmgQlUfGg1iwYlqiDE0fTYxiB3gLgETA
lmTm50J+WB9LoDrnrQpbXFLoegm+JV+uSD8J8H7DL2sCAwEAAaMnMCUwDgYDVR0P
AQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMA0GCSqGSIb3DQEBCwUAA4IB
AQAt0Nvna1c4pPn8kzoN5VvmFmeIgdO/BJpmdhdg0WIQ9aeN/xPXXaVjPp1Mk7ed
XHAvBwQr0Gyzqyy7g/h0gdnAFG7f6blrRNzbrRBCq6cNqX8iwgK/9+2OYKxk1QWj
8Gx0cvu1DN1aXjPPGgQ2j3tHjJvJv32J/zuZa8gU40RPPSLaBlc5ZjpFmyi29sKl
TeeZ+F/Ssic51qXXw2CsYGGWK5yQ3xSCxbw6bb2G/s/YI7/KlWg9BktBJHzRu04Z
NR77W7/dyJ3Lj17PlW1XKmMOFHsQivagXeRCbmYZ43fX4ugFRFKL7KE0EgmGOWpJ
0xv+6ig93sqHzQ/0uv1YgFov
-----END CERTIFICATE-----
Binary file added internal/testdata/tsaRootCA.cer
Binary file not shown.
Loading

0 comments on commit a034721

Please sign in to comment.