maddy/tls.go
fox.cpp 84d150a00f Rework config directives iteration
Create more high-level wrapper (config.Map) instead of walking syntax
tree directly.
2019-03-30 17:34:19 +02:00

81 lines
1.9 KiB
Go

package maddy
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"net"
"time"
"github.com/emersion/maddy/config"
)
func tlsDirective(m *config.Map, node *config.Node) (interface{}, error) {
switch len(node.Args) {
case 1:
switch node.Args[0] {
case "off":
return nil, nil
case "self_signed":
cfg := &tls.Config{}
if err := makeSelfSignedCert(cfg); err != nil {
return nil, err
}
return &cfg, nil
}
case 2:
cfg := tls.Config{}
if cert, err := tls.LoadX509KeyPair(node.Args[0], node.Args[1]); err != nil {
return nil, err
} else {
cfg.Certificates = append(cfg.Certificates, cert)
}
default:
return nil, m.MatchErr("expected 1 or 2 arguments")
}
return nil, nil
}
func makeSelfSignedCert(config *tls.Config) error {
privKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
return err
}
notBefore := time.Now()
notAfter := notBefore.Add(24 * time.Hour * 7)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return err
}
cert := &x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{Organization: []string{"Maddy Self-Signed"}},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
}
if ip := net.ParseIP(config.ServerName); ip != nil {
cert.IPAddresses = append(cert.IPAddresses, ip)
} else {
cert.DNSNames = append(cert.DNSNames, config.ServerName)
}
derBytes, err := x509.CreateCertificate(rand.Reader, cert, cert, &privKey.PublicKey, privKey)
if err != nil {
return err
}
config.Certificates = append(config.Certificates, tls.Certificate{
Certificate: [][]byte{derBytes},
PrivateKey: privKey,
Leaf: cert,
})
return nil
}