You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

69 lines
1.9 KiB
Go

package gemini
import (
"crypto/sha256"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"gophi/core"
)
// Mapped to tls.Version__ where:
// value - 0x300 = index.
// Deprecated versions will always be
// prefixed by 'DEPRECATED'
var tlsVersionStrings = []string{
"DEPRECATED:SSLv3",
"TLSv1.0",
"TLSv1.1",
"TLSv1.2",
"TLSv1.3",
}
func certSha256Hash(cert *x509.Certificate) string {
checksum := sha256.Sum256(cert.Raw)
return hex.EncodeToString(checksum[:])
}
func appendCgiEnv(client *core.Client, request *core.Request, env []string) []string {
// Build and append the full gemini url
env = append(env, "GEMINI_URL=gemini://"+core.Hostname+":"+core.Port+request.Path().Selector())
// Cast client underlying net.Conn as tls.Conn
tlsConn := client.Conn().Conn().(*tls.Conn)
state := tlsConn.ConnectionState()
// Append TLS env vars
env = append(env, "TLS_CIPHER="+tls.CipherSuiteName(state.CipherSuite))
env = append(env, "TLS_VERSION="+tlsVersionStrings[state.Version-0x300])
// Append TLS client cert vars (if present!)
clientCerts := state.PeerCertificates
if len(clientCerts) > 0 {
// Only use first if multiple client
// certs available
cert := clientCerts[0]
// Verify client cert
var isVerified string
_, err := cert.Verify(x509.VerifyOptions{})
if err != nil {
isVerified = "FAILED:" + err.Error()
} else {
isVerified = "SUCCESS"
}
// Set user cert environment vars
env = append(env, "AUTH_TYPE=Certificate")
env = append(env, "REMOTE_USER="+cert.Subject.CommonName)
env = append(env, "TLS_CLIENT_HASH=SHA256:"+certSha256Hash(cert))
env = append(env, "TLS_CLIENT_NOT_BEFORE="+cert.NotBefore.String())
env = append(env, "TLS_CLIENT_NOT_AFTER="+cert.NotAfter.String())
env = append(env, "TLS_CLIENT_ISSUER="+cert.Issuer.String())
env = append(env, "TLS_CLIENT_SUBJECT="+cert.Subject.String())
env = append(env, "TLS_CLIENT_VERIFIED="+isVerified)
}
return env
}