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"
2015-09-14 20:28:46 +00:00
"github.com/hashicorp/vault/logical"
"github.com/hashicorp/vault/logical/framework"
)
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 {
2016-02-02 14:26:25 +00:00
"name" : & framework . FieldSchema {
Type : framework . TypeString ,
Description : "Name of the key" ,
} ,
"min_decryption_version" : & framework . FieldSchema {
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 . ` ,
} ,
"min_encryption_version" : & framework . FieldSchema {
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
} ,
"deletion_allowed" : & framework . FieldSchema {
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
"exportable" : & framework . FieldSchema {
Type : framework . TypeBool ,
Description : ` Enables export of the key. Once set, this cannot be disabled. ` ,
} ,
"allow_plaintext_backup" : & framework . FieldSchema {
Type : framework . TypeBool ,
Description : ` Enables taking a backup of the named key in plaintext format. Once set, this cannot be disabled. ` ,
} ,
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-01-08 18:31:38 +00:00
func ( b * backend ) pathConfigWrite ( ctx context . Context , req * logical . Request , d * framework . FieldData ) ( * logical . Response , 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
2018-01-19 06:44:44 +00:00
p , lock , err := b . lm . GetPolicyExclusive ( ctx , req . Storage , name )
2016-05-03 03:46:39 +00:00
if lock != nil {
defer lock . Unlock ( )
}
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
}
2016-02-02 14:26:25 +00:00
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
}
}
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
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
`