vault/builtin/logical/pki/path_fetch_issuers_test.go
Kit Haines 49ecdad1ad
Sign empty to cert on manual-chain update. (#29473)
* Sign empty to cert on manual-chain update.

* Add role defaults.

* Add changelog.

* More useful error message.

* Suggestions from PR Review.

* Fixes to update as well as write; test that still fails; revert code.

* Unit Test fix.

* Add go doc to TestManualChainValidation
2025-02-10 15:24:52 -05:00

111 lines
4.0 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package pki
import (
"context"
"testing"
"github.com/stretchr/testify/require"
)
// TestManualChainValidation creates a series of issuers, and then tries to set the manual_chain on the final issuer
// to something completely incorrect (missing an intermediate issuer). In this case, the attempt to write the manual
// chain throws an error, and the manual chain is not updated.
func TestManualChainValidation(t *testing.T) {
// Set Up a Cluster
cluster, client := setupTestPkiCluster(t)
defer cluster.Cleanup()
// Set Up Root-A
mount := "pki"
resp, err := client.Logical().WriteWithContext(context.Background(), mount+"/issuers/generate/root/internal",
map[string]interface{}{
"issuer_name": "rootCa",
"key_name": "root-key",
"key_type": "ec",
"common_name": "Test Root",
"ttl": "7200h",
})
require.NoError(t, err, "failed creating root CA")
// Set Up Int-A
resp, err = client.Logical().WriteWithContext(context.Background(), mount+"/issuers/generate/intermediate/internal",
map[string]interface{}{
"key_name": "int-a-key",
"key_type": "ec",
"common_name": "Test Int A",
})
require.NoError(t, err, "failed creating intermediary CSR")
intermediateCSR := resp.Data["csr"].(string)
// Sign the intermediate CSR
resp, err = client.Logical().Write(mount+"/issuer/rootCa/sign-intermediate", map[string]interface{}{
"csr": intermediateCSR,
"ttl": "7100h",
"common_name": "Test Int A",
})
require.NoError(t, err, "failed signing intermediary CSR")
intermediateCertPEM := resp.Data["certificate"].(string)
// Import the intermediate cert
resp, err = client.Logical().Write(mount+"/issuers/import/cert", map[string]interface{}{
"pem_bundle": intermediateCertPEM,
})
require.NoError(t, err, "failed importing intermediary cert")
importedIssuersRaw := resp.Data["imported_issuers"].([]interface{})
require.Len(t, importedIssuersRaw, 1)
intCaUuid := importedIssuersRaw[0].(string)
_, err = client.Logical().Write(mount+"/issuer/"+intCaUuid, map[string]interface{}{
"issuer_name": "intA",
})
require.NoError(t, err, "failed updating issuer name")
// Set Up Int-B (Child of Int-A)
resp, err = client.Logical().WriteWithContext(context.Background(), mount+"/issuers/generate/intermediate/internal",
map[string]interface{}{
"key_name": "int-b-key",
"key_type": "ec",
"common_name": "Test Int B",
})
require.NoError(t, err, "failed creating intermediary CSR")
subIntermediateCSR := resp.Data["csr"].(string)
// Sign the intermediate CSR
resp, err = client.Logical().Write(mount+"/issuer/intA/sign-intermediate", map[string]interface{}{
"csr": subIntermediateCSR,
"ttl": "7100h",
"common_name": "Test Int B",
})
require.NoError(t, err, "failed signing intermediary CSR")
subIntermediateCertPEM := resp.Data["certificate"].(string)
// Import the intermediate cert
resp, err = client.Logical().Write(mount+"/issuers/import/cert", map[string]interface{}{
"pem_bundle": subIntermediateCertPEM,
})
require.NoError(t, err, "failed importing intermediary cert")
subImportedIssuersRaw := resp.Data["imported_issuers"].([]interface{})
require.Len(t, subImportedIssuersRaw, 1)
subIntCaUuid := subImportedIssuersRaw[0].(string)
resp, err = client.Logical().Write(mount+"/issuer/"+subIntCaUuid, map[string]interface{}{
"issuer_name": "intB",
})
require.NoError(t, err, "failed updating issuer name")
// Try to Set Int-B Manual Chain to Just Be Root-A; Expect An Error
resp, err = client.Logical().Write(mount+"/issuer/intB", map[string]interface{}{
"issuer_name": "intB",
"manual_chain": []string{"intB", "rootCa"}, // Misses "intA" which issued "intB"
})
require.Error(t, err, "failed updating intermediary cert")
resp, err = client.Logical().Read(mount + "/issuer/intB")
require.NoError(t, err, "failed reading intermediary cert")
require.Nil(t, resp.Data["manual_chain"], "error reverting manual chain, got non-nil manual chain")
}