vault: Support secret sharing

This commit is contained in:
Armon Dadgar 2015-03-11 11:34:08 -07:00
parent bc7f1a43af
commit 8c49152c78

View file

@ -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
} }