mirror of
https://github.com/cwinfo/yggdrasil-go.git
synced 2024-12-29 00:45:41 +00:00
95 lines
2.3 KiB
Go
95 lines
2.3 KiB
Go
package yggdrasil
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/rand"
|
|
"crypto/tls"
|
|
"crypto/x509"
|
|
"crypto/x509/pkix"
|
|
"encoding/hex"
|
|
"encoding/pem"
|
|
"log"
|
|
"math/big"
|
|
"net"
|
|
"time"
|
|
|
|
"golang.org/x/crypto/ed25519"
|
|
)
|
|
|
|
type tcptls struct {
|
|
tcp *tcp
|
|
config *tls.Config
|
|
forDialer *TcpUpgrade
|
|
forListener *TcpUpgrade
|
|
}
|
|
|
|
func (t *tcptls) init(tcp *tcp) {
|
|
t.tcp = tcp
|
|
t.forDialer = &TcpUpgrade{
|
|
upgrade: t.upgradeDialer,
|
|
name: "tls",
|
|
}
|
|
t.forListener = &TcpUpgrade{
|
|
upgrade: t.upgradeListener,
|
|
name: "tls",
|
|
}
|
|
|
|
edpriv := make(ed25519.PrivateKey, ed25519.PrivateKeySize)
|
|
copy(edpriv[:], tcp.link.core.sigPriv[:])
|
|
|
|
certBuf := &bytes.Buffer{}
|
|
|
|
// TODO: because NotAfter is finite, we should add some mechanism to regenerate the certificate and restart the listeners periodically for nodes with very high uptimes. Perhaps regenerate certs and restart listeners every few months or so.
|
|
pubtemp := x509.Certificate{
|
|
SerialNumber: big.NewInt(1),
|
|
Subject: pkix.Name{
|
|
CommonName: hex.EncodeToString(tcp.link.core.sigPub[:]),
|
|
},
|
|
NotBefore: time.Now(),
|
|
NotAfter: time.Now().Add(time.Hour * 24 * 365),
|
|
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
|
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
|
BasicConstraintsValid: true,
|
|
}
|
|
|
|
derbytes, err := x509.CreateCertificate(rand.Reader, &pubtemp, &pubtemp, edpriv.Public(), edpriv)
|
|
if err != nil {
|
|
log.Fatalf("Failed to create certificate: %s", err)
|
|
}
|
|
|
|
if err := pem.Encode(certBuf, &pem.Block{Type: "CERTIFICATE", Bytes: derbytes}); err != nil {
|
|
panic("failed to encode certificate into PEM")
|
|
}
|
|
|
|
cpool := x509.NewCertPool()
|
|
cpool.AppendCertsFromPEM(derbytes)
|
|
|
|
t.config = &tls.Config{
|
|
RootCAs: cpool,
|
|
Certificates: []tls.Certificate{
|
|
{
|
|
Certificate: [][]byte{derbytes},
|
|
PrivateKey: edpriv,
|
|
},
|
|
},
|
|
InsecureSkipVerify: true,
|
|
MinVersion: tls.VersionTLS13,
|
|
}
|
|
}
|
|
|
|
func (t *tcptls) upgradeListener(c net.Conn) (net.Conn, error) {
|
|
conn := tls.Server(c, t.config)
|
|
if err := conn.Handshake(); err != nil {
|
|
return c, err
|
|
}
|
|
return conn, nil
|
|
}
|
|
|
|
func (t *tcptls) upgradeDialer(c net.Conn) (net.Conn, error) {
|
|
conn := tls.Client(c, t.config)
|
|
if err := conn.Handshake(); err != nil {
|
|
return c, err
|
|
}
|
|
return conn, nil
|
|
}
|