Skip to content

Commit 5507b04

Browse files
committed
feat: add self_signed_certificates for client net test
Signed-off-by: Minh Huy Tran <[email protected]>
1 parent 99867bb commit 5507b04

File tree

2 files changed

+115
-1
lines changed

2 files changed

+115
-1
lines changed

client/test/setup.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,11 @@ func MakeRoleSetups(rng *rand.Rand, s *ethctest.Setup, names []string) []clientt
7676

7777
// MakeNetRoleSetups creates a two party client test setup with the provided names and uses the default TLS-bus from go-perun.
7878
func MakeNetRoleSetups(t *testing.T, rng *rand.Rand, s *ethctest.Setup, names []string) []clienttest.RoleSetup {
79+
t.Helper()
7980
setups := make([]clienttest.RoleSetup, len(names))
8081
commonName := "127.0.0.1"
8182
sans := []string{"127.0.0.1", "localhost"}
82-
tlsConfigs, err := simple.GenerateSelfSignedCertConfigs(commonName, sans, len(names))
83+
tlsConfigs, err := GenerateSelfSignedCertConfigs(commonName, sans, len(names))
8384
if err != nil {
8485
panic("Error generating TLS configs: " + err.Error())
8586
}
@@ -129,6 +130,7 @@ func MakeNetRoleSetups(t *testing.T, rng *rand.Rand, s *ethctest.Setup, names []
129130
}
130131

131132
func makeSimpleDialersListeners(t *testing.T, tlsConfigs []*tls.Config, hosts []string) ([]*simple.Dialer, []*simple.Listener) {
133+
t.Helper()
132134
dialers := make([]*simple.Dialer, len(tlsConfigs))
133135
listeners := make([]*simple.Listener, len(tlsConfigs))
134136

client/test/tls.go

+112
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Copyright 2022 - See NOTICE file for copyright holders.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package test
16+
17+
import (
18+
"crypto/rand"
19+
"crypto/rsa"
20+
"crypto/tls"
21+
"crypto/x509"
22+
"crypto/x509/pkix"
23+
"encoding/pem"
24+
"errors"
25+
"fmt"
26+
"math/big"
27+
"net"
28+
"time"
29+
)
30+
31+
const (
32+
timeout = 24 * time.Hour
33+
)
34+
35+
// GenerateSelfSignedCertConfigs generates self-signed certificates and returns
36+
// a list of TLS configurations for n clients.
37+
func GenerateSelfSignedCertConfigs(commonName string, sans []string, numClients int) ([]*tls.Config, error) {
38+
keySize := 2048
39+
configs := make([]*tls.Config, numClients)
40+
certPEMs := make([][]byte, numClients)
41+
tlsCerts := make([]tls.Certificate, numClients)
42+
43+
for i := 0; i < numClients; i++ {
44+
// Private key for the client
45+
privateKey, err := rsa.GenerateKey(rand.Reader, keySize)
46+
if err != nil {
47+
return nil, err
48+
}
49+
50+
// Create a certificate template
51+
template := x509.Certificate{
52+
SerialNumber: big.NewInt(int64(i) + 1),
53+
Subject: pkix.Name{
54+
Organization: []string{"Perun Network"},
55+
CommonName: fmt.Sprintf("%s-client-%d", commonName, i+1),
56+
},
57+
NotBefore: time.Now(),
58+
NotAfter: time.Now().Add(timeout),
59+
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
60+
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth},
61+
BasicConstraintsValid: true,
62+
}
63+
64+
// Add SANs to the server certificate template
65+
for _, san := range sans {
66+
if ip := net.ParseIP(san); ip != nil {
67+
template.IPAddresses = append(template.IPAddresses, ip)
68+
} else {
69+
template.DNSNames = append(template.DNSNames, san)
70+
}
71+
}
72+
73+
// Generate a self-signed server certificate
74+
certDER, err := x509.CreateCertificate(rand.Reader, &template, &template, &privateKey.PublicKey, privateKey)
75+
if err != nil {
76+
return nil, err
77+
}
78+
79+
// Encode the server certificate to PEM format
80+
certPEMs[i] = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
81+
82+
// Encode the server private key to PEM format
83+
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)})
84+
85+
// Create a tls.Certificate object for the server
86+
tlsCerts[i], err = tls.X509KeyPair(certPEMs[i], keyPEM)
87+
if err != nil {
88+
return nil, err
89+
}
90+
}
91+
92+
for i := 0; i < numClients; i++ {
93+
certPool := x509.NewCertPool()
94+
for j := 0; j < numClients; j++ {
95+
ok := certPool.AppendCertsFromPEM(certPEMs[j])
96+
if !ok {
97+
return nil, errors.New("failed to parse root certificate")
98+
}
99+
}
100+
101+
// Create the server-side TLS configuration
102+
configs[i] = &tls.Config{
103+
RootCAs: certPool,
104+
ClientCAs: certPool,
105+
Certificates: []tls.Certificate{tlsCerts[i]},
106+
ClientAuth: tls.RequireAndVerifyClientCert,
107+
MinVersion: tls.VersionTLS12, // Set minimum TLS version to TLS 1.2
108+
}
109+
}
110+
111+
return configs, nil
112+
}

0 commit comments

Comments
 (0)