Adding PKI Responses 3 (#18596)

This commit is contained in:
AnPucel 2023-02-16 17:31:45 -08:00 committed by GitHub
parent 9c837ef4b5
commit 4c0895188a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 278 additions and 14 deletions

View File

@ -1880,6 +1880,7 @@ func TestBackend_PathFetchValidRaw(t *testing.T) {
Data: map[string]interface{}{},
MountPoint: "pki/",
})
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("ca/pem"), logical.ReadOperation), resp, true)
require.NoError(t, err)
if resp != nil && resp.IsError() {
t.Fatalf("failed read ca/pem, %#v", resp)
@ -2414,6 +2415,7 @@ func TestBackend_Root_Idempotency(t *testing.T) {
// Now because the issued CA's have no links, the call to ca_chain should return the same data (ca chain from default)
resp, err = CBRead(b, s, "cert/ca_chain")
require.NoError(t, err, "error reading ca_chain: %v", err)
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("cert/ca_chain"), logical.ReadOperation), resp, true)
r2Data := resp.Data
if !reflect.DeepEqual(r1Data, r2Data) {
@ -3893,6 +3895,7 @@ func TestBackend_RevokePlusTidy_Intermediate(t *testing.T) {
if err != nil {
t.Fatal(err)
}
if secret == nil || len(secret.Data) == 0 || len(secret.Data["certificate"].(string)) == 0 {
t.Fatal("expected certificate information from read operation")
}
@ -5075,9 +5078,11 @@ func TestPerIssuerAIA(t *testing.T) {
require.Empty(t, rootCert.CRLDistributionPoints)
// Set some local URLs on the issuer.
_, err = CBWrite(b, s, "issuer/default", map[string]interface{}{
resp, err = CBWrite(b, s, "issuer/default", map[string]interface{}{
"issuing_certificates": []string{"https://google.com"},
})
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("issuer/default"), logical.UpdateOperation), resp, true)
require.NoError(t, err)
_, err = CBWrite(b, s, "roles/testing", map[string]interface{}{

View File

@ -439,6 +439,8 @@ func TestCrlRebuilder(t *testing.T) {
err = cb.rebuildIfForced(sc)
require.NoError(t, err, "Failed to rebuild if forced CRL")
resp = requestCrlFromBackend(t, s, b)
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("crl/pem"), logical.ReadOperation), resp, true)
crl3 := parseCrlPemBytes(t, resp.Data["http_raw_body"].([]byte))
require.True(t, crl1.ThisUpdate.Before(crl3.ThisUpdate),
"initial crl time: %#v not before next crl rebuild time: %#v", crl1.ThisUpdate, crl3.ThisUpdate)

View File

@ -4,6 +4,7 @@ import (
"context"
"encoding/pem"
"fmt"
"net/http"
"strings"
"time"
@ -14,6 +15,51 @@ import (
"github.com/hashicorp/vault/sdk/logical"
)
var pathFetchReadSchema = map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"certificate": {
Type: framework.TypeString,
Description: `Certificate`,
Required: false,
},
"revocation_time": {
Type: framework.TypeInt,
Description: `Revocation time`,
Required: false,
},
"revocation_time_rfc3339": {
Type: framework.TypeInt,
Description: `Revocation time RFC 3339 formatted`,
Required: false,
},
"issuer_id": {
Type: framework.TypeString,
Description: `ID of the issuer`,
Required: false,
},
"ca_chain": {
Type: framework.TypeStringSlice,
Description: `Issuing CA Chain`,
Required: false,
},
"http_content_type": {
Type: framework.TypeString,
Required: false,
},
"http_raw_body": {
Type: framework.TypeString,
Required: false,
},
"http_status_code": {
Type: framework.TypeString,
Required: false,
},
},
}},
}
// Returns the CA in raw format
func pathFetchCA(b *backend) *framework.Path {
return &framework.Path{
@ -21,7 +67,8 @@ func pathFetchCA(b *backend) *framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathFetchRead,
Callback: b.pathFetchRead,
Responses: pathFetchReadSchema,
},
},
@ -37,7 +84,8 @@ func pathFetchCAChain(b *backend) *framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathFetchRead,
Callback: b.pathFetchRead,
Responses: pathFetchReadSchema,
},
},
@ -53,7 +101,8 @@ func pathFetchCRL(b *backend) *framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathFetchRead,
Callback: b.pathFetchRead,
Responses: pathFetchReadSchema,
},
},
@ -92,7 +141,8 @@ hyphen-separated octal`,
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathFetchRead,
Callback: b.pathFetchRead,
Responses: pathFetchReadSchema,
},
},
@ -116,7 +166,8 @@ hyphen-separated octal`,
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathFetchRead,
Callback: b.pathFetchRead,
Responses: pathFetchReadSchema,
},
},
@ -137,7 +188,8 @@ func pathFetchCRLViaCertPath(b *backend) *framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathFetchRead,
Callback: b.pathFetchRead,
Responses: pathFetchReadSchema,
},
},
@ -154,6 +206,18 @@ func pathFetchListCerts(b *backend) *framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{
logical.ListOperation: &framework.PathOperation{
Callback: b.pathFetchCertList,
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"keys": {
Type: framework.TypeStringSlice,
Description: `A list of keys`,
Required: true,
},
},
}},
},
},
},

View File

@ -5,6 +5,7 @@ import (
"crypto/x509"
"encoding/pem"
"fmt"
"net/http"
"strings"
"time"
@ -20,6 +21,23 @@ func pathListIssuers(b *backend) *framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{
logical.ListOperation: &framework.PathOperation{
Callback: b.pathListIssuersHandler,
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"keys": {
Type: framework.TypeStringSlice,
Description: `A list of keys`,
Required: true,
},
"key_info": {
Type: framework.TypeMap,
Description: `Key info with issuer name`,
Required: false,
},
},
}},
},
},
},
@ -146,6 +164,79 @@ to be set on all PR secondary clusters.`,
Default: false,
}
updateIssuerSchema := map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"issuer_id": {
Type: framework.TypeString,
Description: `Issuer Id`,
Required: true,
},
"issuer_name": {
Type: framework.TypeString,
Description: `Issuer Name`,
Required: true,
},
"key_id": {
Type: framework.TypeString,
Description: `Key Id`,
Required: true,
},
"certificate": {
Type: framework.TypeString,
Description: `Certificate`,
Required: true,
},
"manual_chain": {
Type: framework.TypeStringSlice,
Description: `Manual Chain`,
Required: true,
},
"ca_chain": {
Type: framework.TypeStringSlice,
Description: `CA Chain`,
Required: true,
},
"leaf_not_after_behavior": {
Type: framework.TypeString,
Description: `Leaf Not After Behavior`,
Required: true,
},
"usage": {
Type: framework.TypeStringSlice,
Description: `Usage`,
Required: true,
},
"revocation_signature_algorithm": {
Type: framework.TypeString,
Description: `Revocation Signature Alogrithm`,
Required: true,
},
"revoked": {
Type: framework.TypeBool,
Description: `Revoked`,
Required: true,
},
"issuing_certificates": {
Type: framework.TypeStringSlice,
Description: `Issuing Certificates`,
Required: true,
},
"crl_distribution_points": {
Type: framework.TypeStringSlice,
Description: `CRL Distribution Points`,
Required: true,
},
"ocsp_servers": {
Type: framework.TypeStringSlice,
Description: `OSCP Servers`,
Required: true,
},
},
}},
}
return &framework.Path{
// Returns a JSON entry.
Pattern: pattern,
@ -153,22 +244,31 @@ to be set on all PR secondary clusters.`,
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathGetIssuer,
Callback: b.pathGetIssuer,
Responses: updateIssuerSchema,
},
logical.UpdateOperation: &framework.PathOperation{
Callback: b.pathUpdateIssuer,
Callback: b.pathUpdateIssuer,
Responses: updateIssuerSchema,
// Read more about why these flags are set in backend.go.
ForwardPerformanceStandby: true,
ForwardPerformanceSecondary: true,
},
logical.DeleteOperation: &framework.PathOperation{
Callback: b.pathDeleteIssuer,
Responses: map[int][]framework.Response{
http.StatusNoContent: {{
Description: "No Content",
}},
},
// Read more about why these flags are set in backend.go.
ForwardPerformanceStandby: true,
ForwardPerformanceSecondary: true,
},
logical.PatchOperation: &framework.PathOperation{
Callback: b.pathPatchIssuer,
Callback: b.pathPatchIssuer,
Responses: updateIssuerSchema,
// Read more about why these flags are set in backend.go.
ForwardPerformanceStandby: true,
ForwardPerformanceSecondary: true,
@ -962,6 +1062,18 @@ func buildPathGetIssuerCRL(b *backend, pattern string) *framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathGetIssuerCRL,
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"crl": {
Type: framework.TypeString,
Description: ``,
Required: false,
},
},
}},
},
},
},

View File

@ -3,6 +3,7 @@ package pki
import (
"context"
"fmt"
"net/http"
"github.com/hashicorp/vault/sdk/helper/errutil"
@ -16,7 +17,24 @@ func pathListKeys(b *backend) *framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{
logical.ListOperation: &framework.PathOperation{
Callback: b.pathListKeysHandler,
Callback: b.pathListKeysHandler,
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"keys": {
Type: framework.TypeStringSlice,
Description: `A list of keys`,
Required: true,
},
"key_info": {
Type: framework.TypeMap,
Description: `Key info with issuer name`,
Required: false,
},
},
}},
},
ForwardPerformanceStandby: false,
ForwardPerformanceSecondary: false,
},
@ -91,17 +109,76 @@ func buildPathKey(b *backend, pattern string) *framework.Path {
Operations: map[logical.Operation]framework.OperationHandler{
logical.ReadOperation: &framework.PathOperation{
Callback: b.pathGetKeyHandler,
Callback: b.pathGetKeyHandler,
Responses: map[int][]framework.Response{
http.StatusOK: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"key_id": {
Type: framework.TypeString,
Description: `Key Id`,
Required: true,
},
"key_name": {
Type: framework.TypeString,
Description: `Key Name`,
Required: true,
},
"key_type": {
Type: framework.TypeString,
Description: `Key Type`,
Required: true,
},
"managed_key_id": {
Type: framework.TypeString,
Description: `Managed Key Id`,
Required: false,
},
"managed_key_name": {
Type: framework.TypeString,
Description: `Managed Key Name`,
Required: false,
},
},
}},
},
ForwardPerformanceStandby: false,
ForwardPerformanceSecondary: false,
},
logical.UpdateOperation: &framework.PathOperation{
Callback: b.pathUpdateKeyHandler,
Callback: b.pathUpdateKeyHandler,
Responses: map[int][]framework.Response{
http.StatusNoContent: {{
Description: "OK",
Fields: map[string]*framework.FieldSchema{
"key_id": {
Type: framework.TypeString,
Description: `Key Id`,
Required: true,
},
"key_name": {
Type: framework.TypeString,
Description: `Key Name`,
Required: true,
},
"key_type": {
Type: framework.TypeString,
Description: `Key Type`,
Required: true,
},
},
}},
},
ForwardPerformanceStandby: true,
ForwardPerformanceSecondary: true,
},
logical.DeleteOperation: &framework.PathOperation{
Callback: b.pathDeleteKeyHandler,
Callback: b.pathDeleteKeyHandler,
Responses: map[int][]framework.Response{
http.StatusNoContent: {{
Description: "No Content",
}},
},
ForwardPerformanceStandby: true,
ForwardPerformanceSecondary: true,
},

View File

@ -331,6 +331,8 @@ func TestPKI_PathManageKeys_UpdateKeyDetails(t *testing.T) {
Data: map[string]interface{}{"key_name": "new-name"},
MountPoint: "pki/",
})
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("key/"+keyId.String()), logical.UpdateOperation), resp, true)
require.NoError(t, err, "failed updating key with new name")
require.NotNil(t, resp, "Got nil response updating key with new name")
require.False(t, resp.IsError(), "unexpected error updating key with new name: %#v", resp.Error())
@ -341,6 +343,8 @@ func TestPKI_PathManageKeys_UpdateKeyDetails(t *testing.T) {
Storage: s,
MountPoint: "pki/",
})
schema.ValidateResponse(t, schema.GetResponseSchema(t, b.Route("key/"+keyId.String()), logical.ReadOperation), resp, true)
require.NoError(t, err, "failed reading key after name update")
require.NotNil(t, resp, "Got nil response reading key after name update")
require.False(t, resp.IsError(), "unexpected error reading key: %#v", resp.Error())