2023-03-15 16:00:52 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2023-02-10 20:27:36 +00:00
|
|
|
package command
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/hashicorp/vault/api"
|
|
|
|
)
|
|
|
|
|
|
|
|
// TestPKIReIssueIntermediate tests that the pki reissue command line tool accurately copies information from the
|
|
|
|
// template certificate to the newly issued certificate, by issuing and reissuing several certificates and seeing how
|
|
|
|
// they related to each other.
|
|
|
|
func TestPKIReIssueIntermediate(t *testing.T) {
|
|
|
|
t.Parallel()
|
|
|
|
|
|
|
|
client, closer := testVaultServer(t)
|
|
|
|
defer closer()
|
|
|
|
|
|
|
|
// Relationship Map to Create
|
|
|
|
// pki-root | pki-newroot | pki-empty
|
|
|
|
// RootX1 RootX2 RootX4 RootX3
|
|
|
|
// | |
|
|
|
|
// ----------------------------------------------
|
|
|
|
// v v
|
|
|
|
// IntX1 IntX2 pki-int
|
|
|
|
// | |
|
|
|
|
// v v
|
|
|
|
// IntX3 (-----------------------) IntX3
|
|
|
|
//
|
|
|
|
// Here X1,X2 have the same name (same mount)
|
|
|
|
// RootX4 uses the same key as RootX1 (but a different common_name/subject)
|
|
|
|
// RootX3 has the same name, and is on a different mount
|
|
|
|
// RootX1 has issued IntX1; RootX3 has issued IntX2
|
|
|
|
createComplicatedIssuerSetUpWithReIssueIntermediate(t, client)
|
|
|
|
|
|
|
|
runPkiVerifySignTests(t, client)
|
|
|
|
|
|
|
|
runPkiListIntermediateTests(t, client)
|
|
|
|
}
|
|
|
|
|
|
|
|
func createComplicatedIssuerSetUpWithReIssueIntermediate(t *testing.T, client *api.Client) {
|
|
|
|
// Relationship Map to Create
|
|
|
|
// pki-root | pki-newroot | pki-empty
|
|
|
|
// RootX1 RootX2 RootX4 RootX3
|
|
|
|
// | |
|
|
|
|
// ----------------------------------------------
|
|
|
|
// v v
|
|
|
|
// IntX1 IntX2 pki-int
|
|
|
|
// | |
|
|
|
|
// v v
|
|
|
|
// IntX3 (-----------------------) IntX3
|
|
|
|
//
|
|
|
|
// Here X1,X2 have the same name (same mount)
|
|
|
|
// RootX4 uses the same key as RootX1 (but a different common_name/subject)
|
|
|
|
// RootX3 has the same name, and is on a different mount
|
|
|
|
// RootX1 has issued IntX1; RootX3 has issued IntX2
|
|
|
|
|
|
|
|
if err := client.Sys().Mount("pki-root", &api.MountInput{
|
|
|
|
Type: "pki",
|
|
|
|
Config: api.MountConfigInput{
|
|
|
|
MaxLeaseTTL: "36500d",
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
t.Fatalf("pki mount error: %#v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := client.Sys().Mount("pki-newroot", &api.MountInput{
|
|
|
|
Type: "pki",
|
|
|
|
Config: api.MountConfigInput{
|
|
|
|
MaxLeaseTTL: "36500d",
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
t.Fatalf("pki mount error: %#v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := client.Sys().Mount("pki-int", &api.MountInput{
|
|
|
|
Type: "pki",
|
|
|
|
Config: api.MountConfigInput{
|
|
|
|
MaxLeaseTTL: "36500d",
|
|
|
|
},
|
|
|
|
}); err != nil {
|
|
|
|
t.Fatalf("pki mount error: %#v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Used to check handling empty list responses: Not Used for Any Issuers / Certificates
|
|
|
|
if err := client.Sys().Mount("pki-empty", &api.MountInput{
|
|
|
|
Type: "pki",
|
|
|
|
Config: api.MountConfigInput{},
|
|
|
|
}); err != nil {
|
|
|
|
t.Fatalf("pki mount error: %#v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := client.Logical().Write("pki-root/root/generate/internal", map[string]interface{}{
|
|
|
|
"key_type": "ec",
|
|
|
|
"common_name": "Root X",
|
|
|
|
"ttl": "3650d",
|
|
|
|
"issuer_name": "rootX1",
|
|
|
|
"key_name": "rootX1",
|
|
|
|
})
|
|
|
|
if err != nil || resp == nil {
|
|
|
|
t.Fatalf("failed to prime CA: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err = client.Logical().Write("pki-root/root/generate/internal", map[string]interface{}{
|
|
|
|
"key_type": "ec",
|
|
|
|
"common_name": "Root X",
|
|
|
|
"ttl": "3650d",
|
|
|
|
"issuer_name": "rootX2",
|
|
|
|
})
|
|
|
|
if err != nil || resp == nil {
|
|
|
|
t.Fatalf("failed to prime CA: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if resp, err := client.Logical().Write("pki-newroot/root/generate/internal", map[string]interface{}{
|
|
|
|
"key_type": "ec",
|
|
|
|
"common_name": "Root X",
|
|
|
|
"ttl": "3650d",
|
|
|
|
"issuer_name": "rootX3",
|
|
|
|
}); err != nil || resp == nil {
|
|
|
|
t.Fatalf("failed to prime CA: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if resp, err := client.Logical().Write("pki-root/root/generate/existing", map[string]interface{}{
|
|
|
|
"common_name": "Root X4",
|
|
|
|
"ttl": "3650d",
|
|
|
|
"issuer_name": "rootX4",
|
|
|
|
"key_ref": "rootX1",
|
|
|
|
}); err != nil || resp == nil {
|
|
|
|
t.Fatalf("failed to prime CA: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
stdout := bytes.NewBuffer(nil)
|
|
|
|
stderr := bytes.NewBuffer(nil)
|
|
|
|
runOpts := &RunOptions{
|
|
|
|
Stdout: stdout,
|
|
|
|
Stderr: stderr,
|
|
|
|
Client: client,
|
|
|
|
}
|
|
|
|
|
|
|
|
// Intermediate X1
|
|
|
|
intX1CallArgs := []string{
|
|
|
|
"pki", "issue", "-format=json", "-issuer_name=intX1",
|
|
|
|
"pki-root/issuer/rootX1",
|
|
|
|
"pki-int/",
|
|
|
|
"key_type=rsa",
|
|
|
|
"common_name=Int X1",
|
|
|
|
"ou=thing",
|
|
|
|
"ttl=3650d",
|
|
|
|
}
|
|
|
|
codeOut := RunCustom(intX1CallArgs, runOpts)
|
|
|
|
if codeOut != 0 {
|
|
|
|
t.Fatalf("error issuing intermediate X1, code: %d \n stdout: %v \n stderr: %v", codeOut, stdout, stderr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Intermediate X2 - using ReIssue
|
|
|
|
intX2CallArgs := []string{
|
|
|
|
"pki", "reissue", "-format=json", "-issuer_name=intX2",
|
|
|
|
"pki-newroot/issuer/rootX3",
|
|
|
|
"pki-int/issuer/intX1",
|
|
|
|
"pki-int/",
|
|
|
|
"key_type=ec",
|
|
|
|
"common_name=Int X2",
|
|
|
|
}
|
|
|
|
codeOut = RunCustom(intX2CallArgs, runOpts)
|
|
|
|
if codeOut != 0 {
|
|
|
|
t.Fatalf("error issuing intermediate X2, code: %d \n stdout: %v \n stderr: %v", codeOut, stdout, stderr)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Intermediate X3
|
|
|
|
intX3OriginalCallArgs := []string{
|
|
|
|
"pki", "issue", "-format=json", "-issuer_name=intX3",
|
|
|
|
"pki-int/issuer/intX1",
|
|
|
|
"pki-int/",
|
|
|
|
"key_type=ec",
|
|
|
|
"use_pss=true", // This is meaningful because rootX1 is an RSA key
|
|
|
|
"signature_bits=512",
|
|
|
|
"common_name=Int X3",
|
|
|
|
"ttl=3650d",
|
|
|
|
}
|
|
|
|
codeOut = RunCustom(intX3OriginalCallArgs, runOpts)
|
|
|
|
if codeOut != 0 {
|
|
|
|
t.Fatalf("error issuing intermediate X3, code: %d \n stdout: %v \n stderr: %v", codeOut, stdout, stderr)
|
|
|
|
}
|
|
|
|
|
|
|
|
intX3AdaptedCallArgs := []string{
|
|
|
|
"pki", "reissue", "-format=json", "-issuer_name=intX3also", "-type=existing",
|
|
|
|
"pki-int/issuer/intX2", // This is a EC key
|
|
|
|
"pki-int/issuer/intX3", // This template includes use_pss = true which can't be accomodated
|
|
|
|
"pki-int/",
|
|
|
|
}
|
|
|
|
codeOut = RunCustom(intX3AdaptedCallArgs, runOpts)
|
|
|
|
if codeOut != 0 {
|
|
|
|
t.Fatalf("error issuing intermediate X3also, code: %d \n stdout: %v \n stderr: %v", codeOut, stdout, stderr)
|
|
|
|
}
|
|
|
|
}
|