63 lines
1.6 KiB
Go
63 lines
1.6 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/sha256"
|
|
"crypto/x509"
|
|
"encoding/hex"
|
|
"net"
|
|
"net/url"
|
|
"regexp"
|
|
"time"
|
|
)
|
|
|
|
func enforceCertificateValidity(clientCerts []*x509.Certificate, conn net.Conn, log *LogEntry) {
|
|
// This will fail if any of multiple certs are invalid
|
|
// Maybe we should just require one valid?
|
|
now := time.Now()
|
|
for _, cert := range clientCerts {
|
|
if now.Before(cert.NotBefore) {
|
|
conn.Write([]byte("64 Client certificate not yet valid!\r\n"))
|
|
log.Status = 64
|
|
return
|
|
} else if now.After(cert.NotAfter) {
|
|
conn.Write([]byte("65 Client certificate has expired!\r\n"))
|
|
log.Status = 65
|
|
return
|
|
}
|
|
}
|
|
}
|
|
|
|
func handleCertificateZones(URL *url.URL, clientCerts []*x509.Certificate, config Config, conn net.Conn, log *LogEntry) {
|
|
authorised := true
|
|
for zone, allowedFingerprints := range config.CertificateZones {
|
|
matched, err := regexp.Match(zone, []byte(URL.Path))
|
|
if !matched || err != nil {
|
|
continue
|
|
}
|
|
authorised = false
|
|
for _, clientCert := range clientCerts {
|
|
for _, allowedFingerprint := range allowedFingerprints {
|
|
if getCertFingerprint(clientCert) == allowedFingerprint {
|
|
authorised = true
|
|
break
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if !authorised {
|
|
if len(clientCerts) > 0 {
|
|
conn.Write([]byte("61 Provided certificate not authorised for this resource\r\n"))
|
|
log.Status = 61
|
|
} else {
|
|
conn.Write([]byte("60 A pre-authorised certificate is required to access this resource\r\n"))
|
|
log.Status = 60
|
|
}
|
|
return
|
|
}
|
|
}
|
|
|
|
func getCertFingerprint(cert *x509.Certificate) string {
|
|
hash := sha256.Sum256(cert.Raw)
|
|
fingerprint := hex.EncodeToString(hash[:])
|
|
return fingerprint
|
|
}
|