2023-03-28 18:39:22 +00:00
|
|
|
// Copyright (c) HashiCorp, Inc.
|
|
|
|
// SPDX-License-Identifier: MPL-2.0
|
|
|
|
|
2020-06-29 19:52:47 +00:00
|
|
|
package consul
|
|
|
|
|
|
|
|
import (
|
2020-07-24 14:00:51 +00:00
|
|
|
"fmt"
|
2020-06-29 19:52:47 +00:00
|
|
|
|
2021-06-23 20:32:59 +00:00
|
|
|
"github.com/hashicorp/go-memdb"
|
2021-06-25 18:00:00 +00:00
|
|
|
|
2020-07-24 14:00:51 +00:00
|
|
|
"github.com/hashicorp/consul/agent/connect"
|
|
|
|
"github.com/hashicorp/consul/agent/consul/state"
|
|
|
|
"github.com/hashicorp/consul/agent/structs"
|
2022-06-01 21:53:52 +00:00
|
|
|
"github.com/hashicorp/consul/lib"
|
2020-06-29 19:52:47 +00:00
|
|
|
)
|
|
|
|
|
2020-07-24 14:00:51 +00:00
|
|
|
func (s *Server) getCARoots(ws memdb.WatchSet, state *state.Store) (*structs.IndexedCARoots, error) {
|
|
|
|
index, roots, config, err := state.CARootsAndConfig(ws)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2021-11-10 17:50:08 +00:00
|
|
|
if config == nil || config.ClusterID == "" {
|
2021-11-08 23:51:49 +00:00
|
|
|
return nil, fmt.Errorf("CA has not finished initializing")
|
|
|
|
}
|
2020-07-24 14:00:51 +00:00
|
|
|
|
|
|
|
indexedRoots := &structs.IndexedCARoots{}
|
|
|
|
|
2021-11-08 23:51:49 +00:00
|
|
|
// Build TrustDomain based on the ClusterID stored.
|
2021-11-05 22:20:24 +00:00
|
|
|
signingID := connect.SpiffeIDSigningForCluster(config.ClusterID)
|
2021-11-08 23:51:49 +00:00
|
|
|
if signingID == nil {
|
|
|
|
// If CA is bootstrapped at all then this should never happen but be
|
|
|
|
// defensive.
|
|
|
|
return nil, fmt.Errorf("no cluster trust domain setup")
|
|
|
|
}
|
2020-07-24 14:00:51 +00:00
|
|
|
|
2021-11-10 17:45:22 +00:00
|
|
|
indexedRoots.TrustDomain = signingID.Host()
|
|
|
|
|
2020-07-24 14:00:51 +00:00
|
|
|
indexedRoots.Index, indexedRoots.Roots = index, roots
|
|
|
|
if indexedRoots.Roots == nil {
|
|
|
|
indexedRoots.Roots = make(structs.CARoots, 0)
|
|
|
|
}
|
|
|
|
|
|
|
|
// The response should not contain all fields as there are sensitive
|
|
|
|
// data such as key material stored within the struct. So here we
|
|
|
|
// pull out some of the fields and copy them into
|
|
|
|
for i, r := range indexedRoots.Roots {
|
2021-07-01 00:48:29 +00:00
|
|
|
var intermediates []string
|
|
|
|
if r.IntermediateCerts != nil {
|
|
|
|
intermediates = make([]string, len(r.IntermediateCerts))
|
|
|
|
for i, intermediate := range r.IntermediateCerts {
|
|
|
|
intermediates[i] = intermediate
|
|
|
|
}
|
|
|
|
}
|
2020-07-24 14:00:51 +00:00
|
|
|
// IMPORTANT: r must NEVER be modified, since it is a pointer
|
|
|
|
// directly to the structure in the memdb store.
|
|
|
|
|
|
|
|
indexedRoots.Roots[i] = &structs.CARoot{
|
|
|
|
ID: r.ID,
|
|
|
|
Name: r.Name,
|
|
|
|
SerialNumber: r.SerialNumber,
|
|
|
|
SigningKeyID: r.SigningKeyID,
|
|
|
|
ExternalTrustDomain: r.ExternalTrustDomain,
|
|
|
|
NotBefore: r.NotBefore,
|
|
|
|
NotAfter: r.NotAfter,
|
2022-06-01 21:53:52 +00:00
|
|
|
RootCert: lib.EnsureTrailingNewline(r.RootCert),
|
2021-07-01 00:48:29 +00:00
|
|
|
IntermediateCerts: intermediates,
|
2020-07-24 14:00:51 +00:00
|
|
|
RaftIndex: r.RaftIndex,
|
|
|
|
Active: r.Active,
|
|
|
|
PrivateKeyType: r.PrivateKeyType,
|
|
|
|
PrivateKeyBits: r.PrivateKeyBits,
|
|
|
|
}
|
|
|
|
|
|
|
|
if r.Active {
|
|
|
|
indexedRoots.ActiveRootID = r.ID
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return indexedRoots, nil
|
|
|
|
}
|