Skip to content

Commit f1c7ffa

Browse files
authored
Prevent hash error bcrypt.ErrPasswordTooLong for passwords > 72 bytes in length (#397)
* Truncating passwords that are longer than 72 bytes (#396) * Adding changelog entry (#396) * Updating changelog entry and docs (#396) * Updating changelog entry (#396) * updated comment msg
1 parent 800bbd5 commit f1c7ffa

File tree

4 files changed

+35
-13
lines changed

4 files changed

+35
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
kind: BUG FIXES
2+
body: 'resource/random_password: Prevent error with `bcrypt` by truncating the bytes
3+
that are hashed to a maximum length of 72'
4+
time: 2023-04-12T13:25:01.113462+01:00
5+
custom:
6+
Issue: "397"

docs/resources/password.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ resource "aws_db_instance" "example" {
5353

5454
### Read-Only
5555

56-
- `bcrypt_hash` (String, Sensitive) A bcrypt hash of the generated random string.
56+
- `bcrypt_hash` (String, Sensitive) A bcrypt hash of the generated random string. **NOTE**: If the generated random string is greater than 72 bytes in length, `bcrypt_hash` will contain a hash of the first 72 bytes.
5757
- `id` (String) A static value used internally by Terraform, this should not be referenced in configurations.
5858
- `result` (String, Sensitive) The generated random string.
5959

internal/provider/resource_password.go

+26-10
Original file line numberDiff line numberDiff line change
@@ -535,8 +535,18 @@ func upgradePasswordStateV2toV3(ctx context.Context, req resource.UpgradeStateRe
535535
resp.Diagnostics.Append(resp.State.Set(ctx, passwordDataV3)...)
536536
}
537537

538+
// generateHash truncates strings that are longer than 72 bytes in
539+
// order to avoid the error returned from bcrypt.GenerateFromPassword
540+
// in versions v0.5.0 and above: https://pkg.go.dev/golang.org/x/[email protected]/bcrypt#GenerateFromPassword
538541
func generateHash(toHash string) (string, error) {
539-
hash, err := bcrypt.GenerateFromPassword([]byte(toHash), bcrypt.DefaultCost)
542+
bytesHash := []byte(toHash)
543+
bytesToHash := bytesHash
544+
545+
if len(bytesHash) > 72 {
546+
bytesToHash = bytesHash[:72]
547+
}
548+
549+
hash, err := bcrypt.GenerateFromPassword(bytesToHash, bcrypt.DefaultCost)
540550

541551
return string(hash), err
542552
}
@@ -693,9 +703,11 @@ func passwordSchemaV3() schema.Schema {
693703
},
694704

695705
"bcrypt_hash": schema.StringAttribute{
696-
Description: "A bcrypt hash of the generated random string.",
697-
Computed: true,
698-
Sensitive: true,
706+
Description: "A bcrypt hash of the generated random string. " +
707+
"**NOTE**: If the generated random string is greater than 72 bytes in length, " +
708+
"`bcrypt_hash` will contain a hash of the first 72 bytes.",
709+
Computed: true,
710+
Sensitive: true,
699711
PlanModifiers: []planmodifier.String{
700712
stringplanmodifier.UseStateForUnknown(),
701713
},
@@ -805,9 +817,11 @@ func passwordSchemaV2() schema.Schema {
805817
},
806818

807819
"bcrypt_hash": schema.StringAttribute{
808-
Description: "A bcrypt hash of the generated random string.",
809-
Computed: true,
810-
Sensitive: true,
820+
Description: "A bcrypt hash of the generated random string. " +
821+
"**NOTE**: If the generated random string is greater than 72 bytes in length, " +
822+
"`bcrypt_hash` will contain a hash of the first 72 bytes.",
823+
Computed: true,
824+
Sensitive: true,
811825
},
812826

813827
"id": schema.StringAttribute{
@@ -903,9 +917,11 @@ func passwordSchemaV1() schema.Schema {
903917
},
904918

905919
"bcrypt_hash": schema.StringAttribute{
906-
Description: "A bcrypt hash of the generated random string.",
907-
Computed: true,
908-
Sensitive: true,
920+
Description: "A bcrypt hash of the generated random string. " +
921+
"**NOTE**: If the generated random string is greater than 72 bytes in length, " +
922+
"`bcrypt_hash` will contain a hash of the first 72 bytes.",
923+
Computed: true,
924+
Sensitive: true,
909925
},
910926

911927
"id": schema.StringAttribute{

internal/provider/resource_password_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ func TestGenerateHash(t *testing.T) {
2828
}{
2929
"defaults": {
3030
input: random.StringParams{
31-
Length: 32, // Required
31+
Length: 73, // Required
3232
Lower: true,
3333
Numeric: true,
3434
Special: true,
@@ -111,7 +111,7 @@ func TestAccResourcePassword_BcryptHash(t *testing.T) {
111111
Steps: []resource.TestStep{
112112
{
113113
Config: `resource "random_password" "test" {
114-
length = 12
114+
length = 73
115115
}`,
116116
Check: resource.ComposeTestCheckFunc(
117117
testExtractResourceAttr("random_password.test", "bcrypt_hash", &bcryptHash),

0 commit comments

Comments
 (0)