1515
1616import { needs } from '@aws-crypto/material-management'
1717
18+ /* See: https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-kms
19+ * regex to match: 'resourceType/resourceId' || 'resourceType'
20+ * This is complicated because the `split(':')`.
21+ * The valid resourceType resourceId delimiters are `/`, `:`.
22+ * This means if the delimiter is a `:` it will be split out,
23+ * when splitting the whole arn.
24+ */
25+ const aliasOrKeyResourceType = / ^ ( a l i a s | k e y ) ( \/ .* ) * $ /
26+
1827export function regionFromKmsKeyArn ( kmsKeyArn : string ) : string {
1928 /* Precondition: A KMS key arn must be a string. */
2029 needs ( typeof kmsKeyArn === 'string' , 'KMS key arn must be a string.' )
@@ -23,17 +32,30 @@ export function regionFromKmsKeyArn (kmsKeyArn: string): string {
2332 * arn:aws:kms:us-east-1:123456789012:key/12345678-1234-1234-1234-123456789012
2433 * arn:aws:kms:us-east-1:123456789012:alias/example-alias
2534 */
26- const [ arnLiteral , partition , service , region ] = kmsKeyArn . split ( ':' )
35+ const [ arnLiteral , partition , service , region = '' ] = kmsKeyArn . split ( ':' )
2736
2837 /* Postcondition: The ARN must be well formed.
2938 * The arn and kms section have defined values,
3039 * but the aws section does not.
40+ * It is also possible to have a a key or alias.
41+ * In this case the partition, service, region
42+ * will be empty.
43+ * In this case the arnLiteral should look like an alias.
3144 */
3245 needs (
33- arnLiteral === 'arn' &&
34- partition &&
35- service === 'kms' &&
36- region ,
46+ ( arnLiteral === 'arn' &&
47+ partition &&
48+ service === 'kms' &&
49+ region ) ||
50+ /* Partition may or may not have a value.
51+ * If the resourceType delimiter is /,
52+ * it will not have a value.
53+ * However if the delimiter is : it will
54+ * because of the split(':')
55+ */
56+ ( ! service &&
57+ ! region &&
58+ arnLiteral . match ( aliasOrKeyResourceType ) ) ,
3759 'Malformed arn.' )
3860
3961 return region
0 commit comments