| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145 |
- //------------------------------------------------------------------------------
- // <copyright file="TdsParserHelperClasses.cs" company="Microsoft">
- // Copyright (c) Microsoft Corporation. All rights reserved.
- // </copyright>
- // <owner current="true" primary="true">[....]</owner>
- // <owner current="true" primary="false">[....]</owner>
- //------------------------------------------------------------------------------
- namespace System.Data.SqlClient {
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Data.Common;
- using System.Data.ProviderBase;
- using System.Data.Sql;
- using System.Data.SqlTypes;
- using System.Diagnostics;
- using System.Reflection;
- using System.Text;
- using System.Threading;
- using System.Security;
- using System.Globalization;
- using Microsoft.SqlServer.Server; // for SMI metadata
- internal enum CallbackType {
- Read = 0,
- Write = 1
- }
- internal enum EncryptionOptions {
- OFF,
- ON,
- NOT_SUP,
- REQ,
- LOGIN
- }
- internal enum PreLoginHandshakeStatus {
- Successful,
- InstanceFailure
- }
- internal enum PreLoginOptions {
- VERSION,
- ENCRYPT,
- INSTANCE,
- THREADID,
- MARS,
- TRACEID,
- FEDAUTHREQUIRED,
- NUMOPT,
- LASTOPT = 255
- }
- internal enum RunBehavior {
- UntilDone = 1, // 0001 binary
- ReturnImmediately = 2, // 0010 binary
- Clean = 5, // 0101 binary - Clean AND UntilDone
- Attention = 13 // 1101 binary - Clean AND UntilDone AND Attention
- }
- internal enum TdsParserState {
- Closed,
- OpenNotLoggedIn,
- OpenLoggedIn,
- Broken,
- }
- /// <summary>
- /// Struct encapsulating the data to be sent to the server as part of Federated Authentication Feature Extension.
- /// </summary>
- internal struct FederatedAuthenticationFeatureExtensionData
- {
- internal TdsEnums.FedAuthLibrary libraryType;
- internal bool fedAuthRequiredPreLoginResponse;
- internal SqlAuthenticationMethod authentication;
- internal byte[] accessToken;
- }
- /// <summary>
- /// <para> Represents a single encrypted value for a CEK. It contains the encrypted CEK,
- /// the store type, name,the key path and encryption algorithm.</para>
- /// </summary>
- internal struct SqlEncryptionKeyInfo {
- internal byte[] encryptedKey; // the encrypted "column encryption key"
- internal int databaseId;
- internal int cekId;
- internal int cekVersion;
- internal byte[] cekMdVersion;
- internal string keyPath;
- internal string keyStoreName;
- internal string algorithmName;
- internal byte normalizationRuleVersion;
- }
- /// <summary>
- /// <para> Encapsulates one entry in the CipherInfo table sent as part of Colmetadata.
- /// The same CEK is encrypted multiple times with different master keys (for master key
- /// rotation scenario) We need to keep all these around until we can resolve the CEK
- /// using the correct master key.</para>
- /// </summary>
- internal struct SqlTceCipherInfoEntry {
- /// <summary>
- /// List of Column Encryption Key Information.
- /// </summary>
- private readonly List<SqlEncryptionKeyInfo> _columnEncryptionKeyValues;
- /// <summary>
- /// Key Ordinal.
- /// </summary>
- private readonly int _ordinal;
- /// <summary>
- /// Database ID
- /// </summary>
- private int _databaseId;
- /// <summary>
- /// Cek ID
- /// </summary>
- private int _cekId;
- /// <summary>
- /// Cek Version
- /// </summary>
- private int _cekVersion;
- /// <summary>
- /// Cek MD Version
- /// </summary>
- private byte[] _cekMdVersion;
- /// <summary>
- /// Return the ordinal.
- /// </summary>
- internal int Ordinal {
- get {
- return _ordinal;
- }
- }
- /// <summary>
- /// Return the DatabaseID.
- /// </summary>
- internal int DatabaseId {
- get {
- return _databaseId;
- }
- }
- /// <summary>
- /// Return the CEK ID.
- /// </summary>
- internal int CekId {
- get {
- return _cekId;
- }
- }
- /// <summary>
- /// Return the CEK Version.
- /// </summary>
- internal int CekVersion {
- get {
- return _cekVersion;
- }
- }
- /// <summary>
- /// Return the CEK MD Version.
- /// </summary>
- internal byte[] CekMdVersion {
- get {
- return _cekMdVersion;
- }
- }
- /// <summary>
- /// Return the list of Column Encryption Key Values.
- /// </summary>
- internal List<SqlEncryptionKeyInfo> ColumnEncryptionKeyValues {
- get {
- return _columnEncryptionKeyValues;
- }
- }
- /// <summary>
- /// Add an entry to the list of ColumnEncryptionKeyValues.
- /// </summary>
- /// <param name="encryptedKey"></param>
- /// <param name="databaseId"></param>
- /// <param name="cekId"></param>
- /// <param name="cekVersion"></param>
- /// <param name="cekMdVersion"></param>
- /// <param name="keyPath"></param>
- /// <param name="keyStoreName"></param>
- /// <param name="algorithmName"></param>
- internal void Add(byte[] encryptedKey, int databaseId, int cekId, int cekVersion, byte[] cekMdVersion, string keyPath, string keyStoreName, string algorithmName) {
- Debug.Assert(_columnEncryptionKeyValues != null, "_columnEncryptionKeyValues should already be initialized.");
- SqlEncryptionKeyInfo encryptionKey = new SqlEncryptionKeyInfo();
- encryptionKey.encryptedKey = encryptedKey;
- encryptionKey.databaseId = databaseId;
- encryptionKey.cekId = cekId;
- encryptionKey.cekVersion = cekVersion;
- encryptionKey.cekMdVersion = cekMdVersion;
- encryptionKey.keyPath = keyPath;
- encryptionKey.keyStoreName = keyStoreName;
- encryptionKey.algorithmName = algorithmName;
- _columnEncryptionKeyValues.Add(encryptionKey);
- if (0 == _databaseId) {
- _databaseId = databaseId;
- _cekId = cekId;
- _cekVersion = cekVersion;
- _cekMdVersion = cekMdVersion;
- }
- else {
- Debug.Assert(_databaseId == databaseId);
- Debug.Assert(_cekId == cekId);
- Debug.Assert(_cekVersion == cekVersion);
- Debug.Assert (_cekMdVersion != null && cekMdVersion != null && _cekMdVersion.Length == _cekMdVersion.Length);
- }
- }
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="ordinal"></param>
- internal SqlTceCipherInfoEntry(int ordinal = 0) : this() {
- _ordinal = ordinal;
- _databaseId = 0;
- _cekId = 0;
- _cekVersion = 0;
- _cekMdVersion = null;
- _columnEncryptionKeyValues = new List<SqlEncryptionKeyInfo>();
- }
- }
- /// <summary>
- /// <para> Represents a table with various CEKs used in a resultset. Each entry corresponds to one (unique) CEK. The CEK
- /// may have been encrypted using multiple master keys (giving us multiple CEK values). All these values form one single
- /// entry in this table.</para>
- ///</summary>
- internal struct SqlTceCipherInfoTable {
- private readonly SqlTceCipherInfoEntry [] keyList;
- internal SqlTceCipherInfoTable (int tabSize) {
- Debug.Assert (0 < tabSize, "Invalid Table Size");
- keyList = new SqlTceCipherInfoEntry[tabSize];
- }
- internal SqlTceCipherInfoEntry this [int index] {
- get {
- Debug.Assert (index < keyList.Length, "Invalid index specified.");
- return keyList[index];
- }
- set {
- Debug.Assert (index < keyList.Length, "Invalid index specified.");
- keyList[index] = value;
- }
- }
- internal int Size {
- get {
- return keyList.Length;
- }
- }
- }
- sealed internal class SqlCollation {
- // First 20 bits of info field represent the lcid, bits 21-25 are compare options
- private const uint IgnoreCase = 1 << 20; // bit 21 - IgnoreCase
- private const uint IgnoreNonSpace = 1 << 21; // bit 22 - IgnoreNonSpace / IgnoreAccent
- private const uint IgnoreWidth = 1 << 22; // bit 23 - IgnoreWidth
- private const uint IgnoreKanaType = 1 << 23; // bit 24 - IgnoreKanaType
- private const uint BinarySort = 1 << 24; // bit 25 - BinarySort
- internal const uint MaskLcid = 0xfffff;
- private const int LcidVersionBitOffset = 28;
- private const uint MaskLcidVersion = unchecked((uint)(0xf << LcidVersionBitOffset));
- private const uint MaskCompareOpt = IgnoreCase | IgnoreNonSpace | IgnoreWidth | IgnoreKanaType | BinarySort;
- internal uint info;
- internal byte sortId;
- static int FirstSupportedCollationVersion(int lcid)
- {
- // NOTE: switch-case works ~3 times faster in this case than search with Dictionary
- switch (lcid)
- {
- case 1044: return 2; // Norwegian_100_BIN
- case 1047: return 2; // Romansh_100_BIN
- case 1056: return 2; // Urdu_100_BIN
- case 1065: return 2; // Persian_100_BIN
- case 1068: return 2; // Azeri_Latin_100_BIN
- case 1070: return 2; // Upper_Sorbian_100_BIN
- case 1071: return 1; // ----n_FYROM_90_BIN
- case 1081: return 1; // Indic_General_90_BIN
- case 1082: return 2; // Maltese_100_BIN
- case 1083: return 2; // Sami_Norway_100_BIN
- case 1087: return 1; // Kazakh_90_BIN
- case 1090: return 2; // Turkmen_100_BIN
- case 1091: return 1; // Uzbek_Latin_90_BIN
- case 1092: return 1; // Tatar_90_BIN
- case 1093: return 2; // Bengali_100_BIN
- case 1101: return 2; // Assamese_100_BIN
- case 1105: return 2; // Tibetan_100_BIN
- case 1106: return 2; // Welsh_100_BIN
- case 1107: return 2; // Khmer_100_BIN
- case 1108: return 2; // Lao_100_BIN
- case 1114: return 1; // Syriac_90_BIN
- case 1121: return 2; // Nepali_100_BIN
- case 1122: return 2; // Frisian_100_BIN
- case 1123: return 2; // Pashto_100_BIN
- case 1125: return 1; // Divehi_90_BIN
- case 1133: return 2; // Bashkir_100_BIN
- case 1146: return 2; // Mapudungan_100_BIN
- case 1148: return 2; // Mohawk_100_BIN
- case 1150: return 2; // Breton_100_BIN
- case 1152: return 2; // Uighur_100_BIN
- case 1153: return 2; // Maori_100_BIN
- case 1155: return 2; // Corsican_100_BIN
- case 1157: return 2; // Yakut_100_BIN
- case 1164: return 2; // Dari_100_BIN
- case 2074: return 2; // Serbian_Latin_100_BIN
- case 2092: return 2; // Azeri_Cyrillic_100_BIN
- case 2107: return 2; // Sami_Sweden_Finland_100_BIN
- case 2143: return 2; // Tamazight_100_BIN
- case 3076: return 1; // Chinese_Hong_Kong_Stroke_90_BIN
- case 3098: return 2; // Serbian_Cyrillic_100_BIN
- case 5124: return 2; // Chinese_Traditional_Pinyin_100_BIN
- case 5146: return 2; // Bosnian_Latin_100_BIN
- case 8218: return 2; // Bosnian_Cyrillic_100_BIN
- default: return 0; // other LCIDs have collation with version 0
- }
- }
- internal int LCID {
- // First 20 bits of info field represent the lcid
- get {
- return unchecked((int)(info & MaskLcid));
- }
- set {
- int lcid = value & (int)MaskLcid;
- Debug.Assert(lcid == value, "invalid set_LCID value");
- // VSTFDEVDIV 479474: some new Katmai LCIDs do not have collation with version = 0
- // since user has no way to specify collation version, we set the first (minimal) supported version for these collations
- int versionBits = FirstSupportedCollationVersion(lcid) << LcidVersionBitOffset;
- Debug.Assert((versionBits & MaskLcidVersion) == versionBits, "invalid version returned by FirstSupportedCollationVersion");
- // combine the current compare options with the new locale ID and its first supported version
- info = (info & MaskCompareOpt) | unchecked((uint)lcid) | unchecked((uint)versionBits);
- }
- }
- internal SqlCompareOptions SqlCompareOptions {
- get {
- SqlCompareOptions options = SqlCompareOptions.None;
- if (0 != (info & IgnoreCase))
- options |= SqlCompareOptions.IgnoreCase;
- if (0 != (info & IgnoreNonSpace))
- options |= SqlCompareOptions.IgnoreNonSpace;
- if (0 != (info & IgnoreWidth))
- options |= SqlCompareOptions.IgnoreWidth;
- if (0 != (info & IgnoreKanaType))
- options |= SqlCompareOptions.IgnoreKanaType;
- if (0 != (info & BinarySort))
- options |= SqlCompareOptions.BinarySort;
- return options;
- }
- set {
- Debug.Assert((value & SqlString.x_iValidSqlCompareOptionMask) == value, "invalid set_SqlCompareOptions value");
- uint tmp = 0;
- if (0 != (value & SqlCompareOptions.IgnoreCase))
- tmp |= IgnoreCase;
- if (0 != (value & SqlCompareOptions.IgnoreNonSpace))
- tmp |= IgnoreNonSpace;
- if (0 != (value & SqlCompareOptions.IgnoreWidth))
- tmp |= IgnoreWidth;
- if (0 != (value & SqlCompareOptions.IgnoreKanaType))
- tmp |= IgnoreKanaType;
- if (0 != (value & SqlCompareOptions.BinarySort))
- tmp |= BinarySort;
- info = (info & MaskLcid) | tmp;
- }
- }
- internal string TraceString() {
- return String.Format(/*IFormatProvider*/ null, "(LCID={0}, Opts={1})", this.LCID, (int)this.SqlCompareOptions);
- }
- static internal bool AreSame(SqlCollation a, SqlCollation b) {
- if (a == null || b == null) {
- return a == b;
- }
- else {
- return a.info == b.info && a.sortId == b.sortId;
- }
- }
-
- }
- internal class RoutingInfo {
- internal byte Protocol { get; private set; }
- internal UInt16 Port { get; private set; }
- internal string ServerName { get; private set; }
- internal RoutingInfo(byte protocol, UInt16 port, string servername) {
- Protocol = protocol;
- Port = port;
- ServerName = servername;
- }
- }
- sealed internal class SqlEnvChange {
- internal byte type;
- internal byte oldLength;
- internal int newLength; // 7206 TDS changes makes this length an int
- internal int length;
- internal string newValue;
- internal string oldValue;
- internal byte[] newBinValue;
- internal byte[] oldBinValue;
- internal long newLongValue;
- internal long oldLongValue;
- internal SqlCollation newCollation;
- internal SqlCollation oldCollation;
- internal RoutingInfo newRoutingInfo;
- }
- sealed internal class SqlLogin {
- internal SqlAuthenticationMethod authentication = SqlAuthenticationMethod.NotSpecified; // Authentication type
- internal int timeout; // login timeout
- internal bool userInstance = false; // user instance
- internal string hostName = ""; // client machine name
- internal string userName = ""; // user id
- internal string password = ""; // password
- internal string applicationName = ""; // application name
- internal string serverName = ""; // server name
- internal string language = ""; // initial language
- internal string database = ""; // initial database
- internal string attachDBFilename = ""; // DB filename to be attached
- internal string newPassword = ""; // new password for reset password
- internal bool useReplication = false; // user login for replication
- internal bool useSSPI = false; // use integrated security
- internal int packetSize = SqlConnectionString.DEFAULT.Packet_Size; // packet size
- internal bool readOnlyIntent = false; // read-only intent
- internal SqlCredential credential; // user id and password in SecureString
- internal SecureString newSecurePassword; // new password in SecureString for resetting pasword
- }
- sealed internal class SqlLoginAck {
- internal string programName;
- internal byte majorVersion;
- internal byte minorVersion;
- internal short buildNum;
- internal bool isVersion8;
- internal UInt32 tdsVersion;
- }
- sealed internal class SqlFedAuthInfo {
- internal string spn;
- internal string stsurl;
- public override string ToString() {
- return String.Format(CultureInfo.InvariantCulture, "STSURL: {0}, SPN: {1}", stsurl ?? String.Empty, spn ?? String.Empty);
- }
- }
- sealed internal class SqlFedAuthToken {
- internal UInt32 dataLen;
- internal byte[] accessToken;
- internal long expirationFileTime;
- }
- sealed internal class _SqlMetaData : SqlMetaDataPriv, ICloneable {
- internal string column;
- internal string baseColumn;
- internal MultiPartTableName multiPartTableName;
- internal readonly int ordinal;
- internal byte updatability; // two bit field (0 is read only, 1 is updatable, 2 is updatability unknown)
- internal byte tableNum;
- internal bool isDifferentName;
- internal bool isKey;
- internal bool isHidden;
- internal bool isExpression;
- internal bool isIdentity;
- internal bool isColumnSet;
- internal byte op; // for altrow-columns only
- internal ushort operand; // for altrow-columns only
- internal _SqlMetaData(int ordinal) : base() {
- this.ordinal = ordinal;
- }
- internal string serverName {
- get {
- return multiPartTableName.ServerName;
- }
- }
- internal string catalogName {
- get {
- return multiPartTableName.CatalogName;
- }
- }
- internal string schemaName {
- get {
- return multiPartTableName.SchemaName;
- }
- }
- internal string tableName {
- get {
- return multiPartTableName.TableName;
- }
- }
- internal bool IsNewKatmaiDateTimeType {
- get {
- return SqlDbType.Date == type || SqlDbType.Time == type || SqlDbType.DateTime2 == type || SqlDbType.DateTimeOffset == type;
- }
- }
- internal bool IsLargeUdt {
- get {
- return type == SqlDbType.Udt && length == Int32.MaxValue;
- }
- }
- public object Clone() {
- _SqlMetaData result = new _SqlMetaData(ordinal);
- result.CopyFrom(this);
- result.column = column;
- result.baseColumn = baseColumn;
- result.multiPartTableName = multiPartTableName;
- result.updatability = updatability;
- result.tableNum = tableNum;
- result.isDifferentName = isDifferentName;
- result.isKey = isKey;
- result.isHidden = isHidden;
- result.isExpression = isExpression;
- result.isIdentity = isIdentity;
- result.isColumnSet = isColumnSet;
- result.op = op;
- result.operand = operand;
- return result;
- }
- }
- sealed internal class _SqlMetaDataSet : ICloneable {
- internal ushort id; // for altrow-columns only
- internal int[] indexMap;
- internal int visibleColumns;
- internal DataTable schemaTable;
- internal readonly SqlTceCipherInfoTable? cekTable; // table of "column encryption keys" used for this metadataset
- internal readonly _SqlMetaData[] metaDataArray;
- internal _SqlMetaDataSet(int count, SqlTceCipherInfoTable? cipherTable) {
- cekTable = cipherTable;
- metaDataArray = new _SqlMetaData[count];
- for(int i = 0; i < metaDataArray.Length; ++i) {
- metaDataArray[i] = new _SqlMetaData(i);
- }
- }
- private _SqlMetaDataSet(_SqlMetaDataSet original) {
- this.id = original.id;
- // although indexMap is not immutable, in practice it is initialized once and then passed around
- this.indexMap = original.indexMap;
- this.visibleColumns = original.visibleColumns;
- this.schemaTable = original.schemaTable;
- if (original.metaDataArray == null) {
- metaDataArray = null;
- }
- else {
- metaDataArray = new _SqlMetaData[original.metaDataArray.Length];
- for (int idx=0; idx<metaDataArray.Length; idx++) {
- metaDataArray[idx] = (_SqlMetaData)original.metaDataArray[idx].Clone();
- }
- }
- }
- internal int Length {
- get {
- return metaDataArray.Length;
- }
- }
- internal _SqlMetaData this [int index] {
- get {
- return metaDataArray[index];
- }
- set {
- Debug.Assert(null == value, "used only by SqlBulkCopy");
- metaDataArray[index] = value;
- }
- }
- public object Clone() {
- return new _SqlMetaDataSet(this);
- }
- }
- sealed internal class _SqlMetaDataSetCollection : ICloneable {
- private readonly List<_SqlMetaDataSet> altMetaDataSetArray;
- internal _SqlMetaDataSet metaDataSet;
- internal _SqlMetaDataSetCollection () {
- altMetaDataSetArray = new List<_SqlMetaDataSet>();
- }
- internal void SetAltMetaData(_SqlMetaDataSet altMetaDataSet) {
- // VSTFDEVDIV 479675: if altmetadata with same id is found, override it rather than adding a new one
- int newId = altMetaDataSet.id;
- for (int i = 0; i < altMetaDataSetArray.Count; i++) {
- if (altMetaDataSetArray[i].id == newId) {
- // override the existing metadata with the same id
- altMetaDataSetArray[i] = altMetaDataSet;
- return;
- }
- }
- // if we did not find metadata to override, add as new
- altMetaDataSetArray.Add(altMetaDataSet);
- }
- internal _SqlMetaDataSet GetAltMetaData(int id) {
- foreach (_SqlMetaDataSet altMetaDataSet in altMetaDataSetArray) {
- if (altMetaDataSet.id == id) {
- return altMetaDataSet;
- }
- }
- Debug.Assert (false, "Can't match up altMetaDataSet with given id");
- return null;
- }
- public object Clone()
- {
- _SqlMetaDataSetCollection result = new _SqlMetaDataSetCollection();
- result.metaDataSet = metaDataSet == null ? null : (_SqlMetaDataSet)metaDataSet.Clone();
- foreach (_SqlMetaDataSet set in altMetaDataSetArray) {
- result.altMetaDataSetArray.Add((_SqlMetaDataSet)set.Clone());
- }
- return result;
- }
- }
- /// <summary>
- /// Represents Encryption related information of the cipher data.
- /// </summary>
- internal class SqlCipherMetadata {
- /// <summary>
- /// Cipher Info Entry.
- /// </summary>
- private SqlTceCipherInfoEntry? _sqlTceCipherInfoEntry;
- /// <summary>
- /// Encryption Algorithm Id.
- /// </summary>
- private readonly byte _cipherAlgorithmId;
- /// <summary>
- /// Encryption Algorithm Name.
- /// </summary>
- private readonly string _cipherAlgorithmName;
- /// <summary>
- /// Encryption Type.
- /// </summary>
- private readonly byte _encryptionType;
- /// <summary>
- /// Normalization Rule Version.
- /// </summary>
- private readonly byte _normalizationRuleVersion;
-
- /// <summary>
- /// Encryption Algorithm Handle.
- /// </summary>
- private SqlClientEncryptionAlgorithm _sqlClientEncryptionAlgorithm;
- /// <summary>
- /// Sql Encryption Key Info.
- /// </summary>
- private SqlEncryptionKeyInfo? _sqlEncryptionKeyInfo;
- /// <summary>
- /// Ordinal (into the Cek Table).
- /// </summary>
- private readonly ushort _ordinal;
- /// <summary>
- /// Return the Encryption Info Entry.
- /// </summary>
- internal SqlTceCipherInfoEntry? EncryptionInfo {
- get {
- return _sqlTceCipherInfoEntry;
- }
- set {
- Debug.Assert(!_sqlTceCipherInfoEntry.HasValue, "We can only set the EncryptionInfo once.");
- _sqlTceCipherInfoEntry = value;
- }
- }
- /// <summary>
- /// Return the cipher's encryption algorithm id.
- /// </summary>
- internal byte CipherAlgorithmId {
- get {
- return _cipherAlgorithmId;
- }
- }
- /// <summary>
- /// Return the cipher's encryption algorithm name (could be null).
- /// </summary>
- internal string CipherAlgorithmName {
- get {
- return _cipherAlgorithmName;
- }
- }
- /// <summary>
- /// Return EncryptionType (Deterministic, Randomized, etc.)
- /// </summary>
- internal byte EncryptionType {
- get {
- return _encryptionType;
- }
- }
- /// <summary>
- /// Return normalization rule version.
- /// </summary>
- internal byte NormalizationRuleVersion {
- get {
- return _normalizationRuleVersion;
- }
- }
- /// <summary>
- /// Return the cipher encyrption algorithm handle.
- /// </summary>
- internal SqlClientEncryptionAlgorithm CipherAlgorithm {
- get {
- return _sqlClientEncryptionAlgorithm;
- }
- set {
- Debug.Assert(_sqlClientEncryptionAlgorithm == null, "_sqlClientEncryptionAlgorithm should not be set more than once.");
- _sqlClientEncryptionAlgorithm = value;
- }
- }
- /// <summary>
- /// Return Encryption Key Info.
- /// </summary>
- internal SqlEncryptionKeyInfo? EncryptionKeyInfo {
- get {
- return _sqlEncryptionKeyInfo;
- }
- set {
- Debug.Assert(!_sqlEncryptionKeyInfo.HasValue, "_sqlEncryptionKeyInfo should not be set more than once.");
- _sqlEncryptionKeyInfo = value;
- }
- }
- /// <summary>
- /// Return Ordinal into Cek Table.
- /// </summary>
- internal ushort CekTableOrdinal {
- get {
- return _ordinal;
- }
- }
- /// <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>
- /// Do we have an handle to the cipher encryption algorithm already ?
- /// </summary>
- /// <returns></returns>
- internal bool IsAlgorithmInitialized() {
- return (null != _sqlClientEncryptionAlgorithm) ? true : false;
- }
- }
- internal class SqlMetaDataPriv {
- internal SqlDbType type; // SqlDbType enum value
- internal byte tdsType; // underlying tds type
- internal byte precision = TdsEnums.UNKNOWN_PRECISION_SCALE; // give default of unknown (-1)
- internal byte scale = TdsEnums.UNKNOWN_PRECISION_SCALE; // give default of unknown (-1)
- internal int length;
- internal SqlCollation collation;
- internal int codePage;
- internal Encoding encoding;
- internal bool isNullable;
- internal bool isMultiValued = false;
- // UDT specific metadata
- // server metadata info
- // additional temporary UDT meta data
- internal string udtDatabaseName;
- internal string udtSchemaName;
- internal string udtTypeName;
- internal string udtAssemblyQualifiedName;
- // on demand
- internal Type udtType;
- // Xml specific metadata
- internal string xmlSchemaCollectionDatabase;
- internal string xmlSchemaCollectionOwningSchema;
- internal string xmlSchemaCollectionName;
- internal MetaType metaType; // cached metaType
- // Structured type-specific metadata
- internal string structuredTypeDatabaseName;
- internal string structuredTypeSchemaName;
- internal string structuredTypeName;
- internal IList<SmiMetaData> structuredFields;
- internal bool isEncrypted; // TCE encrypted?
- internal SqlMetaDataPriv baseTI; // for encrypted columns, represents the TYPE_INFO for plaintext value
- internal SqlCipherMetadata cipherMD; // Cipher related metadata for encrypted columns.
- internal SqlMetaDataPriv() {
- }
- internal virtual void CopyFrom(SqlMetaDataPriv original) {
- this.type = original.type;
- this.tdsType = original.tdsType;
- this.precision = original.precision;
- this.scale = original.scale;
- this.length = original.length;
- this.collation = original.collation;
- this.codePage = original.codePage;
- this.encoding = original.encoding;
- this.isNullable = original.isNullable;
- this.isMultiValued = original.isMultiValued;
- this.udtDatabaseName = original.udtDatabaseName;
- this.udtSchemaName = original.udtSchemaName;
- this.udtTypeName = original.udtTypeName;
- this.udtAssemblyQualifiedName = original.udtAssemblyQualifiedName;
- this.udtType = original.udtType;
- this.xmlSchemaCollectionDatabase = original.xmlSchemaCollectionDatabase;
- this.xmlSchemaCollectionOwningSchema = original.xmlSchemaCollectionOwningSchema;
- this.xmlSchemaCollectionName = original.xmlSchemaCollectionName;
- this.metaType = original.metaType;
- //
- this.structuredTypeDatabaseName = original.structuredTypeDatabaseName;
- this.structuredTypeSchemaName = original.structuredTypeSchemaName;
- this.structuredTypeName = original.structuredTypeName;
- this.structuredFields = original.structuredFields;
- }
- /// <summary>
- /// Is the algorithm handle for the cipher encryption initialized ?
- /// </summary>
- /// <returns></returns>
- internal bool IsAlgorithmInitialized() {
- if (null != cipherMD) {
- return cipherMD.IsAlgorithmInitialized();
- }
- return false;
- }
- /// <summary>
- /// Returns the normalization rule version byte.
- /// </summary>
- /// <returns></returns>
- internal byte NormalizationRuleVersion {
- get {
- if (null != cipherMD){
- return cipherMD.NormalizationRuleVersion;
- }
- return 0x00;
- }
- }
- }
- /// <summary>
- /// Class encapsulating additional information when sending encrypted input parameters.
- /// </summary>
- sealed internal class SqlColumnEncryptionInputParameterInfo
- {
- /// <summary>
- /// Metadata of the parameter to write the TYPE_INFO of the unencrypted column data type.
- /// </summary>
- private readonly SmiParameterMetaData _smiParameterMetadata;
- /// <summary>
- /// Column encryption related metadata.
- /// </summary>
- private readonly SqlCipherMetadata _cipherMetadata;
- /// <summary>
- /// Serialized format for a subset of members.
- /// Does not include _smiParameterMetadata's serialization.
- /// </summary>
- private readonly byte[] _serializedWireFormat;
- /// <summary>
- /// Return the SMI Parameter Metadata.
- /// </summary>
- internal SmiParameterMetaData ParameterMetadata {
- get {
- return _smiParameterMetadata;
- }
- }
- /// <summary>
- /// Return the serialized format for some members.
- /// This is pre-calculated and cached since members are immutable.
- /// Does not include _smiParameterMetadata's serialization.
- /// </summary>
- internal byte[] SerializedWireFormat
- {
- get {
- return _serializedWireFormat;
- }
- }
- /// <summary>
- /// Constructor.
- /// </summary>
- /// <param name="smiParameterMetadata"></param>
- /// <param name="cipherMetadata"></param>
- internal SqlColumnEncryptionInputParameterInfo(SmiParameterMetaData smiParameterMetadata, SqlCipherMetadata cipherMetadata) {
- Debug.Assert(smiParameterMetadata != null, "smiParameterMetadata should not be null.");
- Debug.Assert(cipherMetadata != null, "cipherMetadata should not be null");
- Debug.Assert(cipherMetadata.EncryptionKeyInfo.HasValue, "cipherMetadata.EncryptionKeyInfo.HasValue should be true.");
- _smiParameterMetadata = smiParameterMetadata;
- _cipherMetadata = cipherMetadata;
- _serializedWireFormat = SerializeToWriteFormat();
- }
- /// <summary>
- /// Serializes some data members to wire format.
- /// </summary>
- private byte[] SerializeToWriteFormat() {
- int totalLength = 0;
- // CipherAlgorithmId.
- totalLength += sizeof(byte);
- // Encryption Type.
- totalLength += sizeof(byte);
- // Database id of the encryption key.
- totalLength += sizeof(int);
- // Id of the encryption key.
- totalLength += sizeof(int);
- // Version of the encryption key.
- totalLength += sizeof(int);
- // Metadata version of the encryption key.
- totalLength += _cipherMetadata.EncryptionKeyInfo.Value.cekMdVersion.Length;
- // Normalization Rule Version.
- totalLength += sizeof(byte);
- byte[] serializedWireFormat = new byte[totalLength];
- // No:of bytes consumed till now. Running variable.
- int consumedBytes = 0;
- // 1 - Write Cipher Algorithm Id.
- serializedWireFormat[consumedBytes++] = _cipherMetadata.CipherAlgorithmId;
- // 2 - Write Encryption Type.
- serializedWireFormat[consumedBytes++] = _cipherMetadata.EncryptionType;
- // 3 - Write the database id of the encryption key.
- SerializeIntIntoBuffer(_cipherMetadata.EncryptionKeyInfo.Value.databaseId, serializedWireFormat, ref consumedBytes);
- // 4 - Write the id of the encryption key.
- SerializeIntIntoBuffer(_cipherMetadata.EncryptionKeyInfo.Value.cekId, serializedWireFormat, ref consumedBytes);
- // 5 - Write the version of the encryption key.
- SerializeIntIntoBuffer(_cipherMetadata.EncryptionKeyInfo.Value.cekVersion, serializedWireFormat, ref consumedBytes);
- // 6 - Write the metadata version of the encryption key.
- Buffer.BlockCopy(_cipherMetadata.EncryptionKeyInfo.Value.cekMdVersion, 0, serializedWireFormat, consumedBytes, _cipherMetadata.EncryptionKeyInfo.Value.cekMdVersion.Length);
- consumedBytes += _cipherMetadata.EncryptionKeyInfo.Value.cekMdVersion.Length;
- // 7 - Write Normalization Rule Version.
- serializedWireFormat[consumedBytes++] = _cipherMetadata.NormalizationRuleVersion;
- return serializedWireFormat;
- }
- /// <summary>
- /// Serializes an int into the provided buffer and offset.
- /// </summary>
- private void SerializeIntIntoBuffer(int value, byte[] buffer, ref int offset) {
- buffer[offset++] = (byte)(value & 0xff);
- buffer[offset++] = (byte)((value >> 8) & 0xff);
- buffer[offset++] = (byte)((value >> 16) & 0xff);
- buffer[offset++] = (byte)((value >> 24) & 0xff);
- }
- }
- sealed internal class _SqlRPC {
- internal string rpcName;
- internal string databaseName; // Used for UDTs
- internal ushort ProcID; // Used instead of name
- internal ushort options;
- internal SqlParameter[] parameters;
- internal byte[] paramoptions;
- internal int? recordsAffected;
- internal int cumulativeRecordsAffected;
- internal int errorsIndexStart;
- internal int errorsIndexEnd;
- internal SqlErrorCollection errors;
-
- internal int warningsIndexStart;
- internal int warningsIndexEnd;
- internal SqlErrorCollection warnings;
- internal bool needsFetchParameterEncryptionMetadata;
- internal string GetCommandTextOrRpcName() {
- if (TdsEnums.RPC_PROCID_EXECUTESQL == ProcID) {
- // Param 0 is the actual sql executing
- return (string)parameters[0].Value;
- }
- else {
- return rpcName;
- }
- }
- }
- sealed internal class SqlReturnValue : SqlMetaDataPriv {
- internal ushort parmIndex; //Yukon or later only
- internal string parameter;
- internal readonly SqlBuffer value;
- internal SqlReturnValue() : base() {
- value = new SqlBuffer();
- }
- }
- internal struct MultiPartTableName {
- private string _multipartName;
- private string _serverName;
- private string _catalogName;
- private string _schemaName;
- private string _tableName;
- internal MultiPartTableName(string[] parts) {
- _multipartName = null;
- _serverName = parts[0];
- _catalogName = parts[1];
- _schemaName = parts[2];
- _tableName = parts[3];
- }
- internal MultiPartTableName(string multipartName) {
- _multipartName = multipartName;
- _serverName = null;
- _catalogName = null;
- _schemaName = null;
- _tableName = null;
- }
- internal string ServerName {
- get {
- ParseMultipartName();
- return _serverName;
- }
- set { _serverName = value; }
- }
- internal string CatalogName {
- get {
- ParseMultipartName();
- return _catalogName;
- }
- set { _catalogName = value; }
- }
- internal string SchemaName {
- get {
- ParseMultipartName();
- return _schemaName;
- }
- set { _schemaName = value; }
- }
- internal string TableName {
- get {
- ParseMultipartName();
- return _tableName;
- }
- set { _tableName = value; }
- }
- private void ParseMultipartName() {
- if (null != _multipartName) {
- string[] parts = MultipartIdentifier.ParseMultipartIdentifier(_multipartName, "[\"", "]\"", Res.SQL_TDSParserTableName, false);
- _serverName = parts[0];
- _catalogName = parts[1];
- _schemaName = parts[2];
- _tableName = parts[3];
- _multipartName = null;
- }
- }
- internal static readonly MultiPartTableName Null = new MultiPartTableName(new string[] {null, null, null, null});
- }
- }
|