diff --git a/security/advancedtls/advancedtls.go b/security/advancedtls/advancedtls.go new file mode 100644 index 00000000..ce7fb2e0 --- /dev/null +++ b/security/advancedtls/advancedtls.go @@ -0,0 +1,412 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * 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 advancedtls is a utility library containing functions to construct +// credentials.TransportCredentials that can perform credential reloading and custom +// server authorization. +package advancedtls + +import ( + "context" + "crypto/tls" + "crypto/x509" + "fmt" + "net" + "syscall" + "time" + + "google.golang.org/grpc/credentials" +) + +// VerificationFuncParams contains the parameters available to users when implementing CustomVerificationFunc. +type VerificationFuncParams struct { + ServerName string + RawCerts [][]byte + VerifiedChains [][]*x509.Certificate +} + +// VerificationResults contains the information about results of CustomVerificationFunc. +// VerificationResults is an empty struct for now. It may be extended in the future to include more information. +type VerificationResults struct{} + +// CustomVerificationFunc is the function defined by users to perform custom server authorization. +// CustomVerificationFunc returns nil if the authorization fails; otherwise returns an empty struct. +type CustomVerificationFunc func(params *VerificationFuncParams) (*VerificationResults, error) + +// GetRootCAsParams contains the parameters available to users when implementing GetRootCAs. +type GetRootCAsParams struct { + RawConn net.Conn + RawCerts [][]byte +} + +// GetRootCAsResults contains the results of GetRootCAs. +// If users want to reload the root trust certificate, it is required to return the proper TrustCerts in GetRootCAs. +type GetRootCAsResults struct { + TrustCerts *x509.CertPool +} + +// RootCertificateOptions contains a field and a function for obtaining root trust certificates. +// It is used by both ClientOptions and ServerOptions. Note that RootCertificateOptions is required +// to be correctly set on client side; on server side, it is only required when mutual TLS is +// enabled(RequireClientCert in ServerOptions is true). +type RootCertificateOptions struct { + // If field RootCACerts is set, field GetRootCAs will be ignored. RootCACerts will be used + // every time when verifying the peer certificates, without performing root certificate reloading. + RootCACerts *x509.CertPool + // If GetRootCAs is set and RootCACerts is nil, GetRootCAs will be invoked every time + // asked to check certificates sent from the server when a new connection is established. + // This is known as root CA certificate reloading. + GetRootCAs func(params *GetRootCAsParams) (*GetRootCAsResults, error) +} + +// ClientOptions contains all the fields and functions needed to be filled by the client. +// General rules for certificate setting on client side: +// Certificates or GetClientCertificate indicates the certificates sent from the client to the +// server to prove client's identities. The rules for setting these two fields are: +// If requiring mutual authentication on server side: +// Either Certificates or GetClientCertificate must be set; the other will be ignored +// Otherwise: +// Nothing needed(the two fields will be ignored) +type ClientOptions struct { + // If field Certificates is set, field GetClientCertificate will be ignored. The client will use + // Certificates every time when asked for a certificate, without performing certificate reloading. + Certificates []tls.Certificate + // If GetClientCertificate is set and Certificates is nil, the client will invoke this + // function every time asked to present certificates to the server when a new connection is + // established. This is known as peer certificate reloading. + GetClientCertificate func(*tls.CertificateRequestInfo) (*tls.Certificate, error) + // VerifyPeer is a custom server authorization checking after certificate signature check. + // If this is set, we will replace the hostname check with this customized authorization check. + // If this is nil, we fall back to typical hostname check. + VerifyPeer CustomVerificationFunc + // ServerNameOverride is for testing only. If set to a non-empty string, + // it will override the virtual host name of authority (e.g. :authority header field) in requests. + ServerNameOverride string + RootCertificateOptions +} + +// ServerOptions contains all the fields and functions needed to be filled by the client. +// General rules for certificate setting on server side: +// Certificates or GetClientCertificate indicates the certificates sent from the server to +// the client to prove server's identities. The rules for setting these two fields are: +// Either Certificates or GetCertificate must be set; the other will be ignored +type ServerOptions struct { + // If field Certificates is set, field GetClientCertificate will be ignored. The server will use + // Certificates every time when asked for a certificate, without performing certificate reloading. + Certificates []tls.Certificate + // If GetClientCertificate is set and Certificates is nil, the server will invoke this + // function every time asked to present certificates to the client when a new connection is + // established. This is known as peer certificate reloading. + GetCertificate func(*tls.ClientHelloInfo) (*tls.Certificate, error) + RootCertificateOptions + // If the server want the client to send certificates. + RequireClientCert bool +} + +func (o *ClientOptions) config() (*tls.Config, error) { + if o.RootCACerts == nil && o.GetRootCAs == nil && o.VerifyPeer == nil { + return nil, fmt.Errorf( + "client needs to provide root CA certs, or a custom verification function") + } + // We have to set InsecureSkipVerify to true to skip the default checks and use the + // verification function we built from buildVerifyFunc. + config := &tls.Config{ + ServerName: o.ServerNameOverride, + Certificates: o.Certificates, + GetClientCertificate: o.GetClientCertificate, + RootCAs: o.RootCACerts, + InsecureSkipVerify: true, + } + return config, nil +} + +func (o *ServerOptions) config() (*tls.Config, error) { + if o.Certificates == nil && o.GetCertificate == nil { + return nil, fmt.Errorf("either Certificates or GetCertificate must be specified") + } + if o.RequireClientCert && o.GetRootCAs == nil && o.RootCACerts == nil { + return nil, fmt.Errorf("server needs to provide root CA certs if requiring client cert") + } + clientAuth := tls.NoClientCert + if o.RequireClientCert { + // We fall back to normal config settings if users don't need to reload root certificates. + // If using RequireAndVerifyClientCert, the underlying stack would use the default + // checking and ignore the verification function we built from buildVerifyFunc. + // If using RequireAnyClientCert, the code would skip all the checks and use the + // function from buildVerifyFunc. + if o.RootCACerts != nil { + clientAuth = tls.RequireAndVerifyClientCert + } else { + clientAuth = tls.RequireAnyClientCert + } + } + config := &tls.Config{ + ClientAuth: clientAuth, + Certificates: o.Certificates, + GetCertificate: o.GetCertificate, + } + if o.RootCACerts != nil { + config.ClientCAs = o.RootCACerts + } + return config, nil +} + +// advancedTLSCreds is the credentials required for authenticating a connection using TLS. +type advancedTLSCreds struct { + config *tls.Config + verifyFunc CustomVerificationFunc + getRootCAs func(params *GetRootCAsParams) (*GetRootCAsResults, error) + isClient bool +} + +func (c advancedTLSCreds) Info() credentials.ProtocolInfo { + return credentials.ProtocolInfo{ + SecurityProtocol: "tls", + SecurityVersion: "1.2", + ServerName: c.config.ServerName, + } +} + +func (c *advancedTLSCreds) ClientHandshake(ctx context.Context, authority string, rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { + // Use local cfg to avoid clobbering ServerName if using multiple endpoints. + cfg := cloneTLSConfig(c.config) + // We return the full authority name to users if ServerName is empty without + // stripping the trailing port. + if cfg.ServerName == "" { + cfg.ServerName = authority + } + cfg.VerifyPeerCertificate = buildVerifyFunc(c, cfg.ServerName, rawConn) + conn := tls.Client(rawConn, cfg) + errChannel := make(chan error, 1) + go func() { + errChannel <- conn.Handshake() + close(errChannel) + }() + select { + case err := <-errChannel: + if err != nil { + conn.Close() + return nil, nil, err + } + case <-ctx.Done(): + conn.Close() + return nil, nil, ctx.Err() + } + return WrapSyscallConn(rawConn, conn), credentials.TLSInfo{State: conn.ConnectionState()}, nil +} + +func (c *advancedTLSCreds) ServerHandshake(rawConn net.Conn) (net.Conn, credentials.AuthInfo, error) { + cfg := cloneTLSConfig(c.config) + // We build server side verification function only when root cert reloading is needed. + if c.getRootCAs != nil { + cfg.VerifyPeerCertificate = buildVerifyFunc(c, "", rawConn) + } + conn := tls.Server(rawConn, cfg) + if err := conn.Handshake(); err != nil { + conn.Close() + return nil, nil, err + } + return WrapSyscallConn(rawConn, conn), credentials.TLSInfo{State: conn.ConnectionState()}, nil +} + +func (c *advancedTLSCreds) Clone() credentials.TransportCredentials { + return &advancedTLSCreds{ + config: cloneTLSConfig(c.config), + verifyFunc: c.verifyFunc, + getRootCAs: c.getRootCAs, + isClient: c.isClient, + } +} + +func (c *advancedTLSCreds) OverrideServerName(serverNameOverride string) error { + c.config.ServerName = serverNameOverride + return nil +} + +// The function buildVerifyFunc is used when users want root cert reloading, and possibly custom +// server authorization check. +// We have to build our own verification function here because current tls module: +// 1. does not have a good support on root cert reloading +// 2. will ignore basic certificate check when setting InsecureSkipVerify to true +func buildVerifyFunc(c *advancedTLSCreds, + serverName string, + rawConn net.Conn) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { + return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error { + // If users didn't specify either rootCAs or getRootCAs on client side, + // as we see some use cases such as https://github.com/grpc/grpc/pull/20530, + // instead of failing, we just don't validate the server cert and let + // application decide via VerifyPeer + if c.isClient && c.config.RootCAs == nil && c.getRootCAs == nil { + if c.verifyFunc != nil { + _, err := c.verifyFunc(&VerificationFuncParams{ + ServerName: serverName, + RawCerts: rawCerts, + VerifiedChains: verifiedChains, + }) + return err + } + } + var rootCAs *x509.CertPool + if c.isClient { + rootCAs = c.config.RootCAs + } else { + rootCAs = c.config.ClientCAs + } + // reload root CA certs + if rootCAs == nil && c.getRootCAs != nil { + results, err := c.getRootCAs(&GetRootCAsParams{ + RawConn: rawConn, + RawCerts: rawCerts, + }) + if err != nil { + return err + } + rootCAs = results.TrustCerts + } + // verify peers' certificates against RootCAs and get verifiedChains + certs := make([]*x509.Certificate, len(rawCerts)) + for i, asn1Data := range rawCerts { + cert, err := x509.ParseCertificate(asn1Data) + if err != nil { + return err + } + certs[i] = cert + } + opts := x509.VerifyOptions{ + Roots: rootCAs, + CurrentTime: time.Now(), + Intermediates: x509.NewCertPool(), + } + if !c.isClient { + opts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth} + } else { + opts.KeyUsages = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} + } + for _, cert := range certs[1:] { + opts.Intermediates.AddCert(cert) + } + // We use default hostname check if users don't specify verifyFunc function + if c.isClient && c.verifyFunc == nil && serverName != "" { + opts.DNSName = serverName + } + verifiedChains, err := certs[0].Verify(opts) + if err != nil { + return err + } + if c.isClient && c.verifyFunc != nil { + if c.verifyFunc != nil { + _, err := c.verifyFunc(&VerificationFuncParams{ + ServerName: serverName, + RawCerts: rawCerts, + VerifiedChains: verifiedChains, + }) + return err + } + } + return nil + } +} + +// NewClient uses ClientOptions to construct a TransportCredentials based on TLS. +func NewClient(o *ClientOptions) (credentials.TransportCredentials, error) { + conf, err := o.config() + if err != nil { + return nil, err + } + tc := &advancedTLSCreds{ + config: conf, + isClient: true, + getRootCAs: o.GetRootCAs, + verifyFunc: o.VerifyPeer, + } + tc.config.NextProtos = appendH2ToNextProtos(tc.config.NextProtos) + return tc, nil +} + +// NewServer uses ServerOptions to construct a TransportCredentials based on TLS. +func NewServer(o *ServerOptions) (credentials.TransportCredentials, error) { + conf, err := o.config() + if err != nil { + return nil, err + } + tc := &advancedTLSCreds{ + config: conf, + isClient: false, + getRootCAs: o.GetRootCAs, + } + tc.config.NextProtos = appendH2ToNextProtos(tc.config.NextProtos) + return tc, nil +} + +// TODO(ZhenLian): The code below are duplicates with gRPC-Go under +// credentials/internal. Consider refactoring in the future. +const alpnProtoStrH2 = "h2" + +func appendH2ToNextProtos(ps []string) []string { + for _, p := range ps { + if p == alpnProtoStrH2 { + return ps + } + } + ret := make([]string, 0, len(ps)+1) + ret = append(ret, ps...) + return append(ret, alpnProtoStrH2) +} + +// We give syscall.Conn a new name here since syscall.Conn and net.Conn used +// below have the same names. +type sysConn = syscall.Conn + +// syscallConn keeps reference of rawConn to support syscall.Conn for channelz. +// SyscallConn() (the method in interface syscall.Conn) is explicitly +// implemented on this type, +// +// Interface syscall.Conn is implemented by most net.Conn implementations (e.g. +// TCPConn, UnixConn), but is not part of net.Conn interface. So wrapper conns +// that embed net.Conn don't implement syscall.Conn. (Side note: tls.Conn +// doesn't embed net.Conn, so even if syscall.Conn is part of net.Conn, it won't +// help here). +type syscallConn struct { + net.Conn + // sysConn is a type alias of syscall.Conn. It's necessary because the name + // `Conn` collides with `net.Conn`. + sysConn +} + +// WrapSyscallConn tries to wrap rawConn and newConn into a net.Conn that +// implements syscall.Conn. rawConn will be used to support syscall, and newConn +// will be used for read/write. +// +// This function returns newConn if rawConn doesn't implement syscall.Conn. +func WrapSyscallConn(rawConn, newConn net.Conn) net.Conn { + sysConn, ok := rawConn.(syscall.Conn) + if !ok { + return newConn + } + return &syscallConn{ + Conn: newConn, + sysConn: sysConn, + } +} + +func cloneTLSConfig(cfg *tls.Config) *tls.Config { + if cfg == nil { + return &tls.Config{} + } + return cfg.Clone() +} diff --git a/security/advancedtls/advancedtls_test.go b/security/advancedtls/advancedtls_test.go new file mode 100644 index 00000000..4d9d0fb8 --- /dev/null +++ b/security/advancedtls/advancedtls_test.go @@ -0,0 +1,635 @@ +/* + * + * Copyright 2019 gRPC authors. + * + * 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 advancedtls + +import ( + "context" + "crypto/tls" + "crypto/x509" + "encoding/pem" + "fmt" + "io/ioutil" + "net" + "reflect" + "strings" + "syscall" + "testing" + + "google.golang.org/grpc/credentials" +) + +func TestClientServerHandshake(t *testing.T) { + // ------------------Load Client Trust Cert and Peer Cert------------------- + clientTrustPool, err := readTrustCert("testdata/client_trust_cert_1.pem") + if err != nil { + t.Fatalf("Client is unable to load trust certs. Error: %v", err) + } + getRootCAsForClient := func(params *GetRootCAsParams) (*GetRootCAsResults, error) { + return &GetRootCAsResults{TrustCerts: clientTrustPool}, nil + } + verifyFunc := func(params *VerificationFuncParams) (*VerificationResults, error) { + results := &VerificationResults{} + if strings.HasPrefix(params.ServerName, "127.0.0.1") { + return results, nil + } + return results, fmt.Errorf("custom verification function failed") + } + clientPeerCert, err := tls.LoadX509KeyPair("testdata/client_cert_1.pem", + "testdata/client_key_1.pem") + if err != nil { + t.Fatalf("Client is unable to parse peer certificates. Error: %v", err) + } + // ------------------Load Server Trust Cert and Peer Cert------------------- + serverTrustPool, err := readTrustCert("testdata/server_trust_cert_1.pem") + if err != nil { + t.Fatalf("Server is unable to load trust certs. Error: %v", err) + } + getRootCAsForServer := func(params *GetRootCAsParams) (*GetRootCAsResults, error) { + return &GetRootCAsResults{TrustCerts: serverTrustPool}, nil + } + serverPeerCert, err := tls.LoadX509KeyPair("testdata/server_cert_1.pem", + "testdata/server_key_1.pem") + if err != nil { + t.Fatalf("Server is unable to parse peer certificates. Error: %v", err) + } + getRootCAsForServerBad := func(params *GetRootCAsParams) (*GetRootCAsResults, error) { + return nil, fmt.Errorf("bad root certificate reloading") + } + for _, test := range []struct { + desc string + clientCert []tls.Certificate + clientGetClientCert func(*tls.CertificateRequestInfo) (*tls.Certificate, error) + clientRoot *x509.CertPool + clientGetRoot func(params *GetRootCAsParams) (*GetRootCAsResults, error) + clientVerifyFunc CustomVerificationFunc + clientExpectCreateError bool + clientExpectHandshakeError bool + serverMutualTLS bool + serverCert []tls.Certificate + serverGetCert func(*tls.ClientHelloInfo) (*tls.Certificate, error) + serverRoot *x509.CertPool + serverGetRoot func(params *GetRootCAsParams) (*GetRootCAsResults, error) + serverExpectError bool + }{ + // Client: nil setting + // Server: only set serverCert with mutual TLS off + // Expected Behavior: server side failure + // Reason: if either clientCert or clientGetClientCert is not set and + // verifyFunc is not set, we will fail directly + { + "Client_no_trust_cert_Server_peer_cert", + nil, + nil, + nil, + nil, + nil, + true, + false, + false, + []tls.Certificate{serverPeerCert}, + nil, + nil, + nil, + true, + }, + // Client: nil setting except verifyFunc + // Server: only set serverCert with mutual TLS off + // Expected Behavior: success + // Reason: we will use verifyFunc to verify the server, + // if either clientCert or clientGetClientCert is not set + { + "Client_no_trust_cert_verifyFunc_Server_peer_cert", + nil, + nil, + nil, + nil, + verifyFunc, + false, + false, + false, + []tls.Certificate{serverPeerCert}, + nil, + nil, + nil, + false, + }, + // Client: only set clientRoot + // Server: only set serverCert with mutual TLS off + // Expected Behavior: server side failure and client handshake failure + // Reason: not setting advanced TLS features will fall back to normal check, and will hence fail + // on default host name check. All the default hostname checks will fail in this test suites + // (since it connects to 127.0.0.1). + { + "Client_root_cert_Server_peer_cert", + nil, + nil, + clientTrustPool, + nil, + nil, + false, + true, + false, + []tls.Certificate{serverPeerCert}, + nil, + nil, + nil, + true, + }, + // Client: only set clientGetRoot + // Server: only set serverCert with mutual TLS off + // Expected Behavior: server side failure and client handshake failure + // Reason: setting root reloading function without custom verifyFunc will also fail, + // since it will also fall back to default host name check + { + "Client_reload_root_Server_peer_cert", + nil, + nil, + nil, + getRootCAsForClient, + nil, + false, + true, + false, + []tls.Certificate{serverPeerCert}, + nil, + nil, + nil, + true, + }, + // Client: set clientGetRoot and clientVerifyFunc + // Server: only set serverCert with mutual TLS off + // Expected Behavior: success + { + "Client_reload_root_verifyFunc_Server_peer_cert", + nil, + nil, + nil, + getRootCAsForClient, + verifyFunc, + false, + false, + false, + []tls.Certificate{serverPeerCert}, + nil, + nil, + nil, + false, + }, + // Client: set clientGetRoot and clientVerifyFunc + // Server: nil setting + // Expected Behavior: server side failure + // Reason: server side must either set serverCert or serverGetCert + { + "Client_reload_root_verifyFunc_Server_nil", + nil, + nil, + nil, + getRootCAsForClient, + verifyFunc, + false, + false, + false, + nil, + nil, + nil, + nil, + true, + }, + // Client: set clientGetRoot and clientVerifyFunc + // Server: only set serverCert with mutual TLS on + // Expected Behavior: server side failure + // Reason: server side must either set serverRoot or serverGetRoot when using mutual TLS + { + "Client_reload_root_verifyFunc_Server_peer_cert_no_root_cert_mutualTLS", + nil, + nil, + nil, + getRootCAsForClient, + verifyFunc, + false, + false, + true, + []tls.Certificate{serverPeerCert}, + nil, + nil, + nil, + true, + }, + // Client: set clientGetRoot, clientVerifyFunc and clientCert + // Server: set serverRoot and serverCert with mutual TLS on + // Expected Behavior: success + { + "Client_peer_cert_reload_root_verifyFunc_Server_peer_cert_root_cert_mutualTLS", + []tls.Certificate{clientPeerCert}, + nil, + nil, + getRootCAsForClient, + verifyFunc, + false, + false, + true, + []tls.Certificate{serverPeerCert}, + nil, + serverTrustPool, + nil, + false, + }, + // Client: set clientGetRoot, clientVerifyFunc and clientCert + // Server: set serverGetRoot and serverCert with mutual TLS on + // Expected Behavior: success + { + "Client_peer_cert_reload_root_verifyFunc_Server_peer_cert_reload_root_mutualTLS", + []tls.Certificate{clientPeerCert}, + nil, + nil, + getRootCAsForClient, + verifyFunc, + false, + false, + true, + []tls.Certificate{serverPeerCert}, + nil, + nil, + getRootCAsForServer, + false, + }, + // Client: set clientGetRoot, clientVerifyFunc and clientCert + // Server: set serverGetRoot returning error and serverCert with mutual TLS on + // Expected Behavior: server side failure + // Reason: server side reloading returns failure + { + "Client_peer_cert_reload_root_verifyFunc_Server_peer_cert_bad_reload_root_mutualTLS", + []tls.Certificate{clientPeerCert}, + nil, + nil, + getRootCAsForClient, + verifyFunc, + false, + false, + true, + []tls.Certificate{serverPeerCert}, + nil, + nil, + getRootCAsForServerBad, + true, + }, + // Client: set clientGetRoot, clientVerifyFunc and clientGetClientCert + // Server: set serverGetRoot and serverGetCert with mutual TLS on + // Expected Behavior: success + { + "Client_reload_both_certs_verifyFunc_Server_reload_both_certs_mutualTLS", + nil, + func(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { + return &clientPeerCert, nil + }, + nil, + getRootCAsForClient, + verifyFunc, + false, + false, + true, + nil, + func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + return &serverPeerCert, nil + }, + nil, + getRootCAsForServer, + false, + }, + // Client: set everything but with the wrong peer cert not trusted by server + // Server: set serverGetRoot and serverGetCert with mutual TLS on + // Expected Behavior: server side returns failure because of + // certificate mismatch + { + "Client_wrong_peer_cert_Server_reload_both_certs_mutualTLS", + nil, + func(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { + return &serverPeerCert, nil + }, + nil, + getRootCAsForClient, + verifyFunc, + false, + false, + true, + nil, + func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + return &serverPeerCert, nil + }, + nil, + getRootCAsForServer, + true, + }, + // Client: set everything but with the wrong trust cert not trusting server + // Server: set serverGetRoot and serverGetCert with mutual TLS on + // Expected Behavior: server side and client side return failure due to + // certificate mismatch and handshake failure + { + "Client_wrong_trust_cert_Server_reload_both_certs_mutualTLS", + nil, + func(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { + return &clientPeerCert, nil + }, + nil, + getRootCAsForServer, + verifyFunc, + false, + true, + true, + nil, + func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + return &serverPeerCert, nil + }, + nil, + getRootCAsForServer, + true, + }, + // Client: set clientGetRoot, clientVerifyFunc and clientCert + // Server: set everything but with the wrong peer cert not trusted by client + // Expected Behavior: server side and client side return failure due to + // certificate mismatch and handshake failure + { + "Client_reload_both_certs_verifyFunc_Server_wrong_peer_cert", + nil, + func(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { + return &clientPeerCert, nil + }, + nil, + getRootCAsForClient, + verifyFunc, + false, + false, + true, + nil, + func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + return &clientPeerCert, nil + }, + nil, + getRootCAsForServer, + true, + }, + // Client: set clientGetRoot, clientVerifyFunc and clientCert + // Server: set everything but with the wrong trust cert not trusting client + // Expected Behavior: server side and client side return failure due to + // certificate mismatch and handshake failure + { + "Client_reload_both_certs_verifyFunc_Server_wrong_trust_cert", + nil, + func(info *tls.CertificateRequestInfo) (*tls.Certificate, error) { + return &clientPeerCert, nil + }, + nil, + getRootCAsForClient, + verifyFunc, + false, + true, + true, + nil, + func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { + return &serverPeerCert, nil + }, + nil, + getRootCAsForClient, + true, + }, + } { + test := test + t.Run(test.desc, func(t *testing.T) { + done := make(chan credentials.AuthInfo, 1) + lis, err := net.Listen("tcp", "localhost:0") + if err != nil { + t.Fatalf("Failed to listen: %v", err) + } + // Start a server using ServerOptions in another goroutine. + serverOptions := &ServerOptions{ + Certificates: test.serverCert, + GetCertificate: test.serverGetCert, + RootCertificateOptions: RootCertificateOptions{ + RootCACerts: test.serverRoot, + GetRootCAs: test.serverGetRoot, + }, + RequireClientCert: test.serverMutualTLS, + } + go func(done chan credentials.AuthInfo, lis net.Listener, serverOptions *ServerOptions) { + serverRawConn, err := lis.Accept() + if err != nil { + close(done) + return + } + serverTLS, err := NewServer(serverOptions) + if err != nil { + serverRawConn.Close() + close(done) + return + } + _, serverAuthInfo, err := serverTLS.ServerHandshake(serverRawConn) + if err != nil { + serverRawConn.Close() + close(done) + return + } + done <- serverAuthInfo + }(done, lis, serverOptions) + defer lis.Close() + // Start a client using ClientOptions and connects to the server. + lisAddr := lis.Addr().String() + conn, err := net.Dial("tcp", lisAddr) + if err != nil { + t.Fatalf("Client failed to connect to %s. Error: %v", lisAddr, err) + } + defer conn.Close() + clientOptions := &ClientOptions{ + Certificates: test.clientCert, + GetClientCertificate: test.clientGetClientCert, + VerifyPeer: test.clientVerifyFunc, + RootCertificateOptions: RootCertificateOptions{ + RootCACerts: test.clientRoot, + GetRootCAs: test.clientGetRoot, + }, + } + clientTLS, newClientErr := NewClient(clientOptions) + if newClientErr != nil && test.clientExpectCreateError { + return + } + if newClientErr != nil && !test.clientExpectCreateError || + newClientErr == nil && test.clientExpectCreateError { + t.Fatalf("Expect error: %v, but err is %v", + test.clientExpectCreateError, newClientErr) + } + _, clientAuthInfo, handshakeErr := clientTLS.ClientHandshake(context.Background(), + lisAddr, conn) + // wait until server sends serverAuthInfo or fails. + serverAuthInfo, ok := <-done + if !ok && test.serverExpectError { + return + } + if ok && test.serverExpectError || !ok && !test.serverExpectError { + t.Fatalf("Server side error mismatch, got %v, want %v", !ok, test.serverExpectError) + } + if handshakeErr != nil && test.clientExpectHandshakeError { + return + } + if handshakeErr != nil && !test.clientExpectHandshakeError || + handshakeErr == nil && test.clientExpectHandshakeError { + t.Fatalf("Expect error: %v, but err is %v", + test.clientExpectHandshakeError, handshakeErr) + } + if !compare(clientAuthInfo, serverAuthInfo) { + t.Fatalf("c.ClientHandshake(_, %v, _) = %v, want %v.", lisAddr, + clientAuthInfo, serverAuthInfo) + } + }) + } +} + +func readTrustCert(fileName string) (*x509.CertPool, error) { + trustData, err := ioutil.ReadFile(fileName) + if err != nil { + return nil, err + } + trustBlock, _ := pem.Decode(trustData) + if trustBlock == nil { + return nil, err + } + trustCert, err := x509.ParseCertificate(trustBlock.Bytes) + if err != nil { + return nil, err + } + trustPool := x509.NewCertPool() + trustPool.AddCert(trustCert) + return trustPool, nil +} + +func compare(a1, a2 credentials.AuthInfo) bool { + if a1.AuthType() != a2.AuthType() { + return false + } + switch a1.AuthType() { + case "tls": + state1 := a1.(credentials.TLSInfo).State + state2 := a2.(credentials.TLSInfo).State + if state1.Version == state2.Version && + state1.HandshakeComplete == state2.HandshakeComplete && + state1.CipherSuite == state2.CipherSuite && + state1.NegotiatedProtocol == state2.NegotiatedProtocol { + return true + } + return false + default: + return false + } +} + +func TestAdvancedTLSOverrideServerName(t *testing.T) { + expectedServerName := "server.name" + clientTrustPool, err := readTrustCert("testdata/client_trust_cert_1.pem") + if err != nil { + t.Fatalf("Client is unable to load trust certs. Error: %v", err) + } + clientOptions := &ClientOptions{ + RootCertificateOptions: RootCertificateOptions{ + RootCACerts: clientTrustPool, + }, + ServerNameOverride: expectedServerName, + } + c, err := NewClient(clientOptions) + if err != nil { + t.Fatalf("Client is unable to create credentials. Error: %v", err) + } + c.OverrideServerName(expectedServerName) + if c.Info().ServerName != expectedServerName { + t.Fatalf("c.Info().ServerName = %v, want %v", c.Info().ServerName, expectedServerName) + } +} + +func TestTLSClone(t *testing.T) { + expectedServerName := "server.name" + clientTrustPool, err := readTrustCert("testdata/client_trust_cert_1.pem") + if err != nil { + t.Fatalf("Client is unable to load trust certs. Error: %v", err) + } + clientOptions := &ClientOptions{ + RootCertificateOptions: RootCertificateOptions{ + RootCACerts: clientTrustPool, + }, + ServerNameOverride: expectedServerName, + } + c, err := NewClient(clientOptions) + cc := c.Clone() + if cc.Info().ServerName != expectedServerName { + t.Fatalf("cc.Info().ServerName = %v, want %v", cc.Info().ServerName, expectedServerName) + } + cc.OverrideServerName("") + if c.Info().ServerName != expectedServerName { + t.Fatalf("Change in clone should not affect the original, "+ + "c.Info().ServerName = %v, want %v", c.Info().ServerName, expectedServerName) + } + +} + +func TestAppendH2ToNextProtos(t *testing.T) { + tests := []struct { + name string + ps []string + want []string + }{ + { + name: "empty", + ps: nil, + want: []string{"h2"}, + }, + { + name: "only h2", + ps: []string{"h2"}, + want: []string{"h2"}, + }, + { + name: "with h2", + ps: []string{"alpn", "h2"}, + want: []string{"alpn", "h2"}, + }, + { + name: "no h2", + ps: []string{"alpn"}, + want: []string{"alpn", "h2"}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := appendH2ToNextProtos(tt.ps); !reflect.DeepEqual(got, tt.want) { + t.Errorf("appendH2ToNextProtos() = %v, want %v", got, tt.want) + } + }) + } +} + +type nonSyscallConn struct { + net.Conn +} + +func TestWrapSyscallConn(t *testing.T) { + sc := &syscallConn{} + nsc := &nonSyscallConn{} + + wrapConn := WrapSyscallConn(sc, nsc) + if _, ok := wrapConn.(syscall.Conn); !ok { + t.Errorf("returned conn (type %T) doesn't implement syscall.Conn, want implement", + wrapConn) + } +} diff --git a/security/advancedtls/go.mod b/security/advancedtls/go.mod new file mode 100644 index 00000000..23cd36f4 --- /dev/null +++ b/security/advancedtls/go.mod @@ -0,0 +1,5 @@ +module google.golang.org/grpc/security/advancedtls + +go 1.13 + +require google.golang.org/grpc v1.25.1 diff --git a/security/advancedtls/go.sum b/security/advancedtls/go.sum new file mode 100644 index 00000000..c5932214 --- /dev/null +++ b/security/advancedtls/go.sum @@ -0,0 +1,43 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1 h1:wdKvqQk7IttEw92GoRyKG2IDrUIpgpj6H6m81yfeMW0= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/security/advancedtls/testdata/client_cert_1.pem b/security/advancedtls/testdata/client_cert_1.pem new file mode 100644 index 00000000..ccba154c --- /dev/null +++ b/security/advancedtls/testdata/client_cert_1.pem @@ -0,0 +1,122 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 5 (0x5) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=VA, O=Internet Widgits Pty Ltd, CN=foo.bar.hoo.ca.com + Validity + Not Before: Nov 15 19:15:24 2019 GMT + Not After : Aug 29 19:15:24 2293 GMT + Subject: C=US, ST=CA, O=Internet Widgits Pty Ltd, CN=foo.bar.hoo.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (4096 bit) + Modulus: + 00:c3:3e:b5:d8:bc:73:5f:b4:e5:60:a8:73:0e:8c: + 9c:ff:28:2c:a9:bc:68:12:8b:ae:3e:aa:7b:f5:b9: + 2d:b3:73:f8:9e:64:e9:8e:26:ca:36:11:5f:f9:73: + 39:f0:19:55:d1:ba:f4:4e:2b:ab:ee:01:3b:eb:f0: + 5f:6e:b3:24:39:c1:f5:f0:bd:6a:d0:6c:56:cf:96: + 33:5d:05:48:c4:b5:b3:3e:55:8e:89:8e:6b:79:c5: + 3b:99:1c:e3:03:69:0f:74:a2:97:7b:bf:c4:11:1d: + da:d7:cb:87:0d:90:25:64:29:3e:f6:62:bc:f9:a5: + 56:de:56:e1:27:77:51:1a:30:f1:88:89:01:c2:c8: + 35:40:d3:2e:2d:30:ef:d7:de:3b:28:15:4a:a4:a9: + ba:f0:40:f0:79:3a:16:f9:ae:52:32:c3:52:ad:53: + 9c:94:07:d5:9b:63:50:90:ff:f1:8c:fd:4e:59:b8: + 5e:0a:73:9b:b4:b7:60:e1:7c:07:02:50:74:f3:48: + 69:6a:74:7c:b2:96:70:86:19:2f:82:4c:95:57:aa: + 4c:2f:38:75:8b:9b:a1:3e:7d:dd:da:bf:d2:a4:a3: + 3a:02:17:43:35:0a:52:03:f5:fb:1a:a1:60:28:c3: + e7:41:eb:4a:0c:f4:43:6e:81:64:ba:41:8d:61:40: + 97:9f:e2:67:51:7c:2d:2f:17:72:b9:a0:27:5c:fc: + e3:b6:a6:de:f4:1e:34:95:2c:c5:7f:13:c4:bb:25: + 76:3e:3b:39:b6:36:d0:60:17:1e:c7:01:9c:3d:65: + 9a:96:4c:d8:4c:10:85:32:76:c7:6e:53:64:80:c9: + 33:1a:44:39:a7:c7:69:d3:64:c3:4c:06:20:56:d2: + eb:d9:65:56:02:65:c4:ba:72:db:89:c4:00:3f:89: + f4:75:d5:6d:83:ce:ad:66:fb:73:f8:8e:bb:dc:01: + c0:4f:86:c1:57:45:68:34:3f:55:1f:0e:ef:82:3f: + 9a:26:1c:9c:8d:88:5e:27:ab:b6:b9:58:a7:c5:b0: + 36:0f:99:ba:d8:cc:89:41:ed:ab:26:b8:8a:16:17: + 21:67:b6:4d:83:d1:dd:53:de:67:ab:76:a3:af:f8: + 60:99:29:6a:0a:4f:f2:ad:32:54:69:33:8c:f2:ca: + 9b:d6:59:cd:8c:69:cd:3f:d3:8f:05:28:d1:29:04: + bf:b2:de:98:0f:9d:62:13:6d:fe:de:be:2d:c6:be: + d6:f8:10:cb:b5:b3:4f:ad:a4:60:36:b3:19:29:29: + b9:b4:37:5d:13:e7:36:cb:f9:fa:7f:9e:63:7e:f3: + 05:ee:9e:e6:4d:ff:e3:46:a4:7b:1f:12:72:89:b6: + 10:5f:bd + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 7F:9D:9C:C6:86:DF:9E:07:93:94:EF:18:2D:0A:0A:50:AA:1F:A2:B7 + X509v3 Authority Key Identifier: + keyid:B4:19:08:1C:FC:10:23:C5:30:86:22:BC:CB:B1:5F:AD:EA:7A:5D:F1 + + X509v3 Basic Constraints: + CA:FALSE + X509v3 Key Usage: + Digital Signature, Key Encipherment + Signature Algorithm: sha256WithRSAEncryption + 31:b0:6d:25:5e:8e:9b:73:01:ac:08:b9:a6:70:8e:de:18:fd: + b8:2b:bb:2d:7c:c0:84:20:c8:d2:32:8a:d9:ca:24:b9:75:e2: + c8:91:40:db:0a:4e:e5:05:bd:a6:bb:22:85:3c:8e:be:d3:65: + 0a:7f:cd:c0:fc:eb:94:61:91:30:53:1d:4d:9f:4e:d7:38:0f: + ab:d9:3d:a1:1c:48:c1:e6:3c:35:cc:db:47:31:a6:b2:44:b8: + db:34:6c:28:20:49:ff:e1:2b:cd:48:e1:7e:78:7a:05:0a:31: + 3d:dd:45:51:95:06:ad:5c:8c:0e:ff:0c:98:77:4f:5c:42:dc: + da:d8:d3:30:58:e4:3c:ef:b3:64:3f:f2:e2:19:d9:36:04:1a: + b4:87:c2:1b:89:5d:52:17:fb:27:a2:83:2d:55:6d:1f:80:d5: + a7:ea:20:b0:0a:23:4d:0f:48:36:ae:42:f9:fc:c8:86:f4:69: + 30:e8:cd:52:34:62:ee:b9:fd:12:4b:ba:4d:a2:75:47:d4:b6: + b2:dd:ea:6f:6b:a2:86:f5:c0:3b:06:09:c1:5f:30:96:b6:79: + 32:45:b3:d1:8c:0a:d2:58:d3:39:2f:21:ba:7a:3e:a7:38:cc: + 88:16:1e:75:62:30:fd:79:a3:1d:a9:bd:df:66:dc:b9:f5:79: + bc:fb:bd:bd:e5:f0:46:60:d1:03:7b:58:06:00:f5:d8:36:a0: + a9:b0:2d:4f:4e:1b:6f:17:f0:d9:51:0c:25:a2:48:ac:e3:f4: + a6:52:59:84:83:e3:79:df:ca:9e:5c:24:d3:f9:55:39:8c:3e: + 2a:91:3f:53:0b:d4:22:55:c7:a3:80:41:05:e3:41:7d:16:d1: + af:a2:1e:f7:fa:ee:f3:a7:6e:19:66:af:dd:23:39:5a:33:f9: + 61:3d:e7:90:e2:9a:0e:8e:8b:a0:3b:27:55:e2:ed:09:c5:ca: + 71:14:95:10:be:03:8e:2a:6d:48:c5:85:a5:f4:39:0e:2d:f5: + 64:50:f4:b6:35:f9:63:58:d0:5d:09:01:f9:bc:99:60:dc:25: + 94:36:3b:ee:b9:9d:23:2f:52:80:9c:f1:e4:9b:5f:a4:37:c9: + 63:32:cf:ca:d6:2a:b7:3b:c8:10:54:21:ca:03:d3:ae:0e:da: + cd:08:fe:71:10:f8:db:d4:e6:cf:d2:59:9b:3d:96:4a:a8:80: + 42:69:ff:7f:4b:4b:52:42:aa:e7:e9:6e:7f:84:98:f5:13:16: + 14:b0:4e:22:a6:80:03:29:6b:2e:33:ac:05:b5:75:25:58:72: + 34:ff:ad:95:f0:52:9e:46:81:91:7b:6c:12:b1:43:af:70:06: + 03:d8:c8:cb:4a:85:f2:37 +-----BEGIN CERTIFICATE----- +MIIFiDCCA3CgAwIBAgIBBTANBgkqhkiG9w0BAQsFADBaMQswCQYDVQQGEwJVUzEL +MAkGA1UECAwCVkExITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEb +MBkGA1UEAwwSZm9vLmJhci5ob28uY2EuY29tMCAXDTE5MTExNTE5MTUyNFoYDzIy +OTMwODI5MTkxNTI0WjBXMQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExITAfBgNV +BAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDEYMBYGA1UEAwwPZm9vLmJhci5o +b28uY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAwz612LxzX7Tl +YKhzDoyc/ygsqbxoEouuPqp79bkts3P4nmTpjibKNhFf+XM58BlV0br0Tiur7gE7 +6/BfbrMkOcH18L1q0GxWz5YzXQVIxLWzPlWOiY5recU7mRzjA2kPdKKXe7/EER3a +18uHDZAlZCk+9mK8+aVW3lbhJ3dRGjDxiIkBwsg1QNMuLTDv1947KBVKpKm68EDw +eToW+a5SMsNSrVOclAfVm2NQkP/xjP1OWbheCnObtLdg4XwHAlB080hpanR8spZw +hhkvgkyVV6pMLzh1i5uhPn3d2r/SpKM6AhdDNQpSA/X7GqFgKMPnQetKDPRDboFk +ukGNYUCXn+JnUXwtLxdyuaAnXPzjtqbe9B40lSzFfxPEuyV2Pjs5tjbQYBcexwGc +PWWalkzYTBCFMnbHblNkgMkzGkQ5p8dp02TDTAYgVtLr2WVWAmXEunLbicQAP4n0 +ddVtg86tZvtz+I673AHAT4bBV0VoND9VHw7vgj+aJhycjYheJ6u2uVinxbA2D5m6 +2MyJQe2rJriKFhchZ7ZNg9HdU95nq3ajr/hgmSlqCk/yrTJUaTOM8sqb1lnNjGnN +P9OPBSjRKQS/st6YD51iE23+3r4txr7W+BDLtbNPraRgNrMZKSm5tDddE+c2y/n6 +f55jfvMF7p7mTf/jRqR7HxJyibYQX70CAwEAAaNaMFgwHQYDVR0OBBYEFH+dnMaG +354Hk5TvGC0KClCqH6K3MB8GA1UdIwQYMBaAFLQZCBz8ECPFMIYivMuxX63qel3x +MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQAxsG0l +Xo6bcwGsCLmmcI7eGP24K7stfMCEIMjSMorZyiS5deLIkUDbCk7lBb2muyKFPI6+ +02UKf83A/OuUYZEwUx1Nn07XOA+r2T2hHEjB5jw1zNtHMaayRLjbNGwoIEn/4SvN +SOF+eHoFCjE93UVRlQatXIwO/wyYd09cQtza2NMwWOQ877NkP/LiGdk2BBq0h8Ib +iV1SF/snooMtVW0fgNWn6iCwCiNND0g2rkL5/MiG9Gkw6M1SNGLuuf0SS7pNonVH +1Lay3epva6KG9cA7BgnBXzCWtnkyRbPRjArSWNM5LyG6ej6nOMyIFh51YjD9eaMd +qb3fZty59Xm8+7295fBGYNEDe1gGAPXYNqCpsC1PThtvF/DZUQwlokis4/SmUlmE +g+N538qeXCTT+VU5jD4qkT9TC9QiVcejgEEF40F9FtGvoh73+u7zp24ZZq/dIzla +M/lhPeeQ4poOjougOydV4u0JxcpxFJUQvgOOKm1IxYWl9DkOLfVkUPS2NfljWNBd +CQH5vJlg3CWUNjvuuZ0jL1KAnPHkm1+kN8ljMs/K1iq3O8gQVCHKA9OuDtrNCP5x +EPjb1ObP0lmbPZZKqIBCaf9/S0tSQqrn6W5/hJj1ExYUsE4ipoADKWsuM6wFtXUl +WHI0/62V8FKeRoGRe2wSsUOvcAYD2MjLSoXyNw== +-----END CERTIFICATE----- diff --git a/security/advancedtls/testdata/client_key_1.pem b/security/advancedtls/testdata/client_key_1.pem new file mode 100644 index 00000000..3be62fa7 --- /dev/null +++ b/security/advancedtls/testdata/client_key_1.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIJKAIBAAKCAgEAwz612LxzX7TlYKhzDoyc/ygsqbxoEouuPqp79bkts3P4nmTp +jibKNhFf+XM58BlV0br0Tiur7gE76/BfbrMkOcH18L1q0GxWz5YzXQVIxLWzPlWO +iY5recU7mRzjA2kPdKKXe7/EER3a18uHDZAlZCk+9mK8+aVW3lbhJ3dRGjDxiIkB +wsg1QNMuLTDv1947KBVKpKm68EDweToW+a5SMsNSrVOclAfVm2NQkP/xjP1OWbhe +CnObtLdg4XwHAlB080hpanR8spZwhhkvgkyVV6pMLzh1i5uhPn3d2r/SpKM6AhdD +NQpSA/X7GqFgKMPnQetKDPRDboFkukGNYUCXn+JnUXwtLxdyuaAnXPzjtqbe9B40 +lSzFfxPEuyV2Pjs5tjbQYBcexwGcPWWalkzYTBCFMnbHblNkgMkzGkQ5p8dp02TD +TAYgVtLr2WVWAmXEunLbicQAP4n0ddVtg86tZvtz+I673AHAT4bBV0VoND9VHw7v +gj+aJhycjYheJ6u2uVinxbA2D5m62MyJQe2rJriKFhchZ7ZNg9HdU95nq3ajr/hg +mSlqCk/yrTJUaTOM8sqb1lnNjGnNP9OPBSjRKQS/st6YD51iE23+3r4txr7W+BDL +tbNPraRgNrMZKSm5tDddE+c2y/n6f55jfvMF7p7mTf/jRqR7HxJyibYQX70CAwEA +AQKCAgEAjT9s5yNOhEqmNssmkbwASEeUKCd5UxFiOUu06gvRmCWqE00F+iTt3Tes +qxZFMAHkKBqMa5EEjOavpvz6zWckKfS8LDGceLQoCX2sIvuTrVuWFN5og/NYpXue +piJTyT/UQpjt5kTRX2Ct1bgUOCe0JUYBmtXLyP9oXOmVcavMLJqD4jbb40Jb5E3i +9iaVHSJUwabFnWJ9LxqL3ee8f10xcjAEPAhlGmKgkg3DV2MSKOGIMThEMGN6nb6c +hAPqPi5erTIRsUYcgEZ9mUXXLPiigg1dmDvMLfelK0R7n6luhlTfvmt9331b4Cmw +Q4/DtTokr3e81qpPrj5F1Mlfsp+8EFd8Ucwtu37DFiwpqYpDeMYxbbVC1toa5QQy +6VRa7NQLTHXfRp6mmaf37KnganLYOqX0vF8LMIn2O11jEnfdAfqSkHY8JzvNG9OJ +71LO5FXa7VEfOGfu1lNXScFN3yqukjr2aPo8bd9hIIw4ZEvJtto+0hBBTF4ttJ+r +R5j+h764A6vqxBo8Oh60sahY7sYBD0BIZT/hmxqaEC1PUpPfveGzWcr6r/xb30ak +DhrbWsH2/St8NjCL/9u86K/KyQB8nDwOQlTC/gB+SxLCp9KcEG3HuNVMFtV/pic/ +lzqChT9p+2/F+iv/aIb69FcBuGMfljdrsnnrc9954nco8sXgmDECggEBAOPbmWLb +vnCzZ8VdbqsxlXeF9Ype9tyINE8az9rG0A15tTXtHCwYQRpTi8PWevaTYtJvzj5Z +7DnMH0B56q8p+oMyEP8YkfOQK6OavW9ehSui1y7KSgjFsFXuXPUR6BnLPUZW/BuD +UHrbjspFREWZBrm2y0tOk2sYZirqg9r+Hl1yAZXeXXkAK+UdNygRuoG3by8Nemql +wA22pLu6J0dZ04AQX4ERdxJcTxLx3wf3tpFltSWdsJr6kuevNBcdvpq/Xc9M91bW +n8POxMWIBTZTC5nDTJd9nCip1J8jACFII5evr/L+O3Bwda4k/B277D/DVUtKhhcD +UBucDcLXQro6eHMCggEBANtb9ZBYw3R/JbZrNwShB379I5p2SN30mSbkNB+0PYYx +WNX5YQADFlulG5/spPD15dyHdYWDWI+c40ZXAKfgN12it6id+eUC5hbx4+N9E6yP +4+9mkvPiV2HpIOLSb/fDReJsE/d6l0Fwqh2xGCN6adLSa3DCy4q9IP9pIJHOAkeY +kdBQwtXH0xo9hM25/ZFnWGmhugRvllB2rPCEPFxhsuS1ExgEPLm1T8DnueQTGuEf +lAXUj/s+RVcGgHgQ/ONv9O6uEhmZYST+ZFu3sb2Rq6YwNUjbIiaMuzMgEHAdQ4C4 +xYQDC0Bnf3Lt1iszvypwAxjPBcHhVeqzTL4l1sn4Kw8CggEAEK59Fk28LYgU6tAi +UAo7RRrblRvKuu6F1dzCpuOzS6lDaQVI8Ll92q2PJ/FF41N7AqkI0mvG7ZxSFWhX +lCdgncZGlEZ6OPivGTU09ThYS4+KbXSF4wqGFGR1DcQX1/uXKtUnc+QzOitk0s4r +Z2UCpwoI7CR+inKo2C9/I8NC+dhk4VH8SeWHUSjIZviVTPXe//Tep3wnCVn7yXqh +cYnUACYyt8JNk1yKtXpbt7uc9BwcHPrkeRQrOScMizy0PaQQ/CJIYWUpIS68HTIO +H6II0WMI8nZRvnBgjp4DXmxnnq1QFlwigeLZ2rv+cTbW3vwv/GkiVAD8FmlgYIld +60BonQKCAQBAP2fmFklxBoiKLE7Z+TwT0pqp8/kVoT12KaKmoojek/d7/GWPtlfH +Ec3Mgmgw9ySS+c3PBBBdR8s9X+AeS0qMD0uRhGubysSPdduUVp77jM1q4fUqn2GO +mNR7+ry2qaf/UD5s3qgMj64TsjnqskDqcZzsUvGAujI+/JCAhAEg7SvQAsd+C9/l +sJ0EEHSXMNixX5/3CqPQ/2FZtLFlMWxPFkX4Y81RayxnyLcmeP4Hb9NP/dkJ8kwm +2A2qnPckujbX7X35p3XPev7z6hKR/mdy7m284AnZlqCBseN+ouORgQzAxI94Fpg6 +ljSDRM255ULS8leyWIhsjIVur/CACUK7AoIBAHRqbtOLnfrDS8VlI+V0GtNJXLVS +XDlgTtPNMaDWMKxVLFNwF8MeY5pf1QHNa399bOumZUlmRfZ+AcJYDTyfF366Eoh6 +yatmoQKMJotsQWln9iGWv7wqTP7omrL+Y053R1ypdY4k/4Yf9ptykiCBIUwYqjxk ++NvIcf8r0cZZjsx7SlkjhGGhFHkeFewhbPm7o8bolZ26Nf/luNGuJSOzGac88Sq5 +9jSKbkWTI4Rukw3n73AAKkdbLmGkIw81BnMbXH3bBoB+fdmILgIFx61D1QeCipOQ +WJIht2SLm8UXfYAQLGL2kQ2+C531uFvV+hzNA1H5KHj1Lo4BD2ogjjePdFY= +-----END RSA PRIVATE KEY----- diff --git a/security/advancedtls/testdata/client_trust_cert_1.pem b/security/advancedtls/testdata/client_trust_cert_1.pem new file mode 100644 index 00000000..26b61122 --- /dev/null +++ b/security/advancedtls/testdata/client_trust_cert_1.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFeTCCA2GgAwIBAgIURfVPAG6lOcTq29Ht/6KNbaKhm7IwDQYJKoZIhvcNAQEL +BQAwSzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQwwCgYDVQQHDANTVkwxITAf +BgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAgFw0xOTExMDQyMTQyNTFa +GA8yMjI1MDMwOTIxNDI1MVowSzELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQww +CgYDVQQHDANTVkwxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCC +AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL95INSZmsn3AgGX2Z9bu+6T +7n9VevXuD5bv/oc/Wpfb3d2rueBizpo1xRWMiNFq59wf+6o80LlRsJwqRCnMo7AU +FrR9zaryGzKa7mqkGnrX0oPIe/KP6sw+nUNtpr7m3PMpi3CkqTtZ1Oo1PhphyEu/ +pTF2mmS/Blaez3BKFuX/zMLbnxedUgKD2ok8VqOPUGr8uQ4IPp3eZL9FptQ8Tt7N +7H4U/Wng4YNvCBDSlLP60NGycJ8yrdL1aJSWAHJ1vDbYlSo3JeO4cjHdGUq6HTx0 +7USgg6ZX2OSEiE/DXRQbu7QkGjetssaURmUjUB3vbFCqmWZ9HDtkE3YYhk2vks6H +PQXlunNHUS7Ain+IgYsqK9cNRLWqcBbdo2IEKYYwAaK0xsQox/m4TuWacHMZw4Tg +Zh2Y984n6Hyq1H5FgWMYpng45VihT/iKZpD0r0vUBsDJQSQzsQkHjIJe6333gtey +8nWXm/dcRUZotcL+eJ6essniJ0ZBFz2m2DB/BKJ/5rA3hf1uQCPAdaLCho0QVUeE +gQShwTiP0og/0V6dHhqoDjnEnII9ZItGVn0NTl688a9VpzPGyCDcNtTuB089KtLs +UcE0vLtEmhlM0NI3CpP+ahQfxmF6i37VEzBoEzZfyzeaO2MrvmH7djfP3HYmx85M +yutAMo9NSpGWOiPYi/lFAgMBAAGjUzBRMB0GA1UdDgQWBBRapdqxmdTlDuYelOr/ +/GLi7QnxBjAfBgNVHSMEGDAWgBRapdqxmdTlDuYelOr//GLi7QnxBjAPBgNVHRMB +Af8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBpeytWYsMSa3sTZD1pA39IvQ4v +xAbzmJB6P86sjmt2hNkCZTJYnOdSnwr8mrsKnLgjf/6kpg2OO3RqN+aXUnDeCpjl +9mzDJ4kcoVxbOXYAhTkhgugT/b8HOlMEvC+3yULrKN9deUmQPCdyVOtMBnTHE3++ +VyAlP7T7R2xbgeVpOurO8SM7NLt04xxbtOS1cPVkhU2AE0+KlQBQYK9bProHTynR +zhVixFWtyS9asrMUwGh/xye85xTpy+unUxkzZoPqYvK6YiKv/WB3U3SURuLcOqAD +T/BMpOUwbYAP0KVEL5K82uo7csADLMwBkPvFhDsMaFGTkUdb014NQqRjTXOOK8ad +Xwnm4ur4GgT0Rr/iJ990JTOQkWYWlW3ZO6DSiUZCqeRWWhju290+aviOcrJeXS0V +XKkeJiYjbdnvFp/LIcg+V+n/HCDwwQgC3vQqlwd8PNvl0gKRX4EGjV+1lobZoKvD +WdIuSIIUkIDbv547n2ldp3GhJHIft6jlTOLAd3jonURO2/lZVyxj8yGFPbTWRUa0 +aK7IWkcOzof0+v2BrEhQQoL+lwJahqYEPSKw6WNehQxYWaxr3TL/xeawFzEVW1ve +v8Vh1LvZ/qyucpP3dgDuj7gpVg0xshKpKEbGwzPKMz9PGcHJvgF1GOXVRIdoB9nU +IdXOcawI6rpqTXrTgA== +-----END CERTIFICATE----- diff --git a/security/advancedtls/testdata/client_trust_key_1.pem b/security/advancedtls/testdata/client_trust_key_1.pem new file mode 100644 index 00000000..237f0758 --- /dev/null +++ b/security/advancedtls/testdata/client_trust_key_1.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 ++xZ1BJ0Xfq/t2SnXDABwi9hvqTNOGqY= +-----END PRIVATE KEY----- diff --git a/security/advancedtls/testdata/server_cert_1.pem b/security/advancedtls/testdata/server_cert_1.pem new file mode 100644 index 00000000..73787f18 --- /dev/null +++ b/security/advancedtls/testdata/server_cert_1.pem @@ -0,0 +1,122 @@ +Certificate: + Data: + Version: 3 (0x2) + Serial Number: 3 (0x3) + Signature Algorithm: sha256WithRSAEncryption + Issuer: C=US, ST=CA, L=SVL, O=Internet Widgits Pty Ltd + Validity + Not Before: Nov 4 21:43:00 2019 GMT + Not After : Aug 18 21:43:00 2293 GMT + Subject: C=US, ST=CA, L=DUMMYCITY, O=Internet Widgits Pty Ltd, CN=foo.bar.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public-Key: (4096 bit) + Modulus: + 00:ec:3f:24:2d:91:3a:bd:c3:fc:15:72:42:b3:fb: + 28:e6:04:a3:be:26:20:e6:ea:30:a8:aa:48:78:36: + 0e:0b:99:29:3b:4b:f9:f1:d5:bf:bd:0c:13:7c:ea: + 52:06:f4:bc:34:9e:2b:c0:b4:82:2c:87:fa:2f:e2: + cd:7c:d7:b9:e1:8f:04:71:6d:85:77:ae:18:40:e4: + b1:3a:4a:6b:e5:33:bf:3e:65:db:cf:94:64:87:1a: + 20:46:c0:37:3a:9f:93:3f:d4:4f:ac:c4:e4:e0:28: + b6:0f:28:53:2a:cf:b9:fe:50:f2:ef:47:dc:7e:b6: + 60:c2:47:85:b8:cb:ca:48:5b:fa:9f:8a:97:30:01: + f4:b3:51:0f:68:e1:60:ab:2f:a0:ad:fc:f0:10:4f: + 60:e1:92:db:be:83:04:5c:40:87:ce:51:3e:9a:9e: + d6:1c:1b:19:cb:8c:c2:6c:57:74:6f:7b:af:94:3d: + 53:ad:17:a5:99:69:7c:41:f5:3e:7a:5b:48:c7:78: + ff:d7:3b:a8:1f:f7:30:e7:83:26:78:e2:cb:a2:8f: + 58:92:61:cd:ca:e9:b8:d1:80:c0:40:58:e9:d8:d3: + 42:64:82:8f:e4:0c:b9:b1:36:db:9f:65:3f:3f:5b: + 24:59:31:b3:60:0c:fa:41:5a:1b:b8:9d:ec:99:37: + 90:fa:b5:e7:3f:cb:7c:e0:f9:ed:ea:27:ce:15:24: + c7:77:3b:45:45:2d:19:8e:2e:7f:65:0e:85:df:66: + 50:69:24:2c:a4:6a:07:e5:3f:eb:28:84:53:94:4d: + 5f:9c:a8:65:a6:50:4c:c0:35:06:40:6a:a5:62:b1: + 93:60:e5:1c:85:28:34:9b:29:81:6f:e2:4f:cd:15: + 30:b9:19:d7:4b:bb:30:0c:4b:2d:64:fe:3b:dd:0e: + a4:25:2c:4a:5c:de:d7:74:1f:5e:93:7b:1c:e8:c8: + fa:72:1f:4a:eb:8d:3f:98:e4:55:98:b8:e0:8a:29: + 92:33:af:75:6b:05:84:05:d3:0c:2c:07:78:bc:0e: + b2:6d:a7:00:35:c4:53:1f:7b:e6:ba:07:72:a8:24: + c1:0a:a7:c4:46:e6:f2:6f:3a:79:23:00:0b:b8:e5: + 1f:e0:e2:ee:c6:13:a3:57:d9:86:1a:95:f7:a3:04: + f1:46:d5:5f:21:d2:aa:d2:30:fb:f6:cb:e0:da:24: + c6:c3:30:2f:d2:1f:21:fe:bc:0f:99:ac:ac:9b:65: + 9b:e4:83:9a:00:b8:2f:40:fc:3b:42:d3:7a:e8:b7: + 52:d7:f4:67:2a:a5:f7:eb:78:f1:0a:56:8b:56:12: + d5:48:d8:48:70:ab:b8:69:5a:21:d3:71:b0:59:9d: + 17:b4:4b + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + C0:82:DA:FA:69:46:30:AE:FF:6F:CD:BB:93:49:94:A6:D0:E2:17:EB + X509v3 Authority Key Identifier: + keyid:5A:A5:DA:B1:99:D4:E5:0E:E6:1E:94:EA:FF:FC:62:E2:ED:09:F1:06 + + X509v3 Basic Constraints: + CA:FALSE + X509v3 Key Usage: + Digital Signature, Key Encipherment + Signature Algorithm: sha256WithRSAEncryption + 36:fd:cf:ec:f5:20:4b:52:dc:2e:38:f3:92:b1:e4:b6:a1:06: + 86:aa:2d:c0:e6:f5:0a:58:97:a9:e3:be:13:09:61:79:ed:d4: + 41:83:26:ad:ee:0b:43:83:d1:dd:19:1a:e8:7b:b2:1f:fe:d4: + c1:57:7d:6d:6b:d4:42:ea:7d:cd:34:8c:a4:1f:5b:3b:fa:de: + bb:2f:ae:56:b6:18:e5:53:a9:a3:99:58:ad:36:be:19:54:61: + 0d:52:b6:a7:53:fc:60:e5:ff:f5:7f:82:3f:c1:49:06:cd:b2: + af:25:ee:de:bd:e0:e5:5e:ad:0b:dc:2e:b1:ec:7a:52:6f:9d: + e0:b9:84:18:db:49:53:ee:df:93:ee:8b:9d:9b:8e:3b:2a:82: + 86:7f:45:c8:dd:d1:b0:40:17:ed:63:52:a1:5b:6e:d3:5c:a2: + 72:05:fb:3a:39:71:0d:b4:2c:9d:15:23:1b:1f:8d:ac:89:dc: + c9:56:f2:19:c7:f3:2f:bb:d5:de:40:17:f1:52:ea:e8:93:ff: + 56:43:f5:1d:cb:c0:51:52:25:d7:b0:81:a9:0e:4d:92:24:e7: + 10:81:c7:31:26:ac:cb:66:c1:3f:f6:5f:69:7b:74:87:0d:b0: + 8c:27:d4:24:29:59:e9:5b:a2:cb:0c:c0:f5:9b:1d:42:38:6b: + e3:c3:43:1e:ba:df:b1:51:0a:b7:33:55:26:39:01:2f:9f:c7: + 88:ac:2f:4a:89:f3:69:de:72:43:48:49:08:59:36:86:84:09: + db:6a:82:84:3e:71:6a:9d:f9:bd:d8:b5:1e:7c:2c:29:e1:27: + 45:4c:47:5b:88:b8:e6:fa:9d:9b:ff:d4:e9:8d:2d:5e:64:7f: + 27:87:b2:8c:d8:7e:f5:52:3c:c4:d8:30:03:24:d7:ac:f8:53: + 91:80:98:42:24:5a:6b:cb:34:48:57:e0:82:ac:96:d9:55:6c: + c2:c3:8c:19:7c:56:39:0a:a8:f1:b8:77:64:70:83:a8:04:c8: + 3a:5d:0b:00:4c:e5:ba:f1:40:e5:57:cd:d9:67:48:21:e9:9c: + d3:f2:b8:01:b8:d1:c0:d1:3a:44:c0:97:db:e6:bc:8f:2e:33: + d5:e2:38:3d:d7:7b:50:13:01:36:28:61:cc:28:98:3c:f8:21: + 5d:8c:fe:f5:d0:ab:e0:60:ec:36:22:8d:0b:71:30:1b:3d:56: + ae:96:e9:d2:89:c2:43:8b:ef:25:b7:d6:0d:82:e6:5a:c6:91: + 8a:ad:8c:28:2a:2b:5c:4e:a1:de:cb:7d:cb:29:11:a2:66:c8: + a1:33:35:75:16:fe:28:0b:78:31:0a:1f:fa:d0:a8:f4:f1:69: + c7:97:1e:5d:fb:53:08:b5 +-----BEGIN CERTIFICATE----- +MIIFiTCCA3GgAwIBAgIBAzANBgkqhkiG9w0BAQsFADBLMQswCQYDVQQGEwJVUzEL +MAkGA1UECAwCQ0ExDDAKBgNVBAcMA1NWTDEhMB8GA1UECgwYSW50ZXJuZXQgV2lk +Z2l0cyBQdHkgTHRkMCAXDTE5MTEwNDIxNDMwMFoYDzIyOTMwODE4MjE0MzAwWjBn +MQswCQYDVQQGEwJVUzELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCURVTU1ZQ0lUWTEh +MB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRQwEgYDVQQDDAtmb28u +YmFyLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOw/JC2ROr3D +/BVyQrP7KOYEo74mIObqMKiqSHg2DguZKTtL+fHVv70ME3zqUgb0vDSeK8C0giyH ++i/izXzXueGPBHFthXeuGEDksTpKa+Uzvz5l28+UZIcaIEbANzqfkz/UT6zE5OAo +tg8oUyrPuf5Q8u9H3H62YMJHhbjLykhb+p+KlzAB9LNRD2jhYKsvoK388BBPYOGS +276DBFxAh85RPpqe1hwbGcuMwmxXdG97r5Q9U60XpZlpfEH1PnpbSMd4/9c7qB/3 +MOeDJnjiy6KPWJJhzcrpuNGAwEBY6djTQmSCj+QMubE2259lPz9bJFkxs2AM+kFa +G7id7Jk3kPq15z/LfOD57eonzhUkx3c7RUUtGY4uf2UOhd9mUGkkLKRqB+U/6yiE +U5RNX5yoZaZQTMA1BkBqpWKxk2DlHIUoNJspgW/iT80VMLkZ10u7MAxLLWT+O90O +pCUsSlze13QfXpN7HOjI+nIfSuuNP5jkVZi44IopkjOvdWsFhAXTDCwHeLwOsm2n +ADXEUx975roHcqgkwQqnxEbm8m86eSMAC7jlH+Di7sYTo1fZhhqV96ME8UbVXyHS +qtIw+/bL4NokxsMwL9IfIf68D5msrJtlm+SDmgC4L0D8O0LTeui3Utf0Zyql9+t4 +8QpWi1YS1UjYSHCruGlaIdNxsFmdF7RLAgMBAAGjWjBYMB0GA1UdDgQWBBTAgtr6 +aUYwrv9vzbuTSZSm0OIX6zAfBgNVHSMEGDAWgBRapdqxmdTlDuYelOr//GLi7Qnx +BjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIFoDANBgkqhkiG9w0BAQsFAAOCAgEANv3P +7PUgS1LcLjjzkrHktqEGhqotwOb1CliXqeO+Ewlhee3UQYMmre4LQ4PR3Rka6Huy +H/7UwVd9bWvUQup9zTSMpB9bO/reuy+uVrYY5VOpo5lYrTa+GVRhDVK2p1P8YOX/ +9X+CP8FJBs2yryXu3r3g5V6tC9wusex6Um+d4LmEGNtJU+7fk+6LnZuOOyqChn9F +yN3RsEAX7WNSoVtu01yicgX7OjlxDbQsnRUjGx+NrIncyVbyGcfzL7vV3kAX8VLq +6JP/VkP1HcvAUVIl17CBqQ5NkiTnEIHHMSasy2bBP/ZfaXt0hw2wjCfUJClZ6Vui +ywzA9ZsdQjhr48NDHrrfsVEKtzNVJjkBL5/HiKwvSonzad5yQ0hJCFk2hoQJ22qC +hD5xap35vdi1HnwsKeEnRUxHW4i45vqdm//U6Y0tXmR/J4eyjNh+9VI8xNgwAyTX +rPhTkYCYQiRaa8s0SFfggqyW2VVswsOMGXxWOQqo8bh3ZHCDqATIOl0LAEzluvFA +5VfN2WdIIemc0/K4AbjRwNE6RMCX2+a8jy4z1eI4Pdd7UBMBNihhzCiYPPghXYz+ +9dCr4GDsNiKNC3EwGz1Wrpbp0onCQ4vvJbfWDYLmWsaRiq2MKCorXE6h3st9yykR +ombIoTM1dRb+KAt4MQof+tCo9PFpx5ceXftTCLU= +-----END CERTIFICATE----- diff --git a/security/advancedtls/testdata/server_key_1.pem b/security/advancedtls/testdata/server_key_1.pem new file mode 100644 index 00000000..927a03d6 --- /dev/null +++ b/security/advancedtls/testdata/server_key_1.pem @@ -0,0 +1,51 @@ +-----BEGIN RSA PRIVATE KEY----- +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 +-----END RSA PRIVATE KEY----- diff --git a/security/advancedtls/testdata/server_trust_cert_1.pem b/security/advancedtls/testdata/server_trust_cert_1.pem new file mode 100644 index 00000000..96120469 --- /dev/null +++ b/security/advancedtls/testdata/server_trust_cert_1.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFlzCCA3+gAwIBAgIUdkt73feqv3fH1K1fBBp2ryU4TUMwDQYJKoZIhvcNAQEL +BQAwWjELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAlZBMSEwHwYDVQQKDBhJbnRlcm5l +dCBXaWRnaXRzIFB0eSBMdGQxGzAZBgNVBAMMEmZvby5iYXIuaG9vLmNhLmNvbTAg +Fw0xOTExMTUxOTE1MTFaGA8yMjI1MDMyMDE5MTUxMVowWjELMAkGA1UEBhMCVVMx +CzAJBgNVBAgMAlZBMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQx +GzAZBgNVBAMMEmZvby5iYXIuaG9vLmNhLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQAD +ggIPADCCAgoCggIBAMLHM55ChPP7dk+1uWz2DSkLE/xkoBaagJkjXuBgpgtdcxfp +hG9qTQ/vPAnqRFNSqQPU/A0dbKlnlK2ibrSb1LD4CPiXMqMAVojbEBRiNZK2+E1p +6FDaUO/CiurX8QPsVHUp2Zol38FoGdHL3tHSEf2xfJzs1Ka4g54FASOn+wJSAdAG +Ai+TUT137NqmeIVMIhg8x2vtKJpIH016mBqPENpccb3wsk9kNLj9TonKP16Nkngm +YKdLBnhB5Coz9gFqnTFEXp54ESOKttNtAAdFfhBqJhYMAdoFxSsuDdpr23Nyfuzf +uT5QnIffD0JCxH6bGYpMgJMVLiWJSuZ6wohFl04lwQTj3UXC8GU9o8YGC1UnvJoZ +rTgC8bM+yNJnEsrU90dPMLAi6qN5pl0y18/jtyaP5YXjv2TCGAjmB3dUyFa4nCg+ +7w9tAi4pC3cBusN7e4cOseOM/23qKbcudHWAQ46VkTMs36DQyzxZutgZUI9lesol +o3eCR00v4N3Uf0yXff866EaDg3NmcZzhn1stJMHJMkhPOQZZmD8dd3Pi4DuQZMa/ +74vMcjLxXo2xKTQklBUDCAFVEIR0y0oHwYUCk+AuS0PAXbGred0KOs6Ey8c68JYZ +OfgD/jjY/emYzyNeGGKUkMtNA9xUqWNEnqmIQgpMndzy1c5UlnGpoOt/cfztAgMB +AAGjUzBRMB0GA1UdDgQWBBS0GQgc/BAjxTCGIrzLsV+t6npd8TAfBgNVHSMEGDAW +gBS0GQgc/BAjxTCGIrzLsV+t6npd8TAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3 +DQEBCwUAA4ICAQARMgDs180PFUSjXrRQ6hfpmYaauoq2atSYfzECfo92iemE1KiK +qUAVX/fjRy69/r6BKAo/j8F7BJVRqKhfiZm+EUIGWCtNRpVCx6WCtfJ1G8rEEH+U +E4kNpPC1OyVAhFMYKFJVXkyzpxjggLeY0bGs7BrX4wSid7vj6HM/pzfOShvB6qv0 +VfpAGwTKnqw64kpy+9QPwS0sDH17oJAteJ3WeRopsqCjK9eXljmGBKVZjv2m9/TT +7Jd6VCBm/x1yxPeuJfPTxkfGR3UEcKPgXG84N0nfbTLspQcBf2QqQtW4yL/PyRC/ +8sFAPanSkNc3u1ERQub0oUtd+jQalvxXqW1N0GAJHLvtXa5Etrz3WMfOVdqthEKK +CjGXdt4JoO+gvCGZH9jKa6HTgy+0QZrbOxBsJpbxSjXrJOeeJ2OgGZg8qBe5LqUD +Z3o45x6j3RiQrK24luZE/6A25VUvUke4Hr9oTBQFgMlIPuTeRw6XGkNzScaPrXEU +MnijDX8n7OcME+lCVCpgSd1SZzkTn4JYqlx8U33j1hRD1m5quO9+GOLQpWvZC5A5 +FsikGXULKuIxVCJMuCXeWdY1aDAJ/6cwz77eDzNkySUfDEhxjQGhCmNlNDHN3dCM +NtSqXJSDIwqikj7izot3evkoYa9j6w3qkNyg9fyGbdNHXp135RP5HIhqjA== +-----END CERTIFICATE----- diff --git a/security/advancedtls/testdata/server_trust_key_1.pem b/security/advancedtls/testdata/server_trust_key_1.pem new file mode 100644 index 00000000..b9c072a6 --- /dev/null +++ b/security/advancedtls/testdata/server_trust_key_1.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +HASpvDH+panUrtqSvjDZMuDvkA6qft8= +-----END PRIVATE KEY-----