Skip to content

Commit cc937b4

Browse files
josecorellalucasmcdonald3
andauthoredNov 25, 2024··
chore: Add ECDH examples (#1461)
Co-authored-by: Lucas McDonald <lucasmcdonald3@gmail.com>
1 parent 28d06fe commit cc937b4

File tree

10 files changed

+2868
-126
lines changed

10 files changed

+2868
-126
lines changed
 

‎Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/keyring/KmsEcdhKeyringExample.java

+694
Large diffs are not rendered by default.

‎Examples/runtimes/java/DynamoDbEncryption/src/main/java/software/amazon/cryptography/examples/keyring/RawEcdhKeyringExample.java

+885
Large diffs are not rendered by default.

‎Examples/runtimes/java/DynamoDbEncryption/src/test/java/software/amazon/cryptography/examples/TestUtils.java

+4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ public class TestUtils {
2020
"arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7";
2121
public static final String TEST_MRK_REPLICA_KEY_ID_EU_WEST_1 =
2222
"arn:aws:kms:eu-west-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7";
23+
public static final String TEST_KMS_ECDH_KEY_ID_P256_SENDER =
24+
"arn:aws:kms:us-west-2:370957321024:key/eabdf483-6be2-4d2d-8ee4-8c2583d416e9";
25+
public static final String TEST_KMS_ECDH_KEY_ID_P256_RECIPIENT =
26+
"arn:aws:kms:us-west-2:370957321024:key/0265c8e9-5b6a-4055-8f70-63719e09fda5";
2327

2428
// Our tests require access to DDB Table with this name
2529
public static final String TEST_DDB_TABLE_NAME =
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package software.amazon.cryptography.examples.keyring;
2+
3+
import static software.amazon.cryptography.examples.keyring.KmsEcdhKeyringExample.EXAMPLE_ECC_PUBLIC_KEY_RECIPIENT_FILENAME;
4+
import static software.amazon.cryptography.examples.keyring.KmsEcdhKeyringExample.EXAMPLE_ECC_PUBLIC_KEY_SENDER_FILENAME;
5+
import static software.amazon.cryptography.examples.keyring.KmsEcdhKeyringExample.shouldGetNewPublicKeys;
6+
import static software.amazon.cryptography.examples.keyring.KmsEcdhKeyringExample.writePublicKeyPemForEccKey;
7+
8+
import org.testng.annotations.Test;
9+
import software.amazon.cryptography.examples.TestUtils;
10+
11+
public class TestKmsEcdhKeyringExample {
12+
13+
@Test
14+
public void TestKmsEcdhKeyringExampleStatic() {
15+
// You may provide your own ECC public keys at
16+
// - EXAMPLE_ECC_PUBLIC_KEY_SENDER_FILENAME
17+
// - EXAMPLE_ECC_PUBLIC_KEY_RECIPIENT_FILENAME.
18+
// If you provide these, the keys MUST be on curve P256
19+
// This must be the public key for the ECC key represented at eccKeyArn
20+
// If this file is not present, this will write a UTF-8 encoded PEM file for you.
21+
if (shouldGetNewPublicKeys()) {
22+
writePublicKeyPemForEccKey(
23+
TestUtils.TEST_KMS_ECDH_KEY_ID_P256_SENDER,
24+
EXAMPLE_ECC_PUBLIC_KEY_SENDER_FILENAME
25+
);
26+
writePublicKeyPemForEccKey(
27+
TestUtils.TEST_KMS_ECDH_KEY_ID_P256_RECIPIENT,
28+
EXAMPLE_ECC_PUBLIC_KEY_RECIPIENT_FILENAME
29+
);
30+
}
31+
32+
KmsEcdhKeyringExample.KmsEcdhKeyringGetItemPutItem(
33+
TestUtils.TEST_DDB_TABLE_NAME,
34+
TestUtils.TEST_KMS_ECDH_KEY_ID_P256_SENDER
35+
);
36+
}
37+
38+
@Test
39+
public void TestKmsEcdhKeyringExampleDiscovery() {
40+
// In this example you do not need to provide the recipient ECC Public Key.
41+
// On initialization, the keyring will call KMS:getPublicKey on the configured
42+
// recipientKmsIdentifier set on the keyring. This example uses the previous example
43+
// to write an item meant for the recipient.
44+
KmsEcdhKeyringExample.KmsEcdhDiscoveryGetItem(
45+
TestUtils.TEST_DDB_TABLE_NAME,
46+
TestUtils.TEST_KMS_ECDH_KEY_ID_P256_RECIPIENT
47+
);
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package software.amazon.cryptography.examples.keyring;
2+
3+
import java.nio.ByteBuffer;
4+
import java.security.spec.ECGenParameterSpec;
5+
import org.testng.annotations.Test;
6+
import software.amazon.cryptography.examples.TestUtils;
7+
import software.amazon.cryptography.primitives.model.ECDHCurveSpec;
8+
9+
public class TestRawEcdhKeyringExample {
10+
11+
@Test
12+
public void TestStaticRawEcdhKeyringExample() {
13+
// You may provide your own ECC Key pairs in the files located at
14+
// - EXAMPLE_ECC_PRIVATE_KEY_FILENAME_SENDER
15+
// - EXAMPLE_ECC_PUBLIC_KEY_FILENAME_RECIPIENT
16+
// If you provide this, the keys MUST be on curve P256
17+
// If these files are not present, this will generate a pair for you.
18+
// For this example we will use the curve P256.
19+
if (RawEcdhKeyringExample.shouldGenerateNewEccKeyPairs()) {
20+
RawEcdhKeyringExample.generateEccKeyPairs();
21+
}
22+
23+
// Part of using these keyrings is knowing which curve the keys used in the key agreement
24+
// lie on. The keyring will fail if the keys do not lie on the configured curve.
25+
RawEcdhKeyringExample.RawEcdhKeyringGetItemPutItem(
26+
TestUtils.TEST_DDB_TABLE_NAME,
27+
ECDHCurveSpec.ECC_NIST_P256
28+
);
29+
}
30+
31+
@Test
32+
public void TestEphemeralRawEcdhKeyringExample() {
33+
// You may provide your own ECC Public Key in the files located at
34+
// - EXAMPLE_ECC_PUBLIC_KEY_FILENAME_RECIPIENT
35+
// If you provide this, the keys MUST be on curve P256
36+
// If these files are not present, this will generate a pair for you.
37+
// For this example we will use the curve P256.
38+
if (RawEcdhKeyringExample.shouldGenerateNewEccKeyPairs()) {
39+
RawEcdhKeyringExample.generateEccKeyPairs();
40+
}
41+
42+
// Part of using these keyrings is knowing which curve the keys used in the key agreement
43+
// lie on. The keyring will fail if the keys do not lie on the configured curve.
44+
RawEcdhKeyringExample.EphemeralRawEcdhKeyringPutItem(
45+
TestUtils.TEST_DDB_TABLE_NAME,
46+
ECDHCurveSpec.ECC_NIST_P256
47+
);
48+
}
49+
50+
@Test
51+
public void TestDiscoveryRawEcdhKeyringExample() {
52+
// You may provide your own ECC Public Key in the files located at
53+
// - EXAMPLE_ECC_PUBLIC_KEY_FILENAME_RECIPIENT
54+
// - EXAMPLE_ECC_PRIVATE_KEY_FILENAME_RECIPIENT
55+
// If you provide this, the keys MUST be on curve P256
56+
// If these files are not present, this will generate a pair for you.
57+
// For this example we will use the curve P256.
58+
if (RawEcdhKeyringExample.shouldGenerateNewEccKeyPairs()) {
59+
RawEcdhKeyringExample.generateEccKeyPairs();
60+
}
61+
62+
// The discovery configuration is not allowed to encrypt
63+
// To understand this example best, we will write a record with the ephemeral configuration
64+
// in the previous example. This means that the recipient public key configured on
65+
// both keyrings is the same. This means that the other party has the recipient public key
66+
// and is writing messages meant only for the owner of the recipient public key to decrypt.
67+
68+
// In this call we are writing a record that is written with an ephemeral sender key pair.
69+
// The recipient will be able to decrypt the message
70+
RawEcdhKeyringExample.EphemeralRawEcdhKeyringPutItem(
71+
TestUtils.TEST_DDB_TABLE_NAME,
72+
ECDHCurveSpec.ECC_NIST_P256
73+
);
74+
75+
// In this call we are reading a record that was written with the recipient's public key.
76+
// It will use the recipient's private key and the sender's public key stored in the message to
77+
// calculate the appropriate shared secret to successfully decrypt the message.
78+
RawEcdhKeyringExample.DiscoveryRawEcdhKeyringGetItem(
79+
TestUtils.TEST_DDB_TABLE_NAME,
80+
ECDHCurveSpec.ECC_NIST_P256
81+
);
82+
}
83+
}

‎Examples/runtimes/net/src/Examples.cs

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
using System;
22
using System.Threading;
33
using System.Threading.Tasks;
4+
using Examples.keyring;
45

56
namespace Examples
67
{
@@ -22,6 +23,8 @@ static async Task Main()
2223
await MultiKeyringExample.MultiKeyringGetItemPutItem();
2324
await RawRsaKeyringExample.RawRsaKeyringGetItemPutItem();
2425
await KmsRsaKeyringExample.KmsRsaKeyringGetItemPutItem();
26+
await RawEcdhKeyringExample.RawEcdhKeyringExamples();
27+
await KmsEcdhKeyringExample.KmsEcdhKeyringExamples();
2528

2629
var keyId = CreateKeyStoreKeyExample.KeyStoreCreateKey();
2730
var keyId2 = CreateKeyStoreKeyExample.KeyStoreCreateKey();

‎Examples/runtimes/net/src/TestUtils.cs

+6
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,12 @@ public class TestUtils
2424
public static readonly string TEST_KMS_RSA_KEY_ID =
2525
"arn:aws:kms:us-west-2:658956600833:key/8b432da4-dde4-4bc3-a794-c7d68cbab5a6";
2626

27+
public static readonly string TEST_KMS_ECDH_KEY_ID_P256_SENDER =
28+
"arn:aws:kms:us-west-2:370957321024:key/eabdf483-6be2-4d2d-8ee4-8c2583d416e9";
29+
30+
public static readonly string TEST_KMS_ECDH_KEY_ID_P256_RECIPIENT =
31+
"arn:aws:kms:us-west-2:370957321024:key/0265c8e9-5b6a-4055-8f70-63719e09fda5";
32+
2733
public static readonly string TEST_MRK_REPLICA_KEY_ID_US_EAST_1 =
2834
"arn:aws:kms:us-east-1:658956600833:key/mrk-80bd8ecdcd4342aebd84b7dc9da498a7";
2935

‎Examples/runtimes/net/src/keyring/KmsEcdhKeyringExample.cs

+460
Large diffs are not rendered by default.

‎Examples/runtimes/net/src/keyring/RawEcdhKeyringExample.cs

+675
Large diffs are not rendered by default.

‎cfn/CI.yaml

+9-126
Original file line numberDiff line numberDiff line change
@@ -64,131 +64,13 @@ Resources:
6464
WriteCapacityUnits: "5"
6565
TableName: !Ref TableName
6666

67-
BasicTestJavaTable:
68-
Type: AWS::DynamoDB::Table
69-
Properties:
70-
AttributeDefinitions:
71-
- AttributeName: "partition_key"
72-
AttributeType: "S"
73-
- AttributeName: "sort_key"
74-
AttributeType: "N"
75-
KeySchema:
76-
- AttributeName: "partition_key"
77-
KeyType: "HASH"
78-
- AttributeName: "sort_key"
79-
KeyType: "RANGE"
80-
ProvisionedThroughput:
81-
ReadCapacityUnits: "5"
82-
WriteCapacityUnits: "5"
83-
TableName: !Ref BasicTestJavaTableName
84-
85-
BasicTestDotnetTable:
86-
Type: AWS::DynamoDB::Table
87-
Properties:
88-
AttributeDefinitions:
89-
- AttributeName: "partition_key"
90-
AttributeType: "S"
91-
- AttributeName: "sort_key"
92-
AttributeType: "N"
93-
KeySchema:
94-
- AttributeName: "partition_key"
95-
KeyType: "HASH"
96-
- AttributeName: "sort_key"
97-
KeyType: "RANGE"
98-
ProvisionedThroughput:
99-
ReadCapacityUnits: "5"
100-
WriteCapacityUnits: "5"
101-
TableName: !Ref BasicTestDotnetTableName
102-
103-
SearchTestJavaTable:
104-
Type: AWS::DynamoDB::Table
105-
Properties:
106-
AttributeDefinitions:
107-
- AttributeName: "aws_dbe_b_inspector_id_last4"
108-
AttributeType: "S"
109-
- AttributeName: "aws_dbe_b_last4UnitCompound"
110-
AttributeType: "S"
111-
- AttributeName: "aws_dbe_b_unit"
112-
AttributeType: "S"
113-
- AttributeName: "inspection_date"
114-
AttributeType: "S"
115-
- AttributeName: "work_id"
116-
AttributeType: "S"
117-
KeySchema:
118-
- AttributeName: "work_id"
119-
KeyType: "HASH"
120-
- AttributeName: "inspection_date"
121-
KeyType: "RANGE"
122-
ProvisionedThroughput:
123-
ReadCapacityUnits: "5"
124-
WriteCapacityUnits: "5"
125-
TableName: !Ref SearchTestJavaTableName
126-
GlobalSecondaryIndexes:
127-
- IndexName: "last4-unit-index"
128-
KeySchema:
129-
- AttributeName: "aws_dbe_b_inspector_id_last4"
130-
KeyType: "HASH"
131-
- AttributeName: "aws_dbe_b_unit"
132-
KeyType: "RANGE"
133-
Projection:
134-
ProjectionType: ALL
135-
ProvisionedThroughput:
136-
ReadCapacityUnits: "5"
137-
WriteCapacityUnits: "5"
138-
- IndexName: "last4UnitCompound-index"
139-
KeySchema:
140-
- AttributeName: "aws_dbe_b_last4UnitCompound"
141-
KeyType: "HASH"
142-
Projection:
143-
ProjectionType: ALL
144-
ProvisionedThroughput:
145-
ReadCapacityUnits: "5"
146-
WriteCapacityUnits: "5"
147-
148-
SearchTestDotnetTable:
149-
Type: AWS::DynamoDB::Table
150-
Properties:
151-
AttributeDefinitions:
152-
- AttributeName: "aws_dbe_b_inspector_id_last4"
153-
AttributeType: "S"
154-
- AttributeName: "aws_dbe_b_last4UnitCompound"
155-
AttributeType: "S"
156-
- AttributeName: "aws_dbe_b_unit"
157-
AttributeType: "S"
158-
- AttributeName: "inspection_date"
159-
AttributeType: "S"
160-
- AttributeName: "work_id"
161-
AttributeType: "S"
162-
KeySchema:
163-
- AttributeName: "work_id"
164-
KeyType: "HASH"
165-
- AttributeName: "inspection_date"
166-
KeyType: "RANGE"
167-
ProvisionedThroughput:
168-
ReadCapacityUnits: "5"
169-
WriteCapacityUnits: "5"
170-
TableName: !Ref SearchTestDotnetTableName
171-
GlobalSecondaryIndexes:
172-
- IndexName: "last4-unit-index"
173-
KeySchema:
174-
- AttributeName: "aws_dbe_b_inspector_id_last4"
175-
KeyType: "HASH"
176-
- AttributeName: "aws_dbe_b_unit"
177-
KeyType: "RANGE"
178-
Projection:
179-
ProjectionType: ALL
180-
ProvisionedThroughput:
181-
ReadCapacityUnits: "5"
182-
WriteCapacityUnits: "5"
183-
- IndexName: "last4UnitCompound-index"
184-
KeySchema:
185-
- AttributeName: "aws_dbe_b_last4UnitCompound"
186-
KeyType: "HASH"
187-
Projection:
188-
ProjectionType: ALL
189-
ProvisionedThroughput:
190-
ReadCapacityUnits: "5"
191-
WriteCapacityUnits: "5"
67+
# These tables were manually created but not used in CI
68+
# If we have to start using them in CI we just have to add
69+
# them to the policy below.
70+
# BasicTestJavaTable:
71+
# BasicTestDotnetTable:
72+
# SearchTestJavaTable:
73+
# SearchTestDotnetTable:
19274

19375
TestTableWithSimpleBeaconIndex:
19476
Type: AWS::DynamoDB::Table
@@ -384,7 +266,7 @@ Resources:
384266
- !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${KeystoreTableName}"
385267
- !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${KeystoreTableName}/index/*"
386268
- !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${BasicTestJavaTableName}"
387-
- !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${BasicTestDotnetTableName}"
269+
- !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${BasicTestDotNetTableName}"
388270
- !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${SearchTestJavaTableName}"
389271
- !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${SearchTestJavaTableName}/index/*"
390272
- !Sub "arn:aws:dynamodb:${AWS::Region}:${AWS::AccountId}:table/${SearchTestDotnetTableName}"
@@ -450,6 +332,7 @@ Resources:
450332
- Fn::ImportValue: "Polymorph-CA-GitHubCAReadPolicyArn"
451333
- "arn:aws:iam::370957321024:policy/ESDK-Dafny-DDB-ReadWriteDelete-us-west-2"
452334
- "arn:aws:iam::370957321024:policy/Hierarchical-GitHub-KMS-Key-Policy"
335+
- "arn:aws:iam::370957321024:policy/Github-ECDH-KMS"
453336
- !Ref KMSUsage
454337
- !Ref DDBUsage
455338
AssumeRolePolicyDocument: !Sub |

0 commit comments

Comments
 (0)
Please sign in to comment.