1package command 2 3import ( 4 "context" 5 "crypto/rand" 6 "fmt" 7 "io" 8 9 log "github.com/hashicorp/go-hclog" 10 "github.com/hashicorp/vault/command/server" 11 "github.com/hashicorp/vault/vault" 12 vaultseal "github.com/hashicorp/vault/vault/seal" 13 shamirseal "github.com/hashicorp/vault/vault/seal/shamir" 14 "github.com/pkg/errors" 15) 16 17var ( 18 onEnterprise = false 19 createSecureRandomReaderFunc = createSecureRandomReader 20) 21 22func createSecureRandomReader(config *server.Config, seal *vault.Seal) (io.Reader, error) { 23 return rand.Reader, nil 24} 25 26func adjustCoreForSealMigration(logger log.Logger, core *vault.Core, barrierSeal, unwrapSeal vault.Seal) error { 27 existBarrierSealConfig, existRecoverySealConfig, err := core.PhysicalSealConfigs(context.Background()) 28 if err != nil { 29 return fmt.Errorf("Error checking for existing seal: %s", err) 30 } 31 32 // If we don't have an existing config or if it's the deprecated auto seal 33 // which needs an upgrade, skip out 34 if existBarrierSealConfig == nil || existBarrierSealConfig.Type == vaultseal.HSMAutoDeprecated { 35 return nil 36 } 37 38 if unwrapSeal == nil { 39 // We have the same barrier type and the unwrap seal is nil so we're not 40 // migrating from same to same, IOW we assume it's not a migration 41 if existBarrierSealConfig.Type == barrierSeal.BarrierType() { 42 return nil 43 } 44 45 // If we're not coming from Shamir, and the existing type doesn't match 46 // the barrier type, we need both the migration seal and the new seal 47 if existBarrierSealConfig.Type != vaultseal.Shamir && barrierSeal.BarrierType() != vaultseal.Shamir { 48 return errors.New(`Trying to migrate from auto-seal to auto-seal but no "disabled" seal stanza found`) 49 } 50 } else { 51 if unwrapSeal.BarrierType() == vaultseal.Shamir { 52 return errors.New("Shamir seals cannot be set disabled (they should simply not be set)") 53 } 54 } 55 56 var existSeal vault.Seal 57 var newSeal vault.Seal 58 59 if existBarrierSealConfig.Type == barrierSeal.BarrierType() { 60 // In this case our migration seal is set so we are using it 61 // (potentially) for unwrapping. Set it on core for that purpose then 62 // exit. 63 core.SetSealsForMigration(nil, nil, unwrapSeal) 64 return nil 65 } 66 67 if existBarrierSealConfig.Type != vaultseal.Shamir && existRecoverySealConfig == nil { 68 return errors.New(`Recovery seal configuration not found for existing seal`) 69 } 70 71 switch existBarrierSealConfig.Type { 72 case vaultseal.Shamir: 73 // The value reflected in config is what we're going to 74 existSeal = vault.NewDefaultSeal(shamirseal.NewSeal(logger.Named("shamir"))) 75 newSeal = barrierSeal 76 newBarrierSealConfig := &vault.SealConfig{ 77 Type: newSeal.BarrierType(), 78 SecretShares: 1, 79 SecretThreshold: 1, 80 StoredShares: 1, 81 } 82 newSeal.SetCachedBarrierConfig(newBarrierSealConfig) 83 newSeal.SetCachedRecoveryConfig(existBarrierSealConfig) 84 85 default: 86 if onEnterprise && barrierSeal.BarrierType() == vaultseal.Shamir { 87 return errors.New("Migrating from autoseal to Shamir seal is not currently supported on Vault Enterprise") 88 } 89 90 // If we're not coming from Shamir we expect the previous seal to be 91 // in the config and disabled. 92 existSeal = unwrapSeal 93 newSeal = barrierSeal 94 newSeal.SetCachedBarrierConfig(existRecoverySealConfig) 95 } 96 97 core.SetSealsForMigration(existSeal, newSeal, unwrapSeal) 98 99 return nil 100} 101