github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/backend/remote-state/s3/validate.go (about) 1 package s3 2 3 import ( 4 "fmt" 5 "regexp" 6 7 "github.com/aws/aws-sdk-go/aws/arn" 8 "github.com/terramate-io/tf/tfdiags" 9 "github.com/zclconf/go-cty/cty" 10 ) 11 12 const ( 13 multiRegionKeyIdPattern = `mrk-[a-f0-9]{32}` 14 uuidRegexPattern = `[a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[ab89][a-f0-9]{3}-[a-f0-9]{12}` 15 ) 16 17 func validateKMSKey(path cty.Path, s string) (diags tfdiags.Diagnostics) { 18 if arn.IsARN(s) { 19 return validateKMSKeyARN(path, s) 20 } 21 return validateKMSKeyID(path, s) 22 } 23 24 func validateKMSKeyID(path cty.Path, s string) (diags tfdiags.Diagnostics) { 25 keyIdRegex := regexp.MustCompile(`^` + uuidRegexPattern + `|` + multiRegionKeyIdPattern + `$`) 26 if !keyIdRegex.MatchString(s) { 27 diags = diags.Append(tfdiags.AttributeValue( 28 tfdiags.Error, 29 "Invalid KMS Key ID", 30 fmt.Sprintf("Value must be a valid KMS Key ID, got %q", s), 31 path, 32 )) 33 return diags 34 } 35 36 return diags 37 } 38 39 func validateKMSKeyARN(path cty.Path, s string) (diags tfdiags.Diagnostics) { 40 parsedARN, err := arn.Parse(s) 41 if err != nil { 42 diags = diags.Append(tfdiags.AttributeValue( 43 tfdiags.Error, 44 "Invalid KMS Key ARN", 45 fmt.Sprintf("Value must be a valid KMS Key ARN, got %q", s), 46 path, 47 )) 48 return diags 49 } 50 51 if !isKeyARN(parsedARN) { 52 diags = diags.Append(tfdiags.AttributeValue( 53 tfdiags.Error, 54 "Invalid KMS Key ARN", 55 fmt.Sprintf("Value must be a valid KMS Key ARN, got %q", s), 56 path, 57 )) 58 return diags 59 } 60 61 return diags 62 } 63 64 func isKeyARN(arn arn.ARN) bool { 65 return keyIdFromARNResource(arn.Resource) != "" 66 } 67 68 func keyIdFromARNResource(s string) string { 69 keyIdResourceRegex := regexp.MustCompile(`^key/(` + uuidRegexPattern + `|` + multiRegionKeyIdPattern + `)$`) 70 matches := keyIdResourceRegex.FindStringSubmatch(s) 71 if matches == nil || len(matches) != 2 { 72 return "" 73 } 74 75 return matches[1] 76 }