/// <summary> /// Gets the algorithm handle instance for a given algorithm and instantiates it using the provided key and the encryption type. /// </summary> /// <param name="key"></param> /// <param name="type"></param> /// <param name="algorithmName"></param> /// <param name="encryptionAlgorithm"></param> internal void GetAlgorithm(SqlClientSymmetricKey key, byte type, string algorithmName, out SqlClientEncryptionAlgorithm encryptionAlgorithm) { encryptionAlgorithm = null; SqlClientEncryptionAlgorithmFactory factory = null; if (!_encryptionAlgoFactoryList.TryGetValue(algorithmName, out factory)) { throw SQL.UnknownColumnEncryptionAlgorithm(algorithmName, SqlClientEncryptionAlgorithmFactoryList.GetInstance().GetRegisteredCipherAlgorithmNames()); } Debug.Assert(null != factory, "Null Algorithm Factory class detected"); // If the factory exists, following method will Create an algorithm object. If this fails, // it will raise an exception. encryptionAlgorithm = factory.Create(key, (SqlClientEncryptionType)type, algorithmName); }
/// <summary> /// <para> Decrypts the symmetric key and saves it in metadata. In addition, initializes /// the SqlClientEncryptionAlgorithm for rapid decryption.</para> /// </summary> internal static void DecryptSymmetricKey(SqlCipherMetadata md, SqlConnection connection, SqlCommand command) { Debug.Assert(md is not null, "md should not be null in DecryptSymmetricKey."); SqlClientSymmetricKey symKey = null; SqlEncryptionKeyInfo encryptionkeyInfoChosen = null; DecryptSymmetricKey(md.EncryptionInfo, out symKey, out encryptionkeyInfoChosen, connection, command); // Given the symmetric key instantiate a SqlClientEncryptionAlgorithm object and cache it in metadata md.CipherAlgorithm = null; SqlClientEncryptionAlgorithm cipherAlgorithm = null; string algorithmName = ValidateAndGetEncryptionAlgorithmName(md.CipherAlgorithmId, md.CipherAlgorithmName); // may throw SqlClientEncryptionAlgorithmFactoryList.GetInstance().GetAlgorithm(symKey, md.EncryptionType, algorithmName, out cipherAlgorithm); // will validate algorithm name and type Debug.Assert(cipherAlgorithm is not null); md.CipherAlgorithm = cipherAlgorithm; md.EncryptionKeyInfo = encryptionkeyInfoChosen; return; }
/// <summary> /// Return the algorithm name mapped to an Id. /// </summary> /// <param name="cipherAlgorithmId"></param> /// <param name="cipherAlgorithmName"></param> /// <returns></returns> private static string ValidateAndGetEncryptionAlgorithmName(byte cipherAlgorithmId, string cipherAlgorithmName) { if (TdsEnums.CustomCipherAlgorithmId == cipherAlgorithmId) { if (null == cipherAlgorithmName) { throw SQL.NullColumnEncryptionAlgorithm(SqlClientEncryptionAlgorithmFactoryList.GetInstance().GetRegisteredCipherAlgorithmNames()); } return(cipherAlgorithmName); } else if (TdsEnums.AEAD_AES_256_CBC_HMAC_SHA256 == cipherAlgorithmId) { return(SqlAeadAes256CbcHmac256Algorithm.AlgorithmName); } else { throw SQL.UnknownColumnEncryptionAlgorithmId(cipherAlgorithmId, GetRegisteredCipherAlgorithmIds()); } }