Merge pull request #1404 from hashicorp/non-ca-crl-check

Perform CRL checking for non-CA registered certs
This commit is contained in:
Vishal Nayak 2016-05-12 14:50:59 -04:00
commit 7f2773af05
2 changed files with 89 additions and 12 deletions

View file

@ -110,6 +110,80 @@ func failOnError(t *testing.T, resp *logical.Response, err error) {
}
}
func TestBackend_RegisteredNonCA_CRL(t *testing.T) {
config := logical.TestBackendConfig()
storage := &logical.InmemStorage{}
config.StorageView = storage
b, err := Factory(config)
if err != nil {
t.Fatal(err)
}
nonCACert, err := ioutil.ReadFile(testCertPath1)
if err != nil {
t.Fatal(err)
}
// Register the Non-CA certificate of the client key pair
certData := map[string]interface{}{
"certificate": nonCACert,
"policies": "abc",
"display_name": "cert1",
"ttl": 10000,
}
certReq := &logical.Request{
Operation: logical.UpdateOperation,
Path: "certs/cert1",
Storage: storage,
Data: certData,
}
resp, err := b.HandleRequest(certReq)
failOnError(t, resp, err)
// Connection state is presenting the client Non-CA cert and its key.
// This is exactly what is registered at the backend.
connState := connectionState(t, serverCAPath, serverCertPath, serverKeyPath, testCertPath1, testKeyPath1)
loginReq := &logical.Request{
Operation: logical.UpdateOperation,
Storage: storage,
Path: "login",
Connection: &logical.Connection{
ConnState: &connState,
},
}
// Login should succeed.
resp, err = b.HandleRequest(loginReq)
failOnError(t, resp, err)
// Register a CRL containing the issued client certificate used above.
issuedCRL, err := ioutil.ReadFile(testIssuedCertCRL)
if err != nil {
t.Fatal(err)
}
crlData := map[string]interface{}{
"crl": issuedCRL,
}
crlReq := &logical.Request{
Operation: logical.UpdateOperation,
Storage: storage,
Path: "crls/issuedcrl",
Data: crlData,
}
resp, err = b.HandleRequest(crlReq)
failOnError(t, resp, err)
// Attempt login with the same connection state but with the CRL registered
resp, err = b.HandleRequest(loginReq)
if err != nil {
t.Fatal(err)
}
if resp == nil || !resp.IsError() {
t.Fatalf("expected failure due to revoked certificate")
}
}
func TestBackend_CRLs(t *testing.T) {
config := logical.TestBackendConfig()
storage := &logical.InmemStorage{}

View file

@ -149,7 +149,7 @@ func (b *backend) verifyCredentials(req *logical.Request) (*ParsedCert, *logical
// with the backend.
if len(trustedNonCAs) != 0 {
policy := b.matchNonCAPolicy(connState.PeerCertificates[0], trustedNonCAs)
if policy != nil {
if policy != nil && !b.checkForChainInCRLs(policy.Certificates) {
return policy, nil, nil
}
}
@ -245,18 +245,21 @@ func (b *backend) loadTrustedCerts(store logical.Storage) (pool *x509.CertPool,
return
}
func (b *backend) checkForValidChain(store logical.Storage, chains [][]*x509.Certificate) bool {
var badChain bool
for _, chain := range chains {
badChain = false
for _, cert := range chain {
badCRLs := b.findSerialInCRLs(cert.SerialNumber)
if len(badCRLs) != 0 {
badChain = true
break
}
func (b *backend) checkForChainInCRLs(chain []*x509.Certificate) bool {
badChain := false
for _, cert := range chain {
badCRLs := b.findSerialInCRLs(cert.SerialNumber)
if len(badCRLs) != 0 {
badChain = true
break
}
if !badChain {
}
return badChain
}
func (b *backend) checkForValidChain(store logical.Storage, chains [][]*x509.Certificate) bool {
for _, chain := range chains {
if !b.checkForChainInCRLs(chain) {
return true
}
}