/*
godlighty -- highly-customizable HTTP, HTTP/2, HTTPS server
-Copyright (C) 2021-2022 Sergey Matveev <stargrave@stargrave.org>
+Copyright (C) 2021-2023 Sergey Matveev <stargrave@stargrave.org>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
"encoding/pem"
"errors"
"fmt"
- "io/ioutil"
"log"
+ "os"
)
var (
NextProtos = []string{"h2", "http/1.1"}
- HostToCertificate map[string]*tls.Certificate
- HostClientAuth map[string]*x509.CertPool
+ HostToECDSACertificate map[string]*tls.Certificate
+ HostECDSAClientAuth map[string]*x509.CertPool
+
+ HostToEdDSACertificate map[string]*tls.Certificate
+ HostEdDSAClientAuth map[string]*x509.CertPool
HostToGOSTCertificate map[string]*tls.Certificate
HostGOSTClientAuth map[string]*x509.CertPool
)
+func CHIHasTLS13(chi *tls.ClientHelloInfo) bool {
+ for _, v := range chi.SupportedVersions {
+ if v == tls.VersionTLS13 {
+ return true
+ }
+ }
+ return false
+}
+
+func CHIHasEdDSA(chi *tls.ClientHelloInfo) bool {
+ if !CHIHasTLS13(chi) {
+ return false
+ }
+ for _, ss := range chi.SignatureSchemes {
+ if ss == tls.Ed25519 {
+ return true
+ }
+ }
+ return false
+}
+
func GetCertificate(chi *tls.ClientHelloInfo) (*tls.Certificate, error) {
if CHIHasGOST(chi) {
if cert := HostToGOSTCertificate[chi.ServerName]; cert != nil {
return cert, nil
}
}
- cert := HostToCertificate[chi.ServerName]
+ if CHIHasEdDSA(chi) {
+ if cert := HostToEdDSACertificate[chi.ServerName]; cert != nil {
+ return cert, nil
+ }
+ }
+ cert := HostToECDSACertificate[chi.ServerName]
if cert == nil {
return nil, errors.New("no certificate found")
}
if CHIHasGOST(chi) {
pool = HostGOSTClientAuth[chi.ServerName]
}
+ if pool == nil && CHIHasEdDSA(chi) {
+ pool = HostEdDSAClientAuth[chi.ServerName]
+ }
if pool == nil {
- pool = HostClientAuth[chi.ServerName]
+ pool = HostECDSAClientAuth[chi.ServerName]
}
if pool == nil {
return nil, nil
log.Fatalln(err)
}
if cfg.CACert != "" {
- data, err := ioutil.ReadFile(cfg.CACert)
+ data, err := os.ReadFile(cfg.CACert)
if err != nil {
log.Fatalln(err)
}
(*hostToCertificate)[host] = &cert
pool := x509.NewCertPool()
for _, p := range cfg.ClientCAs {
- data, err := ioutil.ReadFile(p)
+ data, err := os.ReadFile(p)
if err != nil {
log.Fatalln(err)
}
}
func LoadCertificates() {
- HostToCertificate = make(map[string]*tls.Certificate, len(Hosts))
- HostClientAuth = make(map[string]*x509.CertPool)
+ HostToECDSACertificate = make(map[string]*tls.Certificate, len(Hosts))
+ HostECDSAClientAuth = make(map[string]*x509.CertPool)
+ HostToEdDSACertificate = make(map[string]*tls.Certificate, len(Hosts))
+ HostEdDSAClientAuth = make(map[string]*x509.CertPool)
HostToGOSTCertificate = make(map[string]*tls.Certificate, len(Hosts))
HostGOSTClientAuth = make(map[string]*x509.CertPool)
for host, cfg := range Hosts {
- loadCertificates(host, cfg.TLS, &HostToCertificate, &HostClientAuth)
+ loadCertificates(host, cfg.ECDSATLS, &HostToECDSACertificate, &HostECDSAClientAuth)
+ loadCertificates(host, cfg.EdDSATLS, &HostToEdDSACertificate, &HostEdDSAClientAuth)
loadCertificates(host, cfg.GOSTTLS, &HostToGOSTCertificate, &HostGOSTClientAuth)
}
}
func NewTLSConfig() *tls.Config {
return &tls.Config{
+ MinVersion: tls.VersionTLS12,
NextProtos: NextProtos,
GetCertificate: GetCertificate,
GetConfigForClient: GetConfigForClient,