Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static TLS Configuration Store Library Implementation #18

Merged
merged 1 commit into from
May 31, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions internal/v2/tls_config_store/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")

package(
default_visibility = ["//internal/v2:__subpackages__"],
)

# TODO(rmehta19) : Investigate how to use embedsrcs with data in a top level directory. If possible, move example_cert_key under s2a-go/internal/v2

go_library(
name = "tls_config_store",
srcs = ["tls_config_store.go"],
importpath = "github.com/google/s2a-go/internal/v2/tls_config_store",
embedsrcs = [
"example_cert_key/client_cert.pem",
"example_cert_key/client_key.pem",
"example_cert_key/server_cert.pem",
"example_cert_key/server_key.pem",
],
)

go_test(
name = "tls_config_store_test",
srcs = ["tls_config_store_test.go"],
embed = [":tls_config_store"],
embedsrcs = [
"example_cert_key/client_cert.pem",
"example_cert_key/client_key.pem",
"example_cert_key/server_cert.pem",
"example_cert_key/server_key.pem",
],
)
25 changes: 25 additions & 0 deletions internal/v2/tls_config_store/example_cert_key/client_cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
rmehta19 marked this conversation as resolved.
Show resolved Hide resolved
MIID8TCCAtmgAwIBAgIUMAQ1JyjU7PmSuf4+y86CHTI4XHcwDQYJKoZIhvcNAQEL
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
MjIwNTIwMjI0NjM2WhcNMjMwNTIwMjI0NjM2WjCBhzELMAkGA1UEBhMCVVMxCzAJ
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAO9y2k/jBSA4Yzkud/66nxQMPkkPSY/WstVNapiMYrbK5BT9UuPj3GxC
HeW6zsYV3pa3cKyCkohUFSB3l/O/cEMxzi0WwtOZSEoQ6thkLeDG13UUPxYt5KqO
7ymweiKONFELavr0+kIQM6MIxXsjLaVKBNNC32in1VNealsSg0deN4aSDmKCs/0I
42IBloEkq7KHqJL47g5VJHuTiXD+0djM+VmAILPYS2Bg4dZhEAPuLrkyKveZvhy3
s/R+QDfAVysuRisCZSpi9Rm9jbx4ttrBKng2sLWilt5BkkajNGWRbraMnwzkgfjm
9koz22quskGe47g3/W6e3xJEQDWHAVsCAwEAAaNTMFEwHQYDVR0OBBYEFHdUeLnU
YhFunZyD2tnWggLmkTDCMB8GA1UdIwQYMBaAFHdUeLnUYhFunZyD2tnWggLmkTDC
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBADEwoTTcZ2Oyt/2x
9b2adb/IfAU+rbzwk3pmQUkKiTkq7WFmIo+14+ra4RGA/JsfJVkLejZ8gVqkyJu1
lLdQDcGxiP3WjidUwzU7KhUu8Rw0nYXyzgfmQE+aixy9fRHEBsB1Vggofbi0pq+Y
3cmesQ1zpRNL6RNwfa+R51jfatfNFhOjKl7xLj9LcWdYkTwki+233XTqXXH3TEgs
fHjWhSt4/lczlDxZEYZ+/tOdCIPXX0V8YQ74e0vB4NCWW1wZYUAiwhzBJ7GPuVdJ
TByGbU2PavPBvbLTi4zVm8dLoU+1ObLv8PzsbJhA27tIlkOs82im2ul+XLTkHvbB
uIpxoWA=
-----END CERTIFICATE-----

28 changes: 28 additions & 0 deletions internal/v2/tls_config_store/example_cert_key/client_key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA73LaT+MFIDhjOS53/rqfFAw+SQ9Jj9ay1U1qmIxitsrkFP1S
4+PcbEId5brOxhXelrdwrIKSiFQVIHeX879wQzHOLRbC05lIShDq2GQt4MbXdRQ/
Fi3kqo7vKbB6Io40UQtq+vT6QhAzowjFeyMtpUoE00LfaKfVU15qWxKDR143hpIO
YoKz/QjjYgGWgSSrsoeokvjuDlUke5OJcP7R2Mz5WYAgs9hLYGDh1mEQA+4uuTIq
95m+HLez9H5AN8BXKy5GKwJlKmL1Gb2NvHi22sEqeDawtaKW3kGSRqM0ZZFutoyf
DOSB+Ob2SjPbaq6yQZ7juDf9bp7fEkRANYcBWwIDAQABAoIBADJ3vaW6zpjE6bzi
m233/ZFnJzWU4EdN1DF6+K2gYSnvx3TZE8BuhUXYBZ8m6W/8qgaQMVJazvGm7zEB
o+g/ADVZaQA93OBmXUMnH6huLPFEV6MYmlddYuXD7IqX5JYl7MbsJicwvRJxgcCq
F51lg7hjynKQlK/lN+QzcS0y0LKYs7CWKFcTvp5nERWt9SuIz+k+opMXlTMTYXmX
yhnTyt+YR+bvNLBCWj6LUIhyLIKRWAn9mBkyJC7AnE6cIQdRZ1XZ5lcqFsNyZ6B0
DwFQvcNDimlJiQ+R1i2GAGpiJLwO8uv32bEBuWgAEjn+0gg5llYQZLPWe4T56vCo
X9J7RkkCgYEA+yCwk8SefcOOyqblsPcpTXGqHCUbkXz3Ug+iJpGay/qvCJra0I6+
2vjeKRK3LMEBlogvPR9uuJJwtZotwPBS9EH5dEzpxH5fQuj13Hd6MwRDqw9RFzcd
jRoOaUuNOzyNKWMCs2ZqztrTOr/pNqbL0vkJL7XoAZbd5gcw8qckIH0CgYEA9Bgn
s++Q5FLDG8/nCuSXZDhUetidBvgRLTwyQiGmLHcbMDLY6qqq+LMr7dRZV82qvAwQ
GsXfC/kg7NWzann1oX46W5GLvTQG5qRu9xiOXmaLLmdvCSx5jV1MwXJkg9wETujY
0quLuZJ5xcTy0F+EYRQVxbj5Dl4X5Th1IZRVaLcCgYEAkn/Hguy46PUkX+RtKoeF
eMBOVIzxQDZ+sUidd5KJk2Vyprpv3Crp/CQitiNM6LbPjllz9VxY4yPKzKZc+qk4
O3YhaE9WMGLof8gXZb3tc8WRFEGjNL/aZW5F6fdBNMVmNDamZLHirTnK8AL0sgUr
8q+FRGgCKKsyV/bp/ySyVqECgYBmPAu9AHTmPIe9iVlSpaWG81Tm0v0J4zKGiLTg
H+nSq9w2VsWlm+/aFGksxojZDqoY8tB39jJSeHjC2Uq5KPWpOw5ENfSaPUU6qtpT
IfTXMwnOWMIXzInonJA+YaQZ2jfvuPS/X9w40FGydKfigG8Ynen0k2G1E9HcTsY4
V0FihwKBgQDEkhtPHbblmYK0UsNtn18+1+fskfT7RCryw67Ldai9Nn2Ou/T8s0v6
JwHaZY3MBJ9Zt+nBTWntUgdeNRz5XP8hUy65D7W8k1FaNsBGX9MdocYpyleVGkZ1
DaMRMgUu4p47jPSYjNqsqh37FmdRscqRe2F5eLlxCyJh3z5k5ND1YA==
-----END RSA PRIVATE KEY-----

25 changes: 25 additions & 0 deletions internal/v2/tls_config_store/example_cert_key/server_cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
-----BEGIN CERTIFICATE-----
MIID8TCCAtmgAwIBAgIUISXQBSlrMDJp9mRdibxw/RV9X6wwDQYJKoZIhvcNAQEL
BQAwgYcxCzAJBgNVBAYTAlVTMQswCQYDVQQIDAJDQTESMBAGA1UEBwwJU3Vubnl2
YWxlMRAwDgYDVQQKDAdDb21wYW55MREwDwYDVQQLDAhEaXZpc2lvbjEWMBQGA1UE
AwwNczJhX3Rlc3RfY2VydDEaMBgGCSqGSIb3DQEJARYLeHl6QHh5ei5jb20wHhcN
MjIwNTIzMTgwMTE1WhcNMjMwNTIzMTgwMTE1WjCBhzELMAkGA1UEBhMCVVMxCzAJ
BgNVBAgMAkNBMRIwEAYDVQQHDAlTdW5ueXZhbGUxEDAOBgNVBAoMB0NvbXBhbnkx
ETAPBgNVBAsMCERpdmlzaW9uMRYwFAYDVQQDDA1zMmFfdGVzdF9jZXJ0MRowGAYJ
KoZIhvcNAQkBFgt4eXpAeHl6LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAL23L/zvCQd6HlGNXcEn0IG6LTTP2unritO64vBdV3B5rCNfZEZ5kkku
JtCTmJNUOivPkRJ4iYACSlcjepK+fEUdG7ihhYxurrkw3tLCRx3YjexlynZdmKxM
6tcgMToFm4WTeG1E543B0mzM4be5CQyql5zpVOkf664TqYo0WoDlnPw8GsVaN0ek
sAibnVi63Darlko7QBa+tteyBip+FcPpozJocy+GM/skWlZb+2x1lwIJqM1MZOXQ
Ytc1u5ubzPZcinO1kkiGcoH0OlnKLQhjxDr+i4UZ3oQI5wft7Au4Z7K2H+s191+R
x3DOBPvfvmJF1YHPhrj7MsK3KA7vaZMCAwEAAaNTMFEwHQYDVR0OBBYEFIiliZPw
l2xoosx02Is18dytHQnZMB8GA1UdIwQYMBaAFIiliZPwl2xoosx02Is18dytHQnZ
MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBACp2Gkk5rrwMBud1
MyAARaykIZKfbOzk0VXpOmOunjwM8Us2XLc3XUuOtvd3V4b+664+K0Iwlx7QVVO1
ytpeP9+afSIZtvx8kg2EYMHeBo2RHut8paoe3MT40A6vfnLtpOjZCjmuxjEa6LYM
B4SqNcr9Oo80FXsb7i6iIqxXlXwrJBtlcXuHoyWWZW6EpnSNvkrwfGZcgnjXeiiW
i3pujHeZaB6i/4UcS0dp7qpmMoLEpFRjtzXYQnUb0I5qH/O/SmiYKHEJWnfjmj6Y
hW8HK+746OyhGVnEDNjLK91rZPgUvmNlEmUU0vYFZqJPfZmVgIKVAG2Pqs0c9p2y
AhxtER4=
-----END CERTIFICATE-----

28 changes: 28 additions & 0 deletions internal/v2/tls_config_store/example_cert_key/server_key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAvbcv/O8JB3oeUY1dwSfQgbotNM/a6euK07ri8F1XcHmsI19k
RnmSSS4m0JOYk1Q6K8+REniJgAJKVyN6kr58RR0buKGFjG6uuTDe0sJHHdiN7GXK
dl2YrEzq1yAxOgWbhZN4bUTnjcHSbMzht7kJDKqXnOlU6R/rrhOpijRagOWc/Dwa
xVo3R6SwCJudWLrcNquWSjtAFr6217IGKn4Vw+mjMmhzL4Yz+yRaVlv7bHWXAgmo
zUxk5dBi1zW7m5vM9lyKc7WSSIZygfQ6WcotCGPEOv6LhRnehAjnB+3sC7hnsrYf
6zX3X5HHcM4E+9++YkXVgc+GuPsywrcoDu9pkwIDAQABAoIBAQCw16ux2JfQEnNk
jaQRQy3HX2Z4TjC/0EJOb2zPphK105U0O91bHEPSV2TzFEIrQ14eLJQMZbO2UWw+
oeHGHC32ttV6W4YDi8Du+7EZQOPN3GkfLRt3DnQcWG6oLWf1r/hyoS6mnI5Dw6KE
rM7S1XasCfDd4Vq3HHwyfj2RiI+8ibCn0KhQ1MpRxNXEXQwJsorK4dRglw4wISK2
LuviOiB46nlQ8rVLVJ0EUJWuy1sbQnq8OgpkuXVj7GClEUEA0VejEaR6E+czzynI
jtFDTRM2s8xB5ZKz8A7WkMAxNZpzyw9S3xip+7hEh82/oOy3O6ASJhOdH856116l
rUHetVvhAoGBAO3dUMy/+hZSB5qZboLx/gZcgH9E5sRMq79bjesXPU1cQvnL1PvY
nFVDTEVPFkTkqOD+HD7Bd/6hdsQ9qROcL56CTkwtiWLCP+ca2wGBOBQ3qXkKi/f3
1ln3J7O/yCA0jexW0+ToFLbkCRp86RBulbaCuW9RbKYJX9ojmWvkJ5OLAoGBAMwu
F39lZJMD4boImuswBgZ3AlpE0a1EKgC3IOuxMcT22sHtF5wOjT2p2W53KenUFgDn
2x2h+jB0ZlbxpLOFfB7QAeiA2vWSEPMCwfvy1ef0YGcTCgDPQM60Fo0TrLDsSc4/
gO2bw7OFKdewsSrLKChIp6fKgh++ErycnnY+ciMZAoGBAI2UDWPRYKmoaZ47dOu7
3dcrd9BI0pJEkHV1qSMk0fgZ0kOcb0j3xRV62Qrn5/lZoKtKlMVFooaM1IQ5r0lc
zXsrVC9Da2K8/Awyj+h1YUunVdgVzvnpKkyiL59tp1CD93WUuMqm2K2DTWfWsWJ2
b+YSKQ15CZJKQiM0zTzKsEPBAoGBAJfCPnbTHvDitrj2QmdCd4gAlsAPXKVi/7Eu
bAqi1nImZKw1FBJLApHtl42yhnWkzIH50vPwe6veKF7BFoDUW0/vnSt58sUJvw1Q
ZGxmrrTL/4c9MHcvlGTOl+Bd2kJaLfVdX++7kbbx6ArH6rb67ysZ7XsaWqNLPFPy
ORl8CoupAoGAUyhKzR0dnfbayffEDJFSyiumcacc222cXoTFFHQN74wgTbrPyINp
G2moRYYh4exqboiPxUXCMqFQ7zsYlLIfBJV2cEzSmPYcvoi6+9hiV2Es6HTNJ+05
XYTuBDwwVBV+1x7xZQ3vpoohrYcLD9Yd3lUE3LQJcu4zYvaQ/E5H+3I=
-----END RSA PRIVATE KEY-----

99 changes: 99 additions & 0 deletions internal/v2/tls_config_store/tls_config_store.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// Builds TLS configurations that offload operations to S2Av2.
package tlsconfigstore

import (
"log"
"crypto/tls"
"crypto/x509"
"fmt"
"time"

_ "embed"
)

var (
//go:embed example_cert_key/client_cert.pem
clientCert []byte
//go:embed example_cert_key/server_cert.pem
serverCert []byte
//go:embed example_cert_key/client_key.pem
clientKey []byte
//go:embed example_cert_key/server_key.pem
serverKey []byte
)

// GetTlsConfigurationForClient returns a tls.Config instance for use by a client application.
func GetTlsConfigurationForClient() *tls.Config {
// TODO(rmehta19): Call remote signer library for private key.
cert, err := tls.X509KeyPair(clientCert, clientKey)
if err != nil {
log.Fatalf("Failed to generate X509KeyPair: %v", err)
}

rootCertPool := x509.NewCertPool()
rootCertPool.AppendCertsFromPEM(serverCert)

// TODO(rmehta19): Call S2Av2 for config values.
// Create mTLS credentials for client.
return &tls.Config {
Certificates: []tls.Certificate{cert},
VerifyPeerCertificate: verifyPeerCertificateFunc("s2a_test_cert", rootCertPool), // TODO(rmehta19): Call cert verifier library.
RootCAs: rootCertPool,
InsecureSkipVerify: true,
ClientSessionCache: nil,
MinVersion: uint16(tls.VersionTLS13),
MaxVersion: uint16(tls.VersionTLS13),
}
}

// GetTlsConfigurationForServer returns a tls.Config instance for use by a server application.
func GetTlsConfigurationForServer() *tls.Config {
// TODO(rmehta19): Call remote signer library for Private Key.
cert, err := tls.X509KeyPair(serverCert, serverKey)
if err != nil {
log.Fatalf("Failed to generate X509KeyPair: %v", err)
}

certPool := x509.NewCertPool()
certPool.AppendCertsFromPEM(clientCert)


// TODO(rmehta19): Call S2Av2 for config values.
// Create mTLS credentials for server.
return &tls.Config {
Certificates: []tls.Certificate{cert},
VerifyPeerCertificate: verifyPeerCertificateFunc("s2a_test_cert", certPool), // TODO(rmehta19): Call cert verifier library.
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: certPool,
InsecureSkipVerify: true,
MinVersion: uint16(tls.VersionTLS13),
MaxVersion: uint16(tls.VersionTLS13),
}
}

// TODO(rmehta19): Remove this static implementation once Certificate Verifier library(contains APIs for VerifyClientCertificateChain and VerifyServerCertificateChain) implementation completed.
func verifyPeerCertificateFunc(instanceName string, pool *x509.CertPool) func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
return func(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
if len(rawCerts) == 0 {
return fmt.Errorf("no certificate to verify")
}
cert, err := x509.ParseCertificate(rawCerts[0])
if err != nil {
return fmt.Errorf("ParseCertificate failed: %v", err)
}

opts := x509.VerifyOptions{
CurrentTime: time.Now(),
Roots: pool,
}

if _, err = cert.Verify(opts); err != nil {
return err
}

if cert.Subject.CommonName != instanceName {
return fmt.Errorf("certificate had Common Name %q, expected %q", cert.Subject.CommonName, instanceName)
}
return nil
}
}
115 changes: 115 additions & 0 deletions internal/v2/tls_config_store/tls_config_store_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
package tlsconfigstore

import (
"testing"
"crypto/tls"
"bytes"

_ "embed"
)

var (
//go:embed example_cert_key/client_cert.pem
clientCertpem []byte
//go:embed example_cert_key/server_cert.pem
serverCertpem []byte
//go:embed example_cert_key/client_key.pem
clientKeypem []byte
//go:embed example_cert_key/server_key.pem
serverKeypem []byte
)


// TODO(rmehta19): In Client and Server test, verify contents of config.RootCAs once x509.CertPool.Equal function is officially released : https://cs.opensource.google/go/go/+/4aacb7ff0f103d95a724a91736823f44aa599634 .

// TestTLSConfigStoreClient runs unit tests for GetTlsConfigurationForClient.
func TestTLSConfigStoreClient(t *testing.T) {
// Setup for static client test.
cert, err := tls.X509KeyPair(clientCertpem, clientKeypem)
if err != nil {
t.Errorf("Test suite setup failed")
}

for _, tc := range []struct {
description string
Certificates []tls.Certificate
InsecureSkipVerify bool
ClientSessionCache tls.ClientSessionCache
MinVersion uint16
MaxVersion uint16
}{
{
description: "static",
rmehta19 marked this conversation as resolved.
Show resolved Hide resolved
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: true,
ClientSessionCache: nil,
MinVersion: tls.VersionTLS13,
MaxVersion: tls.VersionTLS13,
},
} {
t.Run(tc.description, func(t *testing.T) {
config := GetTlsConfigurationForClient()
if got, want := config.Certificates[0].Certificate[0], tc.Certificates[0].Certificate[0]; !bytes.Equal(got, want) {
t.Errorf("config.Certificates[0].Certificate[0] = %v, want %v", got, want)
}
if got, want := config.InsecureSkipVerify, tc.InsecureSkipVerify; got != want {
t.Errorf("config.InsecureSkipVerify = %v, want %v", got, want)
}
if got, want := config.ClientSessionCache, tc.ClientSessionCache; got != want {
t.Errorf("config.ClientSessionCache = %v, want %v", got, want)
}
if got, want := config.MinVersion, tc.MinVersion; got != want {
t.Errorf("config.MinVersion = %v, want %v", got, want)
}
if got, want := config.MaxVersion, tc.MaxVersion; got != want {
t.Errorf("config.MaxVersion = %v, want %v", got, want)
}
})
}
}

// TestTLSConfigStoreServer runs unit tests for GetTLSConfigurationForServer.
func TestTLSConfigStoreServer(t *testing.T) {
// Setup for static server test.
cert, err := tls.X509KeyPair(serverCertpem, serverKeypem)
if err != nil {
t.Errorf("Test suite setup failed")
}

for _, tc := range []struct {
description string
Certificates []tls.Certificate
ClientAuth tls.ClientAuthType
InsecureSkipVerify bool
MinVersion uint16
MaxVersion uint16
}{
{
description: "static",
Certificates: []tls.Certificate{cert},
ClientAuth: tls.RequireAndVerifyClientCert,
InsecureSkipVerify: true,
MinVersion: tls.VersionTLS13,
MaxVersion: tls.VersionTLS13,
},
} {
t.Run(tc.description, func(t *testing.T) {
config := GetTlsConfigurationForServer()
if got, want := config.Certificates[0].Certificate[0], tc.Certificates[0].Certificate[0]; !bytes.Equal(got,want) {
t.Errorf("config.Certificates[0].Certificate[0] = %v, want %v", got, want)
}
if got, want := config.ClientAuth, tc.ClientAuth; got != want {
t.Errorf("config.ClientAuth = %v, want %v", got, want)
}
if got, want := config.InsecureSkipVerify, tc.InsecureSkipVerify; got != want {
t.Errorf("config.InsecureSkipVerify = %v, want %v", got, want)
}
if got, want := config.MinVersion, tc.MinVersion; got != want {
t.Errorf("config.MinVersion = %v, want %v", got, want)
}
if got, want := config.MaxVersion, tc.MaxVersion; got != want {
t.Errorf("config.MaxVersion = %v, want %v", got, want)
}
})
}
}