/// <summary>
        /// Attempt to generate a KMS datakey using the first successful response using a sorted dictionary of available KMS clients.
        /// </summary>
        /// <param name="sortedRegionToArnAndClientDictionary"> A sorted dictionary mapping regions and their arns and kms clients</param>
        /// <param name="dateKeyKeyId">The KMS arn used to generate the data key</param>
        /// <returns>A GenerateDataKeyResult object that contains the plain text key and the ciphertext for that key</returns>
        /// <exception cref="KmsException">Throw an exception if we're unable to generate a datakey in any AWS region</exception>
        internal virtual GenerateDataKeyResult GenerateDataKey(OrderedDictionary sortedRegionToArnAndClientDictionary, out string dateKeyKeyId)
        {
            foreach (DictionaryEntry regionToArnAndClient in sortedRegionToArnAndClientDictionary)
            {
                try
                {
                    TimerOptions generateDataKeyTimerOptions = new TimerOptions
                    {
                        Name = MetricsUtil.AelMetricsPrefix + ".kms.aws.generatedatakey." + regionToArnAndClient.Key
                    };
                    using (MetricsUtil.MetricsInstance.Measure.Timer.Time(generateDataKeyTimerOptions))
                    {
                        IAmazonKeyManagementService client          = ((AwsKmsArnClient)regionToArnAndClient.Value).AwsKmsClient;
                        string keyIdForDataKeyGeneration            = ((AwsKmsArnClient)regionToArnAndClient.Value).Arn;
                        GenerateDataKeyResult generateDataKeyResult = client.GenerateDataKey(
                            keyIdForDataKeyGeneration,
                            null,
                            DataKeySpec.AES_256);
                        dateKeyKeyId = keyIdForDataKeyGeneration;
                        return(generateDataKeyResult);
                    }
                }
                catch (AmazonServiceException e)
                {
                    Logger.LogWarning(e, "Failed to generate data key via region {region}, trying next region", regionToArnAndClient.Key);

                    // TODO Consider adding notification/CW alert
                }
            }

            throw new KmsException("could not successfully generate data key using any regions");
        }
示例#2
0
        /// <summary>
        /// Generates an instruction that will be used to encrypt an object
        /// using materials with the KMSKeyID set.
        /// </summary>
        /// <param name="kmsClient">
        /// Used to call KMS to generate a data key.
        /// </param>
        /// <param name="materials">
        /// The encryption materials to be used to encrypt and decrypt data.
        /// </param>
        /// <returns>
        /// The instruction that will be used to encrypt an object.
        /// </returns>
        internal static EncryptionInstructions GenerateInstructionsForKMSMaterialsV2(IAmazonKeyManagementService kmsClient, EncryptionMaterialsV2 materials)
        {
            if (materials.KMSKeyID == null)
            {
                throw new ArgumentNullException(nameof(materials.KMSKeyID), KmsKeyIdNullMessage);
            }

            switch (materials.KmsType)
            {
            case KmsType.KmsContext:
            {
                var nonce = new byte[DefaultNonceSize];

                // Generate nonce, and get both the key and the encrypted key from KMS.
                RandomNumberGenerator.Create().GetBytes(nonce);
                var result = kmsClient.GenerateDataKey(materials.KMSKeyID, materials.MaterialsDescription, KMSKeySpec);

                var instructions = new EncryptionInstructions(materials.MaterialsDescription, result.KeyPlaintext, result.KeyCiphertext, nonce,
                                                              XAmzWrapAlgKmsContextValue, XAmzAesGcmCekAlgValue);
                return(instructions);
            }

            default:
                throw new NotSupportedException($"{materials.KmsType} is not supported for KMS Key Id {materials.KMSKeyID}");
            }
        }
示例#3
0
        public void GenerateKey(int keyBits, out byte[] key, out byte[] encryptedKey, IDictionary <string, string> context)
        {
            DataKeySpec keySpec;

            if (keyBits == 128)
            {
                keySpec = DataKeySpec.AES_128;
            }
            else if (keyBits == 256)
            {
                keySpec = DataKeySpec.AES_256;
            }
            else
            {
                throw new ArgumentException("only 128 and 256 bit keys are supported", "keyBits");
            }
            var request = new GenerateDataKeyRequest
            {
                KeyId             = _keyId,
                KeySpec           = keySpec,
                EncryptionContext = AsDictionary(context)
            };
            GenerateDataKeyResponse response = _client.GenerateDataKey(request);

            key          = response.Plaintext.ToArray();
            encryptedKey = response.CiphertextBlob.ToArray();
        }
示例#4
0
        /// <summary>
        /// Generates an instruction that will be used to encrypt an object
        /// using materials with the KMSKeyID set.
        /// </summary>
        /// <param name="kmsClient">
        /// Used to call KMS to generate a data key.
        /// </param>
        /// <param name="materials">
        /// The encryption materials to be used to encrypt and decrypt data.
        /// </param>
        /// <returns>
        /// The instruction that will be used to encrypt an object.
        /// </returns>
        internal static EncryptionInstructions GenerateInstructionsForKMSMaterials(IAmazonKeyManagementService kmsClient, EncryptionMaterials materials)
        {
            if (materials.KMSKeyID == null)
            {
                throw new ArgumentNullException(nameof(materials.KMSKeyID), KmsKeyIdNullMessage);
            }

            var iv = new byte[IVLength];

            // Generate IV, and get both the key and the encrypted key from KMS.
            RandomNumberGenerator.Create().GetBytes(iv);
            var generateDataKeyResult = kmsClient.GenerateDataKey(materials.KMSKeyID, materials.MaterialsDescription, KMSKeySpec);

            return(new EncryptionInstructions(materials.MaterialsDescription, generateDataKeyResult.KeyPlaintext, generateDataKeyResult.KeyCiphertext, iv,
                                              XAmzWrapAlgKmsValue, XAmzAesCbcPaddingCekAlgValue));
        }
示例#5
0
 private Amazon.KeyManagementService.Model.GenerateDataKeyResponse CallAWSServiceOperation(IAmazonKeyManagementService client, Amazon.KeyManagementService.Model.GenerateDataKeyRequest request)
 {
     Utils.Common.WriteVerboseEndpointMessage(this, client.Config, "AWS Key Management Service", "GenerateDataKey");
     try
     {
         #if DESKTOP
         return(client.GenerateDataKey(request));
         #elif CORECLR
         return(client.GenerateDataKeyAsync(request).GetAwaiter().GetResult());
         #else
                 #error "Unknown build edition"
         #endif
     }
     catch (AmazonServiceException exc)
     {
         var webException = exc.InnerException as System.Net.WebException;
         if (webException != null)
         {
             throw new Exception(Utils.Common.FormatNameResolutionFailureMessage(client.Config, webException.Message), webException);
         }
         throw;
     }
 }
 public GenerateDataKeyResult GenerateDataKey(string keyId, Dictionary <string, string> encryptionContext,
                                              string keySpec)
 {
     return(_service.GenerateDataKey(keyId, encryptionContext, keySpec));
 }