mirror of
https://github.com/pomerium/pomerium.git
synced 2025-06-11 15:22:46 +02:00
authorize: add client mTLS support (#751)
* authorize: add client mtls support * authorize: better error messages for envoy * switch from function to input * add TrustedCa to envoy config so that users are prompted for the correct client certificate * update documentation * fix invalid ClientCAFile * regenerate cache protobuf * avoid recursion, add test * move comment line * use http.StatusOK * various fixes
This commit is contained in:
parent
3f1faf2e9e
commit
e4832cb4ed
24 changed files with 995 additions and 279 deletions
58
authorize/evaluator/opa/functions.go
Normal file
58
authorize/evaluator/opa/functions.go
Normal file
|
@ -0,0 +1,58 @@
|
|||
package opa
|
||||
|
||||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
)
|
||||
|
||||
var isValidClientCertificateCache, _ = lru.New2Q(100)
|
||||
|
||||
func isValidClientCertificate(ca, cert string) (bool, error) {
|
||||
// when ca is the empty string, client certificates are always accepted
|
||||
if ca == "" {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// when cert is the empty string, no client certificate was supplied
|
||||
if cert == "" {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
cacheKey := [2]string{ca, cert}
|
||||
|
||||
value, ok := isValidClientCertificateCache.Get(cacheKey)
|
||||
if ok {
|
||||
return value.(bool), nil
|
||||
}
|
||||
|
||||
roots := x509.NewCertPool()
|
||||
roots.AppendCertsFromPEM([]byte(ca))
|
||||
|
||||
xcert, err := parseCertificate(cert)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
_, verifyErr := xcert.Verify(x509.VerifyOptions{
|
||||
Roots: roots,
|
||||
})
|
||||
valid := verifyErr == nil
|
||||
|
||||
isValidClientCertificateCache.Add(cacheKey, valid)
|
||||
|
||||
return valid, nil
|
||||
}
|
||||
|
||||
func parseCertificate(pemStr string) (*x509.Certificate, error) {
|
||||
block, _ := pem.Decode([]byte(pemStr))
|
||||
if block == nil {
|
||||
return nil, fmt.Errorf("invalid certificate")
|
||||
}
|
||||
if block.Type != "CERTIFICATE" {
|
||||
return nil, fmt.Errorf("unknown PEM type: %s", block.Type)
|
||||
}
|
||||
return x509.ParseCertificate(block.Bytes)
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue