vault/builtin/logical/pki/storage_unified.go
Steven Clark cbf6dc2c4f
PKI refactoring to start breaking apart monolith into sub-packages (#24406)
* PKI refactoring to start breaking apart monolith into sub-packages

 - This was broken down by commit within enterprise for ease of review
   but would be too difficult to bring back individual commits back
   to the CE repository. (they would be squashed anyways)
 - This change was created by exporting a patch of the enterprise PR
   and applying it to CE repository

* Fix TestBackend_OID_SANs to not be rely on map ordering
2023-12-07 09:22:53 -05:00

93 lines
2.7 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package pki
import (
"fmt"
"strings"
"time"
"github.com/hashicorp/vault/builtin/logical/pki/issuing"
"github.com/hashicorp/vault/sdk/logical"
)
const (
unifiedRevocationReadPathPrefix = "unified-revocation/"
unifiedRevocationWritePathPrefix = unifiedRevocationReadPathPrefix + "{{clusterId}}/"
)
type unifiedRevocationEntry struct {
SerialNumber string `json:"-"`
CertExpiration time.Time `json:"certificate_expiration_utc"`
RevocationTimeUTC time.Time `json:"revocation_time_utc"`
CertificateIssuer issuing.IssuerID `json:"issuer_id"`
}
func getUnifiedRevocationBySerial(sc *storageContext, serial string) (*unifiedRevocationEntry, error) {
clusterPaths, err := lookupUnifiedClusterPaths(sc)
if err != nil {
return nil, err
}
for _, path := range clusterPaths {
serialPath := path + serial
entryRaw, err := sc.Storage.Get(sc.Context, serialPath)
if err != nil {
return nil, err
}
if entryRaw != nil {
var revEntry unifiedRevocationEntry
if err := entryRaw.DecodeJSON(&revEntry); err != nil {
return nil, fmt.Errorf("failed json decoding of unified entry at path %s: %w", serialPath, err)
}
revEntry.SerialNumber = serial
return &revEntry, nil
}
}
return nil, nil
}
func writeUnifiedRevocationEntry(sc *storageContext, ure *unifiedRevocationEntry) error {
json, err := logical.StorageEntryJSON(unifiedRevocationWritePathPrefix+normalizeSerial(ure.SerialNumber), ure)
if err != nil {
return err
}
return sc.Storage.Put(sc.Context, json)
}
// listClusterSpecificUnifiedRevokedCerts returns a list of revoked certificates from a given cluster
func listClusterSpecificUnifiedRevokedCerts(sc *storageContext, clusterId string) ([]string, error) {
path := unifiedRevocationReadPathPrefix + clusterId + "/"
serials, err := sc.Storage.List(sc.Context, path)
if err != nil {
return nil, err
}
return serials, nil
}
// lookupUnifiedClusterPaths returns a map of cluster id to the prefix storage path for that given cluster's
// unified revoked certificates
func lookupUnifiedClusterPaths(sc *storageContext) (map[string]string, error) {
fullPaths := map[string]string{}
clusterPaths, err := sc.Storage.List(sc.Context, unifiedRevocationReadPathPrefix)
if err != nil {
return nil, err
}
for _, clusterIdWithSlash := range clusterPaths {
// Only include folder listings, if a file were to be stored under this path ignore it.
if strings.HasSuffix(clusterIdWithSlash, "/") {
clusterId := clusterIdWithSlash[:len(clusterIdWithSlash)-1] // remove trailing /
fullPaths[clusterId] = unifiedRevocationReadPathPrefix + clusterIdWithSlash
}
}
return fullPaths, nil
}