vault: Support secret sharing
This commit is contained in:
parent
bc7f1a43af
commit
8c49152c78
|
@ -8,6 +8,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/hashicorp/vault/physical"
|
"github.com/hashicorp/vault/physical"
|
||||||
|
"github.com/hashicorp/vault/shamir"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -34,9 +35,9 @@ var (
|
||||||
|
|
||||||
// SealConfig is used to describe the seal configuration
|
// SealConfig is used to describe the seal configuration
|
||||||
type SealConfig struct {
|
type SealConfig struct {
|
||||||
// SecretParts is the number of parts the secret is
|
// SecretShares is the number of shares the secret is
|
||||||
// split into. This is the N value of Shamir
|
// split into. This is the N value of Shamir
|
||||||
SecretParts int `json:"secret_parts"`
|
SecretShares int `json:"secret_shares"`
|
||||||
|
|
||||||
// SecretThreshold is the number of parts required
|
// SecretThreshold is the number of parts required
|
||||||
// to open the vault. This is the T value of Shamir
|
// to open the vault. This is the T value of Shamir
|
||||||
|
@ -50,14 +51,14 @@ type SealConfig struct {
|
||||||
|
|
||||||
// Validate is used to sanity check the seal configuration
|
// Validate is used to sanity check the seal configuration
|
||||||
func (s *SealConfig) Validate() error {
|
func (s *SealConfig) Validate() error {
|
||||||
if s.SecretParts <= 0 {
|
if s.SecretShares < 1 {
|
||||||
return fmt.Errorf("must have a positive number for secret parts")
|
return fmt.Errorf("secret shares must be at least one")
|
||||||
}
|
}
|
||||||
if s.SecretThreshold <= 0 {
|
if s.SecretThreshold < 1 {
|
||||||
return fmt.Errorf("must have a positive number for secret threshold")
|
return fmt.Errorf("secret threshold must be at least one")
|
||||||
}
|
}
|
||||||
if s.SecretThreshold > s.SecretParts {
|
if s.SecretThreshold > s.SecretShares {
|
||||||
return fmt.Errorf("secret threshold cannot be larger than secret parts")
|
return fmt.Errorf("secret threshold cannot be larger than secret shares")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -65,7 +66,7 @@ func (s *SealConfig) Validate() error {
|
||||||
// InitResult is used to provide the key parts back after
|
// InitResult is used to provide the key parts back after
|
||||||
// they are generated as part of the initialization.
|
// they are generated as part of the initialization.
|
||||||
type InitResult struct {
|
type InitResult struct {
|
||||||
SecretParts [][]byte
|
SecretShares [][]byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// Core is used as the central manager of Vault activity. It is the primary point of
|
// Core is used as the central manager of Vault activity. It is the primary point of
|
||||||
|
@ -156,11 +157,6 @@ func (c *Core) Initialize(config *SealConfig) (*InitResult, error) {
|
||||||
return nil, fmt.Errorf("invalid seal configuration: %v", err)
|
return nil, fmt.Errorf("invalid seal configuration: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Remove restrict
|
|
||||||
if config.SecretParts != 1 {
|
|
||||||
return nil, fmt.Errorf("Unsupported configuration")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Avoid an initialization race
|
// Avoid an initialization race
|
||||||
c.stateLock.Lock()
|
c.stateLock.Lock()
|
||||||
defer c.stateLock.Unlock()
|
defer c.stateLock.Unlock()
|
||||||
|
@ -206,14 +202,20 @@ func (c *Core) Initialize(config *SealConfig) (*InitResult, error) {
|
||||||
|
|
||||||
// Return the master key if only a single key part is used
|
// Return the master key if only a single key part is used
|
||||||
results := new(InitResult)
|
results := new(InitResult)
|
||||||
if config.SecretParts == 1 {
|
if config.SecretShares == 1 {
|
||||||
results.SecretParts = append(results.SecretParts, masterKey)
|
results.SecretShares = append(results.SecretShares, masterKey)
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// TODO: Support multiple parts
|
// Split the master key using the Shamir algorithm
|
||||||
panic("unsupported")
|
shares, err := shamir.Split(masterKey, config.SecretShares, config.SecretThreshold)
|
||||||
|
if err != nil {
|
||||||
|
c.logger.Printf("[ERR] core: failed to generate shares: %v", err)
|
||||||
|
return nil, fmt.Errorf("failed to generate shares: %v", err)
|
||||||
|
}
|
||||||
|
results.SecretShares = shares
|
||||||
}
|
}
|
||||||
|
|
||||||
|
c.logger.Printf("[INFO] core: security barrier initialized")
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue