mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-11-01 02:57:59 +00:00 
			
		
		
		
	oss changes for entropy augmentation feature (#7670)
* oss changes for entropy augmentation feature * fix oss command/server/config tests * update go.sum * fix logical_system and http/ tests * adds vendored files * removes unused variable
This commit is contained in:
		| @@ -38,6 +38,7 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S | ||||
| github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= | ||||
| github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
|   | ||||
| @@ -134,6 +134,7 @@ type MountInput struct { | ||||
| 	Config                MountConfigInput  `json:"config"` | ||||
| 	Local                 bool              `json:"local"` | ||||
| 	SealWrap              bool              `json:"seal_wrap" mapstructure:"seal_wrap"` | ||||
| 	ExternalEntropyAccess bool              `json:"external_entropy_access" mapstructure:"external_entropy_access"` | ||||
| 	Options               map[string]string `json:"options"` | ||||
|  | ||||
| 	// Deprecated: Newer server responses should be returning this information in the | ||||
| @@ -167,6 +168,7 @@ type MountOutput struct { | ||||
| 	Options               map[string]string `json:"options"` | ||||
| 	Local                 bool              `json:"local"` | ||||
| 	SealWrap              bool              `json:"seal_wrap" mapstructure:"seal_wrap"` | ||||
| 	ExternalEntropyAccess bool              `json:"external_entropy_access" mapstructure:"external_entropy_access"` | ||||
| } | ||||
|  | ||||
| type MountConfigOutput struct { | ||||
|   | ||||
| @@ -333,6 +333,7 @@ func (b *backend) pathKeyCreate(ctx context.Context, req *logical.Request, data | ||||
| 			Digits:      keyDigits, | ||||
| 			Algorithm:   keyAlgorithm, | ||||
| 			SecretSize:  uintKeySize, | ||||
| 			Rand:        b.GetRandomReader(), | ||||
| 		}) | ||||
| 		if err != nil { | ||||
| 			return logical.ErrorResponse("an error occurred while generating a key"), err | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package transit | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	cryptoRand "crypto/rand" | ||||
| 	"encoding/base64" | ||||
| 	"fmt" | ||||
| 	"math/rand" | ||||
| @@ -922,7 +923,7 @@ func testDerivedKeyUpgrade(t *testing.T, keyType keysutil.KeyType) { | ||||
| 	} | ||||
|  | ||||
| 	p.MigrateKeyToKeysMap() | ||||
| 	p.Upgrade(context.Background(), storage) // Need to run the upgrade code to make the migration stick | ||||
| 	p.Upgrade(context.Background(), storage, cryptoRand.Reader) // Need to run the upgrade code to make the migration stick | ||||
|  | ||||
| 	if p.KDF != keysutil.Kdf_hmac_sha256_counter { | ||||
| 		t.Fatalf("bad KDF value by default; counter val is %d, KDF val is %d, policy is %#v", keysutil.Kdf_hmac_sha256_counter, p.KDF, *p) | ||||
|   | ||||
| @@ -65,7 +65,7 @@ func (b *backend) pathConfigWrite(ctx context.Context, req *logical.Request, d * | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -102,7 +102,7 @@ func (b *backend) pathDatakeyWrite(ctx context.Context, req *logical.Request, d | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -115,7 +115,7 @@ func (b *backend) pathDecryptWrite(ctx context.Context, req *logical.Request, d | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    d.Get("name").(string), | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -129,7 +129,7 @@ func (b *backend) pathEncryptExistenceCheck(ctx context.Context, req *logical.Re | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return false, err | ||||
| 	} | ||||
| @@ -244,7 +244,7 @@ func (b *backend) pathEncryptWrite(ctx context.Context, req *logical.Request, d | ||||
| 			Name:    name, | ||||
| 		} | ||||
| 	} | ||||
| 	p, upserted, err = b.lm.GetPolicy(ctx, polReq) | ||||
| 	p, upserted, err = b.lm.GetPolicy(ctx, polReq, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -67,7 +67,7 @@ func (b *backend) pathPolicyExportRead(ctx context.Context, req *logical.Request | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -100,7 +100,7 @@ func (b *backend) pathHMACWrite(ctx context.Context, req *logical.Request, d *fr | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -229,7 +229,7 @@ func (b *backend) pathHMACVerify(ctx context.Context, req *logical.Request, d *f | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -29,7 +29,7 @@ func TestTransit_HMAC(t *testing.T) { | ||||
| 	p, _, err := b.lm.GetPolicy(context.Background(), keysutil.PolicyRequest{ | ||||
| 		Storage: storage, | ||||
| 		Name:    "foo", | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -123,7 +123,7 @@ func TestTransit_HMAC(t *testing.T) { | ||||
| 	req.Data["input"] = "dGhlIHF1aWNrIGJyb3duIGZveA==" | ||||
|  | ||||
| 	// Rotate | ||||
| 	err = p.Rotate(context.Background(), storage) | ||||
| 	err = p.Rotate(context.Background(), storage, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -199,7 +199,7 @@ func TestTransit_batchHMAC(t *testing.T) { | ||||
| 	p, _, err := b.lm.GetPolicy(context.Background(), keysutil.PolicyRequest{ | ||||
| 		Storage: storage, | ||||
| 		Name:    "foo", | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -297,7 +297,7 @@ func TestTransit_batchHMAC(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	// Rotate | ||||
| 	err = p.Rotate(context.Background(), storage) | ||||
| 	err = p.Rotate(context.Background(), storage, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|   | ||||
| @@ -161,7 +161,7 @@ func (b *backend) pathPolicyWrite(ctx context.Context, req *logical.Request, d * | ||||
| 		return logical.ErrorResponse(fmt.Sprintf("unknown key type %v", keyType)), logical.ErrInvalidRequest | ||||
| 	} | ||||
|  | ||||
| 	p, upserted, err := b.lm.GetPolicy(ctx, polReq) | ||||
| 	p, upserted, err := b.lm.GetPolicy(ctx, polReq, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -193,7 +193,7 @@ func (b *backend) pathPolicyRead(ctx context.Context, req *logical.Request, d *f | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -118,7 +118,7 @@ func (b *backend) pathRewrapWrite(ctx context.Context, req *logical.Request, d * | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    d.Get("name").(string), | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -34,7 +34,7 @@ func (b *backend) pathRotateWrite(ctx context.Context, req *logical.Request, d * | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -46,7 +46,7 @@ func (b *backend) pathRotateWrite(ctx context.Context, req *logical.Request, d * | ||||
| 	} | ||||
|  | ||||
| 	// Rotate the policy | ||||
| 	err = p.Rotate(ctx, req.Storage) | ||||
| 	err = p.Rotate(ctx, req.Storage, b.GetRandomReader()) | ||||
|  | ||||
| 	p.Unlock() | ||||
| 	return nil, err | ||||
|   | ||||
| @@ -247,7 +247,7 @@ func (b *backend) pathSignWrite(ctx context.Context, req *logical.Request, d *fr | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| @@ -456,7 +456,7 @@ func (b *backend) pathVerifyWrite(ctx context.Context, req *logical.Request, d * | ||||
| 	p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 		Storage: req.Storage, | ||||
| 		Name:    name, | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -58,7 +58,7 @@ func testTransit_SignVerify_ECDSA(t *testing.T, bits int) { | ||||
| 	p, _, err := b.lm.GetPolicy(context.Background(), keysutil.PolicyRequest{ | ||||
| 		Storage: storage, | ||||
| 		Name:    "foo", | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -274,11 +274,11 @@ func testTransit_SignVerify_ECDSA(t *testing.T, bits int) { | ||||
| 	signRequest(req, true, "") | ||||
|  | ||||
| 	// Rotate and set min decryption version | ||||
| 	err = p.Rotate(context.Background(), storage) | ||||
| 	err = p.Rotate(context.Background(), storage, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	err = p.Rotate(context.Background(), storage) | ||||
| 	err = p.Rotate(context.Background(), storage, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -378,7 +378,7 @@ func TestTransit_SignVerify_ED25519(t *testing.T) { | ||||
| 	fooP, _, err := b.lm.GetPolicy(context.Background(), keysutil.PolicyRequest{ | ||||
| 		Storage: storage, | ||||
| 		Name:    "foo", | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -386,7 +386,7 @@ func TestTransit_SignVerify_ED25519(t *testing.T) { | ||||
| 	barP, _, err := b.lm.GetPolicy(context.Background(), keysutil.PolicyRequest{ | ||||
| 		Storage: storage, | ||||
| 		Name:    "bar", | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -566,11 +566,11 @@ func TestTransit_SignVerify_ED25519(t *testing.T) { | ||||
| 	sig = signRequest(req, true, "bar") | ||||
|  | ||||
| 	// Rotate and set min decryption version | ||||
| 	err = fooP.Rotate(context.Background(), storage) | ||||
| 	err = fooP.Rotate(context.Background(), storage, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	err = fooP.Rotate(context.Background(), storage) | ||||
| 	err = fooP.Rotate(context.Background(), storage, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -578,11 +578,11 @@ func TestTransit_SignVerify_ED25519(t *testing.T) { | ||||
| 	if err = fooP.Persist(context.Background(), storage); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	err = barP.Rotate(context.Background(), storage) | ||||
| 	err = barP.Rotate(context.Background(), storage, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| 	err = barP.Rotate(context.Background(), storage) | ||||
| 	err = barP.Rotate(context.Background(), storage, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|   | ||||
| @@ -43,7 +43,7 @@ func (b *backend) pathTrimUpdate() framework.OperationFunc { | ||||
| 		p, _, err := b.lm.GetPolicy(ctx, keysutil.PolicyRequest{ | ||||
| 			Storage: req.Storage, | ||||
| 			Name:    name, | ||||
| 		}) | ||||
| 		}, b.GetRandomReader()) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
|   | ||||
| @@ -39,7 +39,7 @@ func TestTransit_Trim(t *testing.T) { | ||||
| 	p, _, err := b.lm.GetPolicy(namespace.RootContext(nil), keysutil.PolicyRequest{ | ||||
| 		Storage: storage, | ||||
| 		Name:    "aes", | ||||
| 	}) | ||||
| 	}, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|   | ||||
| @@ -32,6 +32,7 @@ type AuthEnableCommand struct { | ||||
| 	flagOptions                   map[string]string | ||||
| 	flagLocal                     bool | ||||
| 	flagSealWrap                  bool | ||||
| 	flagExternalEntropyAccess     bool | ||||
| 	flagTokenType                 string | ||||
| 	flagVersion                   int | ||||
| } | ||||
| @@ -176,6 +177,13 @@ func (c *AuthEnableCommand) Flags() *FlagSets { | ||||
| 		Usage:   "Enable seal wrapping of critical values in the secrets engine.", | ||||
| 	}) | ||||
|  | ||||
| 	f.BoolVar(&BoolVar{ | ||||
| 		Name:    "external-entropy-access", | ||||
| 		Target:  &c.flagExternalEntropyAccess, | ||||
| 		Default: false, | ||||
| 		Usage:   "Enable auth method to access Vault's external entropy source.", | ||||
| 	}) | ||||
|  | ||||
| 	f.StringVar(&StringVar{ | ||||
| 		Name:   flagNameTokenType, | ||||
| 		Target: &c.flagTokenType, | ||||
| @@ -255,6 +263,7 @@ func (c *AuthEnableCommand) Run(args []string) int { | ||||
| 		Description: c.flagDescription, | ||||
| 		Local:       c.flagLocal, | ||||
| 		SealWrap:    c.flagSealWrap, | ||||
| 		ExternalEntropyAccess: c.flagExternalEntropyAccess, | ||||
| 		Config: api.AuthConfigInput{ | ||||
| 			DefaultLeaseTTL: c.flagDefaultLeaseTTL.String(), | ||||
| 			MaxLeaseTTL:     c.flagMaxLeaseTTL.String(), | ||||
|   | ||||
| @@ -143,7 +143,7 @@ func (c *AuthListCommand) detailedMounts(auths map[string]*api.AuthMount) []stri | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Token Type | Replication | Seal Wrap | Options | Description | UUID"} | ||||
| 	out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Token Type | Replication | Seal Wrap | External Entropy Access | Options | Description | UUID"} | ||||
| 	for _, path := range paths { | ||||
| 		mount := auths[path] | ||||
|  | ||||
| @@ -160,7 +160,7 @@ func (c *AuthListCommand) detailedMounts(auths map[string]*api.AuthMount) []stri | ||||
| 			pluginName = mount.Config.PluginName | ||||
| 		} | ||||
|  | ||||
| 		out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %s | %s | %t | %v | %s | %s", | ||||
| 		out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %s | %s | %t | %v | %s | %s | %s", | ||||
| 			path, | ||||
| 			pluginName, | ||||
| 			mount.Accessor, | ||||
| @@ -169,6 +169,7 @@ func (c *AuthListCommand) detailedMounts(auths map[string]*api.AuthMount) []stri | ||||
| 			mount.Config.TokenType, | ||||
| 			replication, | ||||
| 			mount.SealWrap, | ||||
| 			mount.ExternalEntropyAccess, | ||||
| 			mount.Options, | ||||
| 			mount.Description, | ||||
| 			mount.UUID, | ||||
|   | ||||
| @@ -33,6 +33,7 @@ type SecretsEnableCommand struct { | ||||
| 	flagOptions                   map[string]string | ||||
| 	flagLocal                     bool | ||||
| 	flagSealWrap                  bool | ||||
| 	flagExternalEntropyAccess     bool | ||||
| 	flagVersion                   int | ||||
| } | ||||
|  | ||||
| @@ -192,6 +193,13 @@ func (c *SecretsEnableCommand) Flags() *FlagSets { | ||||
| 		Usage:   "Enable seal wrapping of critical values in the secrets engine.", | ||||
| 	}) | ||||
|  | ||||
| 	f.BoolVar(&BoolVar{ | ||||
| 		Name:    "external-entropy-access", | ||||
| 		Target:  &c.flagExternalEntropyAccess, | ||||
| 		Default: false, | ||||
| 		Usage:   "Enable secrets engine to access Vault's external entropy source.", | ||||
| 	}) | ||||
|  | ||||
| 	f.IntVar(&IntVar{ | ||||
| 		Name:    "version", | ||||
| 		Target:  &c.flagVersion, | ||||
| @@ -267,6 +275,7 @@ func (c *SecretsEnableCommand) Run(args []string) int { | ||||
| 		Description:           c.flagDescription, | ||||
| 		Local:                 c.flagLocal, | ||||
| 		SealWrap:              c.flagSealWrap, | ||||
| 		ExternalEntropyAccess: c.flagExternalEntropyAccess, | ||||
| 		Config: api.MountConfigInput{ | ||||
| 			DefaultLeaseTTL: c.flagDefaultLeaseTTL.String(), | ||||
| 			MaxLeaseTTL:     c.flagMaxLeaseTTL.String(), | ||||
|   | ||||
| @@ -143,7 +143,7 @@ func (c *SecretsListCommand) detailedMounts(mounts map[string]*api.MountOutput) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Force No Cache | Replication | Seal Wrap | Options | Description | UUID "} | ||||
| 	out := []string{"Path | Plugin | Accessor | Default TTL | Max TTL | Force No Cache | Replication | Seal Wrap | External Entropy Access | Options | Description | UUID "} | ||||
| 	for _, path := range paths { | ||||
| 		mount := mounts[path] | ||||
|  | ||||
| @@ -160,7 +160,7 @@ func (c *SecretsListCommand) detailedMounts(mounts map[string]*api.MountOutput) | ||||
| 			pluginName = mount.Config.PluginName | ||||
| 		} | ||||
|  | ||||
| 		out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %t | %s | %t | %v | %s | %s", | ||||
| 		out = append(out, fmt.Sprintf("%s | %s | %s | %s | %s | %t | %s | %t | %v | %s | %s | %s", | ||||
| 			path, | ||||
| 			pluginName, | ||||
| 			mount.Accessor, | ||||
| @@ -169,6 +169,7 @@ func (c *SecretsListCommand) detailedMounts(mounts map[string]*api.MountOutput) | ||||
| 			mount.Config.ForceNoCache, | ||||
| 			replication, | ||||
| 			mount.SealWrap, | ||||
| 			mount.ExternalEntropyAccess, | ||||
| 			mount.Options, | ||||
| 			mount.Description, | ||||
| 			mount.UUID, | ||||
|   | ||||
| @@ -1006,6 +1006,13 @@ func (c *ServerCommand) Run(args []string) int { | ||||
| 		return 1 | ||||
| 	} | ||||
|  | ||||
| 	// prepare a secure random reader for core | ||||
| 	secureRandomReader, err := createSecureRandomReaderFunc(config, &barrierSeal) | ||||
| 	if err != nil { | ||||
| 		c.UI.Error(err.Error()) | ||||
| 		return 1 | ||||
| 	} | ||||
|  | ||||
| 	coreConfig := &vault.CoreConfig{ | ||||
| 		RawConfig:                 config, | ||||
| 		Physical:                  backend, | ||||
| @@ -1033,6 +1040,7 @@ func (c *ServerCommand) Run(args []string) int { | ||||
| 		BuiltinRegistry:           builtinplugins.Registry, | ||||
| 		DisableKeyEncodingChecks:  config.DisablePrintableCheck, | ||||
| 		MetricsHelper:             metricsHelper, | ||||
| 		SecureRandomReader:        secureRandomReader, | ||||
| 	} | ||||
| 	if c.flagDev { | ||||
| 		coreConfig.DevToken = c.flagDevRootTokenID | ||||
|   | ||||
| @@ -12,7 +12,6 @@ import ( | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/hashicorp/errwrap" | ||||
|  | ||||
| 	"github.com/hashicorp/go-multierror" | ||||
| 	"github.com/hashicorp/hcl" | ||||
| 	"github.com/hashicorp/hcl/hcl/ast" | ||||
| @@ -30,6 +29,7 @@ type Config struct { | ||||
| 	HAStorage *Storage    `hcl:"-"` | ||||
|  | ||||
| 	Seals   []*Seal  `hcl:"-"` | ||||
| 	Entropy *Entropy `hcl:"-"` | ||||
|  | ||||
| 	CacheSize                int         `hcl:"cache_size"` | ||||
| 	DisableCache             bool        `hcl:"-"` | ||||
| @@ -125,6 +125,18 @@ func (l *Listener) GoString() string { | ||||
| 	return fmt.Sprintf("*%#v", *l) | ||||
| } | ||||
|  | ||||
| // Entropy contains Entropy configuration for the server | ||||
| type EntropyMode int | ||||
|  | ||||
| const ( | ||||
| 	Unknown EntropyMode = iota | ||||
| 	Augmentation | ||||
| ) | ||||
|  | ||||
| type Entropy struct { | ||||
| 	Mode EntropyMode | ||||
| } | ||||
|  | ||||
| // Storage is the underlying storage configuration for the server. | ||||
| type Storage struct { | ||||
| 	Type              string | ||||
| @@ -279,6 +291,11 @@ func (c *Config) Merge(c2 *Config) *Config { | ||||
| 		result.HAStorage = c2.HAStorage | ||||
| 	} | ||||
|  | ||||
| 	result.Entropy = c.Entropy | ||||
| 	if c2.Entropy != nil { | ||||
| 		result.Entropy = c2.Entropy | ||||
| 	} | ||||
|  | ||||
| 	for _, s := range c.Seals { | ||||
| 		result.Seals = append(result.Seals, s) | ||||
| 	} | ||||
| @@ -579,6 +596,12 @@ func ParseConfig(d string) (*Config, error) { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if o := list.Filter("entropy"); len(o.Items) > 0 { | ||||
| 		if err := parseEntropy(&result, o, "entropy"); err != nil { | ||||
| 			return nil, errwrap.Wrapf("error parsing 'entropy': {{err}}", err) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if o := list.Filter("listener"); len(o.Items) > 0 { | ||||
| 		if err := parseListeners(&result, o); err != nil { | ||||
| 			return nil, errwrap.Wrapf("error parsing 'listener': {{err}}", err) | ||||
| @@ -821,7 +844,6 @@ func parseSeals(result *Config, list *ast.ObjectList, blockName string) error { | ||||
| 		if err := hcl.DecodeObject(&m, item.Val); err != nil { | ||||
| 			return multierror.Prefix(err, fmt.Sprintf("seal.%s:", key)) | ||||
| 		} | ||||
|  | ||||
| 		var disabled bool | ||||
| 		var err error | ||||
| 		if v, ok := m["disabled"]; ok { | ||||
|   | ||||
| @@ -1,487 +1,39 @@ | ||||
| // +build !enterprise | ||||
|  | ||||
| package server | ||||
|  | ||||
| import ( | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-test/deep" | ||||
| 	"github.com/hashicorp/hcl" | ||||
| 	"github.com/hashicorp/hcl/hcl/ast" | ||||
| ) | ||||
|  | ||||
| func TestLoadConfigFile(t *testing.T) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config.hcl") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type:         "consul", | ||||
| 			RedirectAddr: "foo", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		HAStorage: &Storage{ | ||||
| 			Type:         "consul", | ||||
| 			RedirectAddr: "snafu", | ||||
| 			Config: map[string]string{ | ||||
| 				"bar": "baz", | ||||
| 			}, | ||||
| 			DisableClustering: true, | ||||
| 		}, | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsdAddr:              "bar", | ||||
| 			StatsiteAddr:            "foo", | ||||
| 			DisableHostname:         false, | ||||
| 			DogStatsDAddr:           "127.0.0.1:7254", | ||||
| 			DogStatsDTags:           []string{"tag_1:val_1", "tag_2:val_2"}, | ||||
| 			PrometheusRetentionTime: prometheusDefaultRetentionTime, | ||||
| 		}, | ||||
|  | ||||
| 		DisableCache:             true, | ||||
| 		DisableCacheRaw:          true, | ||||
| 		DisableMlock:             true, | ||||
| 		DisableMlockRaw:          true, | ||||
| 		DisablePrintableCheckRaw: true, | ||||
| 		DisablePrintableCheck:    true, | ||||
| 		EnableUI:                 true, | ||||
| 		EnableUIRaw:              true, | ||||
|  | ||||
| 		EnableRawEndpoint:    true, | ||||
| 		EnableRawEndpointRaw: true, | ||||
|  | ||||
| 		DisableSealWrap:    true, | ||||
| 		DisableSealWrapRaw: true, | ||||
|  | ||||
| 		MaxLeaseTTL:        10 * time.Hour, | ||||
| 		MaxLeaseTTLRaw:     "10h", | ||||
| 		DefaultLeaseTTL:    10 * time.Hour, | ||||
| 		DefaultLeaseTTLRaw: "10h", | ||||
| 		ClusterName:        "testcluster", | ||||
|  | ||||
| 		PidFile: "./pidfile", | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| 	testLoadConfigFile(t) | ||||
| } | ||||
|  | ||||
| func TestLoadConfigFile_topLevel(t *testing.T) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config2.hcl") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type:         "consul", | ||||
| 			RedirectAddr: "top_level_api_addr", | ||||
| 			ClusterAddr:  "top_level_cluster_addr", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		HAStorage: &Storage{ | ||||
| 			Type:         "consul", | ||||
| 			RedirectAddr: "top_level_api_addr", | ||||
| 			ClusterAddr:  "top_level_cluster_addr", | ||||
| 			Config: map[string]string{ | ||||
| 				"bar": "baz", | ||||
| 			}, | ||||
| 			DisableClustering: true, | ||||
| 		}, | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsdAddr:                 "bar", | ||||
| 			StatsiteAddr:               "foo", | ||||
| 			DisableHostname:            false, | ||||
| 			DogStatsDAddr:              "127.0.0.1:7254", | ||||
| 			DogStatsDTags:              []string{"tag_1:val_1", "tag_2:val_2"}, | ||||
| 			PrometheusRetentionTime:    30 * time.Second, | ||||
| 			PrometheusRetentionTimeRaw: "30s", | ||||
| 		}, | ||||
|  | ||||
| 		DisableCache:    true, | ||||
| 		DisableCacheRaw: true, | ||||
| 		DisableMlock:    true, | ||||
| 		DisableMlockRaw: true, | ||||
| 		EnableUI:        true, | ||||
| 		EnableUIRaw:     true, | ||||
|  | ||||
| 		EnableRawEndpoint:    true, | ||||
| 		EnableRawEndpointRaw: true, | ||||
|  | ||||
| 		DisableSealWrap:    true, | ||||
| 		DisableSealWrapRaw: true, | ||||
|  | ||||
| 		MaxLeaseTTL:        10 * time.Hour, | ||||
| 		MaxLeaseTTLRaw:     "10h", | ||||
| 		DefaultLeaseTTL:    10 * time.Hour, | ||||
| 		DefaultLeaseTTLRaw: "10h", | ||||
| 		ClusterName:        "testcluster", | ||||
|  | ||||
| 		PidFile: "./pidfile", | ||||
|  | ||||
| 		APIAddr:     "top_level_api_addr", | ||||
| 		ClusterAddr: "top_level_cluster_addr", | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| 	testLoadConfigFile_topLevel(t,nil) | ||||
| } | ||||
|  | ||||
| func TestLoadConfigFile_json(t *testing.T) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config.hcl.json") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type: "consul", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 			DisableClustering: true, | ||||
| 		}, | ||||
|  | ||||
| 		ClusterCipherSuites: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsiteAddr:                       "baz", | ||||
| 			StatsdAddr:                         "", | ||||
| 			DisableHostname:                    false, | ||||
| 			CirconusAPIToken:                   "", | ||||
| 			CirconusAPIApp:                     "", | ||||
| 			CirconusAPIURL:                     "", | ||||
| 			CirconusSubmissionInterval:         "", | ||||
| 			CirconusCheckSubmissionURL:         "", | ||||
| 			CirconusCheckID:                    "", | ||||
| 			CirconusCheckForceMetricActivation: "", | ||||
| 			CirconusCheckInstanceID:            "", | ||||
| 			CirconusCheckSearchTag:             "", | ||||
| 			CirconusCheckDisplayName:           "", | ||||
| 			CirconusCheckTags:                  "", | ||||
| 			CirconusBrokerID:                   "", | ||||
| 			CirconusBrokerSelectTag:            "", | ||||
| 			PrometheusRetentionTime:            prometheusDefaultRetentionTime, | ||||
| 		}, | ||||
|  | ||||
| 		MaxLeaseTTL:          10 * time.Hour, | ||||
| 		MaxLeaseTTLRaw:       "10h", | ||||
| 		DefaultLeaseTTL:      10 * time.Hour, | ||||
| 		DefaultLeaseTTLRaw:   "10h", | ||||
| 		ClusterName:          "testcluster", | ||||
| 		DisableCacheRaw:      interface{}(nil), | ||||
| 		DisableMlockRaw:      interface{}(nil), | ||||
| 		EnableUI:             true, | ||||
| 		EnableUIRaw:          true, | ||||
| 		PidFile:              "./pidfile", | ||||
| 		EnableRawEndpoint:    true, | ||||
| 		EnableRawEndpointRaw: true, | ||||
| 		DisableSealWrap:      true, | ||||
| 		DisableSealWrapRaw:   true, | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| 	testLoadConfigFile_json(t) | ||||
| } | ||||
|  | ||||
| func TestLoadConfigFile_json2(t *testing.T) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config2.hcl.json") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:444", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type: "consul", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		HAStorage: &Storage{ | ||||
| 			Type: "consul", | ||||
| 			Config: map[string]string{ | ||||
| 				"bar": "baz", | ||||
| 			}, | ||||
| 			DisableClustering: true, | ||||
| 		}, | ||||
|  | ||||
| 		CacheSize: 45678, | ||||
|  | ||||
| 		EnableUI:    true, | ||||
| 		EnableUIRaw: true, | ||||
|  | ||||
| 		EnableRawEndpoint:    true, | ||||
| 		EnableRawEndpointRaw: true, | ||||
|  | ||||
| 		DisableSealWrap:    true, | ||||
| 		DisableSealWrapRaw: true, | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsiteAddr:                       "foo", | ||||
| 			StatsdAddr:                         "bar", | ||||
| 			DisableHostname:                    true, | ||||
| 			CirconusAPIToken:                   "0", | ||||
| 			CirconusAPIApp:                     "vault", | ||||
| 			CirconusAPIURL:                     "http://api.circonus.com/v2", | ||||
| 			CirconusSubmissionInterval:         "10s", | ||||
| 			CirconusCheckSubmissionURL:         "https://someplace.com/metrics", | ||||
| 			CirconusCheckID:                    "0", | ||||
| 			CirconusCheckForceMetricActivation: "true", | ||||
| 			CirconusCheckInstanceID:            "node1:vault", | ||||
| 			CirconusCheckSearchTag:             "service:vault", | ||||
| 			CirconusCheckDisplayName:           "node1:vault", | ||||
| 			CirconusCheckTags:                  "cat1:tag1,cat2:tag2", | ||||
| 			CirconusBrokerID:                   "0", | ||||
| 			CirconusBrokerSelectTag:            "dc:sfo", | ||||
| 			PrometheusRetentionTime:            30 * time.Second, | ||||
| 			PrometheusRetentionTimeRaw:         "30s", | ||||
| 		}, | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| 	testLoadConfigFile_json2(t,nil) | ||||
| } | ||||
|  | ||||
| func TestLoadConfigDir(t *testing.T) { | ||||
| 	config, err := LoadConfigDir("./test-fixtures/config-dir") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		DisableCache: true, | ||||
| 		DisableMlock: true, | ||||
|  | ||||
| 		DisableClustering:    false, | ||||
| 		DisableClusteringRaw: false, | ||||
|  | ||||
| 		APIAddr:     "https://vault.local", | ||||
| 		ClusterAddr: "https://127.0.0.1:444", | ||||
|  | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type: "consul", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 			RedirectAddr:      "https://vault.local", | ||||
| 			ClusterAddr:       "https://127.0.0.1:444", | ||||
| 			DisableClustering: false, | ||||
| 		}, | ||||
|  | ||||
| 		EnableUI: true, | ||||
|  | ||||
| 		EnableRawEndpoint: true, | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsiteAddr:            "qux", | ||||
| 			StatsdAddr:              "baz", | ||||
| 			DisableHostname:         true, | ||||
| 			PrometheusRetentionTime: prometheusDefaultRetentionTime, | ||||
| 		}, | ||||
|  | ||||
| 		MaxLeaseTTL:     10 * time.Hour, | ||||
| 		DefaultLeaseTTL: 10 * time.Hour, | ||||
| 		ClusterName:     "testcluster", | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| 	testLoadConfigDir(t) | ||||
| } | ||||
|  | ||||
| func TestConfig_Sanitized(t *testing.T) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config3.hcl") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
| 	sanitizedConfig := config.Sanitized() | ||||
|  | ||||
| 	expected := map[string]interface{}{ | ||||
| 		"api_addr":                     "top_level_api_addr", | ||||
| 		"cache_size":                   0, | ||||
| 		"cluster_addr":                 "top_level_cluster_addr", | ||||
| 		"cluster_cipher_suites":        "", | ||||
| 		"cluster_name":                 "testcluster", | ||||
| 		"default_lease_ttl":            10 * time.Hour, | ||||
| 		"default_max_request_duration": 0 * time.Second, | ||||
| 		"disable_cache":                true, | ||||
| 		"disable_clustering":           false, | ||||
| 		"disable_indexing":             false, | ||||
| 		"disable_mlock":                true, | ||||
| 		"disable_performance_standby":  false, | ||||
| 		"disable_printable_check":      false, | ||||
| 		"disable_sealwrap":             true, | ||||
| 		"raw_storage_endpoint":         true, | ||||
| 		"enable_ui":                    true, | ||||
| 		"ha_storage": map[string]interface{}{ | ||||
| 			"cluster_addr":       "top_level_cluster_addr", | ||||
| 			"disable_clustering": true, | ||||
| 			"redirect_addr":      "top_level_api_addr", | ||||
| 			"type":               "consul"}, | ||||
| 		"listeners": []interface{}{ | ||||
| 			map[string]interface{}{ | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 				"type": "tcp", | ||||
| 			}, | ||||
| 		}, | ||||
| 		"log_format":       "", | ||||
| 		"log_level":        "", | ||||
| 		"max_lease_ttl":    10 * time.Hour, | ||||
| 		"pid_file":         "./pidfile", | ||||
| 		"plugin_directory": "", | ||||
| 		"seals": []interface{}{ | ||||
| 			map[string]interface{}{ | ||||
| 				"disabled": false, | ||||
| 				"type":     "awskms", | ||||
| 			}, | ||||
| 		}, | ||||
| 		"storage": map[string]interface{}{ | ||||
| 			"cluster_addr":       "top_level_cluster_addr", | ||||
| 			"disable_clustering": false, | ||||
| 			"redirect_addr":      "top_level_api_addr", | ||||
| 			"type":               "consul", | ||||
| 		}, | ||||
| 		"telemetry": map[string]interface{}{ | ||||
| 			"circonus_api_app":                       "", | ||||
| 			"circonus_api_token":                     "", | ||||
| 			"circonus_api_url":                       "", | ||||
| 			"circonus_broker_id":                     "", | ||||
| 			"circonus_broker_select_tag":             "", | ||||
| 			"circonus_check_display_name":            "", | ||||
| 			"circonus_check_force_metric_activation": "", | ||||
| 			"circonus_check_id":                      "", | ||||
| 			"circonus_check_instance_id":             "", | ||||
| 			"circonus_check_search_tag":              "", | ||||
| 			"circonus_submission_url":                "", | ||||
| 			"circonus_check_tags":                    "", | ||||
| 			"circonus_submission_interval":           "", | ||||
| 			"disable_hostname":                       false, | ||||
| 			"dogstatsd_addr":                         "", | ||||
| 			"dogstatsd_tags":                         []string(nil), | ||||
| 			"prometheus_retention_time":              24 * time.Hour, | ||||
| 			"stackdriver_location":                   "", | ||||
| 			"stackdriver_namespace":                  "", | ||||
| 			"stackdriver_project_id":                 "", | ||||
| 			"statsd_address":                         "bar", | ||||
| 			"statsite_address":                       ""}, | ||||
| 	} | ||||
|  | ||||
| 	if diff := deep.Equal(sanitizedConfig, expected); len(diff) > 0 { | ||||
| 		t.Fatalf("bad, diff: %#v", diff) | ||||
| 	} | ||||
| 	testConfig_Sanitized(t) | ||||
| } | ||||
|  | ||||
| func TestParseListeners(t *testing.T) { | ||||
| 	obj, _ := hcl.Parse(strings.TrimSpace(` | ||||
| listener "tcp" { | ||||
| 	address = "127.0.0.1:443" | ||||
| 	cluster_address = "127.0.0.1:8201" | ||||
| 	tls_disable = false | ||||
| 	tls_cert_file = "./certs/server.crt" | ||||
| 	tls_key_file = "./certs/server.key" | ||||
| 	tls_client_ca_file = "./certs/rootca.crt" | ||||
| 	tls_min_version = "tls12" | ||||
| 	tls_require_and_verify_client_cert = true | ||||
| 	tls_disable_client_certs = true | ||||
| }`)) | ||||
|  | ||||
| 	var config Config | ||||
| 	list, _ := obj.Node.(*ast.ObjectList) | ||||
| 	objList := list.Filter("listener") | ||||
| 	parseListeners(&config, objList) | ||||
| 	listeners := config.Listeners | ||||
| 	if len(listeners) == 0 { | ||||
| 		t.Fatalf("expected at least one listener in the config") | ||||
| 	} | ||||
| 	listener := listeners[0] | ||||
| 	if listener.Type != "tcp" { | ||||
| 		t.Fatalf("expected tcp listener in the config") | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address":                            "127.0.0.1:443", | ||||
| 					"cluster_address":                    "127.0.0.1:8201", | ||||
| 					"tls_disable":                        false, | ||||
| 					"tls_cert_file":                      "./certs/server.crt", | ||||
| 					"tls_key_file":                       "./certs/server.key", | ||||
| 					"tls_client_ca_file":                 "./certs/rootca.crt", | ||||
| 					"tls_min_version":                    "tls12", | ||||
| 					"tls_require_and_verify_client_cert": true, | ||||
| 					"tls_disable_client_certs":           true, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	if !reflect.DeepEqual(config, *expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, *expected) | ||||
| 	} | ||||
|  | ||||
| 	testParseListeners(t) | ||||
| } | ||||
|  | ||||
| func TestParseEntropy(t *testing.T){ | ||||
| 	testParseEntropy(t,true) | ||||
| } | ||||
							
								
								
									
										559
									
								
								command/server/config_test_helpers.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										559
									
								
								command/server/config_test_helpers.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,559 @@ | ||||
| package server | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"strings" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/go-test/deep" | ||||
| 	"github.com/hashicorp/hcl" | ||||
| 	"github.com/hashicorp/hcl/hcl/ast" | ||||
| ) | ||||
|  | ||||
| func testLoadConfigFile_topLevel(t *testing.T, entropy *Entropy) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config2.hcl") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type:         "consul", | ||||
| 			RedirectAddr: "top_level_api_addr", | ||||
| 			ClusterAddr:  "top_level_cluster_addr", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		HAStorage: &Storage{ | ||||
| 			Type:         "consul", | ||||
| 			RedirectAddr: "top_level_api_addr", | ||||
| 			ClusterAddr:  "top_level_cluster_addr", | ||||
| 			Config: map[string]string{ | ||||
| 				"bar": "baz", | ||||
| 			}, | ||||
| 			DisableClustering: true, | ||||
| 		}, | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsdAddr:                 "bar", | ||||
| 			StatsiteAddr:               "foo", | ||||
| 			DisableHostname:            false, | ||||
| 			DogStatsDAddr:              "127.0.0.1:7254", | ||||
| 			DogStatsDTags:              []string{"tag_1:val_1", "tag_2:val_2"}, | ||||
| 			PrometheusRetentionTime:    30 * time.Second, | ||||
| 			PrometheusRetentionTimeRaw: "30s", | ||||
| 		}, | ||||
|  | ||||
| 		DisableCache:    true, | ||||
| 		DisableCacheRaw: true, | ||||
| 		DisableMlock:    true, | ||||
| 		DisableMlockRaw: true, | ||||
| 		EnableUI:        true, | ||||
| 		EnableUIRaw:     true, | ||||
|  | ||||
| 		EnableRawEndpoint:    true, | ||||
| 		EnableRawEndpointRaw: true, | ||||
|  | ||||
| 		DisableSealWrap:    true, | ||||
| 		DisableSealWrapRaw: true, | ||||
|  | ||||
| 		MaxLeaseTTL:        10 * time.Hour, | ||||
| 		MaxLeaseTTLRaw:     "10h", | ||||
| 		DefaultLeaseTTL:    10 * time.Hour, | ||||
| 		DefaultLeaseTTLRaw: "10h", | ||||
| 		ClusterName:        "testcluster", | ||||
|  | ||||
| 		PidFile: "./pidfile", | ||||
|  | ||||
| 		APIAddr:     "top_level_api_addr", | ||||
| 		ClusterAddr: "top_level_cluster_addr", | ||||
| 	} | ||||
| 	if entropy != nil { | ||||
| 		expected.Entropy = entropy | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testLoadConfigFile_json2(t *testing.T, entropy *Entropy) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config2.hcl.json") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:444", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type: "consul", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		HAStorage: &Storage{ | ||||
| 			Type: "consul", | ||||
| 			Config: map[string]string{ | ||||
| 				"bar": "baz", | ||||
| 			}, | ||||
| 			DisableClustering: true, | ||||
| 		}, | ||||
|  | ||||
| 		CacheSize: 45678, | ||||
|  | ||||
| 		EnableUI:    true, | ||||
| 		EnableUIRaw: true, | ||||
|  | ||||
| 		EnableRawEndpoint:    true, | ||||
| 		EnableRawEndpointRaw: true, | ||||
|  | ||||
| 		DisableSealWrap:    true, | ||||
| 		DisableSealWrapRaw: true, | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsiteAddr:                       "foo", | ||||
| 			StatsdAddr:                         "bar", | ||||
| 			DisableHostname:                    true, | ||||
| 			CirconusAPIToken:                   "0", | ||||
| 			CirconusAPIApp:                     "vault", | ||||
| 			CirconusAPIURL:                     "http://api.circonus.com/v2", | ||||
| 			CirconusSubmissionInterval:         "10s", | ||||
| 			CirconusCheckSubmissionURL:         "https://someplace.com/metrics", | ||||
| 			CirconusCheckID:                    "0", | ||||
| 			CirconusCheckForceMetricActivation: "true", | ||||
| 			CirconusCheckInstanceID:            "node1:vault", | ||||
| 			CirconusCheckSearchTag:             "service:vault", | ||||
| 			CirconusCheckDisplayName:           "node1:vault", | ||||
| 			CirconusCheckTags:                  "cat1:tag1,cat2:tag2", | ||||
| 			CirconusBrokerID:                   "0", | ||||
| 			CirconusBrokerSelectTag:            "dc:sfo", | ||||
| 			PrometheusRetentionTime:            30 * time.Second, | ||||
| 			PrometheusRetentionTimeRaw:         "30s", | ||||
| 		}, | ||||
| 	} | ||||
| 	if entropy != nil { | ||||
| 		expected.Entropy = entropy | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testParseEntropy(t *testing.T, oss bool) { | ||||
| 	var tests = []struct { | ||||
| 		inConfig   string | ||||
| 		outErr     error | ||||
| 		outEntropy Entropy | ||||
| 	}{ | ||||
| 		{ | ||||
| 			inConfig: `entropy "seal" { | ||||
| 				mode = "augmentation" | ||||
| 				}`, | ||||
| 			outErr:     nil, | ||||
| 			outEntropy: Entropy{Augmentation}, | ||||
| 		}, | ||||
| 		{ | ||||
| 			inConfig: `entropy "seal" { | ||||
| 				mode = "a_mode_that_is_not_supported" | ||||
| 				}`, | ||||
| 			outErr: fmt.Errorf("the specified entropy mode %q is not supported", "a_mode_that_is_not_supported"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			inConfig: `entropy "device_that_is_not_supported" { | ||||
| 				mode = "augmentation" | ||||
| 				}`, | ||||
| 			outErr: fmt.Errorf("only the %q type of external entropy is supported", "seal"), | ||||
| 		}, | ||||
| 		{ | ||||
| 			inConfig: `entropy "seal" { | ||||
| 				mode = "augmentation" | ||||
| 				} | ||||
| 				entropy "seal" { | ||||
| 				mode = "augmentation" | ||||
| 				}`, | ||||
| 			outErr: fmt.Errorf("only one %q block is permitted", "entropy"), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	var config Config | ||||
|  | ||||
| 	for _, test := range tests { | ||||
| 		obj, _ := hcl.Parse(strings.TrimSpace(test.inConfig)) | ||||
| 		list, _ := obj.Node.(*ast.ObjectList) | ||||
| 		objList := list.Filter("entropy") | ||||
| 		err := parseEntropy(&config, objList, "entropy") | ||||
| 		// validate the error, both should be nil or have the same Error() | ||||
| 		switch { | ||||
| 		case oss: | ||||
| 			if config.Entropy != nil { | ||||
| 				t.Fatalf("parsing Entropy should not be possible in oss but got a non-nil config.Entropy: %#v", config.Entropy) | ||||
| 			} | ||||
| 		case err != nil && test.outErr != nil: | ||||
| 			if err.Error() != test.outErr.Error() { | ||||
| 				t.Fatalf("error mismatch: expected %#v got %#v", err, test.outErr) | ||||
| 			} | ||||
| 		case err != test.outErr: | ||||
| 			t.Fatalf("error mismatch: expected %#v got %#v", err, test.outErr) | ||||
| 		case err == nil && config.Entropy != nil && *config.Entropy != test.outEntropy: | ||||
| 			fmt.Printf("\n config.Entropy: %#v",config.Entropy) | ||||
| 			t.Fatalf("entropy config mismatch: expected %#v got %#v", test.outEntropy, *config.Entropy) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testLoadConfigFile(t *testing.T) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config.hcl") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type:         "consul", | ||||
| 			RedirectAddr: "foo", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		HAStorage: &Storage{ | ||||
| 			Type:         "consul", | ||||
| 			RedirectAddr: "snafu", | ||||
| 			Config: map[string]string{ | ||||
| 				"bar": "baz", | ||||
| 			}, | ||||
| 			DisableClustering: true, | ||||
| 		}, | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsdAddr:              "bar", | ||||
| 			StatsiteAddr:            "foo", | ||||
| 			DisableHostname:         false, | ||||
| 			DogStatsDAddr:           "127.0.0.1:7254", | ||||
| 			DogStatsDTags:           []string{"tag_1:val_1", "tag_2:val_2"}, | ||||
| 			PrometheusRetentionTime: prometheusDefaultRetentionTime, | ||||
| 		}, | ||||
|  | ||||
| 		DisableCache:             true, | ||||
| 		DisableCacheRaw:          true, | ||||
| 		DisableMlock:             true, | ||||
| 		DisableMlockRaw:          true, | ||||
| 		DisablePrintableCheckRaw: true, | ||||
| 		DisablePrintableCheck:    true, | ||||
| 		EnableUI:                 true, | ||||
| 		EnableUIRaw:              true, | ||||
|  | ||||
| 		EnableRawEndpoint:    true, | ||||
| 		EnableRawEndpointRaw: true, | ||||
|  | ||||
| 		DisableSealWrap:    true, | ||||
| 		DisableSealWrapRaw: true, | ||||
|  | ||||
| 		Entropy: nil, | ||||
|  | ||||
| 		MaxLeaseTTL:        10 * time.Hour, | ||||
| 		MaxLeaseTTLRaw:     "10h", | ||||
| 		DefaultLeaseTTL:    10 * time.Hour, | ||||
| 		DefaultLeaseTTLRaw: "10h", | ||||
| 		ClusterName:        "testcluster", | ||||
|  | ||||
| 		PidFile: "./pidfile", | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testLoadConfigFile_json(t *testing.T) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config.hcl.json") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type: "consul", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 			DisableClustering: true, | ||||
| 		}, | ||||
|  | ||||
| 		ClusterCipherSuites: "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsiteAddr:                       "baz", | ||||
| 			StatsdAddr:                         "", | ||||
| 			DisableHostname:                    false, | ||||
| 			CirconusAPIToken:                   "", | ||||
| 			CirconusAPIApp:                     "", | ||||
| 			CirconusAPIURL:                     "", | ||||
| 			CirconusSubmissionInterval:         "", | ||||
| 			CirconusCheckSubmissionURL:         "", | ||||
| 			CirconusCheckID:                    "", | ||||
| 			CirconusCheckForceMetricActivation: "", | ||||
| 			CirconusCheckInstanceID:            "", | ||||
| 			CirconusCheckSearchTag:             "", | ||||
| 			CirconusCheckDisplayName:           "", | ||||
| 			CirconusCheckTags:                  "", | ||||
| 			CirconusBrokerID:                   "", | ||||
| 			CirconusBrokerSelectTag:            "", | ||||
| 			PrometheusRetentionTime:            prometheusDefaultRetentionTime, | ||||
| 		}, | ||||
|  | ||||
| 		MaxLeaseTTL:          10 * time.Hour, | ||||
| 		MaxLeaseTTLRaw:       "10h", | ||||
| 		DefaultLeaseTTL:      10 * time.Hour, | ||||
| 		DefaultLeaseTTLRaw:   "10h", | ||||
| 		ClusterName:          "testcluster", | ||||
| 		DisableCacheRaw:      interface{}(nil), | ||||
| 		DisableMlockRaw:      interface{}(nil), | ||||
| 		EnableUI:             true, | ||||
| 		EnableUIRaw:          true, | ||||
| 		PidFile:              "./pidfile", | ||||
| 		EnableRawEndpoint:    true, | ||||
| 		EnableRawEndpointRaw: true, | ||||
| 		DisableSealWrap:      true, | ||||
| 		DisableSealWrapRaw:   true, | ||||
| 		Entropy:              nil, | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testLoadConfigDir(t *testing.T) { | ||||
| 	config, err := LoadConfigDir("./test-fixtures/config-dir") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		DisableCache: true, | ||||
| 		DisableMlock: true, | ||||
|  | ||||
| 		DisableClustering:    false, | ||||
| 		DisableClusteringRaw: false, | ||||
|  | ||||
| 		APIAddr:     "https://vault.local", | ||||
| 		ClusterAddr: "https://127.0.0.1:444", | ||||
|  | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
|  | ||||
| 		Storage: &Storage{ | ||||
| 			Type: "consul", | ||||
| 			Config: map[string]string{ | ||||
| 				"foo": "bar", | ||||
| 			}, | ||||
| 			RedirectAddr:      "https://vault.local", | ||||
| 			ClusterAddr:       "https://127.0.0.1:444", | ||||
| 			DisableClustering: false, | ||||
| 		}, | ||||
|  | ||||
| 		EnableUI: true, | ||||
|  | ||||
| 		EnableRawEndpoint: true, | ||||
|  | ||||
| 		Telemetry: &Telemetry{ | ||||
| 			StatsiteAddr:            "qux", | ||||
| 			StatsdAddr:              "baz", | ||||
| 			DisableHostname:         true, | ||||
| 			PrometheusRetentionTime: prometheusDefaultRetentionTime, | ||||
| 		}, | ||||
|  | ||||
| 		MaxLeaseTTL:     10 * time.Hour, | ||||
| 		DefaultLeaseTTL: 10 * time.Hour, | ||||
| 		ClusterName:     "testcluster", | ||||
| 	} | ||||
| 	if !reflect.DeepEqual(config, expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, expected) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testConfig_Sanitized(t *testing.T) { | ||||
| 	config, err := LoadConfigFile("./test-fixtures/config3.hcl") | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %s", err) | ||||
| 	} | ||||
| 	sanitizedConfig := config.Sanitized() | ||||
|  | ||||
| 	expected := map[string]interface{}{ | ||||
| 		"api_addr":                     "top_level_api_addr", | ||||
| 		"cache_size":                   0, | ||||
| 		"cluster_addr":                 "top_level_cluster_addr", | ||||
| 		"cluster_cipher_suites":        "", | ||||
| 		"cluster_name":                 "testcluster", | ||||
| 		"default_lease_ttl":            10 * time.Hour, | ||||
| 		"default_max_request_duration": 0 * time.Second, | ||||
| 		"disable_cache":                true, | ||||
| 		"disable_clustering":           false, | ||||
| 		"disable_indexing":             false, | ||||
| 		"disable_mlock":                true, | ||||
| 		"disable_performance_standby":  false, | ||||
| 		"disable_printable_check":      false, | ||||
| 		"disable_sealwrap":             true, | ||||
| 		"raw_storage_endpoint":         true, | ||||
| 		"enable_ui":                    true, | ||||
| 		"ha_storage": map[string]interface{}{ | ||||
| 			"cluster_addr":       "top_level_cluster_addr", | ||||
| 			"disable_clustering": true, | ||||
| 			"redirect_addr":      "top_level_api_addr", | ||||
| 			"type":               "consul"}, | ||||
| 		"listeners": []interface{}{ | ||||
| 			map[string]interface{}{ | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"address": "127.0.0.1:443", | ||||
| 				}, | ||||
| 				"type": "tcp", | ||||
| 			}, | ||||
| 		}, | ||||
| 		"log_format":       "", | ||||
| 		"log_level":        "", | ||||
| 		"max_lease_ttl":    10 * time.Hour, | ||||
| 		"pid_file":         "./pidfile", | ||||
| 		"plugin_directory": "", | ||||
| 		"seals": []interface{}{ | ||||
| 			map[string]interface{}{ | ||||
| 				"disabled": false, | ||||
| 				"type":     "awskms", | ||||
| 			}, | ||||
| 		}, | ||||
| 		"storage": map[string]interface{}{ | ||||
| 			"cluster_addr":       "top_level_cluster_addr", | ||||
| 			"disable_clustering": false, | ||||
| 			"redirect_addr":      "top_level_api_addr", | ||||
| 			"type":               "consul", | ||||
| 		}, | ||||
| 		"telemetry": map[string]interface{}{ | ||||
| 			"circonus_api_app":                       "", | ||||
| 			"circonus_api_token":                     "", | ||||
| 			"circonus_api_url":                       "", | ||||
| 			"circonus_broker_id":                     "", | ||||
| 			"circonus_broker_select_tag":             "", | ||||
| 			"circonus_check_display_name":            "", | ||||
| 			"circonus_check_force_metric_activation": "", | ||||
| 			"circonus_check_id":                      "", | ||||
| 			"circonus_check_instance_id":             "", | ||||
| 			"circonus_check_search_tag":              "", | ||||
| 			"circonus_submission_url":                "", | ||||
| 			"circonus_check_tags":                    "", | ||||
| 			"circonus_submission_interval":           "", | ||||
| 			"disable_hostname":                       false, | ||||
| 			"dogstatsd_addr":                         "", | ||||
| 			"dogstatsd_tags":                         []string(nil), | ||||
| 			"prometheus_retention_time":              24 * time.Hour, | ||||
| 			"stackdriver_location":                   "", | ||||
| 			"stackdriver_namespace":                  "", | ||||
| 			"stackdriver_project_id":                 "", | ||||
| 			"statsd_address":                         "bar", | ||||
| 			"statsite_address":                       ""}, | ||||
| 	} | ||||
|  | ||||
| 	if diff := deep.Equal(sanitizedConfig, expected); len(diff) > 0 { | ||||
| 		t.Fatalf("bad, diff: %#v", diff) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func testParseListeners(t *testing.T) { | ||||
| 	obj, _ := hcl.Parse(strings.TrimSpace(` | ||||
| listener "tcp" { | ||||
| 	address = "127.0.0.1:443" | ||||
| 	cluster_address = "127.0.0.1:8201" | ||||
| 	tls_disable = false | ||||
| 	tls_cert_file = "./certs/server.crt" | ||||
| 	tls_key_file = "./certs/server.key" | ||||
| 	tls_client_ca_file = "./certs/rootca.crt" | ||||
| 	tls_min_version = "tls12" | ||||
| 	tls_require_and_verify_client_cert = true | ||||
| 	tls_disable_client_certs = true | ||||
| }`)) | ||||
|  | ||||
| 	var config Config | ||||
| 	list, _ := obj.Node.(*ast.ObjectList) | ||||
| 	objList := list.Filter("listener") | ||||
| 	parseListeners(&config, objList) | ||||
| 	listeners := config.Listeners | ||||
| 	if len(listeners) == 0 { | ||||
| 		t.Fatalf("expected at least one listener in the config") | ||||
| 	} | ||||
| 	listener := listeners[0] | ||||
| 	if listener.Type != "tcp" { | ||||
| 		t.Fatalf("expected tcp listener in the config") | ||||
| 	} | ||||
|  | ||||
| 	expected := &Config{ | ||||
| 		Listeners: []*Listener{ | ||||
| 			&Listener{ | ||||
| 				Type: "tcp", | ||||
| 				Config: map[string]interface{}{ | ||||
| 					"address":                            "127.0.0.1:443", | ||||
| 					"cluster_address":                    "127.0.0.1:8201", | ||||
| 					"tls_disable":                        false, | ||||
| 					"tls_cert_file":                      "./certs/server.crt", | ||||
| 					"tls_key_file":                       "./certs/server.key", | ||||
| 					"tls_client_ca_file":                 "./certs/rootca.crt", | ||||
| 					"tls_min_version":                    "tls12", | ||||
| 					"tls_require_and_verify_client_cert": true, | ||||
| 					"tls_disable_client_certs":           true, | ||||
| 				}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	if !reflect.DeepEqual(config, *expected) { | ||||
| 		t.Fatalf("expected \n\n%#v\n\n to be \n\n%#v\n\n", config, *expected) | ||||
| 	} | ||||
|  | ||||
| } | ||||
							
								
								
									
										13
									
								
								command/server/config_util.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								command/server/config_util.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| package server | ||||
|  | ||||
| import ( | ||||
| 	"github.com/hashicorp/hcl/hcl/ast" | ||||
| ) | ||||
|  | ||||
| var( | ||||
| 	parseEntropy = parseEntropyOSS | ||||
| ) | ||||
|  | ||||
| func parseEntropyOSS(result *Config, list *ast.ObjectList, blockName string) error { | ||||
| 	return nil | ||||
| } | ||||
| @@ -29,6 +29,10 @@ telemetry { | ||||
|     prometheus_retention_time = "30s" | ||||
| } | ||||
|  | ||||
| entropy "seal" { | ||||
|     mode = "augmentation" | ||||
| } | ||||
|  | ||||
| max_lease_ttl = "10h" | ||||
| default_lease_ttl = "10h" | ||||
| cluster_name = "testcluster" | ||||
|   | ||||
| @@ -44,5 +44,10 @@ | ||||
|     "circonus_broker_id": "0", | ||||
|     "circonus_broker_select_tag": "dc:sfo", | ||||
|     "prometheus_retention_time": "30s" | ||||
|   }, | ||||
|   "entropy": { | ||||
|     "seal": { | ||||
|       "mode": "augmentation" | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -2,9 +2,12 @@ package command | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/rand" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
|  | ||||
| 	log "github.com/hashicorp/go-hclog" | ||||
| 	"github.com/hashicorp/vault/command/server" | ||||
| 	"github.com/hashicorp/vault/vault" | ||||
| 	vaultseal "github.com/hashicorp/vault/vault/seal" | ||||
| 	shamirseal "github.com/hashicorp/vault/vault/seal/shamir" | ||||
| @@ -13,8 +16,13 @@ import ( | ||||
|  | ||||
| var ( | ||||
| 	onEnterprise                 = false | ||||
| 	createSecureRandomReaderFunc = createSecureRandomReader | ||||
| ) | ||||
|  | ||||
| func createSecureRandomReader(config *server.Config, seal *vault.Seal) (io.Reader, error) { | ||||
| 	return rand.Reader, nil | ||||
| } | ||||
|  | ||||
| func adjustCoreForSealMigration(logger log.Logger, core *vault.Core, barrierSeal, unwrapSeal vault.Seal) error { | ||||
| 	existBarrierSealConfig, existRecoverySealConfig, err := core.PhysicalSealConfigs(context.Background()) | ||||
| 	if err != nil { | ||||
|   | ||||
							
								
								
									
										7
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								go.mod
									
									
									
									
									
								
							| @@ -25,7 +25,6 @@ require ( | ||||
| 	github.com/aws/aws-sdk-go v1.19.39 | ||||
| 	github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 // indirect | ||||
| 	github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect | ||||
| 	github.com/boombuler/barcode v1.0.0 // indirect | ||||
| 	github.com/chrismalek/oktasdk-go v0.0.0-20181212195951-3430665dfaa0 | ||||
| 	github.com/cockroachdb/apd v1.1.0 // indirect | ||||
| 	github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c | ||||
| @@ -61,7 +60,7 @@ require ( | ||||
| 	github.com/hashicorp/go-rootcerts v1.0.1 | ||||
| 	github.com/hashicorp/go-sockaddr v1.0.2 | ||||
| 	github.com/hashicorp/go-syslog v1.0.0 | ||||
| 	github.com/hashicorp/go-uuid v1.0.1 | ||||
| 	github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8 | ||||
| 	github.com/hashicorp/golang-lru v0.5.3 | ||||
| 	github.com/hashicorp/hcl v1.0.0 | ||||
| 	github.com/hashicorp/nomad/api v0.0.0-20190412184103-1c38ced33adf | ||||
| @@ -81,7 +80,7 @@ require ( | ||||
| 	github.com/hashicorp/vault-plugin-secrets-azure v0.5.2-0.20190814210135-54b8afbc42ae | ||||
| 	github.com/hashicorp/vault-plugin-secrets-gcp v0.5.3-0.20190814210141-d2086ff79b04 | ||||
| 	github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.2-0.20190814210149-315cdbf5de6e | ||||
| 	github.com/hashicorp/vault-plugin-secrets-kv v0.5.2-0.20190814210155-e060c2a001a8 | ||||
| 	github.com/hashicorp/vault-plugin-secrets-kv v0.5.2-0.20191003164552-6600ec024c24 | ||||
| 	github.com/hashicorp/vault/api v1.0.5-0.20190919134245-4eefe0ebe1a1 | ||||
| 	github.com/hashicorp/vault/sdk v0.1.14-0.20190919081434-645ac174deeb | ||||
| 	github.com/influxdata/influxdb v0.0.0-20190411212539-d24b7ba8c4c4 | ||||
| @@ -113,7 +112,7 @@ require ( | ||||
| 	github.com/patrickmn/go-cache v2.1.0+incompatible | ||||
| 	github.com/pkg/errors v0.8.1 | ||||
| 	github.com/posener/complete v1.2.1 | ||||
| 	github.com/pquerna/otp v1.1.0 | ||||
| 	github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d | ||||
| 	github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829 | ||||
| 	github.com/prometheus/common v0.2.0 | ||||
| 	github.com/ryanuber/columnize v2.1.0+incompatible | ||||
|   | ||||
							
								
								
									
										20
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								go.sum
									
									
									
									
									
								
							| @@ -75,8 +75,8 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 h1:DDGfHa7BWjL4Yn | ||||
| github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= | ||||
| github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= | ||||
| github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= | ||||
| github.com/boombuler/barcode v1.0.0 h1:s1TvRnXwL2xJRaccrdcBQMZxq6X7DvsMogtmJeHDdrc= | ||||
| github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= | ||||
| github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= | ||||
| github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= | ||||
| github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= | ||||
| github.com/briankassouf/jose v0.9.2-0.20180619214549-d2569464773f h1:ZMEzE7R0WNqgbHplzSBaYJhJi5AZWTCK9baU0ebzG6g= | ||||
| github.com/briankassouf/jose v0.9.2-0.20180619214549-d2569464773f/go.mod h1:HQhVmdUf7dBNwIIdBTivnCDxcf6IZY3/zrb+uKSJz6Y= | ||||
| @@ -293,8 +293,6 @@ github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uP | ||||
| github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= | ||||
| github.com/hashicorp/go-plugin v1.0.1 h1:4OtAfUGbnKC6yS48p0CtMX2oFYtzFZVv6rok3cRWgnE= | ||||
| github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= | ||||
| github.com/hashicorp/go-raftchunking v0.6.2 h1:imj6CVkwXj6VzgXZQvzS+fSrkbFCzlJ2t00F3PacnuU= | ||||
| github.com/hashicorp/go-raftchunking v0.6.2/go.mod h1:cGlg3JtDy7qy6c/3Bu660Mic1JF+7lWqIwCFSb08fX0= | ||||
| github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a h1:FmnBDwGwlTgugDGbVxwV8UavqSMACbGrUpfc98yFLR4= | ||||
| github.com/hashicorp/go-raftchunking v0.6.3-0.20191002164813-7e9e8525653a/go.mod h1:xbXnmKqX9/+RhPkJ4zrEx4738HacP72aaUPlT2RZ4sU= | ||||
| github.com/hashicorp/go-retryablehttp v0.5.3 h1:QlWt0KvWT0lq8MFppF9tsJGF+ynG7ztc2KIPhzRGk7s= | ||||
| @@ -315,6 +313,8 @@ github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdv | ||||
| github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= | ||||
| github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8 h1:PKbxRbsOP7R3f/TpdqcgXrO69T3yd9nLoR+RMRUxSxA= | ||||
| github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0= | ||||
| github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||
| github.com/hashicorp/go-version v1.2.0 h1:3vNe/fWF5CBgRIguda1meWhsZHy3m8gCJ5wx+dIzX/E= | ||||
| @@ -334,8 +334,6 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p | ||||
| github.com/hashicorp/nomad/api v0.0.0-20190412184103-1c38ced33adf h1:U/40PQvWkaXCDdK9QHKf1pVDVcA+NIDVbzzonFGkgIA= | ||||
| github.com/hashicorp/nomad/api v0.0.0-20190412184103-1c38ced33adf/go.mod h1:BDngVi1f4UA6aJq9WYTgxhfWSE1+42xshvstLU2fRGk= | ||||
| github.com/hashicorp/raft v1.0.1/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI= | ||||
| github.com/hashicorp/raft v1.1.1 h1:HJr7UE1x/JrJSc9Oy6aDBHtNHUUBHjcQjTgvUVihoZs= | ||||
| github.com/hashicorp/raft v1.1.1/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= | ||||
| github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17 h1:p+2EISNdFCnD9R+B4xCiqSn429MCFtvM41aHJDJ6qW4= | ||||
| github.com/hashicorp/raft v1.1.2-0.20191002163536-9c6bd3e3eb17/go.mod h1:vPAJM8Asw6u8LxC3eJCUZmRP/E4QmUGE1R7g7k8sG/8= | ||||
| github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= | ||||
| @@ -363,8 +361,6 @@ github.com/hashicorp/vault-plugin-auth-oci v0.0.0-20190904175623-97c0c0187c5c h1 | ||||
| github.com/hashicorp/vault-plugin-auth-oci v0.0.0-20190904175623-97c0c0187c5c/go.mod h1:YAl51RsYRihPbSdnug1NsvutzbRVfrZ12FjEIvSiOTs= | ||||
| github.com/hashicorp/vault-plugin-database-elasticsearch v0.0.0-20190814210117-e079e01fbb93 h1:kXTV1ImOPgDGZxAlbEQfiXgnZY/34vfgnZVhI/tscmg= | ||||
| github.com/hashicorp/vault-plugin-database-elasticsearch v0.0.0-20190814210117-e079e01fbb93/go.mod h1:N9XpfMXjeLHBgUd8iy4avOC4mCSqUC7B/R8AtCYhcfE= | ||||
| github.com/hashicorp/vault-plugin-secrets-ad v0.5.3-0.20190814210122-0f2fd536b250 h1:+mm2cM5msg/USImbvnMS2yzCMBYMCO3CrvsATWGtHtY= | ||||
| github.com/hashicorp/vault-plugin-secrets-ad v0.5.3-0.20190814210122-0f2fd536b250/go.mod h1:F8hKHqcB7stN2OhnqE3emwFYtKO0IDNxMBbPs2n8vr0= | ||||
| github.com/hashicorp/vault-plugin-secrets-ad v0.6.0 h1:N0AtdV3w6VCtU7rZiTbPxsxhluJXrzpYH9B1pLZhG6g= | ||||
| github.com/hashicorp/vault-plugin-secrets-ad v0.6.0/go.mod h1:qm2QDW9KNY+pFoxBEYGYvcHnVjdiOr3tXeO9DMeo3mI= | ||||
| github.com/hashicorp/vault-plugin-secrets-alicloud v0.5.2-0.20190814210129-4d18bec92f56 h1:PGE26//x1eiAbZ1ExffhKa4y9xgDKLd9BHDZRkOzbEY= | ||||
| @@ -375,8 +371,8 @@ github.com/hashicorp/vault-plugin-secrets-gcp v0.5.3-0.20190814210141-d2086ff79b | ||||
| github.com/hashicorp/vault-plugin-secrets-gcp v0.5.3-0.20190814210141-d2086ff79b04/go.mod h1:Sc+ba3kscakE5a/pi8JJhWvXWok3cpt1P77DApmUuDc= | ||||
| github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.2-0.20190814210149-315cdbf5de6e h1:RjQBOFneGwxhHsymNtbEUJXAjMO74GlZcmUrGqJnYxY= | ||||
| github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.2-0.20190814210149-315cdbf5de6e/go.mod h1:5prAHuCcBiyv+xfGBviTVYeDQUhmQYN7WrxC2gMRWeQ= | ||||
| github.com/hashicorp/vault-plugin-secrets-kv v0.5.2-0.20190814210155-e060c2a001a8 h1:8nZOMqGQQiuWNld162nxUvM4/7EW4NOO9gpyp7LCC84= | ||||
| github.com/hashicorp/vault-plugin-secrets-kv v0.5.2-0.20190814210155-e060c2a001a8/go.mod h1:5ksi71TrWxz7ZRo0MIlsry2lYDlZQyLalN4cF8a4vnk= | ||||
| github.com/hashicorp/vault-plugin-secrets-kv v0.5.2-0.20191003164552-6600ec024c24 h1:ZGxFf28+4ElvBJKPgms5DigDFtPM90QhAif46uPQjVg= | ||||
| github.com/hashicorp/vault-plugin-secrets-kv v0.5.2-0.20191003164552-6600ec024c24/go.mod h1:5ksi71TrWxz7ZRo0MIlsry2lYDlZQyLalN4cF8a4vnk= | ||||
| github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb h1:b5rjCoWHc7eqmAS4/qyk21ZsHyb6Mxv/jykxvNTkU4M= | ||||
| github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= | ||||
| github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= | ||||
| @@ -532,8 +528,8 @@ github.com/posener/complete v1.2.1 h1:LrvDIY//XNo65Lq84G/akBuMGlawHvGBABv8f/ZN6D | ||||
| github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E= | ||||
| github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= | ||||
| github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= | ||||
| github.com/pquerna/otp v1.1.0 h1:q2gMsMuMl3JzneUaAX1MRGxLvOG6bzXV51hivBaStf0= | ||||
| github.com/pquerna/otp v1.1.0/go.mod h1:Zad1CMQfSQZI5KLpahDiSUX4tMMREnXw98IvL1nhgMk= | ||||
| github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d h1:PinQItctnaL2LtkaSM678+ZLLy5TajwOeXzWvYC7tII= | ||||
| github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg= | ||||
| github.com/prometheus/client_golang v0.8.0 h1:1921Yw9Gc3iSc4VQh3PIoOqgPCZS7G/4xQNVUp8Mda8= | ||||
| github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= | ||||
| github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= | ||||
|   | ||||
| @@ -271,6 +271,7 @@ func TestSysMounts_headerAuth(t *testing.T) { | ||||
| 			"secret/": map[string]interface{}{ | ||||
| 				"description": "key/value secret storage", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -283,6 +284,7 @@ func TestSysMounts_headerAuth(t *testing.T) { | ||||
| 			"sys/": map[string]interface{}{ | ||||
| 				"description": "system endpoints used for control, policy and debugging", | ||||
| 				"type":        "system", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl":           json.Number("0"), | ||||
| 					"max_lease_ttl":               json.Number("0"), | ||||
| @@ -296,6 +298,7 @@ func TestSysMounts_headerAuth(t *testing.T) { | ||||
| 			"cubbyhole/": map[string]interface{}{ | ||||
| 				"description": "per-token private secret storage", | ||||
| 				"type":        "cubbyhole", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -308,6 +311,7 @@ func TestSysMounts_headerAuth(t *testing.T) { | ||||
| 			"identity/": map[string]interface{}{ | ||||
| 				"description": "identity store", | ||||
| 				"type":        "identity", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -321,6 +325,7 @@ func TestSysMounts_headerAuth(t *testing.T) { | ||||
| 		"secret/": map[string]interface{}{ | ||||
| 			"description": "key/value secret storage", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -333,6 +338,7 @@ func TestSysMounts_headerAuth(t *testing.T) { | ||||
| 		"sys/": map[string]interface{}{ | ||||
| 			"description": "system endpoints used for control, policy and debugging", | ||||
| 			"type":        "system", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl":           json.Number("0"), | ||||
| 				"max_lease_ttl":               json.Number("0"), | ||||
| @@ -346,6 +352,7 @@ func TestSysMounts_headerAuth(t *testing.T) { | ||||
| 		"cubbyhole/": map[string]interface{}{ | ||||
| 			"description": "per-token private secret storage", | ||||
| 			"type":        "cubbyhole", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -358,6 +365,7 @@ func TestSysMounts_headerAuth(t *testing.T) { | ||||
| 		"identity/": map[string]interface{}{ | ||||
| 			"description": "identity store", | ||||
| 			"type":        "identity", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
|   | ||||
| @@ -29,6 +29,7 @@ func TestSysAuth(t *testing.T) { | ||||
| 			"token/": map[string]interface{}{ | ||||
| 				"description": "token based credentials", | ||||
| 				"type":        "token", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -43,6 +44,7 @@ func TestSysAuth(t *testing.T) { | ||||
| 		"token/": map[string]interface{}{ | ||||
| 			"description": "token based credentials", | ||||
| 			"type":        "token", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -103,6 +105,7 @@ func TestSysEnableAuth(t *testing.T) { | ||||
| 			"foo/": map[string]interface{}{ | ||||
| 				"description": "foo", | ||||
| 				"type":        "noop", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -116,6 +119,7 @@ func TestSysEnableAuth(t *testing.T) { | ||||
| 			"token/": map[string]interface{}{ | ||||
| 				"description": "token based credentials", | ||||
| 				"type":        "token", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -130,6 +134,7 @@ func TestSysEnableAuth(t *testing.T) { | ||||
| 		"foo/": map[string]interface{}{ | ||||
| 			"description": "foo", | ||||
| 			"type":        "noop", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -143,6 +148,7 @@ func TestSysEnableAuth(t *testing.T) { | ||||
| 		"token/": map[string]interface{}{ | ||||
| 			"description": "token based credentials", | ||||
| 			"type":        "token", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -212,6 +218,7 @@ func TestSysDisableAuth(t *testing.T) { | ||||
| 				}, | ||||
| 				"description": "token based credentials", | ||||
| 				"type":        "token", | ||||
| 				"external_entropy_access": false, | ||||
| 				"local":       false, | ||||
| 				"seal_wrap":   false, | ||||
| 				"options":     interface{}(nil), | ||||
| @@ -226,6 +233,7 @@ func TestSysDisableAuth(t *testing.T) { | ||||
| 			}, | ||||
| 			"description": "token based credentials", | ||||
| 			"type":        "token", | ||||
| 			"external_entropy_access": false, | ||||
| 			"local":       false, | ||||
| 			"seal_wrap":   false, | ||||
| 			"options":     interface{}(nil), | ||||
|   | ||||
| @@ -31,6 +31,7 @@ func TestSysMounts(t *testing.T) { | ||||
| 			"secret/": map[string]interface{}{ | ||||
| 				"description": "key/value secret storage", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -43,6 +44,7 @@ func TestSysMounts(t *testing.T) { | ||||
| 			"sys/": map[string]interface{}{ | ||||
| 				"description": "system endpoints used for control, policy and debugging", | ||||
| 				"type":        "system", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl":           json.Number("0"), | ||||
| 					"max_lease_ttl":               json.Number("0"), | ||||
| @@ -56,6 +58,7 @@ func TestSysMounts(t *testing.T) { | ||||
| 			"cubbyhole/": map[string]interface{}{ | ||||
| 				"description": "per-token private secret storage", | ||||
| 				"type":        "cubbyhole", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -68,6 +71,7 @@ func TestSysMounts(t *testing.T) { | ||||
| 			"identity/": map[string]interface{}{ | ||||
| 				"description": "identity store", | ||||
| 				"type":        "identity", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -81,6 +85,7 @@ func TestSysMounts(t *testing.T) { | ||||
| 		"secret/": map[string]interface{}{ | ||||
| 			"description": "key/value secret storage", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -93,6 +98,7 @@ func TestSysMounts(t *testing.T) { | ||||
| 		"sys/": map[string]interface{}{ | ||||
| 			"description": "system endpoints used for control, policy and debugging", | ||||
| 			"type":        "system", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl":           json.Number("0"), | ||||
| 				"max_lease_ttl":               json.Number("0"), | ||||
| @@ -106,6 +112,7 @@ func TestSysMounts(t *testing.T) { | ||||
| 		"cubbyhole/": map[string]interface{}{ | ||||
| 			"description": "per-token private secret storage", | ||||
| 			"type":        "cubbyhole", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -118,6 +125,7 @@ func TestSysMounts(t *testing.T) { | ||||
| 		"identity/": map[string]interface{}{ | ||||
| 			"description": "identity store", | ||||
| 			"type":        "identity", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -178,6 +186,7 @@ func TestSysMount(t *testing.T) { | ||||
| 			"foo/": map[string]interface{}{ | ||||
| 				"description": "foo", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -190,6 +199,7 @@ func TestSysMount(t *testing.T) { | ||||
| 			"secret/": map[string]interface{}{ | ||||
| 				"description": "key/value secret storage", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -202,6 +212,7 @@ func TestSysMount(t *testing.T) { | ||||
| 			"sys/": map[string]interface{}{ | ||||
| 				"description": "system endpoints used for control, policy and debugging", | ||||
| 				"type":        "system", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl":           json.Number("0"), | ||||
| 					"max_lease_ttl":               json.Number("0"), | ||||
| @@ -215,6 +226,7 @@ func TestSysMount(t *testing.T) { | ||||
| 			"cubbyhole/": map[string]interface{}{ | ||||
| 				"description": "per-token private secret storage", | ||||
| 				"type":        "cubbyhole", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -227,6 +239,7 @@ func TestSysMount(t *testing.T) { | ||||
| 			"identity/": map[string]interface{}{ | ||||
| 				"description": "identity store", | ||||
| 				"type":        "identity", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -240,6 +253,7 @@ func TestSysMount(t *testing.T) { | ||||
| 		"foo/": map[string]interface{}{ | ||||
| 			"description": "foo", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -252,6 +266,7 @@ func TestSysMount(t *testing.T) { | ||||
| 		"secret/": map[string]interface{}{ | ||||
| 			"description": "key/value secret storage", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -264,6 +279,7 @@ func TestSysMount(t *testing.T) { | ||||
| 		"sys/": map[string]interface{}{ | ||||
| 			"description": "system endpoints used for control, policy and debugging", | ||||
| 			"type":        "system", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl":           json.Number("0"), | ||||
| 				"max_lease_ttl":               json.Number("0"), | ||||
| @@ -277,6 +293,7 @@ func TestSysMount(t *testing.T) { | ||||
| 		"cubbyhole/": map[string]interface{}{ | ||||
| 			"description": "per-token private secret storage", | ||||
| 			"type":        "cubbyhole", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -289,6 +306,7 @@ func TestSysMount(t *testing.T) { | ||||
| 		"identity/": map[string]interface{}{ | ||||
| 			"description": "identity store", | ||||
| 			"type":        "identity", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -369,6 +387,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 			"bar/": map[string]interface{}{ | ||||
| 				"description": "foo", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -381,6 +400,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 			"secret/": map[string]interface{}{ | ||||
| 				"description": "key/value secret storage", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -393,6 +413,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 			"sys/": map[string]interface{}{ | ||||
| 				"description": "system endpoints used for control, policy and debugging", | ||||
| 				"type":        "system", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl":           json.Number("0"), | ||||
| 					"max_lease_ttl":               json.Number("0"), | ||||
| @@ -406,6 +427,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 			"cubbyhole/": map[string]interface{}{ | ||||
| 				"description": "per-token private secret storage", | ||||
| 				"type":        "cubbyhole", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -418,6 +440,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 			"identity/": map[string]interface{}{ | ||||
| 				"description": "identity store", | ||||
| 				"type":        "identity", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -431,6 +454,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 		"bar/": map[string]interface{}{ | ||||
| 			"description": "foo", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -443,6 +467,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 		"secret/": map[string]interface{}{ | ||||
| 			"description": "key/value secret storage", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -455,6 +480,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 		"sys/": map[string]interface{}{ | ||||
| 			"description": "system endpoints used for control, policy and debugging", | ||||
| 			"type":        "system", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl":           json.Number("0"), | ||||
| 				"max_lease_ttl":               json.Number("0"), | ||||
| @@ -468,6 +494,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 		"cubbyhole/": map[string]interface{}{ | ||||
| 			"description": "per-token private secret storage", | ||||
| 			"type":        "cubbyhole", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -480,6 +507,7 @@ func TestSysRemount(t *testing.T) { | ||||
| 		"identity/": map[string]interface{}{ | ||||
| 			"description": "identity store", | ||||
| 			"type":        "identity", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -540,6 +568,7 @@ func TestSysUnmount(t *testing.T) { | ||||
| 			"secret/": map[string]interface{}{ | ||||
| 				"description": "key/value secret storage", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -552,6 +581,7 @@ func TestSysUnmount(t *testing.T) { | ||||
| 			"sys/": map[string]interface{}{ | ||||
| 				"description": "system endpoints used for control, policy and debugging", | ||||
| 				"type":        "system", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl":           json.Number("0"), | ||||
| 					"max_lease_ttl":               json.Number("0"), | ||||
| @@ -565,6 +595,7 @@ func TestSysUnmount(t *testing.T) { | ||||
| 			"cubbyhole/": map[string]interface{}{ | ||||
| 				"description": "per-token private secret storage", | ||||
| 				"type":        "cubbyhole", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -577,6 +608,7 @@ func TestSysUnmount(t *testing.T) { | ||||
| 			"identity/": map[string]interface{}{ | ||||
| 				"description": "identity store", | ||||
| 				"type":        "identity", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -590,6 +622,7 @@ func TestSysUnmount(t *testing.T) { | ||||
| 		"secret/": map[string]interface{}{ | ||||
| 			"description": "key/value secret storage", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -602,6 +635,7 @@ func TestSysUnmount(t *testing.T) { | ||||
| 		"sys/": map[string]interface{}{ | ||||
| 			"description": "system endpoints used for control, policy and debugging", | ||||
| 			"type":        "system", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl":           json.Number("0"), | ||||
| 				"max_lease_ttl":               json.Number("0"), | ||||
| @@ -615,6 +649,7 @@ func TestSysUnmount(t *testing.T) { | ||||
| 		"cubbyhole/": map[string]interface{}{ | ||||
| 			"description": "per-token private secret storage", | ||||
| 			"type":        "cubbyhole", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -627,6 +662,7 @@ func TestSysUnmount(t *testing.T) { | ||||
| 		"identity/": map[string]interface{}{ | ||||
| 			"description": "identity store", | ||||
| 			"type":        "identity", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -769,6 +805,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"foo/": map[string]interface{}{ | ||||
| 				"description": "foo", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -781,6 +818,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"secret/": map[string]interface{}{ | ||||
| 				"description": "key/value secret storage", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -793,6 +831,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"sys/": map[string]interface{}{ | ||||
| 				"description": "system endpoints used for control, policy and debugging", | ||||
| 				"type":        "system", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl":           json.Number("0"), | ||||
| 					"max_lease_ttl":               json.Number("0"), | ||||
| @@ -806,6 +845,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"cubbyhole/": map[string]interface{}{ | ||||
| 				"description": "per-token private secret storage", | ||||
| 				"type":        "cubbyhole", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -818,6 +858,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"identity/": map[string]interface{}{ | ||||
| 				"description": "identity store", | ||||
| 				"type":        "identity", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -831,6 +872,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"foo/": map[string]interface{}{ | ||||
| 			"description": "foo", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -843,6 +885,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"secret/": map[string]interface{}{ | ||||
| 			"description": "key/value secret storage", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -855,6 +898,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"sys/": map[string]interface{}{ | ||||
| 			"description": "system endpoints used for control, policy and debugging", | ||||
| 			"type":        "system", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl":           json.Number("0"), | ||||
| 				"max_lease_ttl":               json.Number("0"), | ||||
| @@ -868,6 +912,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"cubbyhole/": map[string]interface{}{ | ||||
| 			"description": "per-token private secret storage", | ||||
| 			"type":        "cubbyhole", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -880,6 +925,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"identity/": map[string]interface{}{ | ||||
| 			"description": "identity store", | ||||
| 			"type":        "identity", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -966,6 +1012,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"foo/": map[string]interface{}{ | ||||
| 				"description": "foo", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("259196400"), | ||||
| 					"max_lease_ttl":     json.Number("259200000"), | ||||
| @@ -978,6 +1025,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"secret/": map[string]interface{}{ | ||||
| 				"description": "key/value secret storage", | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -990,6 +1038,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"sys/": map[string]interface{}{ | ||||
| 				"description": "system endpoints used for control, policy and debugging", | ||||
| 				"type":        "system", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl":           json.Number("0"), | ||||
| 					"max_lease_ttl":               json.Number("0"), | ||||
| @@ -1003,6 +1052,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"cubbyhole/": map[string]interface{}{ | ||||
| 				"description": "per-token private secret storage", | ||||
| 				"type":        "cubbyhole", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -1015,6 +1065,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 			"identity/": map[string]interface{}{ | ||||
| 				"description": "identity store", | ||||
| 				"type":        "identity", | ||||
| 				"external_entropy_access": false, | ||||
| 				"config": map[string]interface{}{ | ||||
| 					"default_lease_ttl": json.Number("0"), | ||||
| 					"max_lease_ttl":     json.Number("0"), | ||||
| @@ -1028,6 +1079,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"foo/": map[string]interface{}{ | ||||
| 			"description": "foo", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("259196400"), | ||||
| 				"max_lease_ttl":     json.Number("259200000"), | ||||
| @@ -1040,6 +1092,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"secret/": map[string]interface{}{ | ||||
| 			"description": "key/value secret storage", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -1052,6 +1105,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"sys/": map[string]interface{}{ | ||||
| 			"description": "system endpoints used for control, policy and debugging", | ||||
| 			"type":        "system", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl":           json.Number("0"), | ||||
| 				"max_lease_ttl":               json.Number("0"), | ||||
| @@ -1065,6 +1119,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"cubbyhole/": map[string]interface{}{ | ||||
| 			"description": "per-token private secret storage", | ||||
| 			"type":        "cubbyhole", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
| @@ -1077,6 +1132,7 @@ func TestSysTuneMount(t *testing.T) { | ||||
| 		"identity/": map[string]interface{}{ | ||||
| 			"description": "identity store", | ||||
| 			"type":        "identity", | ||||
| 			"external_entropy_access": false, | ||||
| 			"config": map[string]interface{}{ | ||||
| 				"default_lease_ttl": json.Number("0"), | ||||
| 				"max_lease_ttl":     json.Number("0"), | ||||
|   | ||||
| @@ -11,6 +11,7 @@ import ( | ||||
| 	"crypto/x509/pkix" | ||||
| 	"errors" | ||||
| 	fmt "fmt" | ||||
| 	"io" | ||||
| 	"math/big" | ||||
| 	mathrand "math/rand" | ||||
| 	"net" | ||||
| @@ -86,8 +87,8 @@ func (k *TLSKeyring) GetActive() *TLSKey { | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func GenerateTLSKey() (*TLSKey, error) { | ||||
| 	key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) | ||||
| func GenerateTLSKey(reader io.Reader) (*TLSKey, error) { | ||||
| 	key, err := ecdsa.GenerateKey(elliptic.P521(), reader) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
| @@ -2,7 +2,9 @@ package framework | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/rand" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"regexp" | ||||
| @@ -14,6 +16,7 @@ import ( | ||||
| 	"github.com/hashicorp/errwrap" | ||||
| 	log "github.com/hashicorp/go-hclog" | ||||
| 	multierror "github.com/hashicorp/go-multierror" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/entropy" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/errutil" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/license" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/logging" | ||||
| @@ -279,6 +282,17 @@ func (b *Backend) Setup(ctx context.Context, config *logical.BackendConfig) erro | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // GetRandomReader returns an io.Reader to use for generating key material in | ||||
| // backends. If the backend has access to an external entropy source it will | ||||
| // return that, otherwise it returns crypto/rand.Reader. | ||||
| func (b *Backend) GetRandomReader() io.Reader { | ||||
| 	if sourcer, ok := b.System().(entropy.Sourcer); ok { | ||||
| 		return entropy.NewReader(sourcer) | ||||
| 	} | ||||
|  | ||||
| 	return rand.Reader | ||||
| } | ||||
|  | ||||
| // Logger can be used to get the logger. If no logger has been set, | ||||
| // the logs will be discarded. | ||||
| func (b *Backend) Logger() log.Logger { | ||||
|   | ||||
| @@ -16,7 +16,7 @@ require ( | ||||
| 	github.com/hashicorp/go-multierror v1.0.0 | ||||
| 	github.com/hashicorp/go-plugin v1.0.1 | ||||
| 	github.com/hashicorp/go-sockaddr v1.0.2 | ||||
| 	github.com/hashicorp/go-uuid v1.0.1 | ||||
| 	github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8 | ||||
| 	github.com/hashicorp/go-version v1.1.0 | ||||
| 	github.com/hashicorp/golang-lru v0.5.1 | ||||
| 	github.com/hashicorp/hcl v1.0.0 | ||||
|   | ||||
| @@ -44,6 +44,7 @@ github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjG | ||||
| github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE= | ||||
| github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-version v1.1.0 h1:bPIoEKD27tNdebFGGxxYwcL4nepeY4j1QP23PFRGzg0= | ||||
| github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
|   | ||||
| @@ -3,7 +3,9 @@ | ||||
| package base62 | ||||
|  | ||||
| import ( | ||||
| 	"crypto/rand" | ||||
| 	uuid "github.com/hashicorp/go-uuid" | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" | ||||
| @@ -12,6 +14,12 @@ const csLen = byte(len(charset)) | ||||
| // Random generates a random string using base-62 characters. | ||||
| // Resulting entropy is ~5.95 bits/character. | ||||
| func Random(length int) (string, error) { | ||||
| 	return RandomWithReader(length, rand.Reader) | ||||
| } | ||||
|  | ||||
| // RandomWithReader generates a random string using base-62 characters and a given reader. | ||||
| // Resulting entropy is ~5.95 bits/character. | ||||
| func RandomWithReader(length int, reader io.Reader) (string, error) { | ||||
| 	if length == 0 { | ||||
| 		return "", nil | ||||
| 	} | ||||
| @@ -22,7 +30,7 @@ func Random(length int) (string, error) { | ||||
| 	batchSize := length + length/4 | ||||
|  | ||||
| 	for { | ||||
| 		buf, err := uuid.GenerateRandomBytes(batchSize) | ||||
| 		buf, err := uuid.GenerateRandomBytesWithReader(batchSize, reader) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										36
									
								
								sdk/helper/entropy/entropy.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								sdk/helper/entropy/entropy.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| package entropy | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/hashicorp/errwrap" | ||||
| ) | ||||
|  | ||||
| type Sourcer interface { | ||||
| 	GetRandom(bytes int) ([]byte, error) | ||||
| } | ||||
|  | ||||
| type Reader struct { | ||||
| 	source Sourcer | ||||
| } | ||||
|  | ||||
| func NewReader(source Sourcer) *Reader{ | ||||
| 	return &Reader{source} | ||||
| } | ||||
|  | ||||
| // Read reads exactly len(p) bytes from r into p. | ||||
| // If r returns an error having read at least len(p) bytes, the error is dropped. | ||||
| // It returns the number of bytes copied and an error if fewer bytes were read. | ||||
| // On return, n == len(p) if and only if err == nil. | ||||
| func (r *Reader) Read(p []byte) (n int, err error){ | ||||
| 	requested := len(p) | ||||
| 	randBytes, err := r.source.GetRandom(requested) | ||||
| 	delivered := copy(p, randBytes) | ||||
| 	if delivered != requested { | ||||
| 		if err != nil { | ||||
| 			return delivered, errwrap.Wrapf("unable to fill provided buffer with entropy: {{err}}", err) | ||||
| 		} | ||||
| 		return delivered, fmt.Errorf("unable to fill provided buffer with entropy") | ||||
| 	} | ||||
|  | ||||
| 	return delivered, nil | ||||
| } | ||||
							
								
								
									
										87
									
								
								sdk/helper/entropy/entropy_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								sdk/helper/entropy/entropy_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
| package entropy | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"github.com/hashicorp/errwrap" | ||||
| 	"testing" | ||||
| ) | ||||
|  | ||||
| type mockSourcer struct{} | ||||
| type mockSourcerWithError struct{} | ||||
| type mockSourcerFailureWithError struct{} | ||||
| type mockSourcerFailureWithoutError struct{} | ||||
|  | ||||
| // simulates a successful sourcer | ||||
| func (m *mockSourcer) GetRandom(bytes int) ([]byte, error) { | ||||
| 	return make([]byte, bytes), nil | ||||
| } | ||||
|  | ||||
| // simulates a sourcer that reads in the requested number of bytes but encounters an error. | ||||
| // Read should drop any error if the number of bytes specified were successfully read. | ||||
| func (m *mockSourcerWithError) GetRandom(bytes int) ([]byte, error) { | ||||
| 	return make([]byte, bytes), errors.New("boom but you shouldn't care") | ||||
| } | ||||
|  | ||||
| func (m *mockSourcerFailureWithError) GetRandom(bytes int) ([]byte, error) { | ||||
| 	numRetBytes := bytes - 1 | ||||
| 	return make([]byte, numRetBytes), fmt.Errorf("requested %d bytes of entropy but only filled %d", bytes, numRetBytes) | ||||
| } | ||||
|  | ||||
| func (m *mockSourcerFailureWithoutError) GetRandom(bytes int) ([]byte, error) { | ||||
| 	numRetBytes := bytes - 1 | ||||
| 	return make([]byte, numRetBytes), nil | ||||
| } | ||||
|  | ||||
| func TestRead(t *testing.T) { | ||||
| 	var tests = []struct { | ||||
| 		sourcer      Sourcer | ||||
| 		preReadBuff  []byte | ||||
| 		postReadBuff []byte | ||||
| 		outErr       error | ||||
| 	}{ | ||||
| 		{ | ||||
| 			new(mockSourcer), | ||||
| 			[]byte{1, 2, 3, 4}, | ||||
| 			[]byte{0, 0, 0, 0}, | ||||
| 			nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			new(mockSourcerWithError), | ||||
| 			[]byte{1, 2, 3, 4}, | ||||
| 			[]byte{0, 0, 0, 0}, | ||||
| 			nil, | ||||
| 		}, | ||||
| 		{ | ||||
| 			new(mockSourcerFailureWithError), | ||||
| 			[]byte{1, 2, 3, 4}, | ||||
| 			nil, | ||||
| 			errwrap.Wrapf("unable to fill provided buffer with entropy: {{err}}", fmt.Errorf("requested %d bytes of entropy but only filled %d", 4, 3)), | ||||
| 		}, | ||||
| 		{ | ||||
| 			new(mockSourcerFailureWithoutError), | ||||
| 			[]byte{1, 2, 3, 4}, | ||||
| 			nil, | ||||
| 			fmt.Errorf("unable to fill provided buffer with entropy"), | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for _, test := range tests { | ||||
| 		mockReader := NewReader(test.sourcer) | ||||
| 		buff := make([]byte, len(test.preReadBuff)) | ||||
| 		copy(buff, test.preReadBuff) | ||||
| 		_, err := mockReader.Read(buff) | ||||
| 		// validate the error, both should be nil or have the same Error() | ||||
| 		switch { | ||||
| 		case err != nil && test.outErr != nil: | ||||
| 			if err.Error() != test.outErr.Error() { | ||||
| 				t.Fatalf("error mismatch: expected %#v got %#v", err, test.outErr) | ||||
| 			} | ||||
| 		case err != test.outErr: | ||||
| 			t.Fatalf("error mismatch: expected %#v got %#v", err, test.outErr) | ||||
| 		case err == nil && !bytes.Equal(buff, test.postReadBuff): | ||||
| 			t.Fatalf("after read expected buff to be: %#v but got: %#v", test.postReadBuff, buff) | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| @@ -2,6 +2,7 @@ package keysutil | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/rand" | ||||
| 	"fmt" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| @@ -77,7 +78,7 @@ func TestEncryptedKeysStorage_List(t *testing.T) { | ||||
|  | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	err := policy.Rotate(ctx, s) | ||||
| 	err := policy.Rotate(ctx, s, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -159,7 +160,7 @@ func TestEncryptedKeysStorage_CRUD(t *testing.T) { | ||||
|  | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	err := policy.Rotate(ctx, s) | ||||
| 	err := policy.Rotate(ctx, s, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -249,7 +250,7 @@ func BenchmarkEncrytedKeyStorage_List(b *testing.B) { | ||||
|  | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	err := policy.Rotate(ctx, s) | ||||
| 	err := policy.Rotate(ctx, s, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		b.Fatal(err) | ||||
| 	} | ||||
| @@ -295,7 +296,7 @@ func BenchmarkEncrytedKeyStorage_Put(b *testing.B) { | ||||
|  | ||||
| 	ctx := context.Background() | ||||
|  | ||||
| 	err := policy.Rotate(ctx, s) | ||||
| 	err := policy.Rotate(ctx, s, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		b.Fatal(err) | ||||
| 	} | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import ( | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
| 	"time" | ||||
| @@ -249,7 +250,7 @@ func (lm *LockManager) BackupPolicy(ctx context.Context, storage logical.Storage | ||||
|  | ||||
| // When the function returns, if caching was disabled, the Policy's lock must | ||||
| // be unlocked when the caller is done (and it should not be re-locked). | ||||
| func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest) (retP *Policy, retUpserted bool, retErr error) { | ||||
| func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io.Reader) (retP *Policy, retUpserted bool, retErr error) { | ||||
| 	var p *Policy | ||||
| 	var err error | ||||
| 	var ok bool | ||||
| @@ -379,7 +380,7 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest) (retP * | ||||
| 		} | ||||
|  | ||||
| 		// Performs the actual persist and does setup | ||||
| 		err = p.Rotate(ctx, req.Storage) | ||||
| 		err = p.Rotate(ctx, req.Storage, rand) | ||||
| 		if err != nil { | ||||
| 			cleanup() | ||||
| 			return nil, false, err | ||||
| @@ -400,7 +401,7 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest) (retP * | ||||
| 	} | ||||
|  | ||||
| 	if p.NeedsUpgrade() { | ||||
| 		if err := p.Upgrade(ctx, req.Storage); err != nil { | ||||
| 		if err := p.Upgrade(ctx, req.Storage, rand); err != nil { | ||||
| 			cleanup() | ||||
| 			return nil, false, err | ||||
| 		} | ||||
|   | ||||
| @@ -613,7 +613,7 @@ func (p *Policy) NeedsUpgrade() bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (p *Policy) Upgrade(ctx context.Context, storage logical.Storage) (retErr error) { | ||||
| func (p *Policy) Upgrade(ctx context.Context, storage logical.Storage, randReader io.Reader) (retErr error) { | ||||
| 	priorKey := p.Key | ||||
| 	priorLatestVersion := p.LatestVersion | ||||
| 	priorMinDecryptionVersion := p.MinDecryptionVersion | ||||
| @@ -670,7 +670,7 @@ func (p *Policy) Upgrade(ctx context.Context, storage logical.Storage) (retErr e | ||||
|  | ||||
| 	if p.Keys[strconv.Itoa(p.LatestVersion)].HMACKey == nil || len(p.Keys[strconv.Itoa(p.LatestVersion)].HMACKey) == 0 { | ||||
| 		entry := p.Keys[strconv.Itoa(p.LatestVersion)] | ||||
| 		hmacKey, err := uuid.GenerateRandomBytes(32) | ||||
| 		hmacKey, err := uuid.GenerateRandomBytesWithReader(32, randReader) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -1371,7 +1371,7 @@ func (p *Policy) VerifySignature(context, input []byte, hashAlgorithm HashType, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr error) { | ||||
| func (p *Policy) Rotate(ctx context.Context, storage logical.Storage, randReader io.Reader) (retErr error) { | ||||
| 	priorLatestVersion := p.LatestVersion | ||||
| 	priorMinDecryptionVersion := p.MinDecryptionVersion | ||||
| 	var priorKeys keyEntryMap | ||||
| @@ -1405,7 +1405,7 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr er | ||||
| 		DeprecatedCreationTime: now.Unix(), | ||||
| 	} | ||||
|  | ||||
| 	hmacKey, err := uuid.GenerateRandomBytes(32) | ||||
| 	hmacKey, err := uuid.GenerateRandomBytesWithReader(32, randReader) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -1418,7 +1418,7 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr er | ||||
| 		if p.Type == KeyType_AES128_GCM96 { | ||||
| 			numBytes = 16 | ||||
| 		} | ||||
| 		newKey, err := uuid.GenerateRandomBytes(numBytes) | ||||
| 		newKey, err := uuid.GenerateRandomBytesWithReader(numBytes, randReader) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -1457,7 +1457,7 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr er | ||||
| 		entry.FormattedPublicKey = string(pemBytes) | ||||
|  | ||||
| 	case KeyType_ED25519: | ||||
| 		pub, pri, err := ed25519.GenerateKey(rand.Reader) | ||||
| 		pub, pri, err := ed25519.GenerateKey(randReader) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -1470,7 +1470,7 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr er | ||||
| 			bitSize = 4096 | ||||
| 		} | ||||
|  | ||||
| 		entry.RSAKey, err = rsa.GenerateKey(rand.Reader, bitSize) | ||||
| 		entry.RSAKey, err = rsa.GenerateKey(randReader, bitSize) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import ( | ||||
| 	"sync" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| 	"crypto/rand" | ||||
|  | ||||
| 	"github.com/hashicorp/vault/sdk/helper/jsonutil" | ||||
| 	"github.com/hashicorp/vault/sdk/logical" | ||||
| @@ -67,7 +68,7 @@ func testKeyUpgradeCommon(t *testing.T, lm *LockManager) { | ||||
| 		Storage: storage, | ||||
| 		KeyType: KeyType_AES256_GCM96, | ||||
| 		Name:    "test", | ||||
| 	}) | ||||
| 	}, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -119,7 +120,7 @@ func testArchivingUpgradeCommon(t *testing.T, lm *LockManager) { | ||||
| 		Storage: storage, | ||||
| 		KeyType: KeyType_AES256_GCM96, | ||||
| 		Name:    "test", | ||||
| 	}) | ||||
| 	}, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -135,7 +136,7 @@ func testArchivingUpgradeCommon(t *testing.T, lm *LockManager) { | ||||
| 	checkKeys(t, ctx, p, storage, keysArchive, "initial", 1, 1, 1) | ||||
|  | ||||
| 	for i := 2; i <= 10; i++ { | ||||
| 		err = p.Rotate(ctx, storage) | ||||
| 		err = p.Rotate(ctx, storage, rand.Reader) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| @@ -176,7 +177,7 @@ func testArchivingUpgradeCommon(t *testing.T, lm *LockManager) { | ||||
| 	p, _, err = lm.GetPolicy(ctx, PolicyRequest{ | ||||
| 		Storage: storage, | ||||
| 		Name:    "test", | ||||
| 	}) | ||||
| 	}, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -216,7 +217,7 @@ func testArchivingUpgradeCommon(t *testing.T, lm *LockManager) { | ||||
| 	p, _, err = lm.GetPolicy(ctx, PolicyRequest{ | ||||
| 		Storage: storage, | ||||
| 		Name:    "test", | ||||
| 	}) | ||||
| 	}, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -249,7 +250,7 @@ func testArchivingUpgradeCommon(t *testing.T, lm *LockManager) { | ||||
| 	p, _, err = lm.GetPolicy(ctx, PolicyRequest{ | ||||
| 		Storage: storage, | ||||
| 		Name:    "test", | ||||
| 	}) | ||||
| 	}, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -279,7 +280,7 @@ func testArchivingCommon(t *testing.T, lm *LockManager) { | ||||
| 		Storage: storage, | ||||
| 		KeyType: KeyType_AES256_GCM96, | ||||
| 		Name:    "test", | ||||
| 	}) | ||||
| 	}, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -295,7 +296,7 @@ func testArchivingCommon(t *testing.T, lm *LockManager) { | ||||
| 	checkKeys(t, ctx, p, storage, keysArchive, "initial", 1, 1, 1) | ||||
|  | ||||
| 	for i := 2; i <= 10; i++ { | ||||
| 		err = p.Rotate(ctx, storage) | ||||
| 		err = p.Rotate(ctx, storage, rand.Reader) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| @@ -433,7 +434,7 @@ func Test_StorageErrorSafety(t *testing.T) { | ||||
| 		Storage: storage, | ||||
| 		KeyType: KeyType_AES256_GCM96, | ||||
| 		Name:    "test", | ||||
| 	}) | ||||
| 	}, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -448,7 +449,7 @@ func Test_StorageErrorSafety(t *testing.T) { | ||||
| 	// We use checkKeys here just for sanity; it doesn't really handle cases of | ||||
| 	// errors below so we do more targeted testing later | ||||
| 	for i := 2; i <= 5; i++ { | ||||
| 		err = p.Rotate(ctx, storage) | ||||
| 		err = p.Rotate(ctx, storage, rand.Reader) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
| @@ -461,7 +462,7 @@ func Test_StorageErrorSafety(t *testing.T) { | ||||
|  | ||||
| 	priorLen := len(p.Keys) | ||||
|  | ||||
| 	err = p.Rotate(ctx, storage) | ||||
| 	err = p.Rotate(ctx, storage, rand.Reader) | ||||
| 	if err == nil { | ||||
| 		t.Fatal("expected error") | ||||
| 	} | ||||
| @@ -480,7 +481,7 @@ func Test_BadUpgrade(t *testing.T) { | ||||
| 		Storage: storage, | ||||
| 		KeyType: KeyType_AES256_GCM96, | ||||
| 		Name:    "test", | ||||
| 	}) | ||||
| 	}, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -498,7 +499,7 @@ func Test_BadUpgrade(t *testing.T) { | ||||
| 	p.Keys = nil | ||||
| 	p.MinDecryptionVersion = 0 | ||||
|  | ||||
| 	if err := p.Upgrade(ctx, storage); err != nil { | ||||
| 	if err := p.Upgrade(ctx, storage, rand.Reader); err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
|  | ||||
| @@ -521,7 +522,7 @@ func Test_BadUpgrade(t *testing.T) { | ||||
| 	p.Keys = nil | ||||
| 	p.MinDecryptionVersion = 0 | ||||
|  | ||||
| 	if err := p.Upgrade(ctx, storage); err == nil { | ||||
| 	if err := p.Upgrade(ctx, storage, rand.Reader); err == nil { | ||||
| 		t.Fatal("expected error") | ||||
| 	} | ||||
|  | ||||
| @@ -545,7 +546,7 @@ func Test_BadArchive(t *testing.T) { | ||||
| 		Storage: storage, | ||||
| 		KeyType: KeyType_AES256_GCM96, | ||||
| 		Name:    "test", | ||||
| 	}) | ||||
| 	}, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatal(err) | ||||
| 	} | ||||
| @@ -554,7 +555,7 @@ func Test_BadArchive(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	for i := 2; i <= 10; i++ { | ||||
| 		err = p.Rotate(ctx, storage) | ||||
| 		err = p.Rotate(ctx, storage, rand.Reader) | ||||
| 		if err != nil { | ||||
| 			t.Fatal(err) | ||||
| 		} | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package vault | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"io" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/hashicorp/vault/sdk/logical" | ||||
| @@ -69,10 +70,10 @@ type SecurityBarrier interface { | ||||
|  | ||||
| 	// Initialize works only if the barrier has not been initialized | ||||
| 	// and makes use of the given master key. | ||||
| 	Initialize(context.Context, []byte) error | ||||
| 	Initialize(context.Context, []byte, io.Reader) error | ||||
|  | ||||
| 	// GenerateKey is used to generate a new key | ||||
| 	GenerateKey() ([]byte, error) | ||||
| 	GenerateKey(io.Reader) ([]byte, error) | ||||
|  | ||||
| 	// KeyLength is used to sanity check a key | ||||
| 	KeyLength() (int, int) | ||||
| @@ -109,7 +110,7 @@ type SecurityBarrier interface { | ||||
|  | ||||
| 	// Rotate is used to create a new encryption key. All future writes | ||||
| 	// should use the new key, while old values should still be decryptable. | ||||
| 	Rotate(ctx context.Context) (uint32, error) | ||||
| 	Rotate(ctx context.Context, reader io.Reader) (uint32, error) | ||||
|  | ||||
| 	// CreateUpgrade creates an upgrade path key to the given term from the previous term | ||||
| 	CreateUpgrade(ctx context.Context, term uint32) error | ||||
|   | ||||
| @@ -9,6 +9,7 @@ import ( | ||||
| 	"encoding/binary" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"time" | ||||
| @@ -114,7 +115,7 @@ func (b *AESGCMBarrier) Initialized(ctx context.Context) (bool, error) { | ||||
|  | ||||
| // Initialize works only if the barrier has not been initialized | ||||
| // and makes use of the given master key. | ||||
| func (b *AESGCMBarrier) Initialize(ctx context.Context, key []byte) error { | ||||
| func (b *AESGCMBarrier) Initialize(ctx context.Context, key []byte, reader io.Reader) error { | ||||
| 	// Verify the key size | ||||
| 	min, max := b.KeyLength() | ||||
| 	if len(key) < min || len(key) > max { | ||||
| @@ -129,7 +130,7 @@ func (b *AESGCMBarrier) Initialize(ctx context.Context, key []byte) error { | ||||
| 	} | ||||
|  | ||||
| 	// Generate encryption key | ||||
| 	encrypt, err := b.GenerateKey() | ||||
| 	encrypt, err := b.GenerateKey(reader) | ||||
| 	if err != nil { | ||||
| 		return errwrap.Wrapf("failed to generate encryption key: {{err}}", err) | ||||
| 	} | ||||
| @@ -214,10 +215,11 @@ func (b *AESGCMBarrier) persistKeyring(ctx context.Context, keyring *Keyring) er | ||||
| } | ||||
|  | ||||
| // GenerateKey is used to generate a new key | ||||
| func (b *AESGCMBarrier) GenerateKey() ([]byte, error) { | ||||
| func (b *AESGCMBarrier) GenerateKey(reader io.Reader) ([]byte, error) { | ||||
| 	// Generate a 256bit key | ||||
| 	buf := make([]byte, 2*aes.BlockSize) | ||||
| 	_, err := rand.Read(buf) | ||||
| 	_, err := reader.Read(buf) | ||||
|  | ||||
| 	return buf, err | ||||
| } | ||||
|  | ||||
| @@ -478,7 +480,7 @@ func (b *AESGCMBarrier) Seal() error { | ||||
|  | ||||
| // Rotate is used to create a new encryption key. All future writes | ||||
| // should use the new key, while old values should still be decryptable. | ||||
| func (b *AESGCMBarrier) Rotate(ctx context.Context) (uint32, error) { | ||||
| func (b *AESGCMBarrier) Rotate(ctx context.Context, reader io.Reader) (uint32, error) { | ||||
| 	b.l.Lock() | ||||
| 	defer b.l.Unlock() | ||||
| 	if b.sealed { | ||||
| @@ -486,7 +488,7 @@ func (b *AESGCMBarrier) Rotate(ctx context.Context) (uint32, error) { | ||||
| 	} | ||||
|  | ||||
| 	// Generate a new key | ||||
| 	encrypt, err := b.GenerateKey() | ||||
| 	encrypt, err := b.GenerateKey(reader) | ||||
| 	if err != nil { | ||||
| 		return 0, errwrap.Wrapf("failed to generate encryption key: {{err}}", err) | ||||
| 	} | ||||
|   | ||||
| @@ -3,6 +3,7 @@ package vault | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"context" | ||||
| 	"crypto/rand" | ||||
| 	"encoding/json" | ||||
| 	"testing" | ||||
|  | ||||
| @@ -29,8 +30,8 @@ func mockBarrier(t testing.TB) (physical.Backend, SecurityBarrier, []byte) { | ||||
| 	} | ||||
|  | ||||
| 	// Initialize and unseal | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	b.Unseal(context.Background(), key) | ||||
| 	return inm, b, key | ||||
| } | ||||
| @@ -116,7 +117,7 @@ func TestAESGCMBarrier_BackwardsCompatible(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	// Generate a barrier/init entry | ||||
| 	encrypt, _ := b.GenerateKey() | ||||
| 	encrypt, _ := b.GenerateKey(rand.Reader) | ||||
| 	init := &barrierInit{ | ||||
| 		Version: 1, | ||||
| 		Key:     encrypt, | ||||
| @@ -124,7 +125,7 @@ func TestAESGCMBarrier_BackwardsCompatible(t *testing.T) { | ||||
| 	buf, _ := json.Marshal(init) | ||||
|  | ||||
| 	// Protect with master key | ||||
| 	master, _ := b.GenerateKey() | ||||
| 	master, _ := b.GenerateKey(rand.Reader) | ||||
| 	gcm, _ := b.aeadFromKey(master) | ||||
| 	value, err := b.encrypt(barrierInitPath, initialKeyTerm, gcm, buf) | ||||
| 	if err != nil { | ||||
| @@ -205,8 +206,8 @@ func TestAESGCMBarrier_Confidential(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	// Initialize and unseal | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	b.Unseal(context.Background(), key) | ||||
|  | ||||
| 	// Put a logical entry | ||||
| @@ -245,8 +246,8 @@ func TestAESGCMBarrier_Integrity(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	// Initialize and unseal | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	b.Unseal(context.Background(), key) | ||||
|  | ||||
| 	// Put a logical entry | ||||
| @@ -284,8 +285,8 @@ func TestAESGCMBarrier_MoveIntegrityV1(t *testing.T) { | ||||
| 	b.currentAESGCMVersionByte = AESGCMVersion1 | ||||
|  | ||||
| 	// Initialize and unseal | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	err = b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	err = b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -328,8 +329,8 @@ func TestAESGCMBarrier_MoveIntegrityV2(t *testing.T) { | ||||
| 	b.currentAESGCMVersionByte = AESGCMVersion2 | ||||
|  | ||||
| 	// Initialize and unseal | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	err = b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	err = b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -372,8 +373,8 @@ func TestAESGCMBarrier_UpgradeV1toV2(t *testing.T) { | ||||
| 	b.currentAESGCMVersionByte = AESGCMVersion1 | ||||
|  | ||||
| 	// Initialize and unseal | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	err = b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	err = b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -425,8 +426,8 @@ func TestEncrypt_Unique(t *testing.T) { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	b.Unseal(context.Background(), key) | ||||
|  | ||||
| 	if b.keyring == nil { | ||||
| @@ -465,19 +466,19 @@ func TestInitialize_KeyLength(t *testing.T) { | ||||
| 	middle := []byte("ThisIsASecretKeyAndMore") | ||||
| 	short := []byte("Key") | ||||
|  | ||||
| 	err = b.Initialize(context.Background(), long) | ||||
| 	err = b.Initialize(context.Background(), long, rand.Reader) | ||||
|  | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("key length protection failed") | ||||
| 	} | ||||
|  | ||||
| 	err = b.Initialize(context.Background(), middle) | ||||
| 	err = b.Initialize(context.Background(), middle, rand.Reader) | ||||
|  | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("key length protection failed") | ||||
| 	} | ||||
|  | ||||
| 	err = b.Initialize(context.Background(), short) | ||||
| 	err = b.Initialize(context.Background(), short, rand.Reader) | ||||
|  | ||||
| 	if err == nil { | ||||
| 		t.Fatalf("key length protection failed") | ||||
| @@ -498,8 +499,8 @@ func TestEncrypt_BarrierEncryptor(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	// Initialize and unseal | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	b.Unseal(context.Background(), key) | ||||
|  | ||||
| 	cipher, err := b.Encrypt(context.Background(), "foo", []byte("quick brown fox")) | ||||
| @@ -528,8 +529,8 @@ func TestAESGCMBarrier_ReloadKeyring(t *testing.T) { | ||||
| 	} | ||||
|  | ||||
| 	// Initialize and unseal | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	b.Unseal(context.Background(), key) | ||||
|  | ||||
| 	keyringRaw, err := inm.Get(context.Background(), keyringPath) | ||||
| @@ -550,7 +551,7 @@ func TestAESGCMBarrier_ReloadKeyring(t *testing.T) { | ||||
| 			t.Fatalf("err: %v", err) | ||||
| 		} | ||||
| 		b2.Unseal(context.Background(), key) | ||||
| 		_, err = b2.Rotate(context.Background()) | ||||
| 		_, err = b2.Rotate(context.Background(), rand.Reader) | ||||
| 		if err != nil { | ||||
| 			t.Fatalf("err: %v", err) | ||||
| 		} | ||||
|   | ||||
| @@ -2,6 +2,7 @@ package vault | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/rand" | ||||
| 	"reflect" | ||||
| 	"testing" | ||||
| 	"time" | ||||
| @@ -49,7 +50,7 @@ func testBarrier(t *testing.T, b SecurityBarrier) { | ||||
| 	} | ||||
|  | ||||
| 	// Get a new key | ||||
| 	key, err := b.GenerateKey() | ||||
| 	key, err := b.GenerateKey(rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -69,12 +70,12 @@ func testBarrier(t *testing.T, b SecurityBarrier) { | ||||
| 	} | ||||
|  | ||||
| 	// Initialize the vault | ||||
| 	if err := b.Initialize(context.Background(), key); err != nil { | ||||
| 	if err := b.Initialize(context.Background(), key, rand.Reader); err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|  | ||||
| 	// Double Initialize should fail | ||||
| 	if err := b.Initialize(context.Background(), key); err != ErrBarrierAlreadyInit { | ||||
| 	if err := b.Initialize(context.Background(), key, rand.Reader); err != ErrBarrierAlreadyInit { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
|  | ||||
| @@ -245,8 +246,8 @@ func testBarrier(t *testing.T, b SecurityBarrier) { | ||||
|  | ||||
| func testBarrier_Rotate(t *testing.T, b SecurityBarrier) { | ||||
| 	// Initialize the barrier | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	err := b.Unseal(context.Background(), key) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| @@ -272,7 +273,7 @@ func testBarrier_Rotate(t *testing.T, b SecurityBarrier) { | ||||
| 	} | ||||
|  | ||||
| 	// Rotate the encryption key | ||||
| 	newTerm, err := b.Rotate(context.Background()) | ||||
| 	newTerm, err := b.Rotate(context.Background(), rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -351,8 +352,8 @@ func testBarrier_Rotate(t *testing.T, b SecurityBarrier) { | ||||
|  | ||||
| func testBarrier_Rekey(t *testing.T, b SecurityBarrier) { | ||||
| 	// Initialize the barrier | ||||
| 	key, _ := b.GenerateKey() | ||||
| 	b.Initialize(context.Background(), key) | ||||
| 	key, _ := b.GenerateKey(rand.Reader) | ||||
| 	b.Initialize(context.Background(), key, rand.Reader) | ||||
| 	err := b.Unseal(context.Background(), key) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| @@ -370,7 +371,7 @@ func testBarrier_Rekey(t *testing.T, b SecurityBarrier) { | ||||
| 	} | ||||
|  | ||||
| 	// Rekey to a new key | ||||
| 	newKey, _ := b.GenerateKey() | ||||
| 	newKey, _ := b.GenerateKey(rand.Reader) | ||||
| 	err = b.Rekey(context.Background(), newKey) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| @@ -431,8 +432,8 @@ func testBarrier_Rekey(t *testing.T, b SecurityBarrier) { | ||||
|  | ||||
| func testBarrier_Upgrade(t *testing.T, b1, b2 SecurityBarrier) { | ||||
| 	// Initialize the barrier | ||||
| 	key, _ := b1.GenerateKey() | ||||
| 	b1.Initialize(context.Background(), key) | ||||
| 	key, _ := b1.GenerateKey(rand.Reader) | ||||
| 	b1.Initialize(context.Background(), key, rand.Reader) | ||||
| 	err := b1.Unseal(context.Background(), key) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| @@ -443,7 +444,7 @@ func testBarrier_Upgrade(t *testing.T, b1, b2 SecurityBarrier) { | ||||
| 	} | ||||
|  | ||||
| 	// Rotate the encryption key | ||||
| 	newTerm, err := b1.Rotate(context.Background()) | ||||
| 	newTerm, err := b1.Rotate(context.Background(), rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -473,7 +474,7 @@ func testBarrier_Upgrade(t *testing.T, b1, b2 SecurityBarrier) { | ||||
| 	} | ||||
|  | ||||
| 	// Rotate the encryption key | ||||
| 	newTerm, err = b1.Rotate(context.Background()) | ||||
| 	newTerm, err = b1.Rotate(context.Background(), rand.Reader) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| 	} | ||||
| @@ -502,8 +503,8 @@ func testBarrier_Upgrade(t *testing.T, b1, b2 SecurityBarrier) { | ||||
|  | ||||
| func testBarrier_Upgrade_Rekey(t *testing.T, b1, b2 SecurityBarrier) { | ||||
| 	// Initialize the barrier | ||||
| 	key, _ := b1.GenerateKey() | ||||
| 	b1.Initialize(context.Background(), key) | ||||
| 	key, _ := b1.GenerateKey(rand.Reader) | ||||
| 	b1.Initialize(context.Background(), key, rand.Reader) | ||||
| 	err := b1.Unseal(context.Background(), key) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
| @@ -514,7 +515,7 @@ func testBarrier_Upgrade_Rekey(t *testing.T, b1, b2 SecurityBarrier) { | ||||
| 	} | ||||
|  | ||||
| 	// Rekey to a new key | ||||
| 	newKey, _ := b1.GenerateKey() | ||||
| 	newKey, _ := b1.GenerateKey(rand.Reader) | ||||
| 	err = b1.Rekey(context.Background(), newKey) | ||||
| 	if err != nil { | ||||
| 		t.Fatalf("err: %v", err) | ||||
|   | ||||
| @@ -205,7 +205,7 @@ func (c *Core) setupCluster(ctx context.Context) error { | ||||
| 		// Create a private key | ||||
| 		if c.localClusterPrivateKey.Load().(*ecdsa.PrivateKey) == nil { | ||||
| 			c.logger.Debug("generating cluster private key") | ||||
| 			key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) | ||||
| 			key, err := ecdsa.GenerateKey(elliptic.P521(), c.secureRandomReader) | ||||
| 			if err != nil { | ||||
| 				c.logger.Error("failed to generate local cluster key", "error", err) | ||||
| 				return err | ||||
|   | ||||
| @@ -3,11 +3,13 @@ package vault | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/rand" | ||||
| 	"crypto/subtle" | ||||
| 	"crypto/x509" | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"net" | ||||
| 	"net/http" | ||||
| 	"net/url" | ||||
| @@ -471,6 +473,9 @@ type Core struct { | ||||
|  | ||||
| 	coreNumber int | ||||
|  | ||||
| 	// secureRandomReader is the reader used for CSP operations | ||||
| 	secureRandomReader io.Reader | ||||
|  | ||||
| 	recoveryMode bool | ||||
| } | ||||
|  | ||||
| @@ -495,6 +500,8 @@ type CoreConfig struct { | ||||
|  | ||||
| 	Seal Seal `json:"seal" structs:"seal" mapstructure:"seal"` | ||||
|  | ||||
| 	SecureRandomReader io.Reader `json:"secure_random_reader" structs:"secure_random_reader" mapstructure:"secure_random_reader"` | ||||
|  | ||||
| 	Logger log.Logger `json:"logger" structs:"logger" mapstructure:"logger"` | ||||
|  | ||||
| 	// Disables the LRU cache on the physical backend | ||||
| @@ -633,6 +640,11 @@ func NewCore(conf *CoreConfig) (*Core, error) { | ||||
| 		syncInterval = 30 * time.Second | ||||
| 	} | ||||
|  | ||||
| 	// secureRandomReader cannot be nil | ||||
| 	if conf.SecureRandomReader == nil { | ||||
| 		conf.SecureRandomReader = rand.Reader | ||||
| 	} | ||||
|  | ||||
| 	// Setup the core | ||||
| 	c := &Core{ | ||||
| 		entCore:                      entCore{}, | ||||
| @@ -673,6 +685,7 @@ func NewCore(conf *CoreConfig) (*Core, error) { | ||||
| 		neverBecomeActive:            new(uint32), | ||||
| 		clusterLeaderParams:          new(atomic.Value), | ||||
| 		metricsHelper:                conf.MetricsHelper, | ||||
| 		secureRandomReader:           conf.SecureRandomReader, | ||||
| 		rawConfig:                    conf.RawConfig, | ||||
| 		counters: counters{ | ||||
| 			requests:     new(uint64), | ||||
| @@ -1152,7 +1165,7 @@ func (c *Core) unsealPart(ctx context.Context, seal Seal, key []byte, useRecover | ||||
| 			} | ||||
|  | ||||
| 			// Generate a new master key | ||||
| 			newMasterKey, err := c.barrier.GenerateKey() | ||||
| 			newMasterKey, err := c.barrier.GenerateKey(c.secureRandomReader) | ||||
| 			if err != nil { | ||||
| 				return nil, errwrap.Wrapf("error generating new master key: {{err}}", err) | ||||
| 			} | ||||
|   | ||||
| @@ -90,7 +90,7 @@ func (c *Core) Initialized(ctx context.Context) (bool, error) { | ||||
|  | ||||
| func (c *Core) generateShares(sc *SealConfig) ([]byte, [][]byte, error) { | ||||
| 	// Generate a master key | ||||
| 	masterKey, err := c.barrier.GenerateKey() | ||||
| 	masterKey, err := c.barrier.GenerateKey(c.secureRandomReader) | ||||
| 	if err != nil { | ||||
| 		return nil, nil, errwrap.Wrapf("key generation failed: {{err}}", err) | ||||
| 	} | ||||
| @@ -213,7 +213,7 @@ func (c *Core) Initialize(ctx context.Context, initParams *InitParams) (*InitRes | ||||
| 	} | ||||
|  | ||||
| 	// Initialize the barrier | ||||
| 	if err := c.barrier.Initialize(ctx, barrierKey); err != nil { | ||||
| 	if err := c.barrier.Initialize(ctx, barrierKey, c.secureRandomReader); err != nil { | ||||
| 		c.logger.Error("failed to initialize barrier", "error", err) | ||||
| 		return nil, errwrap.Wrapf("failed to initialize barrier: {{err}}", err) | ||||
| 	} | ||||
|   | ||||
| @@ -665,6 +665,7 @@ func mountInfo(entry *MountEntry) map[string]interface{} { | ||||
| 		"accessor":                entry.Accessor, | ||||
| 		"local":                   entry.Local, | ||||
| 		"seal_wrap":               entry.SealWrap, | ||||
| 		"external_entropy_access": entry.ExternalEntropyAccess, | ||||
| 		"options":                 entry.Options, | ||||
| 		"uuid":                    entry.UUID, | ||||
| 	} | ||||
| @@ -755,6 +756,7 @@ func (b *SystemBackend) handleMount(ctx context.Context, req *logical.Request, d | ||||
| 	description := data.Get("description").(string) | ||||
| 	pluginName := data.Get("plugin_name").(string) | ||||
| 	sealWrap := data.Get("seal_wrap").(bool) | ||||
| 	externalEntropyAccess := data.Get("external_entropy_access").(bool) | ||||
| 	options := data.Get("options").(map[string]string) | ||||
|  | ||||
| 	var config MountConfig | ||||
| @@ -886,6 +888,7 @@ func (b *SystemBackend) handleMount(ctx context.Context, req *logical.Request, d | ||||
| 		Config:                config, | ||||
| 		Local:                 local, | ||||
| 		SealWrap:              sealWrap, | ||||
| 		ExternalEntropyAccess: externalEntropyAccess, | ||||
| 		Options:               options, | ||||
| 	} | ||||
|  | ||||
| @@ -1055,6 +1058,11 @@ func (b *SystemBackend) handleTuneReadCommon(ctx context.Context, path string) ( | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	// not tunable so doesn't need to be stored/loaded through synthesizedConfigCache | ||||
| 	if mountEntry.ExternalEntropyAccess { | ||||
| 		resp.Data["external_entropy_access"] = true | ||||
| 	} | ||||
|  | ||||
| 	if mountEntry.Table == credentialTableType { | ||||
| 		resp.Data["token_type"] = mountEntry.Config.TokenType.String() | ||||
| 	} | ||||
| @@ -1688,6 +1696,7 @@ func (b *SystemBackend) handleEnableAuth(ctx context.Context, req *logical.Reque | ||||
| 	description := data.Get("description").(string) | ||||
| 	pluginName := data.Get("plugin_name").(string) | ||||
| 	sealWrap := data.Get("seal_wrap").(bool) | ||||
| 	externalEntropyAccess := data.Get("external_entropy_access").(bool) | ||||
| 	options := data.Get("options").(map[string]string) | ||||
|  | ||||
| 	var config MountConfig | ||||
| @@ -1808,6 +1817,7 @@ func (b *SystemBackend) handleEnableAuth(ctx context.Context, req *logical.Reque | ||||
| 		Config:                config, | ||||
| 		Local:                 local, | ||||
| 		SealWrap:              sealWrap, | ||||
| 		ExternalEntropyAccess: externalEntropyAccess, | ||||
| 		Options:               options, | ||||
| 	} | ||||
|  | ||||
| @@ -2240,7 +2250,7 @@ func (b *SystemBackend) handleRotate(ctx context.Context, req *logical.Request, | ||||
| 	} | ||||
|  | ||||
| 	// Rotate to the new term | ||||
| 	newTerm, err := b.Core.barrier.Rotate(ctx) | ||||
| 	newTerm, err := b.Core.barrier.Rotate(ctx, b.Core.secureRandomReader) | ||||
| 	if err != nil { | ||||
| 		b.Backend.Logger().Error("failed to create new encryption key", "error", err) | ||||
| 		return handleError(err) | ||||
| @@ -3503,6 +3513,10 @@ in the plugin catalog.`, | ||||
| 		`Whether to turn on seal wrapping for the mount.`, | ||||
| 	}, | ||||
|  | ||||
| 	"external_entropy_access": { | ||||
| 		`Whether to give the mount access to Vault's external entropy.`, | ||||
| 	}, | ||||
|  | ||||
| 	"tune_default_lease_ttl": { | ||||
| 		`The default lease TTL for this mount.`, | ||||
| 	}, | ||||
|   | ||||
| @@ -1316,6 +1316,11 @@ func (b *SystemBackend) authPaths() []*framework.Path { | ||||
| 					Default:     false, | ||||
| 					Description: strings.TrimSpace(sysHelp["seal_wrap"][0]), | ||||
| 				}, | ||||
| 				"external_entropy_access": &framework.FieldSchema{ | ||||
| 					Type:        framework.TypeBool, | ||||
| 					Default:     false, | ||||
| 					Description: strings.TrimSpace(sysHelp["external_entropy_access"][0]), | ||||
| 				}, | ||||
| 				"plugin_name": &framework.FieldSchema{ | ||||
| 					Type:        framework.TypeString, | ||||
| 					Description: strings.TrimSpace(sysHelp["auth_plugin"][0]), | ||||
| @@ -1606,6 +1611,11 @@ func (b *SystemBackend) mountPaths() []*framework.Path { | ||||
| 					Default:     false, | ||||
| 					Description: strings.TrimSpace(sysHelp["seal_wrap"][0]), | ||||
| 				}, | ||||
| 				"external_entropy_access": &framework.FieldSchema{ | ||||
| 					Type:        framework.TypeBool, | ||||
| 					Default:     false, | ||||
| 					Description: strings.TrimSpace(sysHelp["external_entropy_access"][0]), | ||||
| 				}, | ||||
| 				"plugin_name": &framework.FieldSchema{ | ||||
| 					Type:        framework.TypeString, | ||||
| 					Description: strings.TrimSpace(sysHelp["mount_plugin_name"][0]), | ||||
|   | ||||
| @@ -151,6 +151,7 @@ func TestSystemBackend_mounts(t *testing.T) { | ||||
| 	exp := map[string]interface{}{ | ||||
| 		"secret/": map[string]interface{}{ | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"description": "key/value secret storage", | ||||
| 			"accessor":    resp.Data["secret/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["secret/"].(map[string]interface{})["uuid"], | ||||
| @@ -167,6 +168,7 @@ func TestSystemBackend_mounts(t *testing.T) { | ||||
| 		}, | ||||
| 		"sys/": map[string]interface{}{ | ||||
| 			"type":        "system", | ||||
| 			"external_entropy_access": false, | ||||
| 			"description": "system endpoints used for control, policy and debugging", | ||||
| 			"accessor":    resp.Data["sys/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["sys/"].(map[string]interface{})["uuid"], | ||||
| @@ -183,6 +185,7 @@ func TestSystemBackend_mounts(t *testing.T) { | ||||
| 		"cubbyhole/": map[string]interface{}{ | ||||
| 			"description": "per-token private secret storage", | ||||
| 			"type":        "cubbyhole", | ||||
| 			"external_entropy_access": false, | ||||
| 			"accessor":    resp.Data["cubbyhole/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["cubbyhole/"].(map[string]interface{})["uuid"], | ||||
| 			"config": map[string]interface{}{ | ||||
| @@ -197,6 +200,7 @@ func TestSystemBackend_mounts(t *testing.T) { | ||||
| 		"identity/": map[string]interface{}{ | ||||
| 			"description": "identity store", | ||||
| 			"type":        "identity", | ||||
| 			"external_entropy_access": false, | ||||
| 			"accessor":    resp.Data["identity/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["identity/"].(map[string]interface{})["uuid"], | ||||
| 			"config": map[string]interface{}{ | ||||
| @@ -248,6 +252,7 @@ func TestSystemBackend_mount(t *testing.T) { | ||||
| 	exp := map[string]interface{}{ | ||||
| 		"secret/": map[string]interface{}{ | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"description": "key/value secret storage", | ||||
| 			"accessor":    resp.Data["secret/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["secret/"].(map[string]interface{})["uuid"], | ||||
| @@ -264,6 +269,7 @@ func TestSystemBackend_mount(t *testing.T) { | ||||
| 		}, | ||||
| 		"sys/": map[string]interface{}{ | ||||
| 			"type":        "system", | ||||
| 			"external_entropy_access": false, | ||||
| 			"description": "system endpoints used for control, policy and debugging", | ||||
| 			"accessor":    resp.Data["sys/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["sys/"].(map[string]interface{})["uuid"], | ||||
| @@ -280,6 +286,7 @@ func TestSystemBackend_mount(t *testing.T) { | ||||
| 		"cubbyhole/": map[string]interface{}{ | ||||
| 			"description": "per-token private secret storage", | ||||
| 			"type":        "cubbyhole", | ||||
| 			"external_entropy_access": false, | ||||
| 			"accessor":    resp.Data["cubbyhole/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["cubbyhole/"].(map[string]interface{})["uuid"], | ||||
| 			"config": map[string]interface{}{ | ||||
| @@ -294,6 +301,7 @@ func TestSystemBackend_mount(t *testing.T) { | ||||
| 		"identity/": map[string]interface{}{ | ||||
| 			"description": "identity store", | ||||
| 			"type":        "identity", | ||||
| 			"external_entropy_access": false, | ||||
| 			"accessor":    resp.Data["identity/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["identity/"].(map[string]interface{})["uuid"], | ||||
| 			"config": map[string]interface{}{ | ||||
| @@ -308,6 +316,7 @@ func TestSystemBackend_mount(t *testing.T) { | ||||
| 		"prod/secret/": map[string]interface{}{ | ||||
| 			"description": "", | ||||
| 			"type":        "kv", | ||||
| 			"external_entropy_access": false, | ||||
| 			"accessor":    resp.Data["prod/secret/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["prod/secret/"].(map[string]interface{})["uuid"], | ||||
| 			"config": map[string]interface{}{ | ||||
| @@ -1448,6 +1457,7 @@ func TestSystemBackend_authTable(t *testing.T) { | ||||
| 	exp := map[string]interface{}{ | ||||
| 		"token/": map[string]interface{}{ | ||||
| 			"type":        "token", | ||||
| 			"external_entropy_access": false, | ||||
| 			"description": "token based credentials", | ||||
| 			"accessor":    resp.Data["token/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["token/"].(map[string]interface{})["uuid"], | ||||
| @@ -1502,6 +1512,7 @@ func TestSystemBackend_enableAuth(t *testing.T) { | ||||
| 	exp := map[string]interface{}{ | ||||
| 		"foo/": map[string]interface{}{ | ||||
| 			"type":        "noop", | ||||
| 			"external_entropy_access": false, | ||||
| 			"description": "", | ||||
| 			"accessor":    resp.Data["foo/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["foo/"].(map[string]interface{})["uuid"], | ||||
| @@ -1517,6 +1528,7 @@ func TestSystemBackend_enableAuth(t *testing.T) { | ||||
| 		}, | ||||
| 		"token/": map[string]interface{}{ | ||||
| 			"type":        "token", | ||||
| 			"external_entropy_access": false, | ||||
| 			"description": "token based credentials", | ||||
| 			"accessor":    resp.Data["token/"].(map[string]interface{})["accessor"], | ||||
| 			"uuid":        resp.Data["token/"].(map[string]interface{})["uuid"], | ||||
| @@ -2285,6 +2297,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { | ||||
| 		"secret": map[string]interface{}{ | ||||
| 			"secret/": map[string]interface{}{ | ||||
| 				"type":        "kv", | ||||
| 				"external_entropy_access": false, | ||||
| 				"description": "key/value secret storage", | ||||
| 				"accessor":    resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["accessor"], | ||||
| 				"uuid":        resp.Data["secret"].(map[string]interface{})["secret/"].(map[string]interface{})["uuid"], | ||||
| @@ -2301,6 +2314,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { | ||||
| 			}, | ||||
| 			"sys/": map[string]interface{}{ | ||||
| 				"type":        "system", | ||||
| 				"external_entropy_access": false, | ||||
| 				"description": "system endpoints used for control, policy and debugging", | ||||
| 				"accessor":    resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["accessor"], | ||||
| 				"uuid":        resp.Data["secret"].(map[string]interface{})["sys/"].(map[string]interface{})["uuid"], | ||||
| @@ -2317,6 +2331,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { | ||||
| 			"cubbyhole/": map[string]interface{}{ | ||||
| 				"description": "per-token private secret storage", | ||||
| 				"type":        "cubbyhole", | ||||
| 				"external_entropy_access": false, | ||||
| 				"accessor":    resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["accessor"], | ||||
| 				"uuid":        resp.Data["secret"].(map[string]interface{})["cubbyhole/"].(map[string]interface{})["uuid"], | ||||
| 				"config": map[string]interface{}{ | ||||
| @@ -2331,6 +2346,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { | ||||
| 			"identity/": map[string]interface{}{ | ||||
| 				"description": "identity store", | ||||
| 				"type":        "identity", | ||||
| 				"external_entropy_access": false, | ||||
| 				"accessor":    resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["accessor"], | ||||
| 				"uuid":        resp.Data["secret"].(map[string]interface{})["identity/"].(map[string]interface{})["uuid"], | ||||
| 				"config": map[string]interface{}{ | ||||
| @@ -2353,6 +2369,7 @@ func TestSystemBackend_InternalUIMounts(t *testing.T) { | ||||
| 					"token_type":        "default-service", | ||||
| 				}, | ||||
| 				"type":        "token", | ||||
| 				"external_entropy_access": false, | ||||
| 				"description": "token based credentials", | ||||
| 				"accessor":    resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["accessor"], | ||||
| 				"uuid":        resp.Data["auth"].(map[string]interface{})["token/"].(map[string]interface{})["uuid"], | ||||
|   | ||||
| @@ -220,6 +220,7 @@ type MountEntry struct { | ||||
| 	Options               map[string]string `json:"options"`                 // Backend options | ||||
| 	Local                 bool              `json:"local"`                   // Local mounts are not replicated or affected by replication | ||||
| 	SealWrap              bool              `json:"seal_wrap"`               // Whether to wrap CSPs | ||||
| 	ExternalEntropyAccess bool              `json:"external_entropy_access"` // Whether to allow external entropy source access | ||||
| 	Tainted               bool              `json:"tainted,omitempty"`       // Set as a Write-Ahead flag for unmount/remount | ||||
| 	NamespaceID           string            `json:"namespace_id"` | ||||
|  | ||||
| @@ -1249,18 +1250,6 @@ func (c *Core) newLogicalBackend(ctx context.Context, entry *MountEntry, sysView | ||||
| 	return b, nil | ||||
| } | ||||
|  | ||||
| // mountEntrySysView creates a logical.SystemView from global and | ||||
| // mount-specific entries; because this should be called when setting | ||||
| // up a mountEntry, it doesn't check to ensure that me is not nil | ||||
| func (c *Core) mountEntrySysView(entry *MountEntry) extendedSystemView { | ||||
| 	return extendedSystemViewImpl{ | ||||
| 		dynamicSystemView{ | ||||
| 			core:       c, | ||||
| 			mountEntry: entry, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // defaultMountTable creates a default mount table | ||||
| func (c *Core) defaultMountTable() *MountTable { | ||||
| 	table := &MountTable{ | ||||
|   | ||||
| @@ -41,3 +41,15 @@ func (e *MountEntry) ViewPath() string { | ||||
| } | ||||
|  | ||||
| func verifyNamespace(*Core, *namespace.Namespace, *MountEntry) error { return nil } | ||||
|  | ||||
| // mountEntrySysView creates a logical.SystemView from global and | ||||
| // mount-specific entries; because this should be called when setting | ||||
| // up a mountEntry, it doesn't check to ensure that me is not nil | ||||
| func (c *Core) mountEntrySysView(entry *MountEntry) extendedSystemView { | ||||
| 	return extendedSystemViewImpl{ | ||||
| 		dynamicSystemView{ | ||||
| 			core:       c, | ||||
| 			mountEntry: entry, | ||||
| 		}, | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -105,7 +105,7 @@ func (c *Core) startRaftStorage(ctx context.Context) (retErr error) { | ||||
| 		// this state the unseal will fail and a cluster recovery will need to | ||||
| 		// be done. | ||||
| 		creating = true | ||||
| 		raftTLSKey, err := raft.GenerateTLSKey() | ||||
| 		raftTLSKey, err := raft.GenerateTLSKey(c.secureRandomReader) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -267,7 +267,7 @@ func (c *Core) startPeriodicRaftTLSRotate(ctx context.Context) error { | ||||
| 		logger.Info("creating new raft TLS config") | ||||
|  | ||||
| 		// Create a new key | ||||
| 		raftTLSKey, err := raft.GenerateTLSKey() | ||||
| 		raftTLSKey, err := raft.GenerateTLSKey(c.secureRandomReader) | ||||
| 		if err != nil { | ||||
| 			return time.Time{}, errwrap.Wrapf("failed to generate new raft TLS key: {{err}}", err) | ||||
| 		} | ||||
| @@ -399,7 +399,7 @@ func (c *Core) createRaftTLSKeyring(ctx context.Context) error { | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	raftTLS, err := raft.GenerateTLSKey() | ||||
| 	raftTLS, err := raft.GenerateTLSKey(c.secureRandomReader) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|   | ||||
| @@ -397,7 +397,7 @@ func (c *Core) BarrierRekeyUpdate(ctx context.Context, key []byte, nonce string) | ||||
| 	} | ||||
|  | ||||
| 	// Generate a new master key | ||||
| 	newMasterKey, err := c.barrier.GenerateKey() | ||||
| 	newMasterKey, err := c.barrier.GenerateKey(c.secureRandomReader) | ||||
| 	if err != nil { | ||||
| 		c.logger.Error("failed to generate master key", "error", err) | ||||
| 		return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("master key generation failed: {{err}}", err).Error()) | ||||
| @@ -629,7 +629,7 @@ func (c *Core) RecoveryRekeyUpdate(ctx context.Context, key []byte, nonce string | ||||
| 	} | ||||
|  | ||||
| 	// Generate a new master key | ||||
| 	newMasterKey, err := c.barrier.GenerateKey() | ||||
| 	newMasterKey, err := c.barrier.GenerateKey(c.secureRandomReader) | ||||
| 	if err != nil { | ||||
| 		c.logger.Error("failed to generate recovery key", "error", err) | ||||
| 		return nil, logical.CodedError(http.StatusInternalServerError, errwrap.Wrapf("recovery key generation failed: {{err}}", err).Error()) | ||||
|   | ||||
| @@ -22,7 +22,7 @@ const ( | ||||
| 	HSMAutoDeprecated = "hsm-auto" | ||||
| ) | ||||
|  | ||||
| // Access is the embedded implemention of autoSeal that contains logic | ||||
| // Access is the embedded implementation of autoSeal that contains logic | ||||
| // specific to encrypting and decrypting data, or in this case keys. | ||||
| type Access interface { | ||||
| 	SealType() string | ||||
|   | ||||
| @@ -1368,6 +1368,7 @@ func NewTestCluster(t testing.T, base *CoreConfig, opts *TestClusterOptions) *Te | ||||
| 		coreConfig.LicensingConfig = base.LicensingConfig | ||||
| 		coreConfig.DisablePerformanceStandby = base.DisablePerformanceStandby | ||||
| 		coreConfig.MetricsHelper = base.MetricsHelper | ||||
| 		coreConfig.SecureRandomReader = base.SecureRandomReader | ||||
| 		if base.BuiltinRegistry != nil { | ||||
| 			coreConfig.BuiltinRegistry = base.BuiltinRegistry | ||||
| 		} | ||||
|   | ||||
| @@ -785,7 +785,7 @@ func (ts *TokenStore) create(ctx context.Context, entry *logical.TokenEntry) err | ||||
| 		if entry.ID == "" { | ||||
| 			userSelectedID = false | ||||
| 			var err error | ||||
| 			entry.ID, err = base62.Random(TokenLength) | ||||
| 			entry.ID, err = base62.RandomWithReader(TokenLength, ts.core.secureRandomReader) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
|   | ||||
| @@ -4,7 +4,6 @@ import ( | ||||
| 	"context" | ||||
| 	"crypto/ecdsa" | ||||
| 	"crypto/elliptic" | ||||
| 	"crypto/rand" | ||||
| 	"encoding/json" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| @@ -17,7 +16,7 @@ import ( | ||||
| 	"github.com/hashicorp/vault/sdk/helper/consts" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/jsonutil" | ||||
| 	"github.com/hashicorp/vault/sdk/logical" | ||||
| 	jose "gopkg.in/square/go-jose.v2" | ||||
| 	"gopkg.in/square/go-jose.v2" | ||||
| 	squarejwt "gopkg.in/square/go-jose.v2/jwt" | ||||
| ) | ||||
|  | ||||
| @@ -35,7 +34,7 @@ func (c *Core) ensureWrappingKey(ctx context.Context) error { | ||||
| 	var keyParams certutil.ClusterKeyParams | ||||
|  | ||||
| 	if entry == nil { | ||||
| 		key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) | ||||
| 		key, err := ecdsa.GenerateKey(elliptic.P521(), c.secureRandomReader) | ||||
| 		if err != nil { | ||||
| 			return errwrap.Wrapf("failed to generate wrapping key: {{err}}", err) | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										1
									
								
								vendor/github.com/boombuler/barcode/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/boombuler/barcode/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| module github.com/boombuler/barcode | ||||
							
								
								
									
										2
									
								
								vendor/github.com/boombuler/barcode/utils/base1dcode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/boombuler/barcode/utils/base1dcode.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -46,7 +46,7 @@ func (c *base1DCodeIntCS) CheckSum() int { | ||||
| 	return c.checksum | ||||
| } | ||||
|  | ||||
| // New1DCode creates a new 1D barcode where the bars are represented by the bits in the bars BitList | ||||
| // New1DCodeIntCheckSum creates a new 1D barcode where the bars are represented by the bits in the bars BitList | ||||
| func New1DCodeIntCheckSum(codeKind, content string, bars *BitList, checksum int) barcode.BarcodeIntCS { | ||||
| 	return &base1DCodeIntCS{base1DCode{bars, codeKind, content}, checksum} | ||||
| } | ||||
|   | ||||
							
								
								
									
										22
									
								
								vendor/github.com/hashicorp/go-uuid/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								vendor/github.com/hashicorp/go-uuid/uuid.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -4,22 +4,40 @@ import ( | ||||
| 	"crypto/rand" | ||||
| 	"encoding/hex" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| // GenerateRandomBytes is used to generate random bytes of given size. | ||||
| func GenerateRandomBytes(size int) ([]byte, error) { | ||||
| 	return GenerateRandomBytesWithReader(size, rand.Reader) | ||||
| } | ||||
|  | ||||
| // GenerateRandomBytesWithReader is used to generate random bytes of given size read from a given reader. | ||||
| func GenerateRandomBytesWithReader(size int, reader io.Reader) ([]byte, error) { | ||||
| 	if reader == nil { | ||||
| 		return nil, fmt.Errorf("provided reader is nil") | ||||
| 	} | ||||
| 	buf := make([]byte, size) | ||||
| 	if _, err := rand.Read(buf); err != nil { | ||||
| 	if _, err := io.ReadFull(reader, buf); err != nil { | ||||
| 		return nil, fmt.Errorf("failed to read random bytes: %v", err) | ||||
| 	} | ||||
| 	return buf, nil | ||||
| } | ||||
|  | ||||
|  | ||||
| const uuidLen = 16 | ||||
|  | ||||
| // GenerateUUID is used to generate a random UUID | ||||
| func GenerateUUID() (string, error) { | ||||
| 	buf, err := GenerateRandomBytes(uuidLen) | ||||
| 	return GenerateUUIDWithReader(rand.Reader) | ||||
| } | ||||
|  | ||||
| // GenerateUUIDWithReader is used to generate a random UUID with a given Reader | ||||
| func GenerateUUIDWithReader(reader io.Reader) (string, error) { | ||||
| 	if reader == nil { | ||||
| 		return "", fmt.Errorf("provided reader is nil") | ||||
| 	} | ||||
| 	buf, err := GenerateRandomBytesWithReader(uuidLen, reader) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/hashicorp/vault-plugin-secrets-kv/backend.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/hashicorp/vault-plugin-secrets-kv/backend.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -270,7 +270,7 @@ func (b *versionedKVBackend) policy(ctx context.Context, s logical.Storage) (*ke | ||||
| 		VersionTemplate:      keysutil.EncryptedKeyPolicyVersionTpl, | ||||
| 	}) | ||||
|  | ||||
| 	err = policy.Rotate(ctx, s) | ||||
| 	err = policy.Rotate(ctx, s, b.GetRandomReader()) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										1
									
								
								vendor/github.com/hashicorp/vault/api/go.sum
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/hashicorp/vault/api/go.sum
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -38,6 +38,7 @@ github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0S | ||||
| github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= | ||||
| github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= | ||||
| github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= | ||||
| github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
| github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= | ||||
|   | ||||
							
								
								
									
										16
									
								
								vendor/github.com/hashicorp/vault/api/sys_generate_root.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/hashicorp/vault/api/sys_generate_root.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -10,6 +10,10 @@ func (c *Sys) GenerateDROperationTokenStatus() (*GenerateRootStatusResponse, err | ||||
| 	return c.generateRootStatusCommon("/v1/sys/replication/dr/secondary/generate-operation-token/attempt") | ||||
| } | ||||
|  | ||||
| func (c *Sys) GenerateRecoveryOperationTokenStatus() (*GenerateRootStatusResponse, error) { | ||||
| 	return c.generateRootStatusCommon("/v1/sys/generate-recovery-token/attempt") | ||||
| } | ||||
|  | ||||
| func (c *Sys) generateRootStatusCommon(path string) (*GenerateRootStatusResponse, error) { | ||||
| 	r := c.c.NewRequest("GET", path) | ||||
|  | ||||
| @@ -34,6 +38,10 @@ func (c *Sys) GenerateDROperationTokenInit(otp, pgpKey string) (*GenerateRootSta | ||||
| 	return c.generateRootInitCommon("/v1/sys/replication/dr/secondary/generate-operation-token/attempt", otp, pgpKey) | ||||
| } | ||||
|  | ||||
| func (c *Sys) GenerateRecoveryOperationTokenInit(otp, pgpKey string) (*GenerateRootStatusResponse, error) { | ||||
| 	return c.generateRootInitCommon("/v1/sys/generate-recovery-token/attempt", otp, pgpKey) | ||||
| } | ||||
|  | ||||
| func (c *Sys) generateRootInitCommon(path, otp, pgpKey string) (*GenerateRootStatusResponse, error) { | ||||
| 	body := map[string]interface{}{ | ||||
| 		"otp":     otp, | ||||
| @@ -66,6 +74,10 @@ func (c *Sys) GenerateDROperationTokenCancel() error { | ||||
| 	return c.generateRootCancelCommon("/v1/sys/replication/dr/secondary/generate-operation-token/attempt") | ||||
| } | ||||
|  | ||||
| func (c *Sys) GenerateRecoveryOperationTokenCancel() error { | ||||
| 	return c.generateRootCancelCommon("/v1/sys/generate-recovery-token/attempt") | ||||
| } | ||||
|  | ||||
| func (c *Sys) generateRootCancelCommon(path string) error { | ||||
| 	r := c.c.NewRequest("DELETE", path) | ||||
|  | ||||
| @@ -86,6 +98,10 @@ func (c *Sys) GenerateDROperationTokenUpdate(shard, nonce string) (*GenerateRoot | ||||
| 	return c.generateRootUpdateCommon("/v1/sys/replication/dr/secondary/generate-operation-token/update", shard, nonce) | ||||
| } | ||||
|  | ||||
| func (c *Sys) GenerateRecoveryOperationTokenUpdate(shard, nonce string) (*GenerateRootStatusResponse, error) { | ||||
| 	return c.generateRootUpdateCommon("/v1/sys/generate-recovery-token/update", shard, nonce) | ||||
| } | ||||
|  | ||||
| func (c *Sys) generateRootUpdateCommon(path, shard, nonce string) (*GenerateRootStatusResponse, error) { | ||||
| 	body := map[string]interface{}{ | ||||
| 		"key":   shard, | ||||
|   | ||||
							
								
								
									
										2
									
								
								vendor/github.com/hashicorp/vault/api/sys_mounts.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/hashicorp/vault/api/sys_mounts.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -134,6 +134,7 @@ type MountInput struct { | ||||
| 	Config                MountConfigInput  `json:"config"` | ||||
| 	Local                 bool              `json:"local"` | ||||
| 	SealWrap              bool              `json:"seal_wrap" mapstructure:"seal_wrap"` | ||||
| 	ExternalEntropyAccess bool              `json:"external_entropy_access" mapstructure:"external_entropy_access"` | ||||
| 	Options               map[string]string `json:"options"` | ||||
|  | ||||
| 	// Deprecated: Newer server responses should be returning this information in the | ||||
| @@ -167,6 +168,7 @@ type MountOutput struct { | ||||
| 	Options               map[string]string `json:"options"` | ||||
| 	Local                 bool              `json:"local"` | ||||
| 	SealWrap              bool              `json:"seal_wrap" mapstructure:"seal_wrap"` | ||||
| 	ExternalEntropyAccess bool              `json:"external_entropy_access" mapstructure:"external_entropy_access"` | ||||
| } | ||||
|  | ||||
| type MountConfigOutput struct { | ||||
|   | ||||
							
								
								
									
										14
									
								
								vendor/github.com/hashicorp/vault/sdk/framework/backend.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/hashicorp/vault/sdk/framework/backend.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -2,7 +2,9 @@ package framework | ||||
|  | ||||
| import ( | ||||
| 	"context" | ||||
| 	"crypto/rand" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"regexp" | ||||
| @@ -14,6 +16,7 @@ import ( | ||||
| 	"github.com/hashicorp/errwrap" | ||||
| 	log "github.com/hashicorp/go-hclog" | ||||
| 	multierror "github.com/hashicorp/go-multierror" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/entropy" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/errutil" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/license" | ||||
| 	"github.com/hashicorp/vault/sdk/helper/logging" | ||||
| @@ -279,6 +282,17 @@ func (b *Backend) Setup(ctx context.Context, config *logical.BackendConfig) erro | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // GetRandomReader returns an io.Reader to use for generating key material in | ||||
| // backends. If the backend has access to an external entropy source it will | ||||
| // return that, otherwise it returns crypto/rand.Reader. | ||||
| func (b *Backend) GetRandomReader() io.Reader { | ||||
| 	if sourcer, ok := b.System().(entropy.Sourcer); ok { | ||||
| 		return entropy.NewReader(sourcer) | ||||
| 	} | ||||
|  | ||||
| 	return rand.Reader | ||||
| } | ||||
|  | ||||
| // Logger can be used to get the logger. If no logger has been set, | ||||
| // the logs will be discarded. | ||||
| func (b *Backend) Logger() log.Logger { | ||||
|   | ||||
							
								
								
									
										10
									
								
								vendor/github.com/hashicorp/vault/sdk/helper/base62/base62.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/hashicorp/vault/sdk/helper/base62/base62.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -3,7 +3,9 @@ | ||||
| package base62 | ||||
|  | ||||
| import ( | ||||
| 	"crypto/rand" | ||||
| 	uuid "github.com/hashicorp/go-uuid" | ||||
| 	"io" | ||||
| ) | ||||
|  | ||||
| const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" | ||||
| @@ -12,6 +14,12 @@ const csLen = byte(len(charset)) | ||||
| // Random generates a random string using base-62 characters. | ||||
| // Resulting entropy is ~5.95 bits/character. | ||||
| func Random(length int) (string, error) { | ||||
| 	return RandomWithReader(length, rand.Reader) | ||||
| } | ||||
|  | ||||
| // RandomWithReader generates a random string using base-62 characters and a given reader. | ||||
| // Resulting entropy is ~5.95 bits/character. | ||||
| func RandomWithReader(length int, reader io.Reader) (string, error) { | ||||
| 	if length == 0 { | ||||
| 		return "", nil | ||||
| 	} | ||||
| @@ -22,7 +30,7 @@ func Random(length int) (string, error) { | ||||
| 	batchSize := length + length/4 | ||||
|  | ||||
| 	for { | ||||
| 		buf, err := uuid.GenerateRandomBytes(batchSize) | ||||
| 		buf, err := uuid.GenerateRandomBytesWithReader(batchSize, reader) | ||||
| 		if err != nil { | ||||
| 			return "", err | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										36
									
								
								vendor/github.com/hashicorp/vault/sdk/helper/entropy/entropy.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								vendor/github.com/hashicorp/vault/sdk/helper/entropy/entropy.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| package entropy | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"github.com/hashicorp/errwrap" | ||||
| ) | ||||
|  | ||||
| type Sourcer interface { | ||||
| 	GetRandom(bytes int) ([]byte, error) | ||||
| } | ||||
|  | ||||
| type Reader struct { | ||||
| 	source Sourcer | ||||
| } | ||||
|  | ||||
| func NewReader(source Sourcer) *Reader{ | ||||
| 	return &Reader{source} | ||||
| } | ||||
|  | ||||
| // Read reads exactly len(p) bytes from r into p. | ||||
| // If r returns an error having read at least len(p) bytes, the error is dropped. | ||||
| // It returns the number of bytes copied and an error if fewer bytes were read. | ||||
| // On return, n == len(p) if and only if err == nil. | ||||
| func (r *Reader) Read(p []byte) (n int, err error){ | ||||
| 	requested := len(p) | ||||
| 	randBytes, err := r.source.GetRandom(requested) | ||||
| 	delivered := copy(p, randBytes) | ||||
| 	if delivered != requested { | ||||
| 		if err != nil { | ||||
| 			return delivered, errwrap.Wrapf("unable to fill provided buffer with entropy: {{err}}", err) | ||||
| 		} | ||||
| 		return delivered, fmt.Errorf("unable to fill provided buffer with entropy") | ||||
| 	} | ||||
|  | ||||
| 	return delivered, nil | ||||
| } | ||||
							
								
								
									
										7
									
								
								vendor/github.com/hashicorp/vault/sdk/helper/keysutil/lock_manager.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								vendor/github.com/hashicorp/vault/sdk/helper/keysutil/lock_manager.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -5,6 +5,7 @@ import ( | ||||
| 	"encoding/base64" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"sync" | ||||
| 	"sync/atomic" | ||||
| 	"time" | ||||
| @@ -249,7 +250,7 @@ func (lm *LockManager) BackupPolicy(ctx context.Context, storage logical.Storage | ||||
|  | ||||
| // When the function returns, if caching was disabled, the Policy's lock must | ||||
| // be unlocked when the caller is done (and it should not be re-locked). | ||||
| func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest) (retP *Policy, retUpserted bool, retErr error) { | ||||
| func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest, rand io.Reader) (retP *Policy, retUpserted bool, retErr error) { | ||||
| 	var p *Policy | ||||
| 	var err error | ||||
| 	var ok bool | ||||
| @@ -379,7 +380,7 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest) (retP * | ||||
| 		} | ||||
|  | ||||
| 		// Performs the actual persist and does setup | ||||
| 		err = p.Rotate(ctx, req.Storage) | ||||
| 		err = p.Rotate(ctx, req.Storage, rand) | ||||
| 		if err != nil { | ||||
| 			cleanup() | ||||
| 			return nil, false, err | ||||
| @@ -400,7 +401,7 @@ func (lm *LockManager) GetPolicy(ctx context.Context, req PolicyRequest) (retP * | ||||
| 	} | ||||
|  | ||||
| 	if p.NeedsUpgrade() { | ||||
| 		if err := p.Upgrade(ctx, req.Storage); err != nil { | ||||
| 		if err := p.Upgrade(ctx, req.Storage, rand); err != nil { | ||||
| 			cleanup() | ||||
| 			return nil, false, err | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										14
									
								
								vendor/github.com/hashicorp/vault/sdk/helper/keysutil/policy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										14
									
								
								vendor/github.com/hashicorp/vault/sdk/helper/keysutil/policy.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -613,7 +613,7 @@ func (p *Policy) NeedsUpgrade() bool { | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func (p *Policy) Upgrade(ctx context.Context, storage logical.Storage) (retErr error) { | ||||
| func (p *Policy) Upgrade(ctx context.Context, storage logical.Storage, randReader io.Reader) (retErr error) { | ||||
| 	priorKey := p.Key | ||||
| 	priorLatestVersion := p.LatestVersion | ||||
| 	priorMinDecryptionVersion := p.MinDecryptionVersion | ||||
| @@ -670,7 +670,7 @@ func (p *Policy) Upgrade(ctx context.Context, storage logical.Storage) (retErr e | ||||
|  | ||||
| 	if p.Keys[strconv.Itoa(p.LatestVersion)].HMACKey == nil || len(p.Keys[strconv.Itoa(p.LatestVersion)].HMACKey) == 0 { | ||||
| 		entry := p.Keys[strconv.Itoa(p.LatestVersion)] | ||||
| 		hmacKey, err := uuid.GenerateRandomBytes(32) | ||||
| 		hmacKey, err := uuid.GenerateRandomBytesWithReader(32, randReader) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -1371,7 +1371,7 @@ func (p *Policy) VerifySignature(context, input []byte, hashAlgorithm HashType, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr error) { | ||||
| func (p *Policy) Rotate(ctx context.Context, storage logical.Storage, randReader io.Reader) (retErr error) { | ||||
| 	priorLatestVersion := p.LatestVersion | ||||
| 	priorMinDecryptionVersion := p.MinDecryptionVersion | ||||
| 	var priorKeys keyEntryMap | ||||
| @@ -1405,7 +1405,7 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr er | ||||
| 		DeprecatedCreationTime: now.Unix(), | ||||
| 	} | ||||
|  | ||||
| 	hmacKey, err := uuid.GenerateRandomBytes(32) | ||||
| 	hmacKey, err := uuid.GenerateRandomBytesWithReader(32, randReader) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| @@ -1418,7 +1418,7 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr er | ||||
| 		if p.Type == KeyType_AES128_GCM96 { | ||||
| 			numBytes = 16 | ||||
| 		} | ||||
| 		newKey, err := uuid.GenerateRandomBytes(numBytes) | ||||
| 		newKey, err := uuid.GenerateRandomBytesWithReader(numBytes, randReader) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -1457,7 +1457,7 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr er | ||||
| 		entry.FormattedPublicKey = string(pemBytes) | ||||
|  | ||||
| 	case KeyType_ED25519: | ||||
| 		pub, pri, err := ed25519.GenerateKey(rand.Reader) | ||||
| 		pub, pri, err := ed25519.GenerateKey(randReader) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| @@ -1470,7 +1470,7 @@ func (p *Policy) Rotate(ctx context.Context, storage logical.Storage) (retErr er | ||||
| 			bitSize = 4096 | ||||
| 		} | ||||
|  | ||||
| 		entry.RSAKey, err = rsa.GenerateKey(rand.Reader, bitSize) | ||||
| 		entry.RSAKey, err = rsa.GenerateKey(randReader, bitSize) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|   | ||||
							
								
								
									
										8
									
								
								vendor/github.com/pquerna/otp/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/pquerna/otp/.travis.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,7 +1,7 @@ | ||||
| language: go | ||||
|  | ||||
| env: | ||||
|   - GO111MODULE=on | ||||
|  | ||||
| go: | ||||
|   - "1.8" | ||||
|   - "1.9" | ||||
|   - "1.10" | ||||
|   - "tip" | ||||
|   - "1.12" | ||||
|   | ||||
							
								
								
									
										8
									
								
								vendor/github.com/pquerna/otp/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/pquerna/otp/go.mod
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| module github.com/pquerna/otp | ||||
|  | ||||
| go 1.12 | ||||
|  | ||||
| require ( | ||||
| 	github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc | ||||
| 	github.com/stretchr/testify v1.3.0 | ||||
| ) | ||||
							
								
								
									
										11
									
								
								vendor/github.com/pquerna/otp/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								vendor/github.com/pquerna/otp/go.sum
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| github.com/boombuler/barcode v1.0.0 h1:s1TvRnXwL2xJRaccrdcBQMZxq6X7DvsMogtmJeHDdrc= | ||||
| github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= | ||||
| github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc h1:biVzkmvwrH8WK8raXaxBx6fRVTlJILwEwQGL1I/ByEI= | ||||
| github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8= | ||||
| github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= | ||||
| github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= | ||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
							
								
								
									
										19
									
								
								vendor/github.com/pquerna/otp/hotp/hotp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								vendor/github.com/pquerna/otp/hotp/hotp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -19,6 +19,7 @@ package hotp | ||||
|  | ||||
| import ( | ||||
| 	"github.com/pquerna/otp" | ||||
| 	"io" | ||||
|  | ||||
| 	"crypto/hmac" | ||||
| 	"crypto/rand" | ||||
| @@ -146,12 +147,18 @@ type GenerateOpts struct { | ||||
| 	AccountName string | ||||
| 	// Size in size of the generated Secret. Defaults to 10 bytes. | ||||
| 	SecretSize uint | ||||
| 	// Secret to store. Defaults to a randomly generated secret of SecretSize.  You should generally leave this empty. | ||||
| 	Secret []byte | ||||
| 	// Digits to request. Defaults to 6. | ||||
| 	Digits otp.Digits | ||||
| 	// Algorithm to use for HMAC. Defaults to SHA1. | ||||
| 	Algorithm otp.Algorithm | ||||
| 	// Reader to use for generating HOTP Key. | ||||
| 	Rand io.Reader | ||||
| } | ||||
|  | ||||
| var b32NoPadding = base32.StdEncoding.WithPadding(base32.NoPadding) | ||||
|  | ||||
| // Generate creates a new HOTP Key. | ||||
| func Generate(opts GenerateOpts) (*otp.Key, error) { | ||||
| 	// url encode the Issuer/AccountName | ||||
| @@ -171,16 +178,24 @@ func Generate(opts GenerateOpts) (*otp.Key, error) { | ||||
| 		opts.Digits = otp.DigitsSix | ||||
| 	} | ||||
|  | ||||
| 	if opts.Rand == nil { | ||||
| 		opts.Rand = rand.Reader | ||||
| 	} | ||||
|  | ||||
| 	// otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example | ||||
|  | ||||
| 	v := url.Values{} | ||||
| 	if len(opts.Secret) != 0 { | ||||
| 		v.Set("secret", b32NoPadding.EncodeToString(opts.Secret)) | ||||
| 	} else { | ||||
| 		secret := make([]byte, opts.SecretSize) | ||||
| 	_, err := rand.Read(secret) | ||||
| 		_, err := opts.Rand.Read(secret) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		v.Set("secret", b32NoPadding.EncodeToString(secret)) | ||||
| 	} | ||||
|  | ||||
| 	v.Set("secret", strings.TrimRight(base32.StdEncoding.EncodeToString(secret), "=")) | ||||
| 	v.Set("issuer", opts.Issuer) | ||||
| 	v.Set("algorithm", opts.Algorithm.String()) | ||||
| 	v.Set("digits", opts.Digits.String()) | ||||
|   | ||||
							
								
								
									
										21
									
								
								vendor/github.com/pquerna/otp/totp/totp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/pquerna/otp/totp/totp.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -18,10 +18,9 @@ | ||||
| package totp | ||||
|  | ||||
| import ( | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/pquerna/otp" | ||||
| 	"github.com/pquerna/otp/hotp" | ||||
| 	"io" | ||||
|  | ||||
| 	"crypto/rand" | ||||
| 	"encoding/base32" | ||||
| @@ -138,12 +137,18 @@ type GenerateOpts struct { | ||||
| 	Period uint | ||||
| 	// Size in size of the generated Secret. Defaults to 20 bytes. | ||||
| 	SecretSize uint | ||||
| 	// Secret to store. Defaults to a randomly generated secret of SecretSize.  You should generally leave this empty. | ||||
| 	Secret []byte | ||||
| 	// Digits to request. Defaults to 6. | ||||
| 	Digits otp.Digits | ||||
| 	// Algorithm to use for HMAC. Defaults to SHA1. | ||||
| 	Algorithm otp.Algorithm | ||||
| 	// Reader to use for generating TOTP Key. | ||||
| 	Rand io.Reader | ||||
| } | ||||
|  | ||||
| var b32NoPadding = base32.StdEncoding.WithPadding(base32.NoPadding) | ||||
|  | ||||
| // Generate a new TOTP Key. | ||||
| func Generate(opts GenerateOpts) (*otp.Key, error) { | ||||
| 	// url encode the Issuer/AccountName | ||||
| @@ -167,16 +172,24 @@ func Generate(opts GenerateOpts) (*otp.Key, error) { | ||||
| 		opts.Digits = otp.DigitsSix | ||||
| 	} | ||||
|  | ||||
| 	if opts.Rand == nil { | ||||
| 		opts.Rand = rand.Reader | ||||
| 	} | ||||
|  | ||||
| 	// otpauth://totp/Example:alice@google.com?secret=JBSWY3DPEHPK3PXP&issuer=Example | ||||
|  | ||||
| 	v := url.Values{} | ||||
| 	if len(opts.Secret) != 0 { | ||||
| 		v.Set("secret", b32NoPadding.EncodeToString(opts.Secret)) | ||||
| 	} else { | ||||
| 		secret := make([]byte, opts.SecretSize) | ||||
| 	_, err := rand.Read(secret) | ||||
| 		_, err := opts.Rand.Read(secret) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		v.Set("secret", b32NoPadding.EncodeToString(secret)) | ||||
| 	} | ||||
|  | ||||
| 	v.Set("secret", strings.TrimRight(base32.StdEncoding.EncodeToString(secret), "=")) | ||||
| 	v.Set("issuer", opts.Issuer) | ||||
| 	v.Set("period", strconv.FormatUint(uint64(opts.Period), 10)) | ||||
| 	v.Set("algorithm", opts.Algorithm.String()) | ||||
|   | ||||
							
								
								
									
										9
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								vendor/modules.txt
									
									
									
									
										vendored
									
									
								
							| @@ -145,7 +145,7 @@ github.com/aws/aws-sdk-go/private/protocol/json/jsonutil | ||||
| github.com/beorn7/perks/quantile | ||||
| # github.com/bgentry/speakeasy v0.1.0 | ||||
| github.com/bgentry/speakeasy | ||||
| # github.com/boombuler/barcode v1.0.0 | ||||
| # github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc | ||||
| github.com/boombuler/barcode | ||||
| github.com/boombuler/barcode/qr | ||||
| github.com/boombuler/barcode/utils | ||||
| @@ -316,7 +316,7 @@ github.com/hashicorp/go-rootcerts | ||||
| github.com/hashicorp/go-sockaddr | ||||
| # github.com/hashicorp/go-syslog v1.0.0 | ||||
| github.com/hashicorp/go-syslog | ||||
| # github.com/hashicorp/go-uuid v1.0.1 | ||||
| # github.com/hashicorp/go-uuid v1.0.2-0.20191001231223-f32f5fe8d6a8 | ||||
| github.com/hashicorp/go-uuid | ||||
| # github.com/hashicorp/go-version v1.2.0 | ||||
| github.com/hashicorp/go-version | ||||
| @@ -383,7 +383,7 @@ github.com/hashicorp/vault-plugin-secrets-gcp/plugin/iamutil | ||||
| github.com/hashicorp/vault-plugin-secrets-gcp/plugin/util | ||||
| # github.com/hashicorp/vault-plugin-secrets-gcpkms v0.5.2-0.20190814210149-315cdbf5de6e | ||||
| github.com/hashicorp/vault-plugin-secrets-gcpkms | ||||
| # github.com/hashicorp/vault-plugin-secrets-kv v0.5.2-0.20190814210155-e060c2a001a8 | ||||
| # github.com/hashicorp/vault-plugin-secrets-kv v0.5.2-0.20191003164552-6600ec024c24 | ||||
| github.com/hashicorp/vault-plugin-secrets-kv | ||||
| # github.com/hashicorp/vault/api v1.0.5-0.20190919134245-4eefe0ebe1a1 => ./api | ||||
| github.com/hashicorp/vault/api | ||||
| @@ -428,6 +428,7 @@ github.com/hashicorp/vault/sdk/plugin/pb | ||||
| github.com/hashicorp/vault/sdk/database/helper/connutil | ||||
| github.com/hashicorp/vault/sdk/helper/license | ||||
| github.com/hashicorp/vault/sdk/helper/pluginutil | ||||
| github.com/hashicorp/vault/sdk/helper/entropy | ||||
| github.com/hashicorp/vault/sdk/helper/kdf | ||||
| github.com/hashicorp/vault/sdk/plugin/mock | ||||
| # github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d | ||||
| @@ -572,7 +573,7 @@ github.com/posener/complete/match | ||||
| # github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 | ||||
| github.com/pquerna/cachecontrol | ||||
| github.com/pquerna/cachecontrol/cacheobject | ||||
| # github.com/pquerna/otp v1.1.0 | ||||
| # github.com/pquerna/otp v1.2.1-0.20191009055518-468c2dd2b58d | ||||
| github.com/pquerna/otp | ||||
| github.com/pquerna/otp/totp | ||||
| github.com/pquerna/otp/hotp | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Lexman
					Lexman