* validateCertificates(): change input parameters; added short description

This commit is contained in:
Simon Zolin 2019-02-27 14:11:41 +03:00
parent d218e047a3
commit 766fbab071
3 changed files with 25 additions and 26 deletions

4
app.go
View File

@ -178,13 +178,13 @@ func run(args options) {
}
address := net.JoinHostPort(config.BindHost, strconv.Itoa(config.TLS.PortHTTPS))
// validate current TLS config and update warnings (it could have been loaded from file)
data := validateCertificates(config.TLS)
data := validateCertificates(config.TLS.CertificateChain, config.TLS.PrivateKey, config.TLS.ServerName)
if !data.usable {
log.Fatal(data.WarningValidation)
os.Exit(1)
}
config.Lock()
config.TLS = data // update warnings
config.TLS.tlsConfigStatus = data // update warnings
config.Unlock()
// prepare certs for HTTPS server

View File

@ -1025,7 +1025,7 @@ func handleTLSValidate(w http.ResponseWriter, r *http.Request) {
}
}
data = validateCertificates(data)
data.tlsConfigStatus = validateCertificates(data.CertificateChain, data.PrivateKey, data.ServerName)
marshalTLS(w, data)
}
@ -1051,7 +1051,7 @@ func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
}
restartHTTPS := false
data = validateCertificates(data)
data.tlsConfigStatus = validateCertificates(data.CertificateChain, data.PrivateKey, data.ServerName)
if !reflect.DeepEqual(config.TLS.tlsConfigSettings, data.tlsConfigSettings) {
log.Printf("tls config settings have changed, will restart HTTPS server")
restartHTTPS = true
@ -1078,21 +1078,24 @@ func handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
}
}
func validateCertificates(data tlsConfig) tlsConfig {
/* Process certificate data and its private key.
CertificateChain, PrivateKey parameters are optional.
On error, return partially set object
with 'WarningValidation' field containing error description.
*/
func validateCertificates(CertificateChain, PrivateKey, ServerName string) tlsConfigStatus {
var err error
// clear out status for certificates
data.tlsConfigStatus = tlsConfigStatus{}
var data tlsConfigStatus
// check only public certificate separately from the key
if data.CertificateChain != "" {
log.Tracef("got certificate: %s", data.CertificateChain)
if CertificateChain != "" {
log.Tracef("got certificate: %s", CertificateChain)
// now do a more extended validation
var certs []*pem.Block // PEM-encoded certificates
var skippedBytes []string // skipped bytes
pemblock := []byte(data.CertificateChain)
pemblock := []byte(CertificateChain)
for {
var decoded *pem.Block
decoded, pemblock = pem.Decode(pemblock)
@ -1127,7 +1130,7 @@ func validateCertificates(data tlsConfig) tlsConfig {
// spew.Dump(parsedCerts)
opts := x509.VerifyOptions{
DNSName: data.ServerName,
DNSName: ServerName,
}
log.Printf("number of certs - %d", len(parsedCerts))
@ -1164,13 +1167,13 @@ func validateCertificates(data tlsConfig) tlsConfig {
}
// validate private key (right now the only validation possible is just parsing it)
if data.PrivateKey != "" {
if PrivateKey != "" {
// now do a more extended validation
var key *pem.Block // PEM-encoded certificates
var skippedBytes []string // skipped bytes
// go through all pem blocks, but take first valid pem block and drop the rest
pemblock := []byte(data.PrivateKey)
pemblock := []byte(PrivateKey)
for {
var decoded *pem.Block
decoded, pemblock = pem.Decode(pemblock)
@ -1202,8 +1205,8 @@ func validateCertificates(data tlsConfig) tlsConfig {
}
// if both are set, validate both in unison
if data.PrivateKey != "" && data.CertificateChain != "" {
_, err = tls.X509KeyPair([]byte(data.CertificateChain), []byte(data.PrivateKey))
if PrivateKey != "" && CertificateChain != "" {
_, err = tls.X509KeyPair([]byte(CertificateChain), []byte(PrivateKey))
if err != nil {
data.WarningValidation = fmt.Sprintf("Invalid certificate or key: %s", err)
return data

View File

@ -10,12 +10,10 @@ import (
. Bad private key
. Valid certificate & private key */
func TestValidateCertificates(t *testing.T) {
var data tlsConfig
var data tlsConfigStatus
// bad cert
data.CertificateChain = "bad cert"
data.PrivateKey = ""
data = validateCertificates(data)
data = validateCertificates("bad cert", "", "")
if !(data.WarningValidation != "" &&
!data.ValidCert &&
!data.ValidChain) {
@ -23,16 +21,14 @@ func TestValidateCertificates(t *testing.T) {
}
// bad priv key
data.CertificateChain = ""
data.PrivateKey = "bad priv key"
data = validateCertificates(data)
data = validateCertificates("", "bad priv key", "")
if !(data.WarningValidation != "" &&
!data.ValidKey) {
t.Fatalf("bad priv key: validateCertificates(): %v", data)
}
// valid cert & priv key
data.CertificateChain = `-----BEGIN CERTIFICATE-----
CertificateChain := `-----BEGIN CERTIFICATE-----
MIICKzCCAZSgAwIBAgIJAMT9kPVJdM7LMA0GCSqGSIb3DQEBCwUAMC0xFDASBgNV
BAoMC0FkR3VhcmQgTHRkMRUwEwYDVQQDDAxBZEd1YXJkIEhvbWUwHhcNMTkwMjI3
MDkyNDIzWhcNNDYwNzE0MDkyNDIzWjAtMRQwEgYDVQQKDAtBZEd1YXJkIEx0ZDEV
@ -46,7 +42,7 @@ LwlXfbakf7qkVTlCNXgoY7RaJ8rJdPgOZPoCTVToEhT6u/cb1c2qp8QB0dNExDna
b0Z+dnODTZqQOJo6z/wIXlcUrnR4cQVvytXt8lFn+26l6Y6EMI26twC/xWr+1swq
Muj4FeWHVDerquH4yMr1jsYLD3ci+kc5sbIX6TfVxQ==
-----END CERTIFICATE-----`
data.PrivateKey = `-----BEGIN PRIVATE KEY-----
PrivateKey := `-----BEGIN PRIVATE KEY-----
MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBALC/BSc8mI68tw5p
aYa7pjrySwWvXeetcFywOWHGVfLw9qiFWLdfESa3Y6tWMpZAXD9t1Xh9n211YUBV
FGSB4ZshnM/tgEPU6t787lJD4NsIIRp++MkJxdAitN4oUTqL0bdpIwezQ/CrYuBX
@ -62,7 +58,7 @@ O5EX70gpeGQMPDK0QSWpaazg956njJSDbNCFM4BccrdQbJu1cW4qOsfBAkAMgZuG
O88slmgTRHX4JGFmy3rrLiHNI2BbJSuJ++Yllz8beVzh6NfvuY+HKRCmPqoBPATU
kXS9jgARhhiWXJrk
-----END PRIVATE KEY-----`
data = validateCertificates(data)
data = validateCertificates(CertificateChain, PrivateKey, "")
notBefore, _ := time.Parse(time.RFC3339, "2019-02-27T09:24:23Z")
notAfter, _ := time.Parse(time.RFC3339, "2046-07-14T09:24:23Z")
if !(data.WarningValidation != "" /* self signed */ &&