Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow additional time for PKI certificates to valid #1394

Merged
merged 4 commits into from
Jul 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 5 additions & 25 deletions dependency/vault_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import (
"strings"
"time"

"crypto/x509"
"encoding/json"
"encoding/pem"

"github.com/hashicorp/vault/api"
)

Expand Down Expand Up @@ -115,22 +112,6 @@ func renewSecret(clients *ClientSet, d renewer) error {
}
}

// durationFrom cert gets the duration of validity from cert data and
// returns that value as an integer number of seconds
func durationFromCert(certData string) int {
block, _ := pem.Decode([]byte(certData))
if block == nil {
return -1
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
log.Printf("[WARN] Unable to parse certificate data: %s", err)
return -1
}

return int(cert.NotAfter.Sub(cert.NotBefore).Seconds())
}

// leaseCheckWait accepts a secret and returns the recommended amount of
// time to sleep.
func leaseCheckWait(s *Secret) time.Duration {
Expand All @@ -141,12 +122,11 @@ func leaseCheckWait(s *Secret) time.Duration {
}

// Handle if this is a certificate with no lease
if certInterface, ok := s.Data["certificate"]; ok && s.LeaseID == "" {
if certData, ok := certInterface.(string); ok {
newDuration := durationFromCert(certData)
if newDuration > 0 {
log.Printf("[DEBUG] Found certificate and set lease duration to %d seconds", newDuration)
base = newDuration
if _, ok := s.Data["certificate"]; ok && s.LeaseID == "" {
if expInterface, ok := s.Data["expiration"]; ok {
if expData, err := expInterface.(json.Number).Int64(); err == nil {
base = int(expData - time.Now().Unix())
log.Printf("[DEBUG] Found certificate and set lease duration to %d seconds", base)
}
}
}
Expand Down
48 changes: 15 additions & 33 deletions dependency/vault_common_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package dependency

import (
"encoding/json"
"strconv"
"testing"

"github.com/stretchr/testify/assert"
"time"
)

func init() {
Expand All @@ -26,7 +26,7 @@ func TestVaultRenewDuration(t *testing.T) {

var data = map[string]interface{}{
"rotation_period": json.Number("60"),
"ttl": json.Number("30"),
"ttl": json.Number("30"),
}

nonRenewableRotated := Secret{LeaseDuration: 100, Data: data}
Expand All @@ -39,7 +39,7 @@ func TestVaultRenewDuration(t *testing.T) {

data = map[string]interface{}{
"rotation_period": json.Number("30"),
"ttl": json.Number("5"),
"ttl": json.Number("5"),
}

nonRenewableRotated = Secret{LeaseDuration: 100, Data: data}
Expand All @@ -49,36 +49,18 @@ func TestVaultRenewDuration(t *testing.T) {
if nonRenewableRotatedDur != 6 {
t.Fatalf("renewable duration is not 6: %f", nonRenewableRotatedDur)
}
}

const testGoodCert = `-----BEGIN CERTIFICATE-----
MIICAjCCAWugAwIBAgIJALDrJbXZKXXnMA0GCSqGSIb3DQEBCwUAMBoxGDAWBgNV
BAMMD2NvbnN1bC10ZW1wbGF0ZTAeFw0xODA1MjUxNTAzNDdaFw0xODA2MDQxNTAz
NDdaMBoxGDAWBgNVBAMMD2NvbnN1bC10ZW1wbGF0ZTCBnzANBgkqhkiG9w0BAQEF
AAOBjQAwgYkCgYEAuT1yS2FvX2bpNvEkrapt4wC68NIfTU9Xx55DC4/Pq1ZkuI8b
tC64x1oiJdM7ABEmT58rofTXoEpeHxcLTpXtJcrfLdgHUkPxNdrBgLWJi0BGI3m6
zLF9KLTwEpFfBBTLgM6HIvTqqBD4itFtI0BDS/mqQKqa33Ai6hX0zPAH6AECAwEA
AaNQME4wHQYDVR0OBBYEFLldqcFQ+RF40xBNgSjdNGBN78yHMB8GA1UdIwQYMBaA
FLldqcFQ+RF40xBNgSjdNGBN78yHMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEL
BQADgYEAUXeDp5pyGhH3RCxdJgjbQ67D5nqTVbTJnetEw1UdMEDQGrgCIUrbsJWm
G4SbKUjKP+4wVUJLZpmv9PwJcN0ZxntNkJBDzTk+KULu4+8cCj6A27bBhmzeOu1y
zZlyse1m1NECY3ryPtkst4U/0wCiKcI4ZW58RrhXgKucB3Y0C0w=
-----END CERTIFICATE-----`

const testBadCert = `-----BEGIN CERTIFICATE-----
THIS IS NOT A VALID CERT
-----END CERTIFICATE-----`

func TestDurationFromCert(t *testing.T) {
t.Parallel()

dur := durationFromCert(testGoodCert)
rawExpiration := time.Now().Unix() + 100
expiration := strconv.FormatInt(rawExpiration, 10)

// 10 days in seconds
assert.Equal(t, 864000, dur)

dur = durationFromCert(testBadCert)
data = map[string]interface{}{
"expiration": json.Number(expiration),
"certificate": "foobar",
}

// Negative duration means an invalid cert
assert.Equal(t, -1, dur)
nonRenewableCert := Secret{LeaseDuration: 100, Data: data}
nonRenewableCertDur := leaseCheckWait(&nonRenewableCert).Seconds()
if nonRenewableCertDur < 85 || nonRenewableCertDur > 95 {
t.Fatalf("non renewable certificate duration is not within 85%% to 95%%: %f", nonRenewableCertDur)
}
}