/// <summary> /// Constructor. /// </summary> /// <param name="sqlTceCipherInfoEntry"></param> /// <param name="sqlClientEncryptionAlgorithm"></param> /// <param name="cipherAlgorithmId"></param> /// <param name="encryptionType"></param> /// <param name="normalizationRuleVersion"></param> internal SqlCipherMetadata (SqlTceCipherInfoEntry? sqlTceCipherInfoEntry, ushort ordinal, byte cipherAlgorithmId, string cipherAlgorithmName, byte encryptionType, byte normalizationRuleVersion) { Debug.Assert(!sqlTceCipherInfoEntry.Equals(default(SqlTceCipherInfoEntry)), "sqlTceCipherInfoEntry should not be un-initialized."); _sqlTceCipherInfoEntry = sqlTceCipherInfoEntry; _ordinal = ordinal; _cipherAlgorithmId = cipherAlgorithmId; _cipherAlgorithmName = cipherAlgorithmName; _encryptionType = encryptionType; _normalizationRuleVersion = normalizationRuleVersion; _sqlEncryptionKeyInfo = null; }
/// <summary> /// <para> Parses the TDS message to read single CIPHER_INFO entry.</para> /// </summary> internal bool TryReadCipherInfoEntry (TdsParserStateObject stateObj, out SqlTceCipherInfoEntry entry) { byte cekValueCount = 0; entry = new SqlTceCipherInfoEntry(ordinal: 0); // Read the DB ID int dbId; if (!stateObj.TryReadInt32(out dbId)) { return false; } // Read the keyID int keyId; if (!stateObj.TryReadInt32(out keyId)) { return false; } // Read the key version int keyVersion; if (!stateObj.TryReadInt32(out keyVersion)) { return false; } // Read the key MD Version byte[] keyMDVersion = new byte[8]; if (!stateObj.TryReadByteArray(keyMDVersion, 0, 8)) { return false; } // Read the value count if (!stateObj.TryReadByte (out cekValueCount)) { return false; } for (int i = 0; i < cekValueCount; i++) { // Read individual CEK values byte[] encryptedCek; string keyPath; string keyStoreName; byte algorithmLength; string algorithmName; ushort shortValue; byte byteValue; int length; // Read the length of encrypted CEK if (!stateObj.TryReadUInt16 (out shortValue)) { return false; } length = shortValue; encryptedCek = new byte[length]; // Read the actual encrypted CEK if (!stateObj.TryReadByteArray (encryptedCek, 0, length)) { return false; } // Read the length of key store name if (!stateObj.TryReadByte (out byteValue)) { return false; } length = byteValue; // And read the key store name now if (!stateObj.TryReadString(length, out keyStoreName)) { return false; } // Read the length of key Path if (!stateObj.TryReadUInt16 (out shortValue)) { return false; } length = shortValue; // Read the key path string if (!stateObj.TryReadString(length, out keyPath)) { return false; } // Read the length of the string carrying the encryption algo if (!stateObj.TryReadByte(out algorithmLength)) { return false; } length = (int)algorithmLength; // Read the string carrying the encryption algo (eg. RSA_PKCS_OAEP) if (!stateObj.TryReadString(length, out algorithmName)) { return false; } // Add this encrypted CEK blob to our list of encrypted values for the CEK entry.Add(encryptedCek, databaseId: dbId, cekId: keyId, cekVersion: keyVersion, cekMdVersion: keyMDVersion, keyPath: keyPath, keyStoreName: keyStoreName, algorithmName: algorithmName); } return true; }