Skip to content

Commit

Permalink
Merge pull request #18 from google/tls_config_lib_impl
Browse files Browse the repository at this point in the history
Static TLS Configuration Store Library Implementation
  • Loading branch information
rmehta19 authored May 31, 2022
2 parents b0306a5 + 727a2d7 commit fd87324
Show file tree
Hide file tree
Showing 7 changed files with 351 additions and 0 deletions.
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-----
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",
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)
}
})
}
}

0 comments on commit fd87324

Please sign in to comment.