vault/builtin/logical/pki/issuing/config_issuer.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

125 lines
3.7 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package issuing
import (
"context"
"fmt"
"strings"
"time"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/vault/sdk/helper/errutil"
"github.com/hashicorp/vault/sdk/logical"
)
const StorageIssuerConfig = "config/issuers"
type IssuerConfigEntry struct {
// This new fetchedDefault field allows us to detect if the default
// issuer was modified, in turn dispatching the timestamp updater
// if necessary.
fetchedDefault IssuerID `json:"-"`
DefaultIssuerId IssuerID `json:"default"`
DefaultFollowsLatestIssuer bool `json:"default_follows_latest_issuer"`
}
func GetIssuersConfig(ctx context.Context, s logical.Storage) (*IssuerConfigEntry, error) {
entry, err := s.Get(ctx, StorageIssuerConfig)
if err != nil {
return nil, err
}
issuerConfig := &IssuerConfigEntry{}
if entry != nil {
if err := entry.DecodeJSON(issuerConfig); err != nil {
return nil, errutil.InternalError{Err: fmt.Sprintf("unable to decode issuer configuration: %v", err)}
}
}
issuerConfig.fetchedDefault = issuerConfig.DefaultIssuerId
return issuerConfig, nil
}
func SetIssuersConfig(ctx context.Context, s logical.Storage, config *IssuerConfigEntry) error {
json, err := logical.StorageEntryJSON(StorageIssuerConfig, config)
if err != nil {
return err
}
if err := s.Put(ctx, json); err != nil {
return err
}
if err := changeDefaultIssuerTimestamps(ctx, s, config.fetchedDefault, config.DefaultIssuerId); err != nil {
return err
}
return nil
}
func changeDefaultIssuerTimestamps(ctx context.Context, s logical.Storage, oldDefault IssuerID, newDefault IssuerID) error {
if newDefault == oldDefault {
return nil
}
now := time.Now().UTC()
// When the default issuer changes, we need to modify four
// pieces of information:
//
// 1. The old default issuer's modification time, as it no
// longer works for the /cert/ca path.
// 2. The new default issuer's modification time, as it now
// works for the /cert/ca path.
// 3. & 4. Both issuer's CRLs, as they behave the same, under
// the /cert/crl path!
for _, thisId := range []IssuerID{oldDefault, newDefault} {
if len(thisId) == 0 {
continue
}
// 1 & 2 above.
issuer, err := FetchIssuerById(ctx, s, thisId)
if err != nil {
// Due to the lack of transactions, if we deleted the default
// issuer (successfully), but the subsequent issuer config write
// (to clear the default issuer's old id) failed, we might have
// an inconsistent config. If we later hit this loop (and flush
// these timestamps again -- perhaps because the operator
// selected a new default), we'd have erred out here, because
// the since-deleted default issuer doesn't exist. In this case,
// skip the issuer instead of bailing.
err := fmt.Errorf("unable to update issuer (%v)'s modification time: error fetching issuer: %w", thisId, err)
if strings.Contains(err.Error(), "does not exist") {
hclog.L().Warn(err.Error())
continue
}
return err
}
issuer.LastModified = now
err = WriteIssuer(ctx, s, issuer)
if err != nil {
return fmt.Errorf("unable to update issuer (%v)'s modification time: error persisting issuer: %w", thisId, err)
}
}
// Fetch and update the internalCRLConfigEntry (3&4).
cfg, err := GetLocalCRLConfig(ctx, s)
if err != nil {
return fmt.Errorf("unable to update local CRL config's modification time: error fetching local CRL config: %w", err)
}
cfg.LastModified = now
cfg.DeltaLastModified = now
err = SetLocalCRLConfig(ctx, s, cfg)
if err != nil {
return fmt.Errorf("unable to update local CRL config's modification time: error persisting local CRL config: %w", err)
}
return nil
}