pages-server/certificates.go

98 lines
2.6 KiB
Go
Raw Normal View History

2021-03-17 00:34:31 +01:00
package main
import (
"bytes"
"crypto/rand"
"crypto/rsa"
2021-03-17 00:34:31 +01:00
"crypto/tls"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"strings"
"time"
2021-03-17 00:34:31 +01:00
)
// tlsConfig contains the configuration for generating, serving and cleaning up Let's Encrypt certificates.
var tlsConfig = &tls.Config{
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
// TODO: check DNS name & get certificate from Let's Encrypt
return FallbackCertificate(), nil
2021-03-17 00:34:31 +01:00
},
PreferServerCipherSuites: true,
// generated 2021-07-13, Mozilla Guideline v5.6, Go 1.14.4, intermediate configuration
// https://ssl-config.mozilla.org/#server=go&version=1.14.4&config=intermediate&guideline=5.6
MinVersion: tls.VersionTLS12,
CipherSuites: []uint16{
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
},
}
// GetHSTSHeader returns a HSTS header with includeSubdomains & preload for MainDomainSuffix and RawDomain, or an empty
// string for custom domains.
func GetHSTSHeader(host []byte) string {
if bytes.HasSuffix(host, MainDomainSuffix) || bytes.Equal(host, RawDomain) {
return "max-age=63072000; includeSubdomains; preload"
} else {
return ""
}
2021-03-17 00:34:31 +01:00
}
var fallbackCertificate *tls.Certificate
// FallbackCertificate generates a new self-signed TLS certificate on demand.
func FallbackCertificate() *tls.Certificate {
if fallbackCertificate != nil {
return fallbackCertificate
}
fallbackSerial, err := rand.Int(rand.Reader, (&big.Int{}).Lsh(big.NewInt(1), 159))
if err != nil {
panic(err)
}
fallbackCertKey, err := rsa.GenerateKey(rand.Reader, 1024)
if err != nil {
panic(err)
}
fallbackCertSpecification := &x509.Certificate{
Subject: pkix.Name{
CommonName: strings.TrimPrefix(string(MainDomainSuffix), "."),
},
SerialNumber: fallbackSerial,
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(100, 0, 0),
}
fallbackCertBytes, err := x509.CreateCertificate(
rand.Reader,
fallbackCertSpecification,
fallbackCertSpecification,
fallbackCertKey.Public(),
fallbackCertKey,
)
if err != nil {
panic(err)
}
fallbackCert, err := tls.X509KeyPair(pem.EncodeToMemory(&pem.Block{
Bytes: fallbackCertBytes,
Type: "CERTIFICATE",
}), pem.EncodeToMemory(&pem.Block{
Bytes: x509.MarshalPKCS1PrivateKey(fallbackCertKey),
Type: "RSA PRIVATE KEY",
}))
if err != nil {
panic(err)
}
fallbackCertificate = &fallbackCert
return fallbackCertificate
}