From 0610df0f6c6b719f0cd3fa518c9332c73d2cab6d Mon Sep 17 00:00:00 2001 From: hc-github-team-secure-vault-core <82990506+hc-github-team-secure-vault-core@users.noreply.github.com> Date: Thu, 15 Jun 2023 17:47:54 -0400 Subject: [PATCH] backport of commit 042dd57811c900c9f6e2c85b5460d50560f79105 (#21295) Co-authored-by: Steven Clark --- builtin/logical/pki/path_acme_test.go | 30 ++++++++++++------- builtin/logical/pki/path_ocsp_test.go | 16 ---------- builtin/logical/pki/test_helpers.go | 43 +++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 26 deletions(-) diff --git a/builtin/logical/pki/path_acme_test.go b/builtin/logical/pki/path_acme_test.go index e251c9a00754..436ddd3002ca 100644 --- a/builtin/logical/pki/path_acme_test.go +++ b/builtin/logical/pki/path_acme_test.go @@ -1074,9 +1074,7 @@ func TestAcmeWithCsrIncludingBasicConstraintExtension(t *testing.T) { } } -func markAuthorizationSuccess(t *testing.T, client *api.Client, acmeClient *acme.Client, acct *acme.Account, - order *acme.Order, -) { +func markAuthorizationSuccess(t *testing.T, client *api.Client, acmeClient *acme.Client, acct *acme.Account, order *acme.Order) { testCtx := context.Background() pkiMount := findStorageMountUuid(t, client, "pki") @@ -1090,8 +1088,15 @@ func markAuthorizationSuccess(t *testing.T, client *api.Client, acmeClient *acme for _, authURI := range order.AuthzURLs { authId := authURI[strings.LastIndex(authURI, "/"):] - rawPath := path.Join("/sys/raw/logical/", pkiMount, getAuthorizationPath(accountId, authId)) - resp, err := client.Logical().ReadWithContext(testCtx, rawPath) + // sys/raw does not work with namespaces + baseClient := client.WithNamespace("") + + values, err := baseClient.Logical().ListWithContext(testCtx, "sys/raw/logical/") + require.NoError(t, err) + require.True(t, true, "values: %v", values) + + rawPath := path.Join("sys/raw/logical/", pkiMount, getAuthorizationPath(accountId, authId)) + resp, err := baseClient.Logical().ReadWithContext(testCtx, rawPath) require.NoError(t, err, "failed looking up authorization storage") require.NotNil(t, resp, "sys raw response was nil") require.NotEmpty(t, resp.Data["value"], "no value field in sys raw response") @@ -1106,7 +1111,7 @@ func markAuthorizationSuccess(t *testing.T, client *api.Client, acmeClient *acme encodeJSON, err := jsonutil.EncodeJSON(authz) require.NoError(t, err, "failed encoding authz json") - _, err = client.Logical().WriteWithContext(testCtx, rawPath, map[string]interface{}{ + _, err = baseClient.Logical().WriteWithContext(testCtx, rawPath, map[string]interface{}{ "value": base64.StdEncoding.EncodeToString(encodeJSON), "encoding": "base64", }) @@ -1144,8 +1149,10 @@ func markAuthorizationSuccess(t *testing.T, client *api.Client, acmeClient *acme func deleteCvEntries(t *testing.T, client *api.Client, pkiMount string) bool { testCtx := context.Background() - cvPath := path.Join("/sys/raw/logical/", pkiMount, acmeValidationPrefix) - resp, err := client.Logical().ListWithContext(testCtx, cvPath) + baseClient := client.WithNamespace("") + + cvPath := path.Join("sys/raw/logical/", pkiMount, acmeValidationPrefix) + resp, err := baseClient.Logical().ListWithContext(testCtx, cvPath) require.NoError(t, err, "failed listing cv path items") deletedEntries := false @@ -1153,7 +1160,7 @@ func deleteCvEntries(t *testing.T, client *api.Client, pkiMount string) bool { cvEntries := resp.Data["keys"].([]interface{}) for _, cvEntry := range cvEntries { cvEntryPath := path.Join(cvPath, cvEntry.(string)) - _, err = client.Logical().DeleteWithContext(testCtx, cvEntryPath) + _, err = baseClient.Logical().DeleteWithContext(testCtx, cvEntryPath) require.NoError(t, err, "failed to delete cv entry") deletedEntries = true } @@ -1205,7 +1212,7 @@ func setupAcmeBackendOnClusterAtPath(t *testing.T, cluster *vault.TestCluster, c require.NoError(t, err, "failed to mount new PKI instance at "+mount) } - err := client.Sys().TuneMountWithContext(ctx, mountName, api.MountConfigInput{ + err := client.Sys().TuneMountWithContext(ctx, mount, api.MountConfigInput{ DefaultLeaseTTL: "3000h", MaxLeaseTTL: "600000h", }) @@ -1585,6 +1592,9 @@ func getAcmeClientForCluster(t *testing.T, cluster *vault.TestCluster, baseUrl s if !strings.HasPrefix(baseUrl, "v1/") { baseUrl = "v1/" + baseUrl } + if !strings.HasSuffix(baseUrl, "/") { + baseUrl = baseUrl + "/" + } baseAcmeURL := fmt.Sprintf("https://%s/%s", coreAddr.String(), baseUrl) return &acme.Client{ Key: key, diff --git a/builtin/logical/pki/path_ocsp_test.go b/builtin/logical/pki/path_ocsp_test.go index ab1173fa3429..4828d0207457 100644 --- a/builtin/logical/pki/path_ocsp_test.go +++ b/builtin/logical/pki/path_ocsp_test.go @@ -710,19 +710,3 @@ func sendOcspPostRequest(b *backend, s logical.Storage, ocspRequest []byte) (*lo return resp, err } - -func generateRequest(t *testing.T, requestHash crypto.Hash, cert *x509.Certificate, issuer *x509.Certificate) []byte { - t.Helper() - - opts := &ocsp.RequestOptions{Hash: requestHash} - ocspRequestDer, err := ocsp.CreateRequest(cert, issuer, opts) - require.NoError(t, err, "Failed generating OCSP request") - return ocspRequestDer -} - -func requireOcspResponseSignedBy(t *testing.T, ocspResp *ocsp.Response, issuer *x509.Certificate) { - t.Helper() - - err := ocspResp.CheckSignatureFrom(issuer) - require.NoError(t, err, "Failed signature verification of ocsp response: %w", err) -} diff --git a/builtin/logical/pki/test_helpers.go b/builtin/logical/pki/test_helpers.go index 0a003438ba8a..b2286e7b1fcd 100644 --- a/builtin/logical/pki/test_helpers.go +++ b/builtin/logical/pki/test_helpers.go @@ -16,6 +16,7 @@ import ( "io" "math" "math/big" + http2 "net/http" "strings" "testing" "time" @@ -24,6 +25,7 @@ import ( "github.com/hashicorp/vault/sdk/helper/certutil" "github.com/hashicorp/vault/sdk/logical" "github.com/stretchr/testify/require" + "golang.org/x/crypto/ocsp" ) // Setup helpers @@ -393,3 +395,44 @@ func summarizeCrl(t *testing.T, crl pkix.TBSCertificateList) string { "Revoked Serial Count: %d\n"+ "Revoked Serials: %v", version, crl.ThisUpdate, crl.NextUpdate, len(serials), serials) } + +// OCSP helpers +func generateRequest(t *testing.T, requestHash crypto.Hash, cert *x509.Certificate, issuer *x509.Certificate) []byte { + t.Helper() + + opts := &ocsp.RequestOptions{Hash: requestHash} + ocspRequestDer, err := ocsp.CreateRequest(cert, issuer, opts) + require.NoError(t, err, "Failed generating OCSP request") + return ocspRequestDer +} + +func requireOcspResponseSignedBy(t *testing.T, ocspResp *ocsp.Response, issuer *x509.Certificate) { + t.Helper() + + err := ocspResp.CheckSignatureFrom(issuer) + require.NoError(t, err, "Failed signature verification of ocsp response: %w", err) +} + +func performOcspPost(t *testing.T, cert *x509.Certificate, issuerCert *x509.Certificate, client *api.Client, ocspPath string) *ocsp.Response { + t.Helper() + + baseClient := client.WithNamespace("") + + ocspReq := generateRequest(t, crypto.SHA256, cert, issuerCert) + ocspPostReq := baseClient.NewRequest(http2.MethodPost, ocspPath) + ocspPostReq.Headers.Set("Content-Type", "application/ocsp-request") + ocspPostReq.BodyBytes = ocspReq + rawResp, err := baseClient.RawRequest(ocspPostReq) + require.NoError(t, err, "failed sending unified-ocsp post request") + + require.Equal(t, 200, rawResp.StatusCode) + require.Equal(t, ocspResponseContentType, rawResp.Header.Get("Content-Type")) + bodyReader := rawResp.Body + respDer, err := io.ReadAll(bodyReader) + bodyReader.Close() + require.NoError(t, err, "failed reading response body") + + ocspResp, err := ocsp.ParseResponse(respDer, issuerCert) + require.NoError(t, err, "parsing ocsp get response") + return ocspResp +}