From 8c49152c78f2314581ee65a2d200a477bd896ace Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Wed, 11 Mar 2015 11:34:08 -0700 Subject: [PATCH] vault: Support secret sharing --- vault/core.go | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/vault/core.go b/vault/core.go index 646077e28..a7d0f85b3 100644 --- a/vault/core.go +++ b/vault/core.go @@ -8,6 +8,7 @@ import ( "sync" "github.com/hashicorp/vault/physical" + "github.com/hashicorp/vault/shamir" ) const ( @@ -34,9 +35,9 @@ var ( // SealConfig is used to describe the seal configuration 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 - SecretParts int `json:"secret_parts"` + SecretShares int `json:"secret_shares"` // SecretThreshold is the number of parts required // 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 func (s *SealConfig) Validate() error { - if s.SecretParts <= 0 { - return fmt.Errorf("must have a positive number for secret parts") + if s.SecretShares < 1 { + return fmt.Errorf("secret shares must be at least one") } - if s.SecretThreshold <= 0 { - return fmt.Errorf("must have a positive number for secret threshold") + if s.SecretThreshold < 1 { + return fmt.Errorf("secret threshold must be at least one") } - if s.SecretThreshold > s.SecretParts { - return fmt.Errorf("secret threshold cannot be larger than secret parts") + if s.SecretThreshold > s.SecretShares { + return fmt.Errorf("secret threshold cannot be larger than secret shares") } return nil } @@ -65,7 +66,7 @@ func (s *SealConfig) Validate() error { // InitResult is used to provide the key parts back after // they are generated as part of the initialization. type InitResult struct { - SecretParts [][]byte + SecretShares [][]byte } // 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) } - // TODO: Remove restrict - if config.SecretParts != 1 { - return nil, fmt.Errorf("Unsupported configuration") - } - // Avoid an initialization race c.stateLock.Lock() 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 results := new(InitResult) - if config.SecretParts == 1 { - results.SecretParts = append(results.SecretParts, masterKey) + if config.SecretShares == 1 { + results.SecretShares = append(results.SecretShares, masterKey) } else { - // TODO: Support multiple parts - panic("unsupported") + // Split the master key using the Shamir algorithm + 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 }