2017-04-26 06:46:01 +00:00
|
|
|
package pki
|
|
|
|
|
|
|
|
import (
|
2018-01-19 06:44:44 +00:00
|
|
|
"context"
|
2017-04-27 21:09:59 +00:00
|
|
|
"fmt"
|
2019-05-02 21:31:29 +00:00
|
|
|
"reflect"
|
2017-04-27 21:09:59 +00:00
|
|
|
"strings"
|
2021-04-08 16:43:39 +00:00
|
|
|
"testing"
|
2017-04-27 21:09:59 +00:00
|
|
|
|
2019-05-02 21:31:29 +00:00
|
|
|
"github.com/hashicorp/vault/sdk/framework"
|
2019-05-02 23:29:41 +00:00
|
|
|
"github.com/hashicorp/vault/sdk/logical"
|
2017-04-26 06:46:01 +00:00
|
|
|
)
|
|
|
|
|
2017-04-27 13:47:56 +00:00
|
|
|
func TestPki_FetchCertBySerial(t *testing.T) {
|
2017-04-26 06:46:01 +00:00
|
|
|
storage := &logical.InmemStorage{}
|
|
|
|
|
|
|
|
cases := map[string]struct {
|
2017-04-27 21:09:59 +00:00
|
|
|
Req *logical.Request
|
|
|
|
Prefix string
|
|
|
|
Serial string
|
2017-04-26 06:46:01 +00:00
|
|
|
}{
|
2017-04-27 21:09:59 +00:00
|
|
|
"valid cert": {
|
2017-04-26 06:46:01 +00:00
|
|
|
&logical.Request{
|
2017-04-28 12:55:28 +00:00
|
|
|
Storage: storage,
|
2017-04-26 06:46:01 +00:00
|
|
|
},
|
2017-04-27 21:09:59 +00:00
|
|
|
"certs/",
|
|
|
|
"00:00:00:00:00:00:00:00",
|
2017-04-26 06:46:01 +00:00
|
|
|
},
|
2017-04-27 21:09:59 +00:00
|
|
|
"revoked cert": {
|
2017-04-26 06:46:01 +00:00
|
|
|
&logical.Request{
|
2017-04-28 12:55:28 +00:00
|
|
|
Storage: storage,
|
2017-04-26 06:46:01 +00:00
|
|
|
},
|
2017-04-27 21:09:59 +00:00
|
|
|
"revoked/",
|
|
|
|
"11:11:11:11:11:11:11:11",
|
2017-04-26 06:46:01 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2017-04-27 21:09:59 +00:00
|
|
|
// Test for colon-based paths in storage
|
|
|
|
for name, tc := range cases {
|
|
|
|
storageKey := fmt.Sprintf("%s%s", tc.Prefix, tc.Serial)
|
2018-01-19 06:44:44 +00:00
|
|
|
err := storage.Put(context.Background(), &logical.StorageEntry{
|
2017-04-27 21:09:59 +00:00
|
|
|
Key: storageKey,
|
|
|
|
Value: []byte("some data"),
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error writing to storage on %s colon-based storage path: %s", name, err)
|
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
certEntry, err := fetchCertBySerial(context.Background(), tc.Req, tc.Prefix, tc.Serial)
|
2017-04-27 21:09:59 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error on %s for colon-based storage path: %s", name, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check for non-nil on valid/revoked certs
|
|
|
|
if certEntry == nil {
|
|
|
|
t.Fatalf("nil on %s for colon-based storage path", name)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Ensure that cert serials are converted/updated after fetch
|
2017-05-03 14:12:58 +00:00
|
|
|
expectedKey := tc.Prefix + normalizeSerial(tc.Serial)
|
2018-01-19 06:44:44 +00:00
|
|
|
se, err := storage.Get(context.Background(), expectedKey)
|
2017-04-27 21:09:59 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("error on %s for colon-based storage path:%s", name, err)
|
|
|
|
}
|
|
|
|
if strings.Compare(expectedKey, se.Key) != 0 {
|
|
|
|
t.Fatalf("expected: %s, got: %s", expectedKey, certEntry.Key)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Reset storage
|
|
|
|
storage = &logical.InmemStorage{}
|
|
|
|
|
|
|
|
// Test for hyphen-base paths in storage
|
2017-04-26 06:46:01 +00:00
|
|
|
for name, tc := range cases {
|
2017-05-03 14:12:58 +00:00
|
|
|
storageKey := tc.Prefix + normalizeSerial(tc.Serial)
|
2018-01-19 06:44:44 +00:00
|
|
|
err := storage.Put(context.Background(), &logical.StorageEntry{
|
2017-04-27 21:09:59 +00:00
|
|
|
Key: storageKey,
|
2017-04-26 06:46:01 +00:00
|
|
|
Value: []byte("some data"),
|
|
|
|
})
|
|
|
|
if err != nil {
|
2017-04-27 21:09:59 +00:00
|
|
|
t.Fatalf("error writing to storage on %s hyphen-based storage path: %s", name, err)
|
2017-04-26 06:46:01 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
certEntry, err := fetchCertBySerial(context.Background(), tc.Req, tc.Prefix, tc.Serial)
|
2017-04-28 12:55:28 +00:00
|
|
|
if err != nil || certEntry == nil {
|
|
|
|
t.Fatalf("error on %s for hyphen-based storage path: err: %v, entry: %v", name, err, certEntry)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
noConvCases := map[string]struct {
|
|
|
|
Req *logical.Request
|
|
|
|
Prefix string
|
|
|
|
Serial string
|
|
|
|
}{
|
|
|
|
"ca": {
|
|
|
|
&logical.Request{
|
|
|
|
Storage: storage,
|
|
|
|
},
|
|
|
|
"",
|
|
|
|
"ca",
|
|
|
|
},
|
|
|
|
"crl": {
|
|
|
|
&logical.Request{
|
|
|
|
Storage: storage,
|
|
|
|
},
|
|
|
|
"",
|
|
|
|
"crl",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test for ca and crl case
|
|
|
|
for name, tc := range noConvCases {
|
2018-01-19 06:44:44 +00:00
|
|
|
err := storage.Put(context.Background(), &logical.StorageEntry{
|
2017-04-28 12:55:28 +00:00
|
|
|
Key: tc.Serial,
|
|
|
|
Value: []byte("some data"),
|
|
|
|
})
|
2017-04-26 06:46:01 +00:00
|
|
|
if err != nil {
|
2017-04-28 12:55:28 +00:00
|
|
|
t.Fatalf("error writing to storage on %s: %s", name, err)
|
2017-04-26 06:46:01 +00:00
|
|
|
}
|
|
|
|
|
2018-01-19 06:44:44 +00:00
|
|
|
certEntry, err := fetchCertBySerial(context.Background(), tc.Req, tc.Prefix, tc.Serial)
|
2017-04-28 12:55:28 +00:00
|
|
|
if err != nil || certEntry == nil {
|
|
|
|
t.Fatalf("error on %s: err: %v, entry: %v", name, err, certEntry)
|
2017-04-26 06:46:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-05-02 21:31:29 +00:00
|
|
|
|
2019-05-02 23:02:15 +00:00
|
|
|
// Demonstrate that multiple OUs in the name are handled in an
|
2019-05-02 21:31:29 +00:00
|
|
|
// order-preserving way.
|
|
|
|
func TestPki_MultipleOUs(t *testing.T) {
|
2019-05-02 23:02:15 +00:00
|
|
|
var b backend
|
2019-05-02 21:31:29 +00:00
|
|
|
fields := addCACommonFields(map[string]*framework.FieldSchema{})
|
|
|
|
|
|
|
|
apiData := &framework.FieldData{
|
|
|
|
Schema: fields,
|
2019-05-02 23:29:41 +00:00
|
|
|
Raw: map[string]interface{}{
|
|
|
|
"cn": "example.com",
|
|
|
|
"ttl": 3600,
|
2019-05-02 21:31:29 +00:00
|
|
|
},
|
|
|
|
}
|
2019-05-09 15:59:22 +00:00
|
|
|
input := &inputBundle{
|
2019-05-02 23:29:41 +00:00
|
|
|
apiData: apiData,
|
|
|
|
role: &roleEntry{
|
|
|
|
MaxTTL: 3600,
|
|
|
|
OU: []string{"Z", "E", "V"},
|
2019-05-02 21:31:29 +00:00
|
|
|
},
|
|
|
|
}
|
2019-05-09 15:59:22 +00:00
|
|
|
cb, err := generateCreationBundle(&b, input, nil, nil)
|
2019-05-02 21:31:29 +00:00
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error: %v", err)
|
|
|
|
}
|
|
|
|
|
2019-05-02 23:29:41 +00:00
|
|
|
expected := []string{"Z", "E", "V"}
|
2019-05-09 15:59:22 +00:00
|
|
|
actual := cb.Params.Subject.OrganizationalUnit
|
2019-05-02 21:31:29 +00:00
|
|
|
|
2019-05-02 23:29:41 +00:00
|
|
|
if !reflect.DeepEqual(expected, actual) {
|
|
|
|
t.Fatalf("Expected %v, got %v", expected, actual)
|
2019-05-02 21:31:29 +00:00
|
|
|
}
|
|
|
|
}
|
2020-02-04 22:46:38 +00:00
|
|
|
|
|
|
|
func TestPki_PermitFQDNs(t *testing.T) {
|
|
|
|
var b backend
|
|
|
|
fields := addCACommonFields(map[string]*framework.FieldSchema{})
|
|
|
|
|
2021-03-10 05:28:27 +00:00
|
|
|
cases := map[string]struct {
|
|
|
|
input *inputBundle
|
|
|
|
expected []string
|
|
|
|
}{
|
|
|
|
"base valid case": {
|
|
|
|
input: &inputBundle{
|
|
|
|
apiData: &framework.FieldData{
|
|
|
|
Schema: fields,
|
|
|
|
Raw: map[string]interface{}{
|
|
|
|
"common_name": "example.com.",
|
|
|
|
"ttl": 3600,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
role: &roleEntry{
|
|
|
|
AllowAnyName: true,
|
|
|
|
MaxTTL: 3600,
|
|
|
|
EnforceHostnames: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: []string{"example.com."},
|
2020-02-04 22:46:38 +00:00
|
|
|
},
|
2021-03-10 05:28:27 +00:00
|
|
|
"case insensitivity validation": {
|
|
|
|
input: &inputBundle{
|
|
|
|
apiData: &framework.FieldData{
|
|
|
|
Schema: fields,
|
|
|
|
Raw: map[string]interface{}{
|
|
|
|
"common_name": "Example.Net",
|
|
|
|
"alt_names": "eXaMPLe.COM",
|
|
|
|
"ttl": 3600,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
role: &roleEntry{
|
|
|
|
AllowedDomains: []string{"example.net", "EXAMPLE.COM"},
|
|
|
|
AllowBareDomains: true,
|
|
|
|
MaxTTL: 3600,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
expected: []string{"Example.Net", "eXaMPLe.COM"},
|
2020-02-04 22:46:38 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2021-03-10 05:28:27 +00:00
|
|
|
for _, testCase := range cases {
|
|
|
|
cb, err := generateCreationBundle(&b, testCase.input, nil, nil)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Error: %v", err)
|
|
|
|
}
|
2020-02-04 22:46:38 +00:00
|
|
|
|
2021-03-10 05:28:27 +00:00
|
|
|
actual := cb.Params.DNSNames
|
|
|
|
|
|
|
|
if !reflect.DeepEqual(testCase.expected, actual) {
|
|
|
|
t.Fatalf("Expected %v, got %v", testCase.expected, actual)
|
|
|
|
}
|
2020-02-04 22:46:38 +00:00
|
|
|
}
|
|
|
|
}
|