Skip to content

Commit 2e09e74

Browse files
basic searchable encryption
1 parent 27ce783 commit 2e09e74

File tree

1 file changed

+190
-0
lines changed

1 file changed

+190
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package searchableencryption
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"time"
7+
8+
dbeskstructuredencryption "github.com/aws/aws-database-encryption-sdk-dynamodb/awscryptographydbencryptionsdkstructuredencryptionsmithygeneratedtypes"
9+
"github.com/aws/aws-sdk-go-v2/aws"
10+
11+
keystore "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographykeystoresmithygenerated"
12+
keystoretypes "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographykeystoresmithygeneratedtypes"
13+
mpl "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygenerated"
14+
mpltypes "github.com/aws/aws-cryptographic-material-providers-library/releases/go/mpl/awscryptographymaterialproviderssmithygeneratedtypes"
15+
dbesdktypes "github.com/aws/aws-database-encryption-sdk-dynamodb/awscryptographydbencryptionsdkdynamodbsmithygeneratedtypes"
16+
"github.com/aws/aws-database-encryption-sdk-dynamodb/dbesdkmiddleware"
17+
"github.com/aws/aws-sdk-go-v2/config"
18+
"github.com/aws/aws-sdk-go-v2/service/dynamodb"
19+
"github.com/aws/aws-sdk-go-v2/service/dynamodb/types"
20+
"github.com/aws/aws-sdk-go-v2/service/kms"
21+
)
22+
23+
func putAndQueryWithBeacon(branchKeyId string) {
24+
ddbTableName := "UnitInspectionTestTableCS"
25+
branchKeyWrappingKmsKeyArn := "arn:aws:kms:us-west-2:370957321024:key/9d989aa2-2f9c-438c-a745-cc57d3ad0126"
26+
branchKeyDdbTableName := "KeyStoreDdbTable"
27+
GSI_NAME := "last4-unit-index"
28+
29+
last4Beacon := dbesdktypes.StandardBeacon{
30+
Name: "inspector_id_last4",
31+
Length: 10,
32+
}
33+
34+
unitBeacon := dbesdktypes.StandardBeacon{
35+
Name: "unit",
36+
Length: 30,
37+
}
38+
39+
standard_beacon_list := []dbesdktypes.StandardBeacon{last4Beacon, unitBeacon}
40+
41+
cfg, err := config.LoadDefaultConfig(context.TODO())
42+
if err != nil {
43+
panic(err)
44+
}
45+
// Step 1a: Create the aws kms client
46+
kmsClient := kms.NewFromConfig(cfg)
47+
// Step 1b: Create the ddb client
48+
ddbClient := dynamodb.NewFromConfig(cfg)
49+
50+
kmsConfig := keystoretypes.KMSConfigurationMemberkmsKeyArn{
51+
Value: branchKeyWrappingKmsKeyArn,
52+
}
53+
keyStore, err := keystore.NewClient(keystoretypes.KeyStoreConfig{
54+
DdbTableName: branchKeyDdbTableName,
55+
KmsConfiguration: &kmsConfig,
56+
LogicalKeyStoreName: branchKeyDdbTableName,
57+
DdbClient: ddbClient,
58+
KmsClient: kmsClient,
59+
})
60+
if err != nil {
61+
panic(err)
62+
}
63+
64+
beacon_version := dbesdktypes.BeaconVersion{
65+
StandardBeacons: standard_beacon_list,
66+
Version: 1,
67+
KeyStore: keyStore,
68+
KeySource: &dbesdktypes.BeaconKeySourceMembersingle{
69+
Value: dbesdktypes.SingleKeyStore{
70+
KeyId: branchKeyId,
71+
CacheTTL: 6000,
72+
},
73+
},
74+
}
75+
beaconVersions := []dbesdktypes.BeaconVersion{beacon_version}
76+
77+
// Create the Hierarchical Keyring.
78+
matProv, err := mpl.NewClient(mpltypes.MaterialProvidersConfig{})
79+
if err != nil {
80+
panic(err)
81+
}
82+
hkeyringInput := mpltypes.CreateAwsKmsHierarchicalKeyringInput{
83+
KeyStore: keyStore,
84+
BranchKeyId: &branchKeyId,
85+
TtlSeconds: 6000,
86+
}
87+
keyring, err := matProv.CreateAwsKmsHierarchicalKeyring(context.Background(), hkeyringInput)
88+
if err != nil {
89+
panic(err)
90+
}
91+
92+
attributeActionsOnEncrypt := map[string]dbeskstructuredencryption.CryptoAction{
93+
"work_id": dbeskstructuredencryption.CryptoActionSignOnly, // Our partition attribute must be SIGN_ONLY
94+
"inspection_date": dbeskstructuredencryption.CryptoActionSignOnly, // Our sort attribute must be SIGN_ONLY
95+
"inspector_id_last4": dbeskstructuredencryption.CryptoActionEncryptAndSign, // Beaconized attributes must be encrypted
96+
"unit": dbeskstructuredencryption.CryptoActionEncryptAndSign, // Beaconized attributes must be encrypted
97+
}
98+
99+
sortName := "inspection_date"
100+
tableConfig := dbesdktypes.DynamoDbTableEncryptionConfig{
101+
LogicalTableName: ddbTableName,
102+
PartitionKeyName: "work_id",
103+
SortKeyName: &sortName,
104+
AttributeActionsOnEncrypt: attributeActionsOnEncrypt,
105+
Keyring: keyring,
106+
Search: &dbesdktypes.SearchConfig{
107+
WriteVersion: 1,
108+
Versions: beaconVersions,
109+
},
110+
}
111+
112+
tableConfigs := dbesdktypes.DynamoDbTablesEncryptionConfig{
113+
TableEncryptionConfigs: map[string]dbesdktypes.DynamoDbTableEncryptionConfig{
114+
ddbTableName: tableConfig,
115+
},
116+
}
117+
118+
dbEsdkMiddleware, err := dbesdkmiddleware.NewDBEsdkMiddleware(tableConfigs)
119+
if err != nil {
120+
panic(err)
121+
}
122+
ddb := dynamodb.NewFromConfig(cfg, dbEsdkMiddleware.CreateMiddleware())
123+
124+
item := map[string]types.AttributeValue{
125+
"work_id": &types.AttributeValueMemberS{Value: "1313ba89-5661-41eb-ba6c-cb1b4cb67b2d"},
126+
"inspection_date": &types.AttributeValueMemberS{Value: "2023-06-13"},
127+
"inspector_id_last4": &types.AttributeValueMemberS{Value: "4321"},
128+
"unit": &types.AttributeValueMemberS{Value: "123456789012"},
129+
}
130+
131+
putInput := &dynamodb.PutItemInput{
132+
TableName: aws.String(ddbTableName),
133+
Item: item,
134+
}
135+
136+
_, err = ddb.PutItem(context.TODO(), putInput)
137+
if err != nil {
138+
panic(err)
139+
}
140+
141+
expressionAttributesNames := map[string]string{
142+
"#last4": "inspector_id_last4",
143+
"#unit": "unit",
144+
}
145+
146+
expressionAttributeValues := map[string]types.AttributeValue{
147+
":last4": &types.AttributeValueMemberS{
148+
Value: "4321",
149+
},
150+
":unit": &types.AttributeValueMemberS{
151+
Value: "123456789012",
152+
},
153+
}
154+
keyConditionExpression := "#last4 = :last4 and #unit = :unit"
155+
for i := 0; i < 10; i++ {
156+
queryResponse, err := ddbClient.Query(context.TODO(), &dynamodb.QueryInput{
157+
TableName: &ddbTableName,
158+
IndexName: &GSI_NAME,
159+
KeyConditionExpression: &keyConditionExpression,
160+
ExpressionAttributeNames: expressionAttributesNames,
161+
ExpressionAttributeValues: expressionAttributeValues,
162+
})
163+
if err != nil {
164+
panic(err)
165+
}
166+
167+
// if no results, sleep and try again
168+
if queryResponse.Items == nil || len(queryResponse.Items) == 0 {
169+
time.Sleep(20 * time.Millisecond)
170+
continue
171+
}
172+
173+
attributeValues := queryResponse.Items
174+
// Validate only 1 item was returned: the item we just put
175+
if len(attributeValues) != 1 {
176+
panic("expected 1 item")
177+
}
178+
179+
returnedItem := attributeValues[0]
180+
// Validate the item has the expected attributes
181+
if returnedItem["inspector_id_last4"].(*types.AttributeValueMemberS).Value != "4321" {
182+
panic("expected inspector_id_last4 to be 4321")
183+
}
184+
if returnedItem["unit"].(*types.AttributeValueMemberS).Value != "123456789012" {
185+
panic("expected unit to be 123456789012")
186+
}
187+
break
188+
}
189+
fmt.Println("basic_searchable_encryption successful.")
190+
}

0 commit comments

Comments
 (0)