2015-09-14 20:28:46 +00:00
package transit
import (
2018-01-08 18:31:38 +00:00
"context"
2016-02-02 14:26:25 +00:00
"fmt"
2022-01-20 15:10:15 +00:00
"time"
2016-02-02 14:26:25 +00:00
2019-04-13 07:44:06 +00:00
"github.com/hashicorp/vault/sdk/framework"
2019-04-12 21:54:35 +00:00
"github.com/hashicorp/vault/sdk/helper/keysutil"
"github.com/hashicorp/vault/sdk/logical"
2015-09-14 20:28:46 +00:00
)
2016-01-27 21:24:11 +00:00
func ( b * backend ) pathConfig ( ) * framework . Path {
2015-09-14 20:28:46 +00:00
return & framework . Path {
2016-02-02 14:26:25 +00:00
Pattern : "keys/" + framework . GenericNameRegex ( "name" ) + "/config" ,
2015-09-14 20:28:46 +00:00
Fields : map [ string ] * framework . FieldSchema {
2021-04-08 16:43:39 +00:00
"name" : {
2016-02-02 14:26:25 +00:00
Type : framework . TypeString ,
Description : "Name of the key" ,
} ,
2021-04-08 16:43:39 +00:00
"min_decryption_version" : {
2016-02-02 14:26:25 +00:00
Type : framework . TypeInt ,
Description : ` If set , the minimum version of the key allowed
2017-06-06 20:02:54 +00:00
to be decrypted . For signing keys , the minimum
version allowed to be used for verification . ` ,
} ,
2021-04-08 16:43:39 +00:00
"min_encryption_version" : {
2017-06-06 20:02:54 +00:00
Type : framework . TypeInt ,
Description : ` If set , the minimum version of the key allowed
to be used for encryption ; or for signing keys ,
to be used for signing . If set to zero , only
the latest version of the key is allowed . ` ,
2016-02-02 14:26:25 +00:00
} ,
2021-04-08 16:43:39 +00:00
"deletion_allowed" : {
2016-02-02 14:26:25 +00:00
Type : framework . TypeBool ,
Description : "Whether to allow deletion of the key" ,
2015-09-17 22:49:50 +00:00
} ,
2017-12-14 17:51:50 +00:00
2021-04-08 16:43:39 +00:00
"exportable" : {
2017-12-14 17:51:50 +00:00
Type : framework . TypeBool ,
Description : ` Enables export of the key. Once set, this cannot be disabled. ` ,
} ,
2021-04-08 16:43:39 +00:00
"allow_plaintext_backup" : {
2017-12-14 17:51:50 +00:00
Type : framework . TypeBool ,
Description : ` Enables taking a backup of the named key in plaintext format. Once set, this cannot be disabled. ` ,
} ,
2022-01-20 15:10:15 +00:00
2022-02-17 20:17:59 +00:00
"auto_rotate_period" : {
2022-01-20 15:10:15 +00:00
Type : framework . TypeDurationSecond ,
Description : ` Amount of time the key should live before
being automatically rotated . A value of 0
disables automatic rotation for the key . ` ,
} ,
2015-09-14 20:28:46 +00:00
} ,
Callbacks : map [ logical . Operation ] framework . OperationFunc {
2016-01-27 21:24:11 +00:00
logical . UpdateOperation : b . pathConfigWrite ,
2015-09-14 20:28:46 +00:00
} ,
HelpSynopsis : pathConfigHelpSyn ,
HelpDescription : pathConfigHelpDesc ,
}
}
2018-10-17 16:05:05 +00:00
func ( b * backend ) pathConfigWrite ( ctx context . Context , req * logical . Request , d * framework . FieldData ) ( resp * logical . Response , retErr error ) {
2016-02-02 14:26:25 +00:00
name := d . Get ( "name" ) . ( string )
2015-09-14 20:28:46 +00:00
2016-04-26 15:39:19 +00:00
// Check if the policy already exists before we lock everything
2021-09-13 21:44:56 +00:00
p , _ , err := b . GetPolicy ( ctx , keysutil . PolicyRequest {
2018-06-12 16:24:12 +00:00
Storage : req . Storage ,
Name : name ,
2019-10-17 17:33:00 +00:00
} , b . GetRandomReader ( ) )
2015-09-14 20:28:46 +00:00
if err != nil {
return nil , err
}
2016-04-26 15:39:19 +00:00
if p == nil {
2016-02-02 14:26:25 +00:00
return logical . ErrorResponse (
2016-04-21 20:32:06 +00:00
fmt . Sprintf ( "no existing key named %s could be found" , name ) ) ,
2016-02-02 14:26:25 +00:00
logical . ErrInvalidRequest
2015-09-14 20:28:46 +00:00
}
2018-06-12 16:24:12 +00:00
if ! b . System ( ) . CachingDisabled ( ) {
p . Lock ( true )
}
defer p . Unlock ( )
2015-09-14 20:28:46 +00:00
2018-10-17 16:05:05 +00:00
originalMinDecryptionVersion := p . MinDecryptionVersion
originalMinEncryptionVersion := p . MinEncryptionVersion
originalDeletionAllowed := p . DeletionAllowed
originalExportable := p . Exportable
originalAllowPlaintextBackup := p . AllowPlaintextBackup
defer func ( ) {
if retErr != nil || ( resp != nil && resp . IsError ( ) ) {
p . MinDecryptionVersion = originalMinDecryptionVersion
p . MinEncryptionVersion = originalMinEncryptionVersion
p . DeletionAllowed = originalDeletionAllowed
p . Exportable = originalExportable
p . AllowPlaintextBackup = originalAllowPlaintextBackup
}
} ( )
resp = & logical . Response { }
2016-01-22 19:10:09 +00:00
2016-02-02 14:26:25 +00:00
persistNeeded := false
2015-09-17 22:49:50 +00:00
2016-02-02 14:26:25 +00:00
minDecryptionVersionRaw , ok := d . GetOk ( "min_decryption_version" )
if ok {
minDecryptionVersion := minDecryptionVersionRaw . ( int )
2016-01-22 19:10:09 +00:00
2016-02-02 14:26:25 +00:00
if minDecryptionVersion < 0 {
return logical . ErrorResponse ( "min decryption version cannot be negative" ) , nil
}
2016-01-22 19:10:09 +00:00
2016-02-02 14:26:25 +00:00
if minDecryptionVersion == 0 {
minDecryptionVersion = 1
resp . AddWarning ( "since Vault 0.3, transit key numbering starts at 1; forcing minimum to 1" )
}
2016-01-22 19:10:09 +00:00
2017-06-06 20:02:54 +00:00
if minDecryptionVersion != p . MinDecryptionVersion {
2016-04-26 15:39:19 +00:00
if minDecryptionVersion > p . LatestVersion {
2016-02-02 14:26:25 +00:00
return logical . ErrorResponse (
2016-04-26 15:39:19 +00:00
fmt . Sprintf ( "cannot set min decryption version of %d, latest key version is %d" , minDecryptionVersion , p . LatestVersion ) ) , nil
2016-02-02 14:26:25 +00:00
}
2016-04-26 15:39:19 +00:00
p . MinDecryptionVersion = minDecryptionVersion
2016-02-02 14:26:25 +00:00
persistNeeded = true
}
2015-09-14 20:28:46 +00:00
}
2017-06-06 20:02:54 +00:00
minEncryptionVersionRaw , ok := d . GetOk ( "min_encryption_version" )
if ok {
minEncryptionVersion := minEncryptionVersionRaw . ( int )
if minEncryptionVersion < 0 {
return logical . ErrorResponse ( "min encryption version cannot be negative" ) , nil
}
if minEncryptionVersion != p . MinEncryptionVersion {
if minEncryptionVersion > p . LatestVersion {
return logical . ErrorResponse (
fmt . Sprintf ( "cannot set min encryption version of %d, latest key version is %d" , minEncryptionVersion , p . LatestVersion ) ) , nil
}
p . MinEncryptionVersion = minEncryptionVersion
persistNeeded = true
}
}
// Check here to get the final picture after the logic on each
// individually. MinDecryptionVersion will always be 1 or above.
if p . MinEncryptionVersion > 0 &&
p . MinEncryptionVersion < p . MinDecryptionVersion {
return logical . ErrorResponse (
fmt . Sprintf ( "cannot set min encryption/decryption values; min encryption version of %d must be greater than or equal to min decryption version of %d" , p . MinEncryptionVersion , p . MinDecryptionVersion ) ) , nil
}
2016-02-02 14:26:25 +00:00
allowDeletionInt , ok := d . GetOk ( "deletion_allowed" )
if ok {
allowDeletion := allowDeletionInt . ( bool )
2016-04-26 15:39:19 +00:00
if allowDeletion != p . DeletionAllowed {
p . DeletionAllowed = allowDeletion
2016-02-02 14:26:25 +00:00
persistNeeded = true
}
2015-09-17 22:49:50 +00:00
}
2016-02-02 14:26:25 +00:00
// Add this as a guard here before persisting since we now require the min
// decryption version to start at 1; even if it's not explicitly set here,
// force the upgrade
2016-04-26 15:39:19 +00:00
if p . MinDecryptionVersion == 0 {
p . MinDecryptionVersion = 1
2016-02-02 14:26:25 +00:00
persistNeeded = true
2016-01-26 17:23:42 +00:00
}
2016-02-02 14:26:25 +00:00
2017-12-14 17:51:50 +00:00
exportableRaw , ok := d . GetOk ( "exportable" )
if ok {
exportable := exportableRaw . ( bool )
// Don't unset the already set value
if exportable && ! p . Exportable {
p . Exportable = exportable
persistNeeded = true
}
}
allowPlaintextBackupRaw , ok := d . GetOk ( "allow_plaintext_backup" )
if ok {
allowPlaintextBackup := allowPlaintextBackupRaw . ( bool )
// Don't unset the already set value
if allowPlaintextBackup && ! p . AllowPlaintextBackup {
p . AllowPlaintextBackup = allowPlaintextBackup
persistNeeded = true
}
}
2022-02-17 20:17:59 +00:00
autoRotatePeriodRaw , ok , err := d . GetOkErr ( "auto_rotate_period" )
2022-01-20 15:10:15 +00:00
if err != nil {
return nil , err
}
if ok {
2022-02-17 20:17:59 +00:00
autoRotatePeriod := time . Second * time . Duration ( autoRotatePeriodRaw . ( int ) )
2022-01-20 15:10:15 +00:00
// Provided value must be 0 to disable or at least an hour
2022-02-17 20:17:59 +00:00
if autoRotatePeriod != 0 && autoRotatePeriod < time . Hour {
return logical . ErrorResponse ( "auto rotate period must be 0 to disable or at least an hour" ) , nil
2022-01-20 15:10:15 +00:00
}
2022-02-17 20:17:59 +00:00
if autoRotatePeriod != p . AutoRotatePeriod {
p . AutoRotatePeriod = autoRotatePeriod
2022-01-20 15:10:15 +00:00
persistNeeded = true
}
}
2016-02-02 14:26:25 +00:00
if ! persistNeeded {
return nil , nil
2015-09-17 22:49:50 +00:00
}
2015-09-14 20:28:46 +00:00
2018-10-17 16:05:05 +00:00
switch {
case p . MinAvailableVersion > p . MinEncryptionVersion :
return logical . ErrorResponse ( "min encryption version should not be less than min available version" ) , nil
case p . MinAvailableVersion > p . MinDecryptionVersion :
return logical . ErrorResponse ( "min decryption version should not be less then min available version" ) , nil
}
2017-06-05 14:52:43 +00:00
if len ( resp . Warnings ) == 0 {
2018-01-19 06:44:44 +00:00
return nil , p . Persist ( ctx , req . Storage )
2016-06-20 17:17:48 +00:00
}
2018-01-19 06:44:44 +00:00
return resp , p . Persist ( ctx , req . Storage )
2015-09-14 20:28:46 +00:00
}
2016-02-02 14:26:25 +00:00
const pathConfigHelpSyn = ` Configure a named encryption key `
2015-09-14 20:28:46 +00:00
const pathConfigHelpDesc = `
2016-02-02 14:26:25 +00:00
This path is used to configure the named key . Currently , this
supports adjusting the minimum version of the key allowed to
2018-03-20 18:54:10 +00:00
be used for decryption via the min_decryption_version parameter .
2016-02-02 14:26:25 +00:00
`