private static void cleanUpKMSKeys(Regions testRegion, String testResourcePrefix, Date createdBeforeThreshold, AWSCredentialsProvider awsCredentials) { LOG.info("Cleaning KMS..."); AWSKMS kmsClient = AWSKMSClientBuilder.standard() .withCredentials(awsCredentials) .withRegion(testRegion) .build(); List<AliasListEntry> keys = kmsClient.listAliases().getAliases(); for (AliasListEntry entry: keys) { if (!entry.getAliasName().startsWith("alias/" + testResourcePrefix)) { continue; } DescribeKeyRequest request = new DescribeKeyRequest().withKeyId(entry.getTargetKeyId()); KeyMetadata metadata = kmsClient.describeKey(request).getKeyMetadata(); if (KMSKeyState.fromString(metadata.getKeyState()) != KMSKeyState.PENDING_DELETION && metadata.getCreationDate().before(createdBeforeThreshold)) { LOG.info("Scheduling KMS key for deletion:" + entry.getAliasName()); scheduleKeyDeletion(kmsClient, entry); } } }
@Test public void testCreate() throws Exception { // Mocks the responses from AWS. CreateKeyRequest createKeyRequest = new CreateKeyRequest().withDescription( "This key is automatically managed by Strongbox"); CreateKeyResult createKeyResult = new CreateKeyResult().withKeyMetadata(new KeyMetadata().withArn(KMS_ARN)); CreateAliasRequest createAliasRequest = new CreateAliasRequest().withAliasName(ALIAS_KEY_NAME).withTargetKeyId(KMS_ARN); when(mockKMSClient.describeKey(describeKeyRequest)) .thenThrow(NotFoundException.class) .thenThrow(NotFoundException.class) // still waiting for creation .thenReturn(enabledKeyResult()); when(mockKMSClient.createKey(createKeyRequest)).thenReturn(createKeyResult); // Check the result from create method. String arn = kmsManager.create(); assertEquals(arn, KMS_ARN); // Verify correct number of calls was made to AWS. verify(mockKMSClient, times(3)).describeKey(describeKeyRequest); verify(mockKMSClient, times(1)).createAlias(createAliasRequest); verify(mockKMSClient, times(1)).createKey(createKeyRequest); }
@Test public void test_getKmsKeyState_happy() { String awsRegion = "aws region"; String kmsKeyId = "kms key id"; String state = "state"; AWSKMSClient kmsClient = mock(AWSKMSClient.class); when(kmsClientFactory.getClient(awsRegion)).thenReturn(kmsClient); when(kmsClient.describeKey(anyObject())).thenReturn( new DescribeKeyResult() .withKeyMetadata( new KeyMetadata() .withKeyState(state))); String result = kmsService.getKmsKeyState(kmsKeyId, awsRegion); assertEquals(state, result); }
@Test public void test_validateKmsKeyIsUsable_returns_true_when_state_is_pending_deletion() { String keyId = "key id"; String awsRegion = "aws region"; AWSKMSClient kmsClient = mock(AWSKMSClient.class); when(kmsClientFactory.getClient(awsRegion)).thenReturn(kmsClient); when(kmsClient.describeKey(anyObject())).thenReturn( new DescribeKeyResult() .withKeyMetadata( new KeyMetadata() .withKeyState(KeyState.PendingDeletion))); boolean result = kmsService.kmsKeyIsDisabledOrScheduledForDeletion(keyId, awsRegion); assertTrue(result); }
@Test public void test_validateKmsKeyIsUsable_return_true_when_state_is_disabled() { String keyId = "key id"; String awsRegion = "aws region"; AWSKMSClient kmsClient = mock(AWSKMSClient.class); when(kmsClientFactory.getClient(awsRegion)).thenReturn(kmsClient); when(kmsClient.describeKey(anyObject())).thenReturn( new DescribeKeyResult() .withKeyMetadata( new KeyMetadata() .withKeyState(KeyState.Disabled))); boolean result = kmsService.kmsKeyIsDisabledOrScheduledForDeletion(keyId, awsRegion); assertTrue(result); }
@Test public void test_validateKmsKeyIsUsable_returns_false_when_state_is_not_deletion_or_disabled() { String keyId = "key id"; String awsRegion = "aws region"; AWSKMSClient kmsClient = mock(AWSKMSClient.class); when(kmsClientFactory.getClient(awsRegion)).thenReturn(kmsClient); when(kmsClient.describeKey(anyObject())).thenReturn( new DescribeKeyResult() .withKeyMetadata( new KeyMetadata() .withKeyState(KeyState.Enabled))); boolean result = kmsService.kmsKeyIsDisabledOrScheduledForDeletion(keyId, awsRegion); assertFalse(result); }
@Test(expected = ApiException.class) public void test_validateKmsKeyIsUsable_deletes_kms_key_when_not_usable() { String id = "id"; String awsKmsKeyArn = "aws kms key arn"; String iamPrincipalArn = "arn"; String awsRegion = "aws region"; AwsIamRoleKmsKeyRecord kmsKey = mock(AwsIamRoleKmsKeyRecord.class); when(kmsKey.getId()).thenReturn(id); when(kmsKey.getAwsKmsKeyId()).thenReturn(awsKmsKeyArn); when(kmsKey.getAwsRegion()).thenReturn(awsRegion); AWSKMSClient kmsClient = mock(AWSKMSClient.class); when(kmsClientFactory.getClient(awsRegion)).thenReturn(kmsClient); when(kmsClient.describeKey(anyObject())).thenReturn( new DescribeKeyResult() .withKeyMetadata( new KeyMetadata() .withKeyState(KeyState.PendingDeletion))); kmsService.validateKmsKeyIsUsable(kmsKey, iamPrincipalArn); }
@Test public void test_validateKmsKeyIsUsable_does_not_delete_kms_key_when_usable() { String id = "id"; String awsKmsKeyArn = "aws kms key arn"; String iamPrincipalArn = "arn"; String awsRegion = "aws region"; AwsIamRoleKmsKeyRecord kmsKey = mock(AwsIamRoleKmsKeyRecord.class); when(kmsKey.getId()).thenReturn(id); when(kmsKey.getAwsKmsKeyId()).thenReturn(awsKmsKeyArn); when(kmsKey.getAwsRegion()).thenReturn(awsRegion); AWSKMSClient kmsClient = mock(AWSKMSClient.class); when(kmsClientFactory.getClient(awsRegion)).thenReturn(kmsClient); when(kmsClient.describeKey(anyObject())).thenReturn( new DescribeKeyResult() .withKeyMetadata( new KeyMetadata() .withKeyState(KeyState.Enabled))); kmsService.validateKmsKeyIsUsable(kmsKey, iamPrincipalArn); verify(awsIamRoleDao, never()).deleteKmsKeyById(id); }
@Test public void test_validatePolicy_validates_policy_when_validate_interval_has_passed() { String kmsKeyArn = "kms key arn"; String awsIamRoleRecordId = "aws iam role record id"; String kmsCMKRegion = "kmsCMKRegion"; String policy = "policy"; OffsetDateTime lastValidated = OffsetDateTime.of(2016, 1, 1, 1, 1, 1, 1, ZoneOffset.UTC); OffsetDateTime now = OffsetDateTime.now(); AWSKMSClient client = mock(AWSKMSClient.class); when(client.describeKey(anyObject())).thenReturn( new DescribeKeyResult() .withKeyMetadata( new KeyMetadata() .withKeyState(KeyState.Enabled))); when(kmsClientFactory.getClient(kmsCMKRegion)).thenReturn(client); GetKeyPolicyResult result = mock(GetKeyPolicyResult.class); when(result.getPolicy()).thenReturn(policy); when(client.getKeyPolicy(new GetKeyPolicyRequest().withKeyId(kmsKeyArn) .withPolicyName("default"))).thenReturn(result); when(kmsPolicyService.isPolicyValid(policy)).thenReturn(true); AwsIamRoleKmsKeyRecord kmsKey = mock(AwsIamRoleKmsKeyRecord.class); when(kmsKey.getAwsIamRoleId()).thenReturn(awsIamRoleRecordId); when(kmsKey.getAwsKmsKeyId()).thenReturn(kmsKeyArn); when(kmsKey.getAwsRegion()).thenReturn(kmsCMKRegion); when(kmsKey.getLastValidatedTs()).thenReturn(lastValidated); when(awsIamRoleDao.getKmsKey(awsIamRoleRecordId, kmsCMKRegion)).thenReturn(Optional.of(kmsKey)); when(dateTimeSupplier.get()).thenReturn(now); kmsService.validateKeyAndPolicy(kmsKey, kmsKeyArn); verify(client, times(1)).getKeyPolicy(new GetKeyPolicyRequest().withKeyId(kmsKeyArn) .withPolicyName("default")); verify(kmsPolicyService, times(1)).isPolicyValid(policy); }
@Override public CreateKeyResult createKey(CreateKeyRequest req) throws AmazonServiceException, AmazonClientException { String keyId = UUID.randomUUID().toString(); String arn = "arn:aws:kms:" + region_.getName() + ":" + ACCOUNT_ID + ":key/" + keyId; idToArnMap.put(keyId, arn); activeKeys.add(arn); CreateKeyResult result = new CreateKeyResult(); result.setKeyMetadata(new KeyMetadata().withAWSAccountId(ACCOUNT_ID).withCreationDate(new Date()) .withDescription(req.getDescription()).withEnabled(true).withKeyId(keyId) .withKeyUsage(KeyUsageType.ENCRYPT_DECRYPT).withArn(arn)); return result; }
@Override public DescribeKeyResult describeKey(DescribeKeyRequest arg0) throws AmazonServiceException, AmazonClientException { final String arn = retrieveArn(arg0.getKeyId()); final KeyMetadata keyMetadata = new KeyMetadata().withArn(arn).withKeyId(arn); final DescribeKeyResult describeKeyResult = new DescribeKeyResult().withKeyMetadata(keyMetadata); return describeKeyResult; }
@Override public CreateKeyResult createKey(CreateKeyRequest req) throws AmazonServiceException, AmazonClientException { String keyId = UUID.randomUUID().toString(); String arn = "arn:aws:testing:kms:" + ACCOUNT_ID + ":key/" + keyId; CreateKeyResult result = new CreateKeyResult(); result.setKeyMetadata(new KeyMetadata().withAWSAccountId(ACCOUNT_ID) .withCreationDate(new Date()).withDescription(req.getDescription()) .withEnabled(true).withKeyId(keyId).withKeyUsage(KeyUsageType.ENCRYPT_DECRYPT) .withArn(arn)); return result; }
private DescribeKeyResult constructDescribeKeyResult() { KeyMetadata keyMetadata = new KeyMetadata().withArn(KMS_ARN); return new DescribeKeyResult().withKeyMetadata(keyMetadata); }
private static DescribeKeyResult constructDescribeKeyResult(KeyState state) { return new DescribeKeyResult().withKeyMetadata( new KeyMetadata().withKeyState(state).withArn(KMS_ARN)); }
/** * Provisions a new KMS CMK in the specified region to be used by the specified role. * * @param iamRoleId The IAM role that this CMK will be associated with * @param iamPrincipalArn The AWS IAM principal ARN * @param awsRegion The region to provision the key in * @param user The user requesting it * @param dateTime The date of creation * @return The AWS Key ID ARN */ @Transactional public String provisionKmsKey(final String iamRoleId, final String iamPrincipalArn, final String awsRegion, final String user, final OffsetDateTime dateTime) { final AWSKMSClient kmsClient = kmsClientFactory.getClient(awsRegion); final String awsIamPrincipalKmsKeyId = uuidSupplier.get(); final CreateKeyRequest request = new CreateKeyRequest(); request.setKeyUsage(KeyUsageType.ENCRYPT_DECRYPT); request.setDescription("Key used by Cerberus for IAM role authentication."); String policy = kmsPolicyService.generateStandardKmsPolicy(iamPrincipalArn); request.setPolicy(policy); CreateKeyResult result; try { result = kmsClient.createKey(request); } catch (Throwable t) { logger.error("Failed to provision KMS key using policy: {}", policy, t); throw t; } final CreateAliasRequest aliasRequest = new CreateAliasRequest(); aliasRequest.setAliasName(getAliasName(awsIamPrincipalKmsKeyId)); KeyMetadata keyMetadata = result.getKeyMetadata(); String arn = keyMetadata.getArn(); aliasRequest.setTargetKeyId(arn); kmsClient.createAlias(aliasRequest); final AwsIamRoleKmsKeyRecord awsIamRoleKmsKeyRecord = new AwsIamRoleKmsKeyRecord(); awsIamRoleKmsKeyRecord.setId(awsIamPrincipalKmsKeyId); awsIamRoleKmsKeyRecord.setAwsIamRoleId(iamRoleId); awsIamRoleKmsKeyRecord.setAwsKmsKeyId(result.getKeyMetadata().getArn()); awsIamRoleKmsKeyRecord.setAwsRegion(awsRegion); awsIamRoleKmsKeyRecord.setCreatedBy(user); awsIamRoleKmsKeyRecord.setLastUpdatedBy(user); awsIamRoleKmsKeyRecord.setCreatedTs(dateTime); awsIamRoleKmsKeyRecord.setLastUpdatedTs(dateTime); awsIamRoleKmsKeyRecord.setLastValidatedTs(dateTime); awsIamRoleDao.createIamRoleKmsKey(awsIamRoleKmsKeyRecord); return result.getKeyMetadata().getArn(); }
@Test public void test_provisionKmsKey() { String iamRoleId = "role-id"; String awsRegion = "aws-region"; String user = "user"; OffsetDateTime dateTime = OffsetDateTime.now(); String policy = "policy"; String arn = "arn"; String awsIamRoleKmsKeyId = "awsIamRoleKmsKeyId"; when(uuidSupplier.get()).thenReturn(awsIamRoleKmsKeyId); when(kmsPolicyService.generateStandardKmsPolicy(arn)).thenReturn(policy); AWSKMSClient client = mock(AWSKMSClient.class); when(kmsClientFactory.getClient(awsRegion)).thenReturn(client); CreateKeyRequest request = new CreateKeyRequest(); request.setKeyUsage(KeyUsageType.ENCRYPT_DECRYPT); request.setDescription("Key used by Cerberus for IAM role authentication."); request.setPolicy(policy); CreateKeyResult createKeyResult = mock(CreateKeyResult.class); KeyMetadata metadata = mock(KeyMetadata.class); when(metadata.getArn()).thenReturn(arn); when(createKeyResult.getKeyMetadata()).thenReturn(metadata); when(client.createKey(request)).thenReturn(createKeyResult); // invoke method under test String actualResult = kmsService.provisionKmsKey(iamRoleId, arn, awsRegion, user, dateTime); assertEquals(arn, actualResult); CreateAliasRequest aliasRequest = new CreateAliasRequest(); aliasRequest.setAliasName(kmsService.getAliasName(awsIamRoleKmsKeyId)); aliasRequest.setTargetKeyId(arn); verify(client).createAlias(aliasRequest); AwsIamRoleKmsKeyRecord awsIamRoleKmsKeyRecord = new AwsIamRoleKmsKeyRecord(); awsIamRoleKmsKeyRecord.setId(awsIamRoleKmsKeyId); awsIamRoleKmsKeyRecord.setAwsIamRoleId(iamRoleId); awsIamRoleKmsKeyRecord.setAwsKmsKeyId(arn); awsIamRoleKmsKeyRecord.setAwsRegion(awsRegion); awsIamRoleKmsKeyRecord.setCreatedBy(user); awsIamRoleKmsKeyRecord.setLastUpdatedBy(user); awsIamRoleKmsKeyRecord.setCreatedTs(dateTime); awsIamRoleKmsKeyRecord.setLastUpdatedTs(dateTime); awsIamRoleKmsKeyRecord.setLastValidatedTs(dateTime); verify(awsIamRoleDao).createIamRoleKmsKey(awsIamRoleKmsKeyRecord); }