X-Git-Url: http://www.git.stargrave.org/?a=blobdiff_plain;f=tls.go;h=28f54fb6737d8fee566dcffdbfe53298a7d3933b;hb=HEAD;hp=ff7d7d653fc2050fd60af53701bac3ee0bf9e0da;hpb=5d3931d2a2671ca97cfc0c9f466bb066f2d92e90;p=godlighty.git diff --git a/tls.go b/tls.go index ff7d7d6..28f54fb 100644 --- a/tls.go +++ b/tls.go @@ -1,19 +1,17 @@ -/* -godlighty -- highly-customizable HTTP, HTTP/2, HTTPS server -Copyright (C) 2021-2022 Sergey Matveev - -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 -the Free Software Foundation, version 3 of the License. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ +// godlighty -- highly-customizable HTTP, HTTP/2, HTTPS server +// Copyright (C) 2021-2024 Sergey Matveev +// +// 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 +// the Free Software Foundation, version 3 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . package godlighty @@ -23,27 +21,61 @@ import ( "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] + var cert *tls.Certificate + if len(HostToECDSACertificate) == 0 { + cert = HostToEdDSACertificate[chi.ServerName] + } else { + 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") } @@ -55,8 +87,11 @@ func GetConfigForClient(chi *tls.ClientHelloInfo) (*tls.Config, error) { if CHIHasGOST(chi) { pool = HostGOSTClientAuth[chi.ServerName] } + if pool == nil && (CHIHasEdDSA(chi) || len(HostECDSAClientAuth) == 0) { + pool = HostEdDSAClientAuth[chi.ServerName] + } if pool == nil { - pool = HostClientAuth[chi.ServerName] + pool = HostECDSAClientAuth[chi.ServerName] } if pool == nil { return nil, nil @@ -83,7 +118,7 @@ func loadCertificates( log.Fatalln(err) } if cfg.CACert != "" { - data, err := ioutil.ReadFile(cfg.CACert) + data, err := os.ReadFile(cfg.CACert) if err != nil { log.Fatalln(err) } @@ -99,7 +134,7 @@ func loadCertificates( (*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) } @@ -117,26 +152,28 @@ func loadCertificates( log.Fatalln(err) } pool.AddCert(ca) + (*hostClientAuth)[host] = pool } } - if len(pool.Subjects()) > 0 { - (*hostClientAuth)[host] = pool - } } 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,