tweak TLS configuration options

This commit is contained in:
idk
2021-02-28 16:10:55 -05:00
parent 9b05750814
commit e31a7636d0
6 changed files with 66 additions and 32 deletions

2
.gitignore vendored
View File

@ -5,3 +5,5 @@ bin/*
*/*.i2pkeys */*.i2pkeys
README.md.asc README.md.asc
samcatd samcatd
*/*.pem
*.pem

View File

@ -2,7 +2,9 @@ package i2ptunconf
import ( import (
"crypto/tls" "crypto/tls"
"log" "strings"
"github.com/eyedeekay/sam-forwarder/tls"
) )
// GetPort443 takes an argument and a default. If the argument differs from the // GetPort443 takes an argument and a default. If the argument differs from the
@ -62,7 +64,7 @@ func (c *Conf) GetTLSConfig(arg, def string, label ...string) string {
if c.Config == nil { if c.Config == nil {
return arg return arg
} }
if x, o := c.Get("cert", label...); o { if x, o := c.Get("cert.pem", label...); o {
return x return x
} }
return arg return arg
@ -70,7 +72,7 @@ func (c *Conf) GetTLSConfig(arg, def string, label ...string) string {
// SetClientDest sets the key name from the config file // SetClientDest sets the key name from the config file
func (c *Conf) SetTLSConfig(label ...string) { func (c *Conf) SetTLSConfig(label ...string) {
if v, ok := c.Get("cert", label...); ok { if v, ok := c.Get("cert.pem", label...); ok {
c.Cert = v c.Cert = v
} else { } else {
c.Cert = "" c.Cert = ""
@ -85,7 +87,7 @@ func (c *Conf) GetTLSConfigPem(arg, def string, label ...string) string {
if c.Config == nil { if c.Config == nil {
return arg return arg
} }
if x, o := c.Get("pem", label...); o { if x, o := c.Get("key.pem", label...); o {
return x return x
} }
return arg return arg
@ -93,17 +95,17 @@ func (c *Conf) GetTLSConfigPem(arg, def string, label ...string) string {
// SetClientDest sets the key name from the config file // SetClientDest sets the key name from the config file
func (c *Conf) SetTLSConfigPem(label ...string) { func (c *Conf) SetTLSConfigPem(label ...string) {
if v, ok := c.Get("pem", label...); ok { if v, ok := c.Get("key.pem", label...); ok {
c.Pem = v c.Pem = v
} else { } else {
c.Pem = "" c.Pem = ""
} }
} }
func (c *Conf) TLSConfig() *tls.Config { func (c *Conf) TLSConfig() (*tls.Config, error) {
cert, err := tls.LoadX509KeyPair(c.Cert, c.Pem) names := []string{c.Base32()}
if err != nil { if c.HostName != "" && strings.HasSuffix(c.HostName, ".i2p") {
log.Fatal(err) names = append(names, c.HostName)
} }
return &tls.Config{Certificates: []tls.Certificate{cert}} return i2ptls.TLSConfig(c.Cert, c.Pem, names)
} }

View File

@ -70,6 +70,7 @@ type Conf struct {
UseTLS bool `default:false` UseTLS bool `default:false`
Cert string `default:""` Cert string `default:""`
Pem string `default:""` Pem string `default:""`
HostName string `default:""`
//TLSConf *tls.Config //TLSConf *tls.Config
LoadedKeys i2pkeys.I2PKeys LoadedKeys i2pkeys.I2PKeys
} }

View File

@ -361,7 +361,11 @@ func (f *SAMForwarder) Serve() error {
log.Println("SAM Listener created,", f.Base32()) log.Println("SAM Listener created,", f.Base32())
log.Println("Human-readable hash:\n ", f.Base32Readable()) log.Println("Human-readable hash:\n ", f.Base32Readable())
if f.Conf.UseTLS { if f.Conf.UseTLS {
f.publishListen = tls.NewListener(publishListen, f.Conf.TLSConfig()) tlsconf, err := f.Conf.TLSConfig()
if err != nil {
return err
}
f.publishListen = tls.NewListener(publishListen, tlsconf)
} else { } else {
f.publishListen = publishListen f.publishListen = publishListen
} }

View File

@ -8,6 +8,7 @@ import (
"crypto/x509/pkix" "crypto/x509/pkix"
"encoding/pem" "encoding/pem"
"log" "log"
"math/big"
"os" "os"
) )
@ -18,9 +19,15 @@ func CheckFile(path string) bool {
return true return true
} }
func Certificate(Cert, Pem string, names []string, priv *ed25519.PrivateKey) (*tls.Certificate, error) { func CertPemificate(CertPem, KeyPem string, names []string, priv ed25519.PrivateKey) (tls.Certificate, error) {
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
log.Fatalf("Failed to generate serial number: %v", err)
}
template := x509.Certificate{ template := x509.Certificate{
// SerialNumber: serialNumber, SerialNumber: serialNumber,
Subject: pkix.Name{ Subject: pkix.Name{
Organization: []string{"Acme Co"}, Organization: []string{"Acme Co"},
}, },
@ -30,27 +37,28 @@ func Certificate(Cert, Pem string, names []string, priv *ed25519.PrivateKey) (*t
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true, BasicConstraintsValid: true,
} }
template.DNSNames = append(template.DNSNames, names...) if len(names) > 0 {
template.DNSNames = append(template.DNSNames, names...)
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public().(ed25519.PublicKey), priv) derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public().(ed25519.PublicKey), priv)
if err != nil { if err != nil {
log.Fatalf("Failed to create certificate: %v", err) log.Fatalf("Failed to create certificate: %v", err)
} }
certOut, err := os.Create(Cert) certOut, err := os.Create(CertPem)
if err != nil { if err != nil {
log.Fatalf("Failed to open "+Cert+" for writing: %v", err) log.Fatalf("Failed to open "+CertPem+" for writing: %v", err)
} }
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil {
log.Fatalf("Failed to write data to "+Cert+": %v", err) log.Fatalf("Failed to write data to "+CertPem+": %v", err)
} }
if err := certOut.Close(); err != nil { if err := certOut.Close(); err != nil {
log.Fatalf("Error closing "+Cert+": %v", err) log.Fatalf("Error closing "+CertPem+": %v", err)
} }
log.Print("wrote " + Cert + "\n") log.Print("wrote " + CertPem + "\n")
keyOut, err := os.OpenFile(Pem, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) keyOut, err := os.OpenFile(KeyPem, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil { if err != nil {
log.Fatalf("Failed to open "+Pem+" for writing: %v", err) log.Fatalf("Failed to open "+KeyPem+" for writing: %v", err)
} }
privBytes, err := x509.MarshalPKCS8PrivateKey(priv) privBytes, err := x509.MarshalPKCS8PrivateKey(priv)
if err != nil { if err != nil {
@ -62,25 +70,31 @@ func Certificate(Cert, Pem string, names []string, priv *ed25519.PrivateKey) (*t
if err := keyOut.Close(); err != nil { if err := keyOut.Close(); err != nil {
log.Fatalf("Error closing key.pem: %v", err) log.Fatalf("Error closing key.pem: %v", err)
} }
return tls.LoadX509KeyPair(Cert, Pem) return tls.LoadX509KeyPair(CertPem, KeyPem)
} }
func TLSConfig(Cert, Pem string, names []string) *tls.Config { func TLSConfig(CertPem, KeyPem string, names []string) (*tls.Config, error) {
if CheckFile(Cert) && CheckFile(Pem) { var ServerName string
cert, err := tls.LoadX509KeyPair(Cert, Pem) if len(names) > 0 {
ServerName = names[0]
}
if CheckFile(CertPem) && CheckFile(KeyPem) {
cert, err := tls.LoadX509KeyPair(CertPem, KeyPem)
if err != nil { if err != nil {
log.Fatal(err) return nil, err
} }
return &tls.Config{Certificates: []tls.Certificate{cert}}
return &tls.Config{Certificates: []tls.Certificate{cert}, ServerName: ServerName}, nil
} else { } else {
_, priv, err := ed25519.GenerateKey(rand.Reader) _, priv, err := ed25519.GenerateKey(rand.Reader)
if err != nil { if err != nil {
log.Fatal(err) return nil, err
} }
cert, err := Certificate(Cert, Pem, names, priv) cert, err := CertPemificate(CertPem, KeyPem, names, priv)
if err != nil { if err != nil {
log.Fatal(err) return nil, err
} }
return &tls.Config{Certificates: []tls.Certificate{cert}} return &tls.Config{Certificates: []tls.Certificate{cert}, ServerName: ServerName}, nil
} }
} }

11
tls/tls_test.go Normal file
View File

@ -0,0 +1,11 @@
package i2ptls
import "testing"
func TestTLSGenerate(t *testing.T) {
config, err := TLSConfig("cert.pem", "key.pem", []string{"idk.i2p"})
if err != nil {
t.Fatal(err.Error())
}
t.Log(config.ServerName)
}