diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/incident-report.md
similarity index 91%
rename from .github/ISSUE_TEMPLATE/bug_report.md
rename to .github/ISSUE_TEMPLATE/incident-report.md
index a43efd7d3..2eb2e3a78 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/incident-report.md
@@ -1,8 +1,8 @@
---
-name: Bug report
-about: Report a bug to help us improve
-title: "[BUG]"
-labels: bug
+name: Incident report
+about: Report an incident
+title: ''
+labels: ''
assignees: ''
---
diff --git a/.github/ISSUE_TEMPLATE/question.md b/.github/ISSUE_TEMPLATE/question.md
index 1131f35db..9681d198d 100644
--- a/.github/ISSUE_TEMPLATE/question.md
+++ b/.github/ISSUE_TEMPLATE/question.md
@@ -1,6 +1,6 @@
---
name: Question
-about: Discuss an idea to see if it would be an appropriate Issue.
+about: Ask a question
title: "[QUESTION]"
labels: question
assignees: ''
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1ed74ab66..c319b9d72 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -3,6 +3,28 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
+## [8.1.0] Preview Release
+### Added
+- Added ISQLServerBulkData to remove implementation details from ISQLServerBulkRecord [#1099](https://github.com/microsoft/mssql-jdbc/pull/1099)
+- Added support for Azure national clouds when using Azure Key Vault [#1130](https://github.com/microsoft/mssql-jdbc/pull/1130)
+- Implemented hashCode() and equals() APIs for SQLServerDataTable and SQLServerDataColumn [#1146](https://github.com/Microsoft/mssql-jdbc/pull/1146)
+- Added support for JAVA 13 [#1151](https://github.com/Microsoft/mssql-jdbc/pull/1151)
+- Added support for Always Encrypted with Secure Enclaves [#1155](https://github.com/Microsoft/mssql-jdbc/pull/1155)
+
+### Fixed Issues
+- Fixed Geography.STAsBinary() returning null for a single point [#1074](https://github.com/microsoft/mssql-jdbc/pull/1074)
+- Fixed DatabaseMetaData.getImportedKeys() returning duplicate rows [#1092](https://github.com/microsoft/mssql-jdbc/pull/1092)
+- Fixed issue with truststore password being removed too early for XA connections [#1133](https://github.com/microsoft/mssql-jdbc/pull/1133)
+- Fixed issue with SQLServerDatabaseMetada.getColumns() not escaping wildcard characters [#1138](https://github.com/microsoft/mssql-jdbc/pull/1138)
+- Removed extra spaces in SQLServerDatabaseMetaData.getNumericFunctions() and SQLServerDatabaseMetaData.getStringFunctions() return values [#1117](https://github.com/microsoft/mssql-jdbc/pull/1117)
+
+### Changed
+- Improved performance of column name lookups [#1066](https://github.com/microsoft/mssql-jdbc/pull/1066)
+- Test improvements [#1100](https://github.com/microsoft/mssql-jdbc/pull/1100)
+- Updated issue templates [#1148](https://github.com/microsoft/mssql-jdbc/pull/1148)
+- Improved performance of CallableStatement and ParameterMetaData when using procedure names that contain wildcard characters [#1149](https://github.com/microsoft/mssql-jdbc/pull/1149)
+- Updated CI to use SQL Server 2012 instead of 2008R2 [#1153](https://github.com/microsoft/mssql-jdbc/pull/1153)
+
## [7.4.1] HotFix & Stable Release
### Fixed Issues
- Reverted [#1025](https://github.com/Microsoft/mssql-jdbc/pull/1025) as it contains breaking changes. This removes `hashCode()` and `equals()` APIs from `SQLServerDataTable` and `SQLServerDataColumn`.
diff --git a/README.md b/README.md
index 02dabfedd..71408da85 100644
--- a/README.md
+++ b/README.md
@@ -48,16 +48,16 @@ To build the jar files, you must use minimum version of Java 11 with Maven. You
* Maven:
1. If you have not already done so, add the environment variable `mssql_jdbc_test_connection_properties` in your system with the connection properties for your SQL Server or SQL DB instance.
2. Run one of the commands below to build a JRE 11 and newer versions compatible jar or JRE 8 compatible jar in the `\target` directory.
- * Run `mvn install -Pjre12`. This creates JRE 12 compatible jar in `\target` directory which is JDBC 4.3 compliant (Build with JDK 12+).
- * Run `mvn install -Pjre11`. This creates JRE 11 compatible jar in `\target` directory which is JDBC 4.3 compliant (Build with JDK 11+).
- * Run `mvn install -Pjre8`. This creates JRE 8 compatible jar in `\target` directory which is JDBC 4.2 compliant (Build with JDK 11+).
+ * Run `mvn install -Pjre13`. This creates JRE 13 compatible jar in `\target` directory which is JDBC 4.3 compliant (Build with JDK 13+).
+ * Run `mvn install -Pjre11`. This creates JRE 11 compatible jar in `\target` directory which is JDBC 4.3 compliant (Build with JDK 11+).
+ * Run `mvn install -Pjre8`. This creates JRE 8 compatible jar in `\target` directory which is JDBC 4.2 compliant (Build with JDK 11+).
* Gradle:
1. If you have not already done so, add the environment variable `mssql_jdbc_test_connection_properties` in your system with the connection properties for your SQL Server or SQL DB instance.
2. Run one of the commands below to build a JRE 11 and newer versions compatible jar or JRE 8 compatible jar in the `\build\libs` directory.
- * Run `gradle build -PbuildProfile=jre12`. This creates JRE 12 compatible jar in `\build\libs` directory which is JDBC 4.3 compliant (Build with JDK 12+).
- * Run `gradle build -PbuildProfile=jre11`. This creates JRE 11 compatible jar in `\build\libs` directory which is JDBC 4.3 compliant (Build with JDK 11+).
- * Run `gradle build -PbuildProfile=jre8`. This creates JRE 8 compatible jar in `\build\libs` directory which is JDBC 4.2 compliant (Build with JDK 11+).
+ * Run `gradle build -PbuildProfile=jre13`. This creates JRE 13 compatible jar in `\build\libs` directory which is JDBC 4.3 compliant (Build with JDK 13+).
+ * Run `gradle build -PbuildProfile=jre11`. This creates JRE 11 compatible jar in `\build\libs` directory which is JDBC 4.3 compliant (Build with JDK 11+).
+ * Run `gradle build -PbuildProfile=jre8`. This creates JRE 8 compatible jar in `\build\libs` directory which is JDBC 4.2 compliant (Build with JDK 11+).
## Resources
@@ -92,7 +92,7 @@ To get the latest preview version of the driver, add the following to your POM f
com.microsoft.sqlserver
mssql-jdbc
- 7.3.1.jre12-preview
+ 8.1.0.jre13-preview
```
@@ -127,7 +127,7 @@ Projects that require either of the two features need to explicitly declare the
com.microsoft.sqlserver
mssql-jdbc
- 7.4.1.jre12
+ 8.1.0.jre13-preview
compile
@@ -150,7 +150,7 @@ Projects that require either of the two features need to explicitly declare the
com.microsoft.sqlserver
mssql-jdbc
- 7.4.1.jre12
+ 8.1.0.jre13-preview
compile
@@ -183,7 +183,7 @@ When setting 'useFmtOnly' property to 'true' for establishing a connection or cr
com.microsoft.sqlserver
mssql-jdbc
- 7.4.1.jre12
+ 8.1.0.jre13-preview
@@ -223,7 +223,7 @@ Preview releases happen approximately monthly between stable releases. This give
You can see what is going into a future release by monitoring [Milestones](https://github.com/Microsoft/mssql-jdbc/milestones) in the repository.
### Version conventions
-Starting with 6.0, stable versions have an even minor version. For example, 6.0, 6.2, 6.4, 7.0, 7.2, 7.4. Preview versions have an odd minor version. For example, 6.1, 6.3, 6.5, 7.1, 7.3, and so on
+Starting with 6.0, stable versions have an even minor version. For example, 6.0, 6.2, 6.4, 7.0, 7.2, 7.4. Preview versions have an odd minor version. For example, 6.1, 6.3, 6.5, 7.1, 7.3, 8.1 and so on
## Contributors
Special thanks to everyone who has contributed to the project.
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index e80e73dae..3c025fa33 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -1,6 +1,6 @@
-# Microsoft JDBC Driver for SQL Server CI Build triggers tests against below SQL Servers:
+# Microsoft JDBC Driver for SQL Server CI build triggers tests against below SQL Servers:
# - SQL Server 2019
-# - SQL Server 2008 R2
+# - SQL Server 2012
jobs:
- job: "CI_Build"
pool:
@@ -11,8 +11,8 @@ jobs:
SQL-2019:
Target_SQL: 'SQL-2k19-01'
Ex_Groups: 'xSQLv15'
- SQL-2008R2:
- Target_SQL: 'SQL-2k8R2-SP3-1'
+ SQL-2012:
+ Target_SQL: 'SQL-2K12-SP3-1'
Ex_Groups: 'xSQLv12'
maxParallel: 2
steps:
@@ -29,30 +29,35 @@ jobs:
Get-Content .\JavaKeyStoreBase.txt | Set-Content -Encoding utf8 JavaKeyStore.txt
Remove-Item –path .\JavaKeyStoreBase.txt
displayName: 'PowerShell Script'
+ - task: DownloadSecureFile@1
+ name: pkcs12_truststore
+ displayName: 'Download PKCS12 truststore file'
+ inputs:
+ secureFile: 'pkcs12_truststore'
- task: Maven@3
- displayName: 'Maven build jre12'
+ displayName: 'Maven build jre13'
inputs:
mavenPomFile: 'pom.xml'
- goals: 'clean -Dmssql_jdbc_test_connection_properties=jdbc:sqlserver://$(Target_SQL)$(server_domain);$(database);$(user);$(password); install -Pjre12 -DuserNTLM=$(userNTLM) -DpasswordNTLM=$(passwordNTLM) -DdomainNTLM=$(domainNTLM) -DexcludedGroups=$(Ex_Groups)'
+ goals: 'clean -Dmssql_jdbc_test_connection_properties=jdbc:sqlserver://$(Target_SQL)$(server_domain);$(database);$(user);$(password); install -Pjre13 -DuserNTLM=$(userNTLM) -DpasswordNTLM=$(passwordNTLM) -DdomainNTLM=$(domainNTLM) -DexcludedGroups=$(Ex_Groups) -Dpkcs12_truststore_password=$(pkcs12_truststore_password) -Dpkcs12_truststore=$(pkcs12_truststore.secureFilePath)'
testResultsFiles: '**/TEST-*.xml'
- testRunTitle: 'Maven build jre12'
+ testRunTitle: 'Maven build jre13'
javaHomeOption: Path
- jdkDirectory: $(JDK12)
+ jdkDirectory: $(JDK13)
- task: Maven@3
displayName: 'Maven build jre11'
inputs:
mavenPomFile: 'pom.xml'
- goals: 'clean -Dmssql_jdbc_test_connection_properties=jdbc:sqlserver://$(Target_SQL)$(server_domain);$(database);$(user);$(password); install -Pjre11 -DuserNTLM=$(userNTLM) -DpasswordNTLM=$(passwordNTLM) -DdomainNTLM=$(domainNTLM) -DexcludedGroups=$(Ex_Groups)'
+ goals: 'clean -Dmssql_jdbc_test_connection_properties=jdbc:sqlserver://$(Target_SQL)$(server_domain);$(database);$(user);$(password); install -Pjre11 -DuserNTLM=$(userNTLM) -DpasswordNTLM=$(passwordNTLM) -DdomainNTLM=$(domainNTLM) -DexcludedGroups=$(Ex_Groups) -Dpkcs12_truststore_password=$(pkcs12_truststore_password) -Dpkcs12_truststore=$(pkcs12_truststore.secureFilePath)'
testResultsFiles: '**/TEST-*.xml'
testRunTitle: 'Maven build jre11'
javaHomeOption: Path
- jdkDirectory: $(JDK12)
+ jdkDirectory: $(JDK13)
- task: Maven@3
displayName: 'Maven build jre8'
inputs:
mavenPomFile: 'pom.xml'
- goals: 'clean -Dmssql_jdbc_test_connection_properties=jdbc:sqlserver://$(Target_SQL)$(server_domain);$(database);$(user);$(password); install -Pjre8 -DuserNTLM=$(userNTLM) -DpasswordNTLM=$(passwordNTLM) -DdomainNTLM=$(domainNTLM) -DexcludedGroups=$(Ex_Groups)'
+ goals: 'clean -Dmssql_jdbc_test_connection_properties=jdbc:sqlserver://$(Target_SQL)$(server_domain);$(database);$(user);$(password); install -Pjre8 -DuserNTLM=$(userNTLM) -DpasswordNTLM=$(passwordNTLM) -DdomainNTLM=$(domainNTLM) -DexcludedGroups=$(Ex_Groups) -Dpkcs12_truststore_password=$(pkcs12_truststore_password) -Dpkcs12_truststore=$(pkcs12_truststore.secureFilePath)'
testResultsFiles: '**/TEST-*.xml'
testRunTitle: 'Maven build jre8'
javaHomeOption: Path
- jdkDirectory: $(JDK12)
+ jdkDirectory: $(JDK13)
diff --git a/build.gradle b/build.gradle
index c5ead5be4..cda572c46 100644
--- a/build.gradle
+++ b/build.gradle
@@ -3,8 +3,8 @@
****************************************************************
* Instruction for Building JDBC Driver:
* For building particular version of the driver, use commands:
- * jre12 - - PS> gradle build
- PS> gradle build -PbuildProfile=jre12
+ * jre13 - - PS> gradle build
+ PS> gradle build -PbuildProfile=jre13
* jre11 - - PS> gradle build -PbuildProfile=jre11
* jre8 - - PS> gradle build -PbuildProfile=jre8
*
@@ -14,7 +14,7 @@
apply plugin: 'java'
-version = '7.4.1'
+version = '8.1.0'
def jreVersion = ""
def testOutputDir = file("build/classes/java/test")
def archivesBaseName = 'mssql-jdbc'
@@ -31,21 +31,21 @@ allprojects {
test {
useJUnitPlatform {
- excludeTags (hasProperty('excludedGroups') ? excludedGroups : 'xSQLv15','xGradle','NTLM')
+ excludeTags (hasProperty('excludedGroups') ? excludedGroups : 'xSQLv15','xGradle','reqExternalSetup','NTLM')
}
}
-if (!hasProperty('buildProfile') || (hasProperty('buildProfile') && buildProfile == "jre12")){
+if (!hasProperty('buildProfile') || (hasProperty('buildProfile') && buildProfile == "jre13")){
- jreVersion = "jre12"
+ jreVersion = "jre13"
excludedFile = 'com/microsoft/sqlserver/jdbc/SQLServerJdbc42.java'
jar {
manifest {
attributes 'Automatic-Module-Name': 'com.microsoft.sqlserver.jdbc'
}
}
- sourceCompatibility = 12
- targetCompatibility = 12
+ sourceCompatibility = 13
+ targetCompatibility = 13
}
if (hasProperty('buildProfile') && buildProfile == "jre11"){
@@ -70,12 +70,12 @@ if(hasProperty('buildProfile') && buildProfile == "jre8") {
targetCompatibility = 1.8
test {
useJUnitPlatform {
- excludeTags (hasProperty('excludedGroups') ? excludedGroups : 'xSQLv15','xGradle','NTLM','xJDBC42')
+ excludeTags (hasProperty('excludedGroups') ? excludedGroups : 'xSQLv15','xGradle','NTLM','reqExternalSetup','xJDBC42')
}
}
}
-jar.archiveName = "${archivesBaseName}-${version}.${jreVersion}.jar"
+jar.archiveName = "${archivesBaseName}-${version}.${jreVersion}-preview.jar"
jar {
manifest {
attributes 'Title': "Microsoft JDBC Driver ${version} for SQL Server",
diff --git a/pom.xml b/pom.xml
index 2c7c0bbdd..ebdd69f7c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.microsoft.sqlserver
mssql-jdbc
- 7.4.1
+ 8.1.0
jar
Microsoft JDBC Driver for SQL Server
@@ -49,10 +49,11 @@
xAzureSQLDB - - - - For tests not compatible with Azure SQL Database - -
xAzureSQLDW - - - - For tests not compatible with Azure Data Warehouse -
xAzureSQLMI - - - - For tests not compatible with Azure SQL Managed Instance
- NTLM - - - - - - For tests using NTLM Authentication mode (excluded by default)
+ NTLM - - - - - - - For tests using NTLM Authentication mode (excluded by default)
+ reqExternalSetup - For tests requiring external setup (excluded by default)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Default testing enabled with SQL Server 2019 (SQLv14) -->
- xSQLv15, NTLM
+ xSQLv15, NTLM, reqExternalSetup
1.2.1
@@ -196,7 +197,7 @@
jre8
- ${project.artifactId}-${project.version}.jre8
+ ${project.artifactId}-${project.version}.jre8-preview
org.apache.maven.plugins
@@ -242,7 +243,7 @@
jre11
- ${project.artifactId}-${project.version}.jre11
+ ${project.artifactId}-${project.version}.jre11-preview
org.apache.maven.plugins
@@ -273,12 +274,12 @@
- jre12
+ jre13
true
- ${project.artifactId}-${project.version}.jre12
+ ${project.artifactId}-${project.version}.jre13-preview
org.apache.maven.plugins
@@ -288,8 +289,8 @@
**/com/microsoft/sqlserver/jdbc/SQLServerJdbc42.java
-
- 12
+
+ 13
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/AE.java b/src/main/java/com/microsoft/sqlserver/jdbc/AE.java
index 4ba6d0f69..c75e3c46d 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/AE.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/AE.java
@@ -242,7 +242,9 @@ enum DescribeParameterEncryptionResultSet1 {
EncryptedKey,
ProviderName,
KeyPath,
- KeyEncryptionAlgorithm;
+ KeyEncryptionAlgorithm,
+ IsRequestedByEnclave,
+ EnclaveCMKSignature;
int value() {
// Column indexing starts from 1;
@@ -266,5 +268,15 @@ int value() {
// Column indexing starts from 1;
return ordinal() + 1;
}
+}
+
+enum ColumnEncryptionVersion {
+ AE_NotSupported,
+ AE_v1,
+ AE_v2;
+ int value() {
+ // Column indexing starts from 1;
+ return ordinal() + 1;
+ }
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/AuthenticationJNI.java b/src/main/java/com/microsoft/sqlserver/jdbc/AuthenticationJNI.java
index ae53c3c6c..859a9f96d 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/AuthenticationJNI.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/AuthenticationJNI.java
@@ -160,4 +160,7 @@ private static native FedAuthDllInfo ADALGetAccessTokenForWindowsIntegrated(Stri
static native byte[] DecryptColumnEncryptionKey(String masterKeyPath, String encryptionAlgorithm,
byte[] encryptedColumnEncryptionKey) throws DLLException;
+
+ static native boolean VerifyColumnMasterKeyMetadata(String keyPath, boolean allowEnclaveComputations,
+ byte[] signature) throws DLLException;
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
index c82b0e628..2cd9404f8 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
@@ -40,6 +40,7 @@
import java.text.MessageFormat;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
@@ -113,7 +114,9 @@ final class TDS {
// AE constants
// 0x03 is for x_eFeatureExtensionId_Rcs
static final byte TDS_FEATURE_EXT_AE = 0x04;
- static final byte MAX_SUPPORTED_TCE_VERSION = 0x01; // max version
+ static final byte COLUMNENCRYPTION_NOT_SUPPORTED = 0x00; // column encryption not supported
+ static final byte COLUMNENCRYPTION_VERSION1 = 0x01; // column encryption without enclave
+ static final byte COLUMNENCRYPTION_VERSION2 = 0x02; // column encryption with enclave
static final int CUSTOM_CIPHER_ALGORITHM_ID = 0; // max version
// 0x06 is for x_eFeatureExtensionId_LoginToken
// 0x07 is for x_eFeatureExtensionId_ClientSideTelemetry
@@ -3701,8 +3704,9 @@ void writeBytes(byte[] value, int offset, int length) throws SQLServerException
int bytesWritten = 0;
int bytesToWrite;
- if (logger.isLoggable(Level.FINEST))
+ if (logger.isLoggable(Level.FINEST)) {
logger.finest(toString() + " Writing " + length + " bytes");
+ }
while ((bytesToWrite = length - bytesWritten) > 0) {
if (0 == stagingBuffer.remaining())
@@ -6189,6 +6193,22 @@ void writeRPCReaderUnicode(String sName, Reader re, long reLength, boolean bOut,
// Write the data
writeReader(re, reLength, usePLP);
}
+
+ void sendEnclavePackage(String sql, ArrayList enclaveCEKs) throws SQLServerException {
+ if (null != con && con.isAEv2()) {
+ if (null != sql && "" != sql && null != enclaveCEKs && 0 < enclaveCEKs.size() && con.enclaveEstablished()) {
+ byte[] b = con.generateEncalvePackage(sql, enclaveCEKs);
+ if (null != b && 0 != b.length) {
+ this.writeShort((short) b.length);
+ this.writeBytes(b);
+ } else {
+ this.writeShort((short) 0);
+ }
+ } else {
+ this.writeShort((short) 0);
+ }
+ }
+ }
}
@@ -6284,6 +6304,7 @@ final SQLServerConnection getConnection() {
private boolean useColumnEncryption = false;
private boolean serverSupportsColumnEncryption = false;
private boolean serverSupportsDataClassification = false;
+ private ColumnEncryptionVersion columnEncryptionVersion;
private final byte valueBytes[] = new byte[256];
@@ -6308,6 +6329,7 @@ private static int nextReaderID() {
useColumnEncryption = true;
}
serverSupportsColumnEncryption = con.getServerSupportsColumnEncryption();
+ columnEncryptionVersion = con.getServerColumnEncryptionVersion();
serverSupportsDataClassification = con.getServerSupportsDataClassification();
}
@@ -7162,6 +7184,8 @@ final boolean readingResponse() {
return readingResponse;
}
+ protected ArrayList enclaveCEKs;
+
/**
* Creates this command with an optional timeout.
*
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerBulkData.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerBulkData.java
new file mode 100644
index 000000000..0b60a8fcd
--- /dev/null
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerBulkData.java
@@ -0,0 +1,79 @@
+/*
+ * Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made
+ * available under the terms of the MIT License. See the LICENSE file in the project root for more information.
+ */
+
+package com.microsoft.sqlserver.jdbc;
+
+import java.io.Serializable;
+
+/**
+ * Provides an interface used to create classes that read in data from any source (such as a file) and allows a
+ * SQLServerBulkCopy class to write the data to SQL Server tables.
+ */
+public interface ISQLServerBulkData extends Serializable {
+
+ /**
+ * Returns the ordinals for each of the columns represented in this data record.
+ *
+ * @return Set of ordinals for the columns.
+ */
+ java.util.Set getColumnOrdinals();
+
+ /**
+ * Returns the name of the given column.
+ *
+ * @param column
+ * Column ordinal
+ * @return Name of the column
+ */
+ String getColumnName(int column);
+
+ /**
+ * Returns the JDBC data type of the given column.
+ *
+ * @param column
+ * Column ordinal
+ * @return JDBC data type of the column
+ */
+ int getColumnType(int column);
+
+ /**
+ * Returns the precision for the given column.
+ *
+ * @param column
+ * Column ordinal
+ * @return Precision of the column
+ */
+ int getPrecision(int column);
+
+ /**
+ * Returns the scale for the given column.
+ *
+ * @param column
+ * Column ordinal
+ * @return Scale of the column
+ */
+ int getScale(int column);
+
+ /**
+ * Returns the data for the current row as an array of Objects.
+ *
+ * Each Object must match the Java language Type that is used to represent the indicated JDBC data type for the
+ * given column. For more information, see 'Understanding the JDBC Driver Data Types' for the appropriate mappings.
+ *
+ * @return The data for the row.
+ * @throws SQLServerException
+ * If there are any errors in obtaining the data.
+ */
+ Object[] getRowData() throws SQLServerException;
+
+ /**
+ * Advances to the next data row.
+ *
+ * @return True if rows are available; false if there are no more rows
+ * @throws SQLServerException
+ * If there are any errors in advancing to the next row.
+ */
+ boolean next() throws SQLServerException;
+}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerBulkRecord.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerBulkRecord.java
index 36aa40ebd..7767cf868 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerBulkRecord.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerBulkRecord.java
@@ -5,7 +5,6 @@
package com.microsoft.sqlserver.jdbc;
-import java.io.Serializable;
import java.time.format.DateTimeFormatter;
@@ -14,81 +13,20 @@
* SQLServerBulkCopy class to write the data to SQL Server tables.
*
* This interface is implemented by {@link SQLServerBulkRecord} Class
+ *
+ * @deprecated as of 7.5.0, because the interface contains methods which are not called as part of actual bulk copy
+ * process. Use {@link ISQLServerBulkData}} instead.
*/
-public interface ISQLServerBulkRecord extends Serializable {
-
- /**
- * Returns the ordinals for each of the columns represented in this data record.
- *
- * @return Set of ordinals for the columns.
- */
- public java.util.Set getColumnOrdinals();
-
- /**
- * Returns the name of the given column.
- *
- * @param column
- * Column ordinal
- * @return Name of the column
- */
- public String getColumnName(int column);
-
- /**
- * Returns the JDBC data type of the given column.
- *
- * @param column
- * Column ordinal
- * @return JDBC data type of the column
- */
- public int getColumnType(int column);
-
- /**
- * Returns the precision for the given column.
- *
- * @param column
- * Column ordinal
- * @return Precision of the column
- */
- public int getPrecision(int column);
-
- /**
- * Returns the scale for the given column.
- *
- * @param column
- * Column ordinal
- * @return Scale of the column
- */
- public int getScale(int column);
-
+@Deprecated
+public interface ISQLServerBulkRecord extends ISQLServerBulkData {
/**
* Returns whether the column represents an identity column.
- *
+ *
* @param column
* Column ordinal
* @return True if the column is an identity column; false otherwise.
*/
- public boolean isAutoIncrement(int column);
-
- /**
- * Returns the data for the current row as an array of Objects.
- *
- * Each Object must match the Java language Type that is used to represent the indicated JDBC data type for the
- * given column. For more information, see 'Understanding the JDBC Driver Data Types' for the appropriate mappings.
- *
- * @return The data for the row.
- * @throws SQLServerException
- * If there are any errors in obtaining the data.
- */
- public Object[] getRowData() throws SQLServerException;
-
- /**
- * Advances to the next data row.
- *
- * @return True if rows are available; false if there are no more rows
- * @throws SQLServerException
- * If there are any errors in advancing to the next row.
- */
- public boolean next() throws SQLServerException;
+ boolean isAutoIncrement(int column);
/**
* Adds metadata for the given column in the file.
@@ -108,7 +46,7 @@ public interface ISQLServerBulkRecord extends Serializable {
* @throws SQLServerException
* when an error occurs
*/
- public void addColumnMetadata(int positionInFile, String name, int jdbcType, int precision, int scale,
+ void addColumnMetadata(int positionInFile, String name, int jdbcType, int precision, int scale,
DateTimeFormatter dateTimeFormatter) throws SQLServerException;
/**
@@ -127,7 +65,7 @@ public void addColumnMetadata(int positionInFile, String name, int jdbcType, int
* @throws SQLServerException
* when an error occurs
*/
- public void addColumnMetadata(int positionInFile, String name, int jdbcType, int precision,
+ void addColumnMetadata(int positionInFile, String name, int jdbcType, int precision,
int scale) throws SQLServerException;
/**
@@ -136,7 +74,7 @@ public void addColumnMetadata(int positionInFile, String name, int jdbcType, int
* @param dateTimeFormat
* format to parse data sent as java.sql.Types.TIMESTAMP_WITH_TIMEZONE
*/
- public void setTimestampWithTimezoneFormat(String dateTimeFormat);
+ void setTimestampWithTimezoneFormat(String dateTimeFormat);
/**
* Sets the format for reading in dates from the file.
@@ -144,7 +82,7 @@ public void addColumnMetadata(int positionInFile, String name, int jdbcType, int
* @param dateTimeFormatter
* format to parse data sent as java.sql.Types.TIMESTAMP_WITH_TIMEZONE
*/
- public void setTimestampWithTimezoneFormat(DateTimeFormatter dateTimeFormatter);
+ void setTimestampWithTimezoneFormat(DateTimeFormatter dateTimeFormatter);
/**
* Sets the format for reading in dates from the file.
@@ -152,7 +90,7 @@ public void addColumnMetadata(int positionInFile, String name, int jdbcType, int
* @param timeFormat
* format to parse data sent as java.sql.Types.TIME_WITH_TIMEZONE
*/
- public void setTimeWithTimezoneFormat(String timeFormat);
+ void setTimeWithTimezoneFormat(String timeFormat);
/**
* Sets the format for reading in dates from the file.
@@ -160,7 +98,7 @@ public void addColumnMetadata(int positionInFile, String name, int jdbcType, int
* @param dateTimeFormatter
* format to parse data sent as java.sql.Types.TIME_WITH_TIMEZONE
*/
- public void setTimeWithTimezoneFormat(DateTimeFormatter dateTimeFormatter);
+ void setTimeWithTimezoneFormat(DateTimeFormatter dateTimeFormatter);
/**
* Returns the dateTimeFormatter
for the given column.
@@ -169,5 +107,5 @@ public void addColumnMetadata(int positionInFile, String name, int jdbcType, int
* Column ordinal
* @return dateTimeFormatter
*/
- public DateTimeFormatter getColumnDateTimeFormatter(int column);
+ DateTimeFormatter getColumnDateTimeFormatter(int column);
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerCallableStatement.java
index da7d75fde..9ad83fc86 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerCallableStatement.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerCallableStatement.java
@@ -17,7 +17,7 @@
public interface ISQLServerCallableStatement extends java.sql.CallableStatement, ISQLServerPreparedStatement {
@Deprecated
- public BigDecimal getBigDecimal(String parameterName, int scale) throws SQLServerException;
+ BigDecimal getBigDecimal(String parameterName, int scale) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -29,7 +29,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public Timestamp getDateTime(int index) throws SQLServerException;
+ Timestamp getDateTime(int index) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -42,7 +42,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public Timestamp getDateTime(String parameterName) throws SQLServerException;
+ Timestamp getDateTime(String parameterName) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -57,7 +57,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public Timestamp getDateTime(int index, Calendar cal) throws SQLServerException;
+ Timestamp getDateTime(int index, Calendar cal) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -72,7 +72,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public Timestamp getDateTime(String name, Calendar cal) throws SQLServerException;
+ Timestamp getDateTime(String name, Calendar cal) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -84,7 +84,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public Timestamp getSmallDateTime(int index) throws SQLServerException;
+ Timestamp getSmallDateTime(int index) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -96,7 +96,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public Timestamp getSmallDateTime(String parameterName) throws SQLServerException;
+ Timestamp getSmallDateTime(String parameterName) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -110,7 +110,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public Timestamp getSmallDateTime(int index, Calendar cal) throws SQLServerException;
+ Timestamp getSmallDateTime(int index, Calendar cal) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -124,7 +124,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public Timestamp getSmallDateTime(String name, Calendar cal) throws SQLServerException;
+ Timestamp getSmallDateTime(String name, Calendar cal) throws SQLServerException;
/**
* Returns the DateTimeOffset value of parameter with index parameterIndex.
@@ -136,7 +136,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* if parameterIndex is out of range; if a database access error occurs or this method is called on a closed
* CallableStatement
*/
- public microsoft.sql.DateTimeOffset getDateTimeOffset(int parameterIndex) throws SQLServerException;
+ microsoft.sql.DateTimeOffset getDateTimeOffset(int parameterIndex) throws SQLServerException;
/**
* Returns the DateTimeOffset value of parameter with name parameterName.
@@ -148,7 +148,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public microsoft.sql.DateTimeOffset getDateTimeOffset(String parameterName) throws SQLServerException;
+ microsoft.sql.DateTimeOffset getDateTimeOffset(String parameterName) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet
object as a stream
@@ -169,7 +169,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* if the columnIndex is not valid; if a database access error occurs or this method is called on a closed
* result set
*/
- public java.io.InputStream getAsciiStream(int parameterIndex) throws SQLServerException;
+ java.io.InputStream getAsciiStream(int parameterIndex) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet
object as a stream
@@ -190,7 +190,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* if the columnLabel is not valid; if a database access error occurs or this method is called on a closed
* result set
*/
- public java.io.InputStream getAsciiStream(String parameterName) throws SQLServerException;
+ java.io.InputStream getAsciiStream(String parameterName) throws SQLServerException;
/**
* Returns the value of the column specified as a java.math.BigDecimal object.
@@ -201,7 +201,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public BigDecimal getMoney(int parameterIndex) throws SQLServerException;
+ BigDecimal getMoney(int parameterIndex) throws SQLServerException;
/**
* Returns the value of the column specified as a java.math.BigDecimal object.
@@ -212,7 +212,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public BigDecimal getMoney(String parameterName) throws SQLServerException;
+ BigDecimal getMoney(String parameterName) throws SQLServerException;
/**
* Returns the value of the column specified as a java.math.BigDecimal object.
@@ -223,7 +223,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public BigDecimal getSmallMoney(int parameterIndex) throws SQLServerException;
+ BigDecimal getSmallMoney(int parameterIndex) throws SQLServerException;
/**
* Returns the value of the column specified as a java.math.BigDecimal object.
@@ -234,7 +234,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* @throws SQLServerException
* when an error occurs
*/
- public BigDecimal getSmallMoney(String parameterName) throws SQLServerException;
+ BigDecimal getSmallMoney(String parameterName) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet
object as a stream
@@ -254,7 +254,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* if the columnIndex is not valid; if a database access error occurs or this method is called on a closed
* result set
*/
- public java.io.InputStream getBinaryStream(int parameterIndex) throws SQLServerException;
+ java.io.InputStream getBinaryStream(int parameterIndex) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet
object as a stream
@@ -274,7 +274,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* if the columnLabel is not valid; if a database access error occurs or this method is called on a closed
* result set
*/
- public java.io.InputStream getBinaryStream(String parameterName) throws SQLServerException;
+ java.io.InputStream getBinaryStream(String parameterName) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value. The driver converts this to an
@@ -295,7 +295,7 @@ public interface ISQLServerCallableStatement extends java.sql.CallableStatement,
* method is called on a closed CallableStatement
* @see #getTimestamp
*/
- public void setTimestamp(String parameterName, java.sql.Timestamp value, Calendar calendar,
+ void setTimestamp(String parameterName, java.sql.Timestamp value, Calendar calendar,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -320,7 +320,7 @@ public void setTimestamp(String parameterName, java.sql.Timestamp value, Calenda
* method is called on a closed CallableStatement
* @see #getTime
*/
- public void setTime(String parameterName, java.sql.Time value, Calendar calendar,
+ void setTime(String parameterName, java.sql.Time value, Calendar calendar,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -345,7 +345,7 @@ public void setTime(String parameterName, java.sql.Time value, Calendar calendar
* method is called on a closed CallableStatement
* @see #getDate
*/
- public void setDate(String parameterName, java.sql.Date value, Calendar calendar,
+ void setDate(String parameterName, java.sql.Date value, Calendar calendar,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -365,7 +365,7 @@ public void setDate(String parameterName, java.sql.Date value, Calendar calendar
* character sets; if the driver can detect that a data conversion error could occur; if a database access
* error occurs or this method is called on a closed CallableStatement
*/
- public void setNString(String parameterName, String value, boolean forceEncrypt) throws SQLServerException;
+ void setNString(String parameterName, String value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the value of the designated parameter with the given object.
@@ -401,7 +401,7 @@ public void setDate(String parameterName, java.sql.Date value, Calendar calendar
* @see java.sql.Types
* @see #getObject
*/
- public void setObject(String parameterName, Object value, int sqlType, int decimals,
+ void setObject(String parameterName, Object value, int sqlType, int decimals,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -435,7 +435,7 @@ public void setObject(String parameterName, Object value, int sqlType, int decim
* @see java.sql.Types
* @see #getObject
*/
- public void setObject(String parameterName, Object value, int targetSqlType, Integer precision,
+ void setObject(String parameterName, Object value, int targetSqlType, Integer precision,
int scale) throws SQLServerException;
/**
@@ -453,7 +453,7 @@ public void setObject(String parameterName, Object value, int targetSqlType, Int
* method is called on a closed CallableStatement
* @see #getTimestamp
*/
- public void setTimestamp(String parameterName, java.sql.Timestamp value, int scale) throws SQLServerException;
+ void setTimestamp(String parameterName, java.sql.Timestamp value, int scale) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value. The driver converts this to an
@@ -474,7 +474,7 @@ public void setObject(String parameterName, Object value, int targetSqlType, Int
* method is called on a closed CallableStatement
* @see #getTimestamp
*/
- public void setTimestamp(String parameterName, java.sql.Timestamp value, int scale,
+ void setTimestamp(String parameterName, java.sql.Timestamp value, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -487,7 +487,7 @@ public void setTimestamp(String parameterName, java.sql.Timestamp value, int sca
* @throws SQLServerException
* if an error occurs
*/
- public void setDateTimeOffset(String parameterName, microsoft.sql.DateTimeOffset value) throws SQLServerException;
+ void setDateTimeOffset(String parameterName, microsoft.sql.DateTimeOffset value) throws SQLServerException;
/**
* Sets parameter parameterName to DateTimeOffset value.
@@ -501,7 +501,7 @@ public void setTimestamp(String parameterName, java.sql.Timestamp value, int sca
* @throws SQLServerException
* if an error occurs
*/
- public void setDateTimeOffset(String parameterName, microsoft.sql.DateTimeOffset value,
+ void setDateTimeOffset(String parameterName, microsoft.sql.DateTimeOffset value,
int scale) throws SQLServerException;
/**
@@ -520,7 +520,7 @@ public void setDateTimeOffset(String parameterName, microsoft.sql.DateTimeOffset
* @throws SQLServerException
* if an error occurs
*/
- public void setDateTimeOffset(String parameterName, microsoft.sql.DateTimeOffset value, int scale,
+ void setDateTimeOffset(String parameterName, microsoft.sql.DateTimeOffset value, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -538,7 +538,7 @@ public void setDateTimeOffset(String parameterName, microsoft.sql.DateTimeOffset
* method is called on a closed CallableStatement
* @see #getTime
*/
- public void setTime(String parameterName, java.sql.Time value, int scale) throws SQLServerException;
+ void setTime(String parameterName, java.sql.Time value, int scale) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Time
value. The driver converts this to an SQL
@@ -559,8 +559,7 @@ public void setDateTimeOffset(String parameterName, microsoft.sql.DateTimeOffset
* method is called on a closed CallableStatement
* @see #getTime
*/
- public void setTime(String parameterName, java.sql.Time value, int scale,
- boolean forceEncrypt) throws SQLServerException;
+ void setTime(String parameterName, java.sql.Time value, int scale, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value. The driver converts this to an
@@ -574,7 +573,7 @@ public void setTime(String parameterName, java.sql.Time value, int scale,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setDateTime(String parameterName, java.sql.Timestamp value) throws SQLServerException;
+ void setDateTime(String parameterName, java.sql.Timestamp value) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value. The driver converts this to an
@@ -592,8 +591,7 @@ public void setTime(String parameterName, java.sql.Time value, int scale,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setDateTime(String parameterName, java.sql.Timestamp value,
- boolean forceEncrypt) throws SQLServerException;
+ void setDateTime(String parameterName, java.sql.Timestamp value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value. The driver converts this to an
@@ -607,7 +605,7 @@ public void setDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setSmallDateTime(String parameterName, java.sql.Timestamp value) throws SQLServerException;
+ void setSmallDateTime(String parameterName, java.sql.Timestamp value) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value. The driver converts this to an
@@ -625,7 +623,7 @@ public void setDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
+ void setSmallDateTime(String parameterName, java.sql.Timestamp value,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -640,7 +638,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setUniqueIdentifier(String parameterName, String guid) throws SQLServerException;
+ void setUniqueIdentifier(String parameterName, String guid) throws SQLServerException;
/**
* Sets the designated parameter to the given String
value. The driver converts this to an SQL
@@ -658,7 +656,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setUniqueIdentifier(String parameterName, String guid, boolean forceEncrypt) throws SQLServerException;
+ void setUniqueIdentifier(String parameterName, String guid, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java array of bytes. The driver converts this to an SQL
@@ -677,7 +675,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setBytes(String parameterName, byte[] value, boolean forceEncrypt) throws SQLServerException;
+ void setBytes(String parameterName, byte[] value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java byte
value. The driver converts this to an SQL
@@ -695,7 +693,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setByte(String parameterName, byte value, boolean forceEncrypt) throws SQLServerException;
+ void setByte(String parameterName, byte value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java String
value. The driver converts this to an SQL
@@ -714,7 +712,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setString(String parameterName, String value, boolean forceEncrypt) throws SQLServerException;
+ void setString(String parameterName, String value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java java.math.BigDecimal
value. The driver converts this
@@ -728,7 +726,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setMoney(String parameterName, BigDecimal value) throws SQLServerException;
+ void setMoney(String parameterName, BigDecimal value) throws SQLServerException;
/**
* Sets the designated parameter to the given Java java.math.BigDecimal
value. The driver converts this
@@ -746,7 +744,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setMoney(String parameterName, BigDecimal value, boolean forceEncrypt) throws SQLServerException;
+ void setMoney(String parameterName, BigDecimal value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java java.math.BigDecimal
value. The driver converts this
@@ -760,7 +758,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setSmallMoney(String parameterName, BigDecimal value) throws SQLServerException;
+ void setSmallMoney(String parameterName, BigDecimal value) throws SQLServerException;
/**
* Sets the designated parameter to the given Java java.math.BigDecimal
value. The driver converts this
@@ -778,7 +776,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setSmallMoney(String parameterName, BigDecimal value, boolean forceEncrypt) throws SQLServerException;
+ void setSmallMoney(String parameterName, BigDecimal value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given java.math.BigDecimal
value. The driver converts this to
@@ -796,8 +794,7 @@ public void setSmallDateTime(String parameterName, java.sql.Timestamp value,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setBigDecimal(String parameterName, BigDecimal value, int precision,
- int scale) throws SQLServerException;
+ void setBigDecimal(String parameterName, BigDecimal value, int precision, int scale) throws SQLServerException;
/**
* Sets the designated parameter to the given java.math.BigDecimal
value. The driver converts this to
@@ -819,7 +816,7 @@ public void setBigDecimal(String parameterName, BigDecimal value, int precision,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setBigDecimal(String parameterName, BigDecimal value, int precision, int scale,
+ void setBigDecimal(String parameterName, BigDecimal value, int precision, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -838,7 +835,7 @@ public void setBigDecimal(String parameterName, BigDecimal value, int precision,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setDouble(String parameterName, double value, boolean forceEncrypt) throws SQLServerException;
+ void setDouble(String parameterName, double value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java float
value. The driver converts this to an SQL
@@ -856,7 +853,7 @@ public void setBigDecimal(String parameterName, BigDecimal value, int precision,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setFloat(String parameterName, float value, boolean forceEncrypt) throws SQLServerException;
+ void setFloat(String parameterName, float value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java int
value. The driver converts this to an SQL
@@ -874,7 +871,7 @@ public void setBigDecimal(String parameterName, BigDecimal value, int precision,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setInt(String parameterName, int value, boolean forceEncrypt) throws SQLServerException;
+ void setInt(String parameterName, int value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java long
value. The driver converts this to an SQL
@@ -892,7 +889,7 @@ public void setBigDecimal(String parameterName, BigDecimal value, int precision,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setLong(String parameterName, long value, boolean forceEncrypt) throws SQLServerException;
+ void setLong(String parameterName, long value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java short
value. The driver converts this to an SQL
@@ -910,7 +907,7 @@ public void setBigDecimal(String parameterName, BigDecimal value, int precision,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setShort(String parameterName, short value, boolean forceEncrypt) throws SQLServerException;
+ void setShort(String parameterName, short value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java boolean
value. The driver converts this to an SQL
@@ -928,7 +925,7 @@ public void setBigDecimal(String parameterName, BigDecimal value, int precision,
* if parameterName does not correspond to a named parameter; if a database access error occurs or this
* method is called on a closed CallableStatement
*/
- public void setBoolean(String parameterName, boolean value, boolean forceEncrypt) throws SQLServerException;
+ void setBoolean(String parameterName, boolean value, boolean forceEncrypt) throws SQLServerException;
/**
* Populates a table valued parameter passed to a stored procedure with a data table.
@@ -942,8 +939,7 @@ public void setBigDecimal(String parameterName, BigDecimal value, int precision,
* @throws SQLServerException
* when an error occurs
*/
- public void setStructured(String parameterName, String tvpName,
- SQLServerDataTable tvpDataTable) throws SQLServerException;
+ void setStructured(String parameterName, String tvpName, SQLServerDataTable tvpDataTable) throws SQLServerException;
/**
* Populates a table valued parameter passed to a stored procedure with a ResultSet retrieved from another table
@@ -957,8 +953,7 @@ public void setStructured(String parameterName, String tvpName,
* @throws SQLServerException
* when an error occurs
*/
- public void setStructured(String parameterName, String tvpName,
- java.sql.ResultSet tvpResultSet) throws SQLServerException;
+ void setStructured(String parameterName, String tvpName, java.sql.ResultSet tvpResultSet) throws SQLServerException;
/**
* Populates a table valued parameter passed to a stored procedure with an ISQLServerDataRecord object.
@@ -973,7 +968,7 @@ public void setStructured(String parameterName, String tvpName,
* @throws SQLServerException
* when an error occurs
*/
- public void setStructured(String parameterName, String tvpName,
+ void setStructured(String parameterName, String tvpName,
ISQLServerDataRecord tvpDataRecord) throws SQLServerException;
/**
@@ -995,7 +990,7 @@ public void setStructured(String parameterName, String tvpName,
* @throws SQLServerException
* If any errors occur.
*/
- public void registerOutParameter(String parameterName, SQLType sqlType, int precision,
+ void registerOutParameter(String parameterName, SQLType sqlType, int precision,
int scale) throws SQLServerException;
/**
@@ -1017,8 +1012,7 @@ public void registerOutParameter(String parameterName, SQLType sqlType, int prec
* @throws SQLServerException
* If any errors occur.
*/
- public void registerOutParameter(int parameterIndex, SQLType sqlType, int precision,
- int scale) throws SQLServerException;
+ void registerOutParameter(int parameterIndex, SQLType sqlType, int precision, int scale) throws SQLServerException;
/**
* Registers the parameter in ordinal position index to be of JDBC type sqlType. All OUT parameters must be
@@ -1039,8 +1033,7 @@ public void registerOutParameter(int parameterIndex, SQLType sqlType, int precis
* @throws SQLServerException
* If any errors occur.
*/
- public void registerOutParameter(int parameterIndex, int sqlType, int precision,
- int scale) throws SQLServerException;
+ void registerOutParameter(int parameterIndex, int sqlType, int precision, int scale) throws SQLServerException;
/**
* Registers the parameter in ordinal position index to be of JDBC type sqlType. All OUT parameters must be
@@ -1061,8 +1054,7 @@ public void registerOutParameter(int parameterIndex, int sqlType, int precision,
* @throws SQLServerException
* If any errors occur.
*/
- public void registerOutParameter(String parameterName, int sqlType, int precision,
- int scale) throws SQLServerException;
+ void registerOutParameter(String parameterName, int sqlType, int precision, int scale) throws SQLServerException;
/**
* Sets the value of the designated parameter with the given object.
@@ -1097,6 +1089,6 @@ public void registerOutParameter(String parameterName, int sqlType, int precisio
* @see java.sql.Types
* @see #getObject
*/
- public void setObject(String parameterName, Object value, SQLType jdbcType, int scale,
+ void setObject(String parameterName, Object value, SQLType jdbcType, int scale,
boolean forceEncrypt) throws SQLServerException;
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerConnection.java
index 19b9fe2f9..58e5e5f75 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerConnection.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerConnection.java
@@ -18,7 +18,7 @@ public interface ISQLServerConnection extends java.sql.Connection {
// Transaction types.
// TRANSACTION_SNAPSHOT corresponds to -> SET TRANSACTION ISOLATION LEVEL SNAPSHOT
- public final static int TRANSACTION_SNAPSHOT = 0x1000;
+ int TRANSACTION_SNAPSHOT = 0x1000;
/**
* Returns the connection ID of the most recent connection attempt, regardless of whether the attempt succeeded or
@@ -29,7 +29,7 @@ public interface ISQLServerConnection extends java.sql.Connection {
* @throws SQLServerException
* If any errors occur.
*/
- public UUID getClientConnectionId() throws SQLServerException;
+ UUID getClientConnectionId() throws SQLServerException;
/**
* Creates a Statement
object that will generate ResultSet
objects with the given type,
@@ -53,7 +53,7 @@ public interface ISQLServerConnection extends java.sql.Connection {
* if a database access error occurs, this method is called on a closed connection or the given parameters
* are not ResultSet
constants indicating type, concurrency, and holdability
*/
- public Statement createStatement(int nType, int nConcur, int nHold,
+ Statement createStatement(int nType, int nConcur, int nHold,
SQLServerStatementColumnEncryptionSetting stmtColEncSetting) throws SQLServerException;
/**
@@ -85,7 +85,7 @@ public Statement createStatement(int nType, int nConcur, int nHold,
* if a database access error occurs, this method is called on a closed connection or the given parameter is
* not a Statement
constant indicating whether auto-generated keys should be returned
*/
- public PreparedStatement prepareStatement(String sql, int flag,
+ PreparedStatement prepareStatement(String sql, int flag,
SQLServerStatementColumnEncryptionSetting stmtColEncSetting) throws SQLServerException;
/**
@@ -119,7 +119,7 @@ public PreparedStatement prepareStatement(String sql, int flag,
* @throws SQLServerException
* if a database access error occurs or this method is called on a closed connection
*/
- public PreparedStatement prepareStatement(String sql, int[] columnIndexes,
+ PreparedStatement prepareStatement(String sql, int[] columnIndexes,
SQLServerStatementColumnEncryptionSetting stmtColEncSetting) throws SQLServerException;
/**
@@ -153,7 +153,7 @@ public PreparedStatement prepareStatement(String sql, int[] columnIndexes,
* @throws SQLServerException
* if a database access error occurs or this method is called on a closed connection
*/
- public PreparedStatement prepareStatement(String sql, String[] columnNames,
+ PreparedStatement prepareStatement(String sql, String[] columnNames,
SQLServerStatementColumnEncryptionSetting stmtColEncSetting) throws SQLServerException;
/**
@@ -183,7 +183,7 @@ public PreparedStatement prepareStatement(String sql, String[] columnNames,
* if a database access error occurs, this method is called on a closed connection or the given parameters
* are not ResultSet
constants indicating type, concurrency, and holdability
*/
- public PreparedStatement prepareStatement(java.lang.String sql, int nType, int nConcur, int resultSetHoldability,
+ PreparedStatement prepareStatement(java.lang.String sql, int nType, int nConcur, int resultSetHoldability,
SQLServerStatementColumnEncryptionSetting stmtColEncSetting) throws SQLServerException;
/**
@@ -211,7 +211,7 @@ public PreparedStatement prepareStatement(java.lang.String sql, int nType, int n
* if a database access error occurs, this method is called on a closed connection or the given parameters
* are not ResultSet
constants indicating type, concurrency, and holdability
*/
- public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHold,
+ CallableStatement prepareCall(String sql, int nType, int nConcur, int nHold,
SQLServerStatementColumnEncryptionSetting stmtColEncSetting) throws SQLServerException;
/**
@@ -229,7 +229,7 @@ public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHo
* @throws SQLServerException
* if a database access error occurs
*/
- public void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue) throws SQLServerException;
+ void setSendTimeAsDatetime(boolean sendTimeAsDateTimeValue) throws SQLServerException;
/**
* Returns the value of the sendTimeAsDatetime property.
@@ -239,19 +239,19 @@ public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHo
* @throws SQLServerException
* if a database access error occurs
*/
- public boolean getSendTimeAsDatetime() throws SQLServerException;
+ boolean getSendTimeAsDatetime() throws SQLServerException;
/**
* Returns the number of currently outstanding prepared statement un-prepare actions.
*
* @return Returns the current value per the description.
*/
- public int getDiscardedServerPreparedStatementCount();
+ int getDiscardedServerPreparedStatementCount();
/**
* Forces the un-prepare requests for any outstanding discarded prepared statements to be executed.
*/
- public void closeUnreferencedPreparedStatementHandles();
+ void closeUnreferencedPreparedStatementHandles();
/**
* Returns the behavior for a specific connection instance. If false the first execution will call sp_executesql and
@@ -262,7 +262,7 @@ public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHo
*
* @return Returns the current setting per the description.
*/
- public boolean getEnablePrepareOnFirstPreparedStatementCall();
+ boolean getEnablePrepareOnFirstPreparedStatementCall();
/**
* Sets the behavior for a specific connection instance. If value is false the first execution will call
@@ -273,7 +273,7 @@ public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHo
* @param value
* Changes the setting per the description.
*/
- public void setEnablePrepareOnFirstPreparedStatementCall(boolean value);
+ void setEnablePrepareOnFirstPreparedStatementCall(boolean value);
/**
* Returns the behavior for a specific connection instance. This setting controls how many outstanding prepared
@@ -285,7 +285,7 @@ public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHo
*
* @return Returns the current setting per the description.
*/
- public int getServerPreparedStatementDiscardThreshold();
+ int getServerPreparedStatementDiscardThreshold();
/**
* Sets the behavior for a specific connection instance. This setting controls how many outstanding prepared
@@ -297,7 +297,7 @@ public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHo
* @param value
* Changes the setting per the description.
*/
- public void setServerPreparedStatementDiscardThreshold(int value);
+ void setServerPreparedStatementDiscardThreshold(int value);
/**
* Sets the size of the prepared statement cache for this connection. A value less than 1 means no cache.
@@ -306,28 +306,28 @@ public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHo
* The new cache size.
*
*/
- public void setStatementPoolingCacheSize(int value);
+ void setStatementPoolingCacheSize(int value);
/**
* Returns the size of the prepared statement cache for this connection. A value less than 1 means no cache.
*
* @return Returns the current setting per the description.
*/
- public int getStatementPoolingCacheSize();
+ int getStatementPoolingCacheSize();
/**
* Returns whether statement pooling is enabled or not for this connection.
*
* @return Returns the current setting per the description.
*/
- public boolean isStatementPoolingEnabled();
+ boolean isStatementPoolingEnabled();
/**
* Returns the current number of pooled prepared statement handles.
*
* @return Returns the current setting per the description.
*/
- public int getStatementHandleCacheEntryCount();
+ int getStatementHandleCacheEntryCount();
/**
* Sets the value to Disable/enable statement pooling.
@@ -335,27 +335,27 @@ public CallableStatement prepareCall(String sql, int nType, int nConcur, int nHo
* @param value
* true to disable statement pooling, false to enable it.
*/
- public void setDisableStatementPooling(boolean value);
+ void setDisableStatementPooling(boolean value);
/**
* Returns the value whether statement pooling is disabled.
*
* @return true if statement pooling is disabled, false if it is enabled.
*/
- public boolean getDisableStatementPooling();
+ boolean getDisableStatementPooling();
/**
* Returns the current flag value for useFmtOnly.
- *
+ *
* @return 'useFmtOnly' property value.
*/
- public boolean getUseFmtOnly();
+ boolean getUseFmtOnly();
/**
* Specifies the flag to use FMTONLY for parameter metadata queries.
- *
+ *
* @param useFmtOnly
* boolean value for 'useFmtOnly'.
*/
- public void setUseFmtOnly(boolean useFmtOnly);
+ void setUseFmtOnly(boolean useFmtOnly);
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerConnection43.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerConnection43.java
index b17597aa6..9eb725def 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerConnection43.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerConnection43.java
@@ -43,7 +43,7 @@ public interface ISQLServerConnection43 extends ISQLServerConnection {
* @see #endRequest()
*/
@Override
- public void beginRequest() throws SQLException;
+ void beginRequest() throws SQLException;
/**
* Hints to the driver that a request, an independent unit of work, has completed. It rolls back the open
@@ -59,5 +59,5 @@ public interface ISQLServerConnection43 extends ISQLServerConnection {
* @see #beginRequest()
*/
@Override
- public void endRequest() throws SQLException;
+ void endRequest() throws SQLException;
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataRecord.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataRecord.java
index 7c45b8449..288479e73 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataRecord.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataRecord.java
@@ -17,14 +17,14 @@ public interface ISQLServerDataRecord {
* the first column is 1, the second is 2, and so on
* @return SQLServerMetaData of column
*/
- public SQLServerMetaData getColumnMetaData(int column);
+ SQLServerMetaData getColumnMetaData(int column);
/**
* Returns the column count.
*
* @return Set of ordinals for the columns.
*/
- public int getColumnCount();
+ int getColumnCount();
/**
* Returns the data for the current row as an array of Objects.
@@ -34,12 +34,12 @@ public interface ISQLServerDataRecord {
*
* @return The data for the row.
*/
- public Object[] getRowData();
+ Object[] getRowData();
/**
* Advances to the next data row.
*
* @return True if rows are available; false if there are no more rows
*/
- public boolean next();
+ boolean next();
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataSource.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataSource.java
index b1c15c048..c9e4e1379 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataSource.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerDataSource.java
@@ -843,7 +843,14 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource {
* Client Key of Azure Key Vault (AKV) Provider to be used for column encryption.
*/
void setKeyVaultProviderClientKey(String keyVaultProviderClientKey);
-
+
+ /**
+ * Returns the value for the connection property 'domain'.
+ *
+ * @return 'domain' property value
+ */
+ String getDomain();
+
/**
* Sets the 'domain' connection property used for NTLM Authentication.
*
@@ -853,24 +860,48 @@ public interface ISQLServerDataSource extends javax.sql.CommonDataSource {
void setDomain(String domain);
/**
- * Returns the value for the connection property 'domain'.
+ * Returns the current flag value for useFmtOnly.
+ *
+ * @return 'useFmtOnly' property value.
+ */
+ boolean getUseFmtOnly();
+
+ /**
+ * Specifies the flag to use FMTONLY for parameter metadata queries.
+ *
+ * @param useFmtOnly
+ * boolean value for 'useFmtOnly'.
+ */
+ void setUseFmtOnly(boolean useFmtOnly);
+
+ /**
+ * Returns the enclave attestation URL used in Always Encrypted with Secure Enclaves.
*
- * @return 'domain' property value
+ * @return enclave attestation URL.
*/
- String getDomain();
+ String getEnclaveAttestationUrl();
/**
- * Returns the current flag value for useFmtOnly.
+ * Sets the enclave attestation URL used in Always Encrypted with Secure Enclaves.
*
- * @return 'useFmtOnly' property value.
+ * @param url
+ * Enclave attestation URL.
*/
- public boolean getUseFmtOnly();
+ void setEnclaveAttestationUrl(String url);
/**
- * Specifies the flag to use FMTONLY for parameter metadata queries.
+ * Returns the enclave attestation protocol used in Always Encrypted with Secure Enclaves.
*
- * @param useFmtOnly
- * boolean value for 'useFmtOnly'.
+ * @return Enclave attestation protocol.
+ */
+ String getEnclaveAttestationProtocol();
+
+ /**
+ * Sets the enclave attestation protocol to be used in Always Encrypted with Secure Enclaves.
+ *
+ * @param protocol
+ * Enclave attestation protocol.
*/
- public void setUseFmtOnly(boolean useFmtOnly);
+ void setEnclaveAttestationProtocol(String protocol);
+
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerEnclaveProvider.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerEnclaveProvider.java
new file mode 100644
index 000000000..51f75ec6a
--- /dev/null
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerEnclaveProvider.java
@@ -0,0 +1,98 @@
+/*
+ * Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made
+ * available under the terms of the MIT License. See the LICENSE file in the project root for more information.
+ */
+
+package com.microsoft.sqlserver.jdbc;
+
+import java.security.PrivateKey;
+import java.util.ArrayList;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ *
+ * Provides an interface to create an Enclave Session
+ *
+ */
+public interface ISQLServerEnclaveProvider {
+ byte[] getEnclavePackage(String userSQL, ArrayList enclaveCEKs) throws SQLServerException;
+
+ /**
+ * Returns the attestation parameters
+ * @param createNewParameters
+ * indicates whether to create new parameters
+ * @param url
+ * attestation url
+ * @throws SQLServerException
+ * when an error occurs.
+ */
+ void getAttestationParameters(boolean createNewParameters, String url) throws SQLServerException;
+
+ /**
+ * Creates the enclave session
+ *
+ * @param connection
+ * connection
+ * @param userSql
+ * user sql
+ * @param preparedTypeDefinitions
+ * preparedTypeDefinitions
+ * @param params
+ * params
+ * @param parameterNames
+ * parameterNames
+ * @return
+ * list of enclave requested CEKs
+ * @throws SQLServerException
+ * when an error occurs.
+ */
+ ArrayList createEnclaveSession(SQLServerConnection connection, String userSql,
+ String preparedTypeDefinitions, Parameter[] params,
+ ArrayList parameterNames) throws SQLServerException;
+
+ /**
+ * Invalidates an enclave session
+ */
+ void invalidateEnclaveSession();
+
+ /**
+ * Returns the enclave session
+ * @return
+ * the enclave session
+ */
+ EnclaveSession getEnclaveSession();
+}
+
+
+abstract class BaseAttestationRequest {
+ protected PrivateKey privateKey;
+
+ byte[] getBytes() {
+ return null;
+ };
+}
+
+
+class EnclaveSession {
+ private byte[] sessionID;
+ private AtomicInteger counter;
+ private byte[] sessionSecret;
+
+ EnclaveSession(byte[] cs, byte[] b) {
+ sessionID = cs;
+ sessionSecret = b;
+ counter = new AtomicInteger(0);
+ }
+
+ byte[] getSessionID() {
+ return sessionID;
+ }
+
+ byte[] getSessionSecret() {
+ return sessionSecret;
+ }
+
+ long getCounter() {
+ return counter.getAndIncrement();
+ }
+}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerPreparedStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerPreparedStatement.java
index e8eb211db..647185163 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerPreparedStatement.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerPreparedStatement.java
@@ -26,7 +26,7 @@ public interface ISQLServerPreparedStatement extends java.sql.PreparedStatement,
* if parameterIndex does not correspond to a parameter marker in the SQL statement; if a database access
* error occurs or this method is called on a closed PreparedStatement
*/
- public void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x) throws SQLServerException;
+ void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x) throws SQLServerException;
/**
* Sets the value of the designated parameter with the given object.
@@ -51,7 +51,7 @@ public interface ISQLServerPreparedStatement extends java.sql.PreparedStatement,
* if parameterIndex does not correspond to a parameter marker in the SQL statement; if a database access
* error occurs or this method is called on a closed {@code PreparedStatement}
*/
- public void setObject(int parameterIndex, Object x, SQLType targetSqlType, Integer precision,
+ void setObject(int parameterIndex, Object x, SQLType targetSqlType, Integer precision,
Integer scale) throws SQLServerException;
/**
@@ -81,7 +81,7 @@ public void setObject(int parameterIndex, Object x, SQLType targetSqlType, Integ
* if parameterIndex does not correspond to a parameter marker in the SQL statement; if a database access
* error occurs or this method is called on a closed {@code PreparedStatement}
*/
- public void setObject(int parameterIndex, Object x, SQLType targetSqlType, Integer precision, Integer scale,
+ void setObject(int parameterIndex, Object x, SQLType targetSqlType, Integer precision, Integer scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -91,7 +91,7 @@ public void setObject(int parameterIndex, Object x, SQLType targetSqlType, Integ
* @throws SQLServerException
* when an error occurs
*/
- public int getPreparedStatementHandle() throws SQLServerException;
+ int getPreparedStatementHandle() throws SQLServerException;
/**
* Sets the designated parameter to the given java.math.BigDecimal
value. The driver converts this to
@@ -108,7 +108,7 @@ public void setObject(int parameterIndex, Object x, SQLType targetSqlType, Integ
* @throws SQLServerException
* when an error occurs
*/
- public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int scale) throws SQLServerException;
+ void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int scale) throws SQLServerException;
/**
* Sets the designated parameter to the given java.math.BigDecimal
value. The driver converts this to
@@ -129,7 +129,7 @@ public void setObject(int parameterIndex, Object x, SQLType targetSqlType, Integ
* @throws SQLServerException
* when an error occurs
*/
- public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int scale,
+ void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -143,7 +143,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setMoney(int parameterIndex, BigDecimal x) throws SQLServerException;
+ void setMoney(int parameterIndex, BigDecimal x) throws SQLServerException;
/**
* Sets the designated parameter to the given java.math.BigDecimal
value. The driver converts this to
@@ -160,7 +160,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setMoney(int parameterIndex, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
+ void setMoney(int parameterIndex, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given java.math.BigDecimal
value. The driver converts this to
@@ -173,7 +173,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setSmallMoney(int parameterIndex, BigDecimal x) throws SQLServerException;
+ void setSmallMoney(int parameterIndex, BigDecimal x) throws SQLServerException;
/**
* Sets the designated parameter to the given java.math.BigDecimal
value. The driver converts this to
@@ -190,7 +190,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setSmallMoney(int parameterIndex, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
+ void setSmallMoney(int parameterIndex, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java boolean
value. The driver converts this to an SQL
@@ -207,7 +207,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setBoolean(int parameterIndex, boolean x, boolean forceEncrypt) throws SQLServerException;
+ void setBoolean(int parameterIndex, boolean x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java byte
value. The driver converts this to an SQL
@@ -224,7 +224,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setByte(int parameterIndex, byte x, boolean forceEncrypt) throws SQLServerException;
+ void setByte(int parameterIndex, byte x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java array of bytes. The driver converts this to an SQL
@@ -242,7 +242,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setBytes(int parameterIndex, byte x[], boolean forceEncrypt) throws SQLServerException;
+ void setBytes(int parameterIndex, byte x[], boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given String. The driver converts this to an SQL GUID
@@ -254,7 +254,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setUniqueIdentifier(int parameterIndex, String guid) throws SQLServerException;
+ void setUniqueIdentifier(int parameterIndex, String guid) throws SQLServerException;
/**
* Sets the designated parameter to the given String. The driver converts this to an SQL GUID
@@ -270,7 +270,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setUniqueIdentifier(int parameterIndex, String guid, boolean forceEncrypt) throws SQLServerException;
+ void setUniqueIdentifier(int parameterIndex, String guid, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java double
value. The driver converts this to an SQL
@@ -287,7 +287,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setDouble(int parameterIndex, double x, boolean forceEncrypt) throws SQLServerException;
+ void setDouble(int parameterIndex, double x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java float
value. The driver converts this to an SQL
@@ -304,7 +304,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setFloat(int parameterIndex, float x, boolean forceEncrypt) throws SQLServerException;
+ void setFloat(int parameterIndex, float x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given microsoft.sql.Geometry
Class object. The driver converts
@@ -317,7 +317,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setGeometry(int parameterIndex, Geometry x) throws SQLServerException;
+ void setGeometry(int parameterIndex, Geometry x) throws SQLServerException;
/**
* Sets the designated parameter to the given microsoft.sql.Geography
Class object. The driver converts
@@ -330,7 +330,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setGeography(int parameterIndex, Geography x) throws SQLServerException;
+ void setGeography(int parameterIndex, Geography x) throws SQLServerException;
/**
* Sets the designated parameter to the given Java int
value. The driver converts this to an SQL
@@ -347,7 +347,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setInt(int parameterIndex, int value, boolean forceEncrypt) throws SQLServerException;
+ void setInt(int parameterIndex, int value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java long
value. The driver converts this to an SQL
@@ -364,7 +364,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setLong(int parameterIndex, long x, boolean forceEncrypt) throws SQLServerException;
+ void setLong(int parameterIndex, long x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the value of the designated parameter with the given object.
@@ -395,7 +395,7 @@ public void setBigDecimal(int parameterIndex, BigDecimal x, int precision, int s
* @throws SQLServerException
* when an error occurs
*/
- public void setObject(int parameterIndex, Object x, int targetSqlType, Integer precision,
+ void setObject(int parameterIndex, Object x, int targetSqlType, Integer precision,
int scale) throws SQLServerException;
/**
@@ -431,7 +431,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, Integer p
* @throws SQLServerException
* when an error occurs
*/
- public void setObject(int parameterIndex, Object x, int targetSqlType, Integer precision, int scale,
+ void setObject(int parameterIndex, Object x, int targetSqlType, Integer precision, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -449,7 +449,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, Integer p
* @throws SQLServerException
* when an error occurs
*/
- public void setShort(int parameterIndex, short x, boolean forceEncrypt) throws SQLServerException;
+ void setShort(int parameterIndex, short x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given Java String
value. The driver converts this to an SQL
@@ -467,7 +467,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, Integer p
* @throws SQLServerException
* when an error occurs
*/
- public void setString(int parameterIndex, String str, boolean forceEncrypt) throws SQLServerException;
+ void setString(int parameterIndex, String str, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given String
object. The driver converts this to a SQL
@@ -485,7 +485,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, Integer p
* @throws SQLServerException
* when an error occurs
*/
- public void setNString(int parameterIndex, String value, boolean forceEncrypt) throws SQLServerException;
+ void setNString(int parameterIndex, String value, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Time
value.
@@ -499,7 +499,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, Integer p
* @throws SQLServerException
* when an error occurs
*/
- public void setTime(int parameterIndex, java.sql.Time x, int scale) throws SQLServerException;
+ void setTime(int parameterIndex, java.sql.Time x, int scale) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Time
value.
@@ -517,7 +517,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, Integer p
* @throws SQLServerException
* when an error occurs
*/
- public void setTime(int parameterIndex, java.sql.Time x, int scale, boolean forceEncrypt) throws SQLServerException;
+ void setTime(int parameterIndex, java.sql.Time x, int scale, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value.
@@ -531,7 +531,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, Integer p
* @throws SQLServerException
* when an error occurs
*/
- public void setTimestamp(int parameterIndex, java.sql.Timestamp x, int scale) throws SQLServerException;
+ void setTimestamp(int parameterIndex, java.sql.Timestamp x, int scale) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value.
@@ -549,7 +549,7 @@ public void setObject(int parameterIndex, Object x, int targetSqlType, Integer p
* @throws SQLServerException
* when an error occurs
*/
- public void setTimestamp(int parameterIndex, java.sql.Timestamp x, int scale,
+ void setTimestamp(int parameterIndex, java.sql.Timestamp x, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -564,8 +564,7 @@ public void setTimestamp(int parameterIndex, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* when an error occurs
*/
- public void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x,
- int scale) throws SQLServerException;
+ void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x, int scale) throws SQLServerException;
/**
* Sets the designated parameter to the given microsoft.sql.DatetimeOffset
value.
@@ -583,7 +582,7 @@ public void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x
* @throws SQLServerException
* when an error occurs
*/
- public void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x, int scale,
+ void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -596,7 +595,7 @@ public void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x
* @throws SQLServerException
* when an error occurs
*/
- public void setDateTime(int parameterIndex, java.sql.Timestamp x) throws SQLServerException;
+ void setDateTime(int parameterIndex, java.sql.Timestamp x) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value.
@@ -612,7 +611,7 @@ public void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x
* @throws SQLServerException
* when an error occurs
*/
- public void setDateTime(int parameterIndex, java.sql.Timestamp x, boolean forceEncrypt) throws SQLServerException;
+ void setDateTime(int parameterIndex, java.sql.Timestamp x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value.
@@ -624,7 +623,7 @@ public void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x
* @throws SQLServerException
* when an error occurs
*/
- public void setSmallDateTime(int parameterIndex, java.sql.Timestamp x) throws SQLServerException;
+ void setSmallDateTime(int parameterIndex, java.sql.Timestamp x) throws SQLServerException;
/**
* Sets the designated parameter to the given java.sql.Timestamp
value.
@@ -640,8 +639,7 @@ public void setDateTimeOffset(int parameterIndex, microsoft.sql.DateTimeOffset x
* @throws SQLServerException
* when an error occurs
*/
- public void setSmallDateTime(int parameterIndex, java.sql.Timestamp x,
- boolean forceEncrypt) throws SQLServerException;
+ void setSmallDateTime(int parameterIndex, java.sql.Timestamp x, boolean forceEncrypt) throws SQLServerException;
/**
* Sets the data table to populates a table valued parameter.
@@ -655,8 +653,7 @@ public void setSmallDateTime(int parameterIndex, java.sql.Timestamp x,
* @throws SQLServerException
* when an error occurs
*/
- public void setStructured(int parameterIndex, String tvpName,
- SQLServerDataTable tvpDataTable) throws SQLServerException;
+ void setStructured(int parameterIndex, String tvpName, SQLServerDataTable tvpDataTable) throws SQLServerException;
/**
* Sets the result set to populate a table-valued parameter.
@@ -670,7 +667,7 @@ public void setStructured(int parameterIndex, String tvpName,
* @throws SQLServerException
* when an error occurs
*/
- public void setStructured(int parameterIndex, String tvpName, ResultSet tvpResultSet) throws SQLServerException;
+ void setStructured(int parameterIndex, String tvpName, ResultSet tvpResultSet) throws SQLServerException;
/**
* Sets the server bulk record to populate a table valued parameter.
@@ -684,7 +681,7 @@ public void setStructured(int parameterIndex, String tvpName,
* @throws SQLServerException
* when an error occurs
*/
- public void setStructured(int parameterIndex, String tvpName,
+ void setStructured(int parameterIndex, String tvpName,
ISQLServerDataRecord tvpBulkRecord) throws SQLServerException;
/**
@@ -707,7 +704,7 @@ public void setStructured(int parameterIndex, String tvpName,
* @throws SQLServerException
* when an error occurs
*/
- public void setDate(int parameterIndex, java.sql.Date x, java.util.Calendar cal,
+ void setDate(int parameterIndex, java.sql.Date x, java.util.Calendar cal,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -727,7 +724,7 @@ public void setDate(int parameterIndex, java.sql.Date x, java.util.Calendar cal,
* @throws SQLServerException
* when an error occurs
*/
- public void setTime(int parameterIndex, java.sql.Time x, java.util.Calendar cal,
+ void setTime(int parameterIndex, java.sql.Time x, java.util.Calendar cal,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -747,7 +744,7 @@ public void setTime(int parameterIndex, java.sql.Time x, java.util.Calendar cal,
* @throws SQLServerException
* when an error occurs
*/
- public void setTimestamp(int parameterIndex, java.sql.Timestamp x, java.util.Calendar cal,
+ void setTimestamp(int parameterIndex, java.sql.Timestamp x, java.util.Calendar cal,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -759,7 +756,7 @@ public void setTimestamp(int parameterIndex, java.sql.Timestamp x, java.util.Cal
* @throws SQLServerException
* when an error occurs
*/
- public ParameterMetaData getParameterMetaData(boolean forceRefresh) throws SQLServerException;
+ ParameterMetaData getParameterMetaData(boolean forceRefresh) throws SQLServerException;
/**
* Returns the current flag value for useFmtOnly.
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerResultSet.java
index 2ac7bc1b5..068d3cb5f 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerResultSet.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerResultSet.java
@@ -17,16 +17,16 @@
*/
public interface ISQLServerResultSet extends java.sql.ResultSet {
- public static final int TYPE_SS_DIRECT_FORWARD_ONLY = 2003; // TYPE_FORWARD_ONLY + 1000
- public static final int TYPE_SS_SERVER_CURSOR_FORWARD_ONLY = 2004; // TYPE_FORWARD_ONLY + 1001
- public static final int TYPE_SS_SCROLL_STATIC = 1004; // TYPE_SCROLL_INSENSITIVE
- public static final int TYPE_SS_SCROLL_KEYSET = 1005; // TYPE_SCROLL_SENSITIVE
- public static final int TYPE_SS_SCROLL_DYNAMIC = 1006; // TYPE_SCROLL_SENSITIVE + 1
+ int TYPE_SS_DIRECT_FORWARD_ONLY = 2003; // TYPE_FORWARD_ONLY + 1000
+ int TYPE_SS_SERVER_CURSOR_FORWARD_ONLY = 2004; // TYPE_FORWARD_ONLY + 1001
+ int TYPE_SS_SCROLL_STATIC = 1004; // TYPE_SCROLL_INSENSITIVE
+ int TYPE_SS_SCROLL_KEYSET = 1005; // TYPE_SCROLL_SENSITIVE
+ int TYPE_SS_SCROLL_DYNAMIC = 1006; // TYPE_SCROLL_SENSITIVE + 1
/* SQL Server concurrency values */
- public static final int CONCUR_SS_OPTIMISTIC_CC = 1008; // CONCUR_UPDATABLE
- public static final int CONCUR_SS_SCROLL_LOCKS = 1009; // CONCUR_UPDATABLE + 1
- public static final int CONCUR_SS_OPTIMISTIC_CCVAL = 1010; // CONCUR_UPDATABLE + 2
+ int CONCUR_SS_OPTIMISTIC_CC = 1008; // CONCUR_UPDATABLE
+ int CONCUR_SS_SCROLL_LOCKS = 1009; // CONCUR_UPDATABLE + 1
+ int CONCUR_SS_OPTIMISTIC_CCVAL = 1010; // CONCUR_UPDATABLE + 2
/**
* Returns the value of the designated column in the current row of this ResultSet object as a
@@ -38,7 +38,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public Geometry getGeometry(int columnIndex) throws SQLServerException;
+ Geometry getGeometry(int columnIndex) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a
@@ -50,7 +50,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public Geometry getGeometry(String columnName) throws SQLServerException;
+ Geometry getGeometry(String columnName) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a
@@ -62,7 +62,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public Geography getGeography(int columnIndex) throws SQLServerException;
+ Geography getGeography(int columnIndex) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a
@@ -74,7 +74,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public Geography getGeography(String columnName) throws SQLServerException;
+ Geography getGeography(String columnName) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a String object in the
@@ -86,7 +86,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public String getUniqueIdentifier(int columnIndex) throws SQLServerException;
+ String getUniqueIdentifier(int columnIndex) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a String object in the
@@ -98,7 +98,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public String getUniqueIdentifier(String columnLabel) throws SQLServerException;
+ String getUniqueIdentifier(String columnLabel) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -110,7 +110,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public java.sql.Timestamp getDateTime(int columnIndex) throws SQLServerException;
+ java.sql.Timestamp getDateTime(int columnIndex) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -122,7 +122,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public java.sql.Timestamp getDateTime(String columnName) throws SQLServerException;
+ java.sql.Timestamp getDateTime(String columnName) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -137,7 +137,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public java.sql.Timestamp getDateTime(int columnIndex, Calendar cal) throws SQLServerException;
+ java.sql.Timestamp getDateTime(int columnIndex, Calendar cal) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -153,7 +153,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public java.sql.Timestamp getDateTime(String colName, Calendar cal) throws SQLServerException;
+ java.sql.Timestamp getDateTime(String colName, Calendar cal) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -165,7 +165,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public java.sql.Timestamp getSmallDateTime(int columnIndex) throws SQLServerException;
+ java.sql.Timestamp getSmallDateTime(int columnIndex) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -177,7 +177,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public java.sql.Timestamp getSmallDateTime(String columnName) throws SQLServerException;
+ java.sql.Timestamp getSmallDateTime(String columnName) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -191,7 +191,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public java.sql.Timestamp getSmallDateTime(int columnIndex, Calendar cal) throws SQLServerException;
+ java.sql.Timestamp getSmallDateTime(int columnIndex, Calendar cal) throws SQLServerException;
/**
* Returns the value of the designated column in the current row of this ResultSet object as a java.sql.Timestamp
@@ -205,7 +205,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public java.sql.Timestamp getSmallDateTime(String colName, Calendar cal) throws SQLServerException;
+ java.sql.Timestamp getSmallDateTime(String colName, Calendar cal) throws SQLServerException;
/**
* Returns the value of the designated column as a microsoft.sql.DateTimeOffset object, given a zero-based column
@@ -217,7 +217,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public microsoft.sql.DateTimeOffset getDateTimeOffset(int columnIndex) throws SQLServerException;
+ microsoft.sql.DateTimeOffset getDateTimeOffset(int columnIndex) throws SQLServerException;
/**
* Returns the value of the column specified as a microsoft.sql.DateTimeOffset object, given a column name.
@@ -228,7 +228,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public microsoft.sql.DateTimeOffset getDateTimeOffset(String columnName) throws SQLServerException;
+ microsoft.sql.DateTimeOffset getDateTimeOffset(String columnName) throws SQLServerException;
/**
* Returns the value of the column specified as a java.math.BigDecimal object.
@@ -239,7 +239,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public BigDecimal getMoney(int columnIndex) throws SQLServerException;
+ BigDecimal getMoney(int columnIndex) throws SQLServerException;
/**
* Returns the value of the column specified as a java.math.BigDecimal object.
@@ -250,7 +250,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public BigDecimal getMoney(String columnName) throws SQLServerException;
+ BigDecimal getMoney(String columnName) throws SQLServerException;
/**
* Returns the value of the column specified as a java.math.BigDecimal object.
@@ -261,7 +261,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public BigDecimal getSmallMoney(int columnIndex) throws SQLServerException;
+ BigDecimal getSmallMoney(int columnIndex) throws SQLServerException;
/**
* Returns the value of the column specified as a java.math.BigDecimal object.
@@ -272,7 +272,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public BigDecimal getSmallMoney(String columnName) throws SQLServerException;
+ BigDecimal getSmallMoney(String columnName) throws SQLServerException;
/**
* Updates the value of the column specified to the DateTimeOffset Class value, given a zero-based column ordinal.
@@ -284,7 +284,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x) throws SQLServerException;
+ void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x) throws SQLServerException;
/**
* Updates the value of the column specified to the DateTimeOffset Class value, given a column name.
@@ -296,7 +296,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset x) throws SQLServerException;
+ void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset x) throws SQLServerException;
/**
* Updates the designated column with an {@code Object} value.
@@ -316,7 +316,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* when an error occurs
*/
- public void updateObject(int index, Object x, int precision, int scale) throws SQLServerException;
+ void updateObject(int index, Object x, int precision, int scale) throws SQLServerException;
/**
* Updates the designated column with an Object value. The updater methods are used to update column values in the
@@ -344,7 +344,7 @@ public interface ISQLServerResultSet extends java.sql.ResultSet {
* @throws SQLServerException
* If any errors occur.
*/
- public void updateObject(int index, Object obj, SQLType targetSqlType, int scale,
+ void updateObject(int index, Object obj, SQLType targetSqlType, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -375,7 +375,7 @@ public void updateObject(int index, Object obj, SQLType targetSqlType, int scale
* @throws SQLServerException
* If any errors occur.
*/
- public void updateObject(String columnName, Object obj, SQLType targetSqlType, int scale,
+ void updateObject(String columnName, Object obj, SQLType targetSqlType, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -394,7 +394,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateBoolean(int index, boolean x, boolean forceEncrypt) throws SQLServerException;
+ void updateBoolean(int index, boolean x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a byte
value. The updater methods are used to update column
@@ -412,7 +412,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateByte(int index, byte x, boolean forceEncrypt) throws SQLServerException;
+ void updateByte(int index, byte x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a short
value. The updater methods are used to update column
@@ -430,7 +430,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateShort(int index, short x, boolean forceEncrypt) throws SQLServerException;
+ void updateShort(int index, short x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with an int
value. The updater methods are used to update column
@@ -448,7 +448,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateInt(int index, int x, boolean forceEncrypt) throws SQLServerException;
+ void updateInt(int index, int x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a long
value. The updater methods are used to update column
@@ -466,7 +466,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateLong(int index, long x, boolean forceEncrypt) throws SQLServerException;
+ void updateLong(int index, long x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a float
value. The updater methods are used to update column
@@ -484,7 +484,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateFloat(int index, float x, boolean forceEncrypt) throws SQLServerException;
+ void updateFloat(int index, float x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a double
value. The updater methods are used to update column
@@ -502,7 +502,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateDouble(int index, double x, boolean forceEncrypt) throws SQLServerException;
+ void updateDouble(int index, double x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a money
value. The updater methods are used to update column
@@ -516,7 +516,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateMoney(int index, BigDecimal x) throws SQLServerException;
+ void updateMoney(int index, BigDecimal x) throws SQLServerException;
/**
* Updates the designated column with a money
value. The updater methods are used to update column
@@ -534,7 +534,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateMoney(int index, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
+ void updateMoney(int index, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a money
value. The updater methods are used to update column
@@ -548,7 +548,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* If any errors occur.
*/
- public void updateMoney(String columnName, BigDecimal x) throws SQLServerException;
+ void updateMoney(String columnName, BigDecimal x) throws SQLServerException;
/**
* Updates the designated column with a money
value. The updater methods are used to update column
@@ -566,7 +566,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* If any errors occur.
*/
- public void updateMoney(String columnName, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
+ void updateMoney(String columnName, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a smallmoney
value. The updater methods are used to update column
@@ -580,7 +580,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateSmallMoney(int index, BigDecimal x) throws SQLServerException;
+ void updateSmallMoney(int index, BigDecimal x) throws SQLServerException;
/**
* Updates the designated column with a smallmoney
value. The updater methods are used to update column
@@ -598,7 +598,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateSmallMoney(int index, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
+ void updateSmallMoney(int index, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a smallmoney
value. The updater methods are used to update column
@@ -612,7 +612,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* If any errors occur.
*/
- public void updateSmallMoney(String columnName, BigDecimal x) throws SQLServerException;
+ void updateSmallMoney(String columnName, BigDecimal x) throws SQLServerException;
/**
* Updates the designated column with a smallmoney
value. The updater methods are used to update column
@@ -630,7 +630,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* If any errors occur.
*/
- public void updateSmallMoney(String columnName, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
+ void updateSmallMoney(String columnName, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.math.BigDecimal
value. The updater methods are used to
@@ -648,7 +648,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer scale) throws SQLServerException;
+ void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer scale) throws SQLServerException;
/**
* Updates the designated column with a java.math.BigDecimal
value. The updater methods are used to
@@ -670,7 +670,7 @@ public void updateObject(String columnName, Object obj, SQLType targetSqlType, i
* @throws SQLServerException
* when an error occurs
*/
- public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer scale,
+ void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -689,7 +689,7 @@ public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer
* @throws SQLServerException
* when an error occurs
*/
- public void updateString(int columnIndex, String stringValue, boolean forceEncrypt) throws SQLServerException;
+ void updateString(int columnIndex, String stringValue, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a String
value. It is intended for use when updating
@@ -708,7 +708,7 @@ public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer
* @throws SQLServerException
* when an error occurs
*/
- public void updateNString(int columnIndex, String nString, boolean forceEncrypt) throws SQLServerException;
+ void updateNString(int columnIndex, String nString, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a String
value. It is intended for use when updating
@@ -728,7 +728,7 @@ public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer
* @throws SQLServerException
* when an error occurs
*/
- public void updateNString(String columnLabel, String nString, boolean forceEncrypt) throws SQLServerException;
+ void updateNString(String columnLabel, String nString, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a byte
array value. The updater methods are used to update column
@@ -746,7 +746,7 @@ public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer
* @throws SQLServerException
* when an error occurs
*/
- public void updateBytes(int index, byte x[], boolean forceEncrypt) throws SQLServerException;
+ void updateBytes(int index, byte x[], boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Date
value. The updater methods are used to update
@@ -764,7 +764,7 @@ public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer
* @throws SQLServerException
* when an error occurs
*/
- public void updateDate(int index, java.sql.Date x, boolean forceEncrypt) throws SQLServerException;
+ void updateDate(int index, java.sql.Date x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Time
value. The updater methods are used to update
@@ -780,7 +780,7 @@ public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer
* @throws SQLServerException
* when an error occurs
*/
- public void updateTime(int index, java.sql.Time x, Integer scale) throws SQLServerException;
+ void updateTime(int index, java.sql.Time x, Integer scale) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Time
value. The updater methods are used to update
@@ -800,7 +800,7 @@ public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer
* @throws SQLServerException
* when an error occurs
*/
- public void updateTime(int index, java.sql.Time x, Integer scale, boolean forceEncrypt) throws SQLServerException;
+ void updateTime(int index, java.sql.Time x, Integer scale, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -816,7 +816,7 @@ public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer
* @throws SQLServerException
* when an error occurs
*/
- public void updateTimestamp(int index, java.sql.Timestamp x, int scale) throws SQLServerException;
+ void updateTimestamp(int index, java.sql.Timestamp x, int scale) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -836,8 +836,7 @@ public void updateBigDecimal(int index, BigDecimal x, Integer precision, Integer
* @throws SQLServerException
* when an error occurs
*/
- public void updateTimestamp(int index, java.sql.Timestamp x, int scale,
- boolean forceEncrypt) throws SQLServerException;
+ void updateTimestamp(int index, java.sql.Timestamp x, int scale, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -851,7 +850,7 @@ public void updateTimestamp(int index, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* when an error occurs
*/
- public void updateDateTime(int index, java.sql.Timestamp x) throws SQLServerException;
+ void updateDateTime(int index, java.sql.Timestamp x) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -867,7 +866,7 @@ public void updateTimestamp(int index, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* when an error occurs
*/
- public void updateDateTime(int index, java.sql.Timestamp x, Integer scale) throws SQLServerException;
+ void updateDateTime(int index, java.sql.Timestamp x, Integer scale) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -887,8 +886,7 @@ public void updateTimestamp(int index, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* when an error occurs
*/
- public void updateDateTime(int index, java.sql.Timestamp x, Integer scale,
- boolean forceEncrypt) throws SQLServerException;
+ void updateDateTime(int index, java.sql.Timestamp x, Integer scale, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -902,7 +900,7 @@ public void updateDateTime(int index, java.sql.Timestamp x, Integer scale,
* @throws SQLServerException
* when an error occurs
*/
- public void updateSmallDateTime(int index, java.sql.Timestamp x) throws SQLServerException;
+ void updateSmallDateTime(int index, java.sql.Timestamp x) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -918,7 +916,7 @@ public void updateDateTime(int index, java.sql.Timestamp x, Integer scale,
* @throws SQLServerException
* when an error occurs
*/
- public void updateSmallDateTime(int index, java.sql.Timestamp x, Integer scale) throws SQLServerException;
+ void updateSmallDateTime(int index, java.sql.Timestamp x, Integer scale) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -938,7 +936,7 @@ public void updateDateTime(int index, java.sql.Timestamp x, Integer scale,
* @throws SQLServerException
* when an error occurs
*/
- public void updateSmallDateTime(int index, java.sql.Timestamp x, Integer scale,
+ void updateSmallDateTime(int index, java.sql.Timestamp x, Integer scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -953,8 +951,7 @@ public void updateSmallDateTime(int index, java.sql.Timestamp x, Integer scale,
* @throws SQLServerException
* when an error occurs
*/
- public void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x,
- Integer scale) throws SQLServerException;
+ void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x, Integer scale) throws SQLServerException;
/**
* Updates the value of the column specified to the DateTimeOffset Class value, given a zero-based column ordinal.
@@ -972,7 +969,7 @@ public void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x,
* @throws SQLServerException
* when an error occurs
*/
- public void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x, Integer scale,
+ void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x, Integer scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -987,7 +984,7 @@ public void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x, Inte
* @throws SQLServerException
* when an error occurs
*/
- public void updateUniqueIdentifier(int index, String x) throws SQLServerException;
+ void updateUniqueIdentifier(int index, String x) throws SQLServerException;
/**
* Updates the designated column with a String
value. The updater methods are used to update column
@@ -1005,7 +1002,7 @@ public void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x, Inte
* @throws SQLServerException
* when an error occurs
*/
- public void updateUniqueIdentifier(int index, String x, boolean forceEncrypt) throws SQLServerException;
+ void updateUniqueIdentifier(int index, String x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with an {@code Object} value.
@@ -1029,8 +1026,7 @@ public void updateDateTimeOffset(int index, microsoft.sql.DateTimeOffset x, Inte
* @throws SQLServerException
* when an error occurs
*/
- public void updateObject(int index, Object x, int precision, int scale,
- boolean forceEncrypt) throws SQLServerException;
+ void updateObject(int index, Object x, int precision, int scale, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a boolean
value. The updater methods are used to update column
@@ -1048,7 +1044,7 @@ public void updateObject(int index, Object x, int precision, int scale,
* @throws SQLServerException
* when an error occurs
*/
- public void updateBoolean(String columnName, boolean x, boolean forceEncrypt) throws SQLServerException;
+ void updateBoolean(String columnName, boolean x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a byte
value. The updater methods are used to update column
@@ -1067,7 +1063,7 @@ public void updateObject(int index, Object x, int precision, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateByte(String columnName, byte x, boolean forceEncrypt) throws SQLServerException;
+ void updateByte(String columnName, byte x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a short
value. The updater methods are used to update column
@@ -1085,7 +1081,7 @@ public void updateObject(int index, Object x, int precision, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateShort(String columnName, short x, boolean forceEncrypt) throws SQLServerException;
+ void updateShort(String columnName, short x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with an int
value. The updater methods are used to update column
@@ -1103,7 +1099,7 @@ public void updateObject(int index, Object x, int precision, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateInt(String columnName, int x, boolean forceEncrypt) throws SQLServerException;
+ void updateInt(String columnName, int x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a long
value. The updater methods are used to update column
@@ -1121,7 +1117,7 @@ public void updateObject(int index, Object x, int precision, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateLong(String columnName, long x, boolean forceEncrypt) throws SQLServerException;
+ void updateLong(String columnName, long x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a float
value. The updater methods are used to update column
@@ -1139,7 +1135,7 @@ public void updateObject(int index, Object x, int precision, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateFloat(String columnName, float x, boolean forceEncrypt) throws SQLServerException;
+ void updateFloat(String columnName, float x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a double
value. The updater methods are used to update column
@@ -1157,7 +1153,7 @@ public void updateObject(int index, Object x, int precision, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateDouble(String columnName, double x, boolean forceEncrypt) throws SQLServerException;
+ void updateDouble(String columnName, double x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.BigDecimal
value. The updater methods are used to
@@ -1175,7 +1171,7 @@ public void updateObject(int index, Object x, int precision, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateBigDecimal(String columnName, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
+ void updateBigDecimal(String columnName, BigDecimal x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.BigDecimal
value. The updater methods are used to
@@ -1194,8 +1190,7 @@ public void updateObject(int index, Object x, int precision, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateBigDecimal(String columnName, BigDecimal x, Integer precision,
- Integer scale) throws SQLServerException;
+ void updateBigDecimal(String columnName, BigDecimal x, Integer precision, Integer scale) throws SQLServerException;
/**
* Updates the designated column with a java.sql.BigDecimal
value. The updater methods are used to
@@ -1218,7 +1213,7 @@ public void updateBigDecimal(String columnName, BigDecimal x, Integer precision,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateBigDecimal(String columnName, BigDecimal x, Integer precision, Integer scale,
+ void updateBigDecimal(String columnName, BigDecimal x, Integer precision, Integer scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -1237,7 +1232,7 @@ public void updateBigDecimal(String columnName, BigDecimal x, Integer precision,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateString(String columnName, String x, boolean forceEncrypt) throws SQLServerException;
+ void updateString(String columnName, String x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a byte array value.
@@ -1257,7 +1252,7 @@ public void updateBigDecimal(String columnName, BigDecimal x, Integer precision,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateBytes(String columnName, byte x[], boolean forceEncrypt) throws SQLServerException;
+ void updateBytes(String columnName, byte x[], boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Date
value. The updater methods are used to update
@@ -1275,7 +1270,7 @@ public void updateBigDecimal(String columnName, BigDecimal x, Integer precision,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateDate(String columnName, java.sql.Date x, boolean forceEncrypt) throws SQLServerException;
+ void updateDate(String columnName, java.sql.Date x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Time
value. The updater methods are used to update
@@ -1291,7 +1286,7 @@ public void updateBigDecimal(String columnName, BigDecimal x, Integer precision,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateTime(String columnName, java.sql.Time x, int scale) throws SQLServerException;
+ void updateTime(String columnName, java.sql.Time x, int scale) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Time
value. The updater methods are used to update
@@ -1311,8 +1306,7 @@ public void updateBigDecimal(String columnName, BigDecimal x, Integer precision,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateTime(String columnName, java.sql.Time x, int scale,
- boolean forceEncrypt) throws SQLServerException;
+ void updateTime(String columnName, java.sql.Time x, int scale, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -1328,7 +1322,7 @@ public void updateTime(String columnName, java.sql.Time x, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateTimestamp(String columnName, java.sql.Timestamp x, int scale) throws SQLServerException;
+ void updateTimestamp(String columnName, java.sql.Timestamp x, int scale) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -1348,7 +1342,7 @@ public void updateTime(String columnName, java.sql.Time x, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateTimestamp(String columnName, java.sql.Timestamp x, int scale,
+ void updateTimestamp(String columnName, java.sql.Timestamp x, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -1363,7 +1357,7 @@ public void updateTimestamp(String columnName, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateDateTime(String columnName, java.sql.Timestamp x) throws SQLServerException;
+ void updateDateTime(String columnName, java.sql.Timestamp x) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -1379,7 +1373,7 @@ public void updateTimestamp(String columnName, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateDateTime(String columnName, java.sql.Timestamp x, int scale) throws SQLServerException;
+ void updateDateTime(String columnName, java.sql.Timestamp x, int scale) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -1399,7 +1393,7 @@ public void updateTimestamp(String columnName, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateDateTime(String columnName, java.sql.Timestamp x, int scale,
+ void updateDateTime(String columnName, java.sql.Timestamp x, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -1414,7 +1408,7 @@ public void updateDateTime(String columnName, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateSmallDateTime(String columnName, java.sql.Timestamp x) throws SQLServerException;
+ void updateSmallDateTime(String columnName, java.sql.Timestamp x) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -1430,7 +1424,7 @@ public void updateDateTime(String columnName, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateSmallDateTime(String columnName, java.sql.Timestamp x, int scale) throws SQLServerException;
+ void updateSmallDateTime(String columnName, java.sql.Timestamp x, int scale) throws SQLServerException;
/**
* Updates the designated column with a java.sql.Timestamp
value. The updater methods are used to
@@ -1450,7 +1444,7 @@ public void updateDateTime(String columnName, java.sql.Timestamp x, int scale,
* @throws SQLServerException
* If any errors occur.
*/
- public void updateSmallDateTime(String columnName, java.sql.Timestamp x, int scale,
+ void updateSmallDateTime(String columnName, java.sql.Timestamp x, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -1465,8 +1459,7 @@ public void updateSmallDateTime(String columnName, java.sql.Timestamp x, int sca
* @throws SQLServerException
* If any errors occur.
*/
- public void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset x,
- int scale) throws SQLServerException;
+ void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset x, int scale) throws SQLServerException;
/**
* Updates the value of the column specified to the DateTimeOffset Class value, given a column name.
@@ -1484,7 +1477,7 @@ public void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset
* @throws SQLServerException
* If any errors occur.
*/
- public void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset x, int scale,
+ void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset x, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -1499,7 +1492,7 @@ public void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset
* @throws SQLServerException
* If any errors occur.
*/
- public void updateUniqueIdentifier(String columnName, String x) throws SQLServerException;
+ void updateUniqueIdentifier(String columnName, String x) throws SQLServerException;
/**
* Updates the designated column with a String
value. The updater methods are used to update column
@@ -1517,7 +1510,7 @@ public void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset
* @throws SQLServerException
* If any errors occur.
*/
- public void updateUniqueIdentifier(String columnName, String x, boolean forceEncrypt) throws SQLServerException;
+ void updateUniqueIdentifier(String columnName, String x, boolean forceEncrypt) throws SQLServerException;
/**
* Updates the designated column with an {@code Object} value.
@@ -1537,7 +1530,7 @@ public void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset
* @throws SQLServerException
* If any errors occur.
*/
- public void updateObject(String columnName, Object x, int precision, int scale) throws SQLServerException;
+ void updateObject(String columnName, Object x, int precision, int scale) throws SQLServerException;
/**
* Updates the designated column with an {@code Object} value.
@@ -1561,7 +1554,7 @@ public void updateDateTimeOffset(String columnName, microsoft.sql.DateTimeOffset
* @throws SQLServerException
* If any errors occur.
*/
- public void updateObject(String columnName, Object x, int precision, int scale,
+ void updateObject(String columnName, Object x, int precision, int scale,
boolean forceEncrypt) throws SQLServerException;
/**
@@ -1570,5 +1563,5 @@ public void updateObject(String columnName, Object x, int precision, int scale,
*
* @return SensitivityClassification
*/
- public SensitivityClassification getSensitivityClassification();
+ SensitivityClassification getSensitivityClassification();
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerResultSetMetaData.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerResultSetMetaData.java
index 6f6366469..0db7fbb08 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerResultSetMetaData.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerResultSetMetaData.java
@@ -23,6 +23,6 @@ public interface ISQLServerResultSetMetaData extends ResultSetMetaData, Serializ
* @throws SQLServerException
* when an error occurs
*/
- public boolean isSparseColumnSet(int column) throws SQLServerException;
+ boolean isSparseColumnSet(int column) throws SQLServerException;
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerSavepoint.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerSavepoint.java
index a988a0204..f9cd9313e 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerSavepoint.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerSavepoint.java
@@ -19,20 +19,20 @@ public interface ISQLServerSavepoint extends Savepoint, Serializable {
*
* @return the name of savepoint
*/
- public String getSavepointName() throws SQLServerException;
+ String getSavepointName() throws SQLServerException;
/**
* Returns the savepoint label
*
* @return the label for Savepoint
*/
- public String getLabel();
+ String getLabel();
/**
* Returns if the savepoint label is null
*
* @return true is the savepoint is named. Otherwise, false.
*/
- public boolean isNamed();
+ boolean isNamed();
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerStatement.java
index 49ddd7a83..fbc078f37 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerStatement.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/ISQLServerStatement.java
@@ -28,7 +28,7 @@ public interface ISQLServerStatement extends java.sql.Statement, Serializable {
* @throws SQLServerException
* If there are any errors in setting the response buffering mode.
*/
- public void setResponseBuffering(String value) throws SQLServerException;
+ void setResponseBuffering(String value) throws SQLServerException;
/**
* Returns the response buffering mode for this SQLServerStatement object.
@@ -37,7 +37,7 @@ public interface ISQLServerStatement extends java.sql.Statement, Serializable {
* @throws SQLServerException
* If there are any errors in retrieving the response buffering mode.
*/
- public String getResponseBuffering() throws SQLServerException;
+ String getResponseBuffering() throws SQLServerException;
/**
* Returns the cancelQueryTimeout
property set on this SQLServerStatement object.
@@ -46,7 +46,7 @@ public interface ISQLServerStatement extends java.sql.Statement, Serializable {
* @throws SQLServerException
* if any error occurs
*/
- public int getCancelQueryTimeout() throws SQLServerException;
+ int getCancelQueryTimeout() throws SQLServerException;
/**
* Sets the cancelQueryTimeout
property on this SQLServerStatement object to cancel
@@ -57,5 +57,5 @@ public interface ISQLServerStatement extends java.sql.Statement, Serializable {
* @throws SQLServerException
* if any error occurs
*/
- public void setCancelQueryTimeout(int seconds) throws SQLServerException;
+ void setCancelQueryTimeout(int seconds) throws SQLServerException;
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/KeyStoreProviderCommon.java b/src/main/java/com/microsoft/sqlserver/jdbc/KeyStoreProviderCommon.java
index 32e02dc57..d3f0fa9be 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/KeyStoreProviderCommon.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/KeyStoreProviderCommon.java
@@ -139,7 +139,7 @@ private static byte[] decryptRSAOAEP(byte[] cipherText,
}
- private static boolean verifyRSASignature(byte[] hash, byte[] signature, X509Certificate certificate,
+ static boolean verifyRSASignature(byte[] hash, byte[] signature, X509Certificate certificate,
String masterKeyPath) throws SQLServerException {
Signature signVerify;
boolean verificationSuccess = false;
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLJdbcVersion.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLJdbcVersion.java
index e41ebd7f1..e90e6ff62 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLJdbcVersion.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLJdbcVersion.java
@@ -6,8 +6,8 @@
package com.microsoft.sqlserver.jdbc;
final class SQLJdbcVersion {
- static final int major = 7;
- static final int minor = 4;
- static final int patch = 1;
+ static final int major = 8;
+ static final int minor = 1;
+ static final int patch = 0;
static final int build = 0;
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java
index 7214164a8..4192d5013 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerBulkCopy.java
@@ -145,7 +145,7 @@ private class ColumnMapping implements Serializable {
/**
* Source data (from a Record). Is null unless the corresponding version of writeToServer is called.
*/
- private ISQLServerBulkRecord sourceBulkRecord;
+ private ISQLServerBulkData serverBulkData;
/**
* Source data (from ResultSet). Is null unless the corresponding version of writeToServer is called.
@@ -583,7 +583,7 @@ private void writeResultSet(ResultSet sourceData, boolean isRowSet) throws SQLSe
sourceResultSet = sourceData;
- sourceBulkRecord = null;
+ serverBulkData = null;
// Save the resultset metadata as it is used in many places.
try {
@@ -602,18 +602,18 @@ private void writeResultSet(ResultSet sourceData, boolean isRowSet) throws SQLSe
* destinationTableName property of the SQLServerBulkCopy object.
*
* @param sourceData
- * SQLServerBulkReader to read data rows from.
+ * ISQLServerBulkData to read data rows from.
* @throws SQLServerException
* If there are any issues encountered when performing the bulk copy operation
*/
- public void writeToServer(ISQLServerBulkRecord sourceData) throws SQLServerException {
+ public void writeToServer(ISQLServerBulkData sourceData) throws SQLServerException {
loggerExternal.entering(loggerClassName, "writeToServer");
if (null == sourceData) {
throwInvalidArgument("sourceData");
}
- sourceBulkRecord = sourceData;
+ serverBulkData = sourceData;
sourceResultSet = null;
writeToServer();
@@ -627,7 +627,7 @@ public void writeToServer(ISQLServerBulkRecord sourceData) throws SQLServerExcep
private void initializeDefaults() {
columnMappings = new ArrayList<>();
destinationTableName = null;
- sourceBulkRecord = null;
+ serverBulkData = null;
sourceResultSet = null;
sourceResultSetMetaData = null;
srcColumnCount = 0;
@@ -1001,7 +1001,7 @@ private void writeTypeInfo(TDSWriter tdsWriter, int srcJdbcType, int srcScale, i
case microsoft.sql.Types.DATETIME:
case microsoft.sql.Types.SMALLDATETIME:
case java.sql.Types.TIMESTAMP:
- if ((!isBaseType) && (null != sourceBulkRecord)) {
+ if ((!isBaseType) && (null != serverBulkData)) {
tdsWriter.writeByte(TDSType.BIGVARCHAR.byteValue());
tdsWriter.writeShort((short) (srcPrecision));
collation.writeCollation(tdsWriter);
@@ -1039,7 +1039,7 @@ private void writeTypeInfo(TDSWriter tdsWriter, int srcJdbcType, int srcScale, i
* unencrypted. string literal formats supported by temporal types are available in MSDN page on data
* types.
*/
- if ((!isBaseType) && (null != sourceBulkRecord)) {
+ if ((!isBaseType) && (null != serverBulkData)) {
tdsWriter.writeByte(TDSType.BIGVARCHAR.byteValue());
tdsWriter.writeShort((short) (srcPrecision));
collation.writeCollation(tdsWriter);
@@ -1049,7 +1049,7 @@ private void writeTypeInfo(TDSWriter tdsWriter, int srcJdbcType, int srcScale, i
break;
case java.sql.Types.TIME: // 0x29
- if ((!isBaseType) && (null != sourceBulkRecord)) {
+ if ((!isBaseType) && (null != serverBulkData)) {
tdsWriter.writeByte(TDSType.BIGVARCHAR.byteValue());
tdsWriter.writeShort((short) (srcPrecision));
collation.writeCollation(tdsWriter);
@@ -1067,7 +1067,7 @@ private void writeTypeInfo(TDSWriter tdsWriter, int srcJdbcType, int srcScale, i
break;
case microsoft.sql.Types.DATETIMEOFFSET: // 0x2B
- if ((!isBaseType) && (null != sourceBulkRecord)) {
+ if ((!isBaseType) && (null != serverBulkData)) {
tdsWriter.writeByte(TDSType.BIGVARCHAR.byteValue());
tdsWriter.writeShort((short) (srcPrecision));
collation.writeCollation(tdsWriter);
@@ -1314,7 +1314,7 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx,
case java.sql.Types.TIMESTAMP:
switch (destSSType) {
case SMALLDATETIME:
- if (null != sourceBulkRecord) {
+ if (null != serverBulkData) {
return "varchar("
+ ((0 == bulkPrecision) ? sourceBulkRecordTemporalMaxPrecision : bulkPrecision)
+ ")";
@@ -1322,7 +1322,7 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx,
return "smalldatetime";
}
case DATETIME:
- if (null != sourceBulkRecord) {
+ if (null != serverBulkData) {
return "varchar("
+ ((0 == bulkPrecision) ? sourceBulkRecordTemporalMaxPrecision : bulkPrecision)
+ ")";
@@ -1337,7 +1337,7 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx,
* will do the conversion. if the source is ResultSet, we send the data as the corresponding
* temporal type.
*/
- if (null != sourceBulkRecord) {
+ if (null != serverBulkData) {
return "varchar(" + ((0 == bulkPrecision) ? destPrecision : bulkPrecision) + ")";
} else {
return "datetime2(" + bulkScale + ")";
@@ -1350,7 +1350,7 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx,
* unencrypted bulk copy if the source is CSV, we send the data as varchar and SQL Server will do the
* conversion. if the source is ResultSet, we send the data as the corresponding temporal type.
*/
- if (null != sourceBulkRecord) {
+ if (null != serverBulkData) {
return "varchar(" + ((0 == bulkPrecision) ? destPrecision : bulkPrecision) + ")";
} else {
return "date";
@@ -1362,7 +1362,7 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx,
* unencrypted bulk copy if the source is CSV, we send the data as varchar and SQL Server will do the
* conversion. if the source is ResultSet, we send the data as the corresponding temporal type.
*/
- if (null != sourceBulkRecord) {
+ if (null != serverBulkData) {
return "varchar(" + ((0 == bulkPrecision) ? destPrecision : bulkPrecision) + ")";
} else {
return "time(" + bulkScale + ")";
@@ -1379,7 +1379,7 @@ private String getDestTypeFromSrcType(int srcColIndx, int destColIndx,
* unencrypted bulk copy if the source is CSV, we send the data as varchar and SQL Server will do the
* conversion. if the source is ResultSet, we send the data as the corresponding temporal type.
*/
- if (null != sourceBulkRecord) {
+ if (null != serverBulkData) {
return "varchar(" + ((0 == bulkPrecision) ? destPrecision : bulkPrecision) + ")";
} else {
return "datetimeoffset(" + bulkScale + ")";
@@ -1544,13 +1544,14 @@ private TDSWriter sendBulkCopyCommand(TDSCommand command) throws SQLServerExcept
// Create and send the initial command for bulk copy ("INSERT BULK ...").
TDSWriter tdsWriter = command.startRequest(TDS.PKT_QUERY);
String bulkCmd = createInsertBulkCommand(tdsWriter);
+ tdsWriter.sendEnclavePackage(null, null);
tdsWriter.writeString(bulkCmd);
TDSParser.parse(command.startResponse(), command.getLogContext());
// Send the bulk data. This is the BulkLoadBCP TDS stream.
tdsWriter = command.startRequest(TDS.PKT_BULK);
-
// Write the COLUMNMETADATA token in the stream.
+
writeColumnMetaData(tdsWriter);
return tdsWriter;
@@ -1720,8 +1721,8 @@ private void getSourceMetadata() throws SQLServerException {
// Unable to retrieve meta data for destination
throw new SQLServerException(SQLServerException.getErrString("R_unableRetrieveColMeta"), e);
}
- } else if (null != sourceBulkRecord) {
- Set columnOrdinals = sourceBulkRecord.getColumnOrdinals();
+ } else if (null != serverBulkData) {
+ Set columnOrdinals = serverBulkData.getColumnOrdinals();
if (null == columnOrdinals || 0 == columnOrdinals.size()) {
throw new SQLServerException(SQLServerException.getErrString("R_unableRetrieveColMeta"), null);
} else {
@@ -1729,10 +1730,10 @@ private void getSourceMetadata() throws SQLServerException {
for (Integer columnOrdinal : columnOrdinals) {
currentColumn = columnOrdinal;
srcColumnMetadata.put(currentColumn, new BulkColumnMetaData(
- sourceBulkRecord.getColumnName(currentColumn), true,
- sourceBulkRecord.getPrecision(currentColumn), sourceBulkRecord.getScale(currentColumn),
- sourceBulkRecord.getColumnType(currentColumn),
- ((sourceBulkRecord instanceof SQLServerBulkCSVFileRecord) ? ((SQLServerBulkCSVFileRecord) sourceBulkRecord)
+ serverBulkData.getColumnName(currentColumn), true,
+ serverBulkData.getPrecision(currentColumn), serverBulkData.getScale(currentColumn),
+ serverBulkData.getColumnType(currentColumn),
+ ((serverBulkData instanceof SQLServerBulkCSVFileRecord) ? ((SQLServerBulkCSVFileRecord) serverBulkData)
.getColumnDateTimeFormatter(currentColumn) : null)));
}
}
@@ -1779,8 +1780,8 @@ private void validateColumnMappings() throws SQLServerException {
}
}
// if no mapping is provided for csv file and metadata is missing for some columns throw error
- if (null != sourceBulkRecord) {
- Set columnOrdinals = sourceBulkRecord.getColumnOrdinals();
+ if (null != serverBulkData) {
+ Set columnOrdinals = serverBulkData.getColumnOrdinals();
Iterator columnsIterator = columnOrdinals.iterator();
int j = 1;
while (columnsIterator.hasNext()) {
@@ -1847,9 +1848,9 @@ private void validateColumnMappings() throws SQLServerException {
}
}
} else {
- Set columnOrdinals = sourceBulkRecord.getColumnOrdinals();
+ Set columnOrdinals = serverBulkData.getColumnOrdinals();
for (Integer currentColumn : columnOrdinals) {
- if (sourceBulkRecord.getColumnName(currentColumn).equals(cm.sourceColumnName)) {
+ if (serverBulkData.getColumnName(currentColumn).equals(cm.sourceColumnName)) {
foundColumn = true;
cm.sourceColumnOrdinal = currentColumn;
break;
@@ -1985,7 +1986,7 @@ private void writeColumnToTdsWriter(TDSWriter tdsWriter, int bulkPrecision, int
else if (null != sourceCryptoMeta) {
bulkJdbcType = destColumnMetadata.get(destColOrdinal).jdbcType;
bulkScale = destColumnMetadata.get(destColOrdinal).scale;
- } else if (null != sourceBulkRecord) {
+ } else if (null != serverBulkData) {
// Bulk copy from CSV and destination is not encrypted. In this case, we send the temporal types as varchar
// and
// SQL Server does the conversion. If destination is encrypted, then temporal types can not be sent as
@@ -2074,7 +2075,7 @@ else if (null != sourceCryptoMeta) {
tdsWriter.writeDouble((float) colValue);
}
break;
-
+
case java.sql.Types.DOUBLE:
if (null == colValue) {
writeNullToTdsWriter(tdsWriter, bulkJdbcType, isStreaming);
@@ -2861,9 +2862,9 @@ private void writeColumn(TDSWriter tdsWriter, int srcColOrdinal, int destColOrdi
}
// If we are using ISQLBulkRecord and the data we are passing is char type, we need to check the source and dest
// precision
- else if (null != sourceBulkRecord && (null == destCryptoMeta)) {
+ else if (null != serverBulkData && (null == destCryptoMeta)) {
validateStringBinaryLengths(colValue, srcColOrdinal, destColOrdinal);
- } else if ((null != sourceBulkRecord) && (null != destCryptoMeta)) {
+ } else if ((null != serverBulkData) && (null != destCryptoMeta)) {
// From CSV to encrypted column. Convert to respective object.
if ((java.sql.Types.DATE == srcJdbcType) || (java.sql.Types.TIME == srcJdbcType)
|| (java.sql.Types.TIMESTAMP == srcJdbcType) || (microsoft.sql.Types.DATETIMEOFFSET == srcJdbcType)
@@ -3362,7 +3363,7 @@ private byte[] normalizedValue(JDBCType destJdbcType, Object value, JDBCType src
Float floatValue = (value instanceof String) ? Float.parseFloat((String) value) : (Float) value;
return ByteBuffer.allocate((Float.SIZE / Byte.SIZE)).order(ByteOrder.LITTLE_ENDIAN)
.putFloat(floatValue).array();
-
+
case FLOAT:
case DOUBLE:
Double doubleValue = (value instanceof String) ? Double.parseDouble((String) value)
@@ -3436,7 +3437,7 @@ private boolean goToNextRow() throws SQLServerException {
if (null != sourceResultSet) {
return sourceResultSet.next();
} else {
- return sourceBulkRecord.next();
+ return serverBulkData.next();
}
} catch (SQLException e) {
throw new SQLServerException(SQLServerException.getErrString("R_unableRetrieveSourceData"), e);
@@ -3493,7 +3494,7 @@ private boolean writeBatchData(TDSWriter tdsWriter, TDSCommand command,
Object[] rowObjects;
try {
- rowObjects = sourceBulkRecord.getRowData();
+ rowObjects = serverBulkData.getRowData();
} catch (Exception ex) {
// if no more data available to retrive
throw new SQLServerException(SQLServerException.getErrString("R_unableRetrieveSourceData"), ex);
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java
index 76eabac63..cf22b6a43 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerCallableStatement.java
@@ -24,8 +24,9 @@
import java.sql.Time;
import java.sql.Timestamp;
import java.text.MessageFormat;
-import java.util.ArrayList;
import java.util.Calendar;
+import java.util.HashMap;
+import java.util.TreeMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
@@ -49,7 +50,8 @@ public class SQLServerCallableStatement extends SQLServerPreparedStatement imple
private static final long serialVersionUID = 5044984771674532350L;
/** the call param names */
- private ArrayList parameterNames;
+ private HashMap parameterNames;
+ private TreeMap insensitiveParameterNames;
/** Number of registered OUT parameters */
int nOutParams = 0;
@@ -702,7 +704,7 @@ public Object getObject(int index) throws SQLServerException {
loggerExternal.entering(getClassNameLogging(), "getObject", index);
checkClosed();
Object value = getValue(index,
- getterGetParam(index).getJdbcTypeSetByUser() != null ? getterGetParam(index).getJdbcTypeSetByUser()
+ null != getterGetParam(index).getJdbcTypeSetByUser() ? getterGetParam(index).getJdbcTypeSetByUser()
: getterGetParam(index).getJdbcType());
loggerExternal.exiting(getClassNameLogging(), "getObject", value);
return value;
@@ -743,7 +745,7 @@ public T getObject(int index, Class type) throws SQLException {
} else if (type == UUID.class) {
// read binary, avoid string allocation and parsing
byte[] guid = getBytes(index);
- returnValue = guid != null ? Util.readGUIDtoUUID(guid) : null;
+ returnValue = null != guid ? Util.readGUIDtoUUID(guid) : null;
} else if (type == SQLXML.class) {
returnValue = getSQLXML(index);
} else if (type == Blob.class) {
@@ -778,7 +780,7 @@ public Object getObject(String parameterName) throws SQLServerException {
checkClosed();
int parameterIndex = findColumn(parameterName);
Object value = getValue(parameterIndex,
- getterGetParam(parameterIndex).getJdbcTypeSetByUser() != null ? getterGetParam(parameterIndex)
+ null != getterGetParam(parameterIndex).getJdbcTypeSetByUser() ? getterGetParam(parameterIndex)
.getJdbcTypeSetByUser() : getterGetParam(parameterIndex).getJdbcType());
loggerExternal.exiting(getClassNameLogging(), "getObject", value);
return value;
@@ -1253,7 +1255,7 @@ public java.sql.Array getArray(String parameterName) throws SQLException {
* @return the index
*/
private int findColumn(String columnName) throws SQLServerException {
- if (parameterNames == null) {
+ if (null == parameterNames) {
try (SQLServerStatement s = (SQLServerStatement) connection.createStatement()) {
// Note we are concatenating the information from the passed in sql, not any arguments provided by the
// user
@@ -1277,7 +1279,7 @@ private int findColumn(String columnName) throws SQLServerException {
// we should always have a procedure name part
metaQuery.append("@procedure_name=");
metaQuery.append(threePartName.getProcedurePart());
- metaQuery.append(" , @ODBCVer=3");
+ metaQuery.append(" , @ODBCVer=3, @fUsePattern=0");
} else {
// This should rarely happen, this will only happen if we can't find the stored procedure name
// invalidly formatted call syntax.
@@ -1287,11 +1289,15 @@ private int findColumn(String columnName) throws SQLServerException {
SQLServerException.makeFromDriverError(connection, this, form.format(msgArgs), "07009", false);
}
- ResultSet rs = s.executeQueryInternal(metaQuery.toString());
- parameterNames = new ArrayList<>();
- while (rs.next()) {
- String parameterName = rs.getString(4);
- parameterNames.add(parameterName.trim());
+ try (ResultSet rs = s.executeQueryInternal(metaQuery.toString())) {
+ parameterNames = new HashMap<>();
+ insensitiveParameterNames = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
+ int columnIndex = 0;
+ while (rs.next()) {
+ String p = rs.getString(4).trim();
+ parameterNames.put(p, columnIndex);
+ insensitiveParameterNames.put(p, columnIndex++);
+ }
}
} catch (SQLException e) {
SQLServerException.makeFromDriverError(connection, this, e.toString(), null, false);
@@ -1310,12 +1316,7 @@ private int findColumn(String columnName) throws SQLServerException {
// handle `@name` as well as `name`, since `@name` is what's returned
// by DatabaseMetaData#getProcedureColumns
- String columnNameWithoutAtSign = null;
- if (columnName.startsWith("@")) {
- columnNameWithoutAtSign = columnName.substring(1, columnName.length());
- } else {
- columnNameWithoutAtSign = columnName;
- }
+ String columnNameWithSign = columnName.startsWith("@") ? columnName : "@" + columnName;
// In order to be as accurate as possible when locating parameter name
// indexes, as well as be deterministic when running on various client
@@ -1323,34 +1324,11 @@ private int findColumn(String columnName) throws SQLServerException {
// 1. Search using case-sensitive non-locale specific (binary) compare first.
// 2. Search using case-insensitive, non-locale specific (binary) compare last.
-
- int i;
- int matchPos = -1;
- // Search using case-sensitive, non-locale specific (binary) compare.
- // If the user supplies a true match for the parameter name, we will find it here.
- for (i = 0; i < l; i++) {
- String sParam = parameterNames.get(i);
- sParam = sParam.substring(1, sParam.length());
- if (sParam.equals(columnNameWithoutAtSign)) {
- matchPos = i;
- break;
- }
+ Integer matchPos = parameterNames.get(columnNameWithSign);
+ if (null == matchPos) {
+ matchPos = insensitiveParameterNames.get(columnNameWithSign);
}
-
- if (-1 == matchPos) {
- // Check for case-insensitive match using a non-locale aware method.
- // Use VM supplied String.equalsIgnoreCase to do the "case-insensitive search".
- for (i = 0; i < l; i++) {
- String sParam = parameterNames.get(i);
- sParam = sParam.substring(1, sParam.length());
- if (sParam.equalsIgnoreCase(columnNameWithoutAtSign)) {
- matchPos = i;
- break;
- }
- }
- }
-
- if (-1 == matchPos) {
+ if (null == matchPos) {
MessageFormat form = new MessageFormat(
SQLServerException.getErrString("R_parameterNotDefinedForProcedure"));
Object[] msgArgs = {columnName, procedureName};
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionAzureKeyVaultProvider.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionAzureKeyVaultProvider.java
index 5b3e25eab..2e21f69fb 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionAzureKeyVaultProvider.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionAzureKeyVaultProvider.java
@@ -50,7 +50,14 @@ public class SQLServerColumnEncryptionAzureKeyVaultProvider extends SQLServerCol
private final String baseUrl = "https://{vaultBaseUrl}";
- private final String azureKeyVaultDomainName = "vault.azure.net";
+ /**
+ * List of Azure trusted endpoints https://docs.microsoft.com/en-us/azure/key-vault/key-vault-secure-your-key-vault
+ */
+ private final String azureTrustedEndpoints[] = {"vault.azure.net", // default
+ "vault.azure.cn", // Azure China
+ "vault.usgovcloudapi.net", // US Government
+ "vault.microsoftazure.de" // Azure Germany
+ };
private final String rsaEncryptionAlgorithmWithOAEPForAKV = "RSA-OAEP";
@@ -441,20 +448,27 @@ private void ValidateNonEmptyAKVPath(String masterKeyPath) throws SQLServerExcep
URI parsedUri = null;
try {
parsedUri = new URI(masterKeyPath);
+
+ // A valid URI.
+ // Check if it is pointing to a trusted endpoint.
+ String host = parsedUri.getHost();
+ if (null != host) {
+ host = host.toLowerCase(Locale.ENGLISH);
+ }
+ for (final String endpoint : azureTrustedEndpoints) {
+ if (null != host && host.endsWith(endpoint)) {
+ return;
+ }
+ }
} catch (URISyntaxException e) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_AKVURLInvalid"));
Object[] msgArgs = {masterKeyPath};
throw new SQLServerException(form.format(msgArgs), null, 0, e);
}
- // A valid URI.
- // Check if it is pointing to AKV.
- if (!parsedUri.getHost().toLowerCase(Locale.ENGLISH).endsWith(azureKeyVaultDomainName)) {
- // Return an error indicating that the AKV url is invalid.
- MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_AKVMasterKeyPathInvalid"));
- Object[] msgArgs = {masterKeyPath};
- throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
- }
+ MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_AKVMasterKeyPathInvalid"));
+ Object[] msgArgs = {masterKeyPath};
+ throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
}
}
@@ -581,4 +595,37 @@ private int getAKVKeySize(String masterKeyPath) throws SQLServerException {
return retrievedKey.key().n().length;
}
+
+ @Override
+ public boolean verifyColumnMasterKeyMetadata(String masterKeyPath, boolean allowEnclaveComputations,
+ byte[] signature) throws SQLServerException {
+ if (!allowEnclaveComputations)
+ return false;
+
+ KeyStoreProviderCommon.validateNonEmptyMasterKeyPath(masterKeyPath);
+
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ md.update(name.toLowerCase().getBytes(java.nio.charset.StandardCharsets.UTF_16LE));
+ md.update(masterKeyPath.toLowerCase().getBytes(java.nio.charset.StandardCharsets.UTF_16LE));
+ // value of allowEnclaveComputations is always true here
+ md.update("true".getBytes(java.nio.charset.StandardCharsets.UTF_16LE));
+
+ byte[] dataToVerify = md.digest();
+ if (null == dataToVerify) {
+ throw new SQLServerException(SQLServerException.getErrString("R_HashNull"), null);
+ }
+
+ // Sign the hash
+ byte[] signedHash = AzureKeyVaultSignHashedData(dataToVerify, masterKeyPath);
+ if (null == signedHash) {
+ throw new SQLServerException(SQLServerException.getErrString("R_SignedHashLengthError"), null);
+ }
+
+ // Validate the signature
+ return AzureKeyVaultVerifySignature(dataToVerify, signature, masterKeyPath);
+ } catch (NoSuchAlgorithmException e) {
+ throw new SQLServerException(SQLServerException.getErrString("R_NoSHA256Algorithm"), e);
+ }
+ }
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionCertificateStoreProvider.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionCertificateStoreProvider.java
index 7733e6db2..f4f6cd458 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionCertificateStoreProvider.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionCertificateStoreProvider.java
@@ -81,4 +81,15 @@ public byte[] decryptColumnEncryptionKey(String masterKeyPath, String encryption
"decryptColumnEncryptionKey", "Finished decrypting Column Encryption Key.");
return plainCek;
}
+
+ @Override
+ public boolean verifyColumnMasterKeyMetadata(String masterKeyPath, boolean allowEnclaveComputations,
+ byte[] signature) throws SQLServerException {
+ try {
+ return AuthenticationJNI.VerifyColumnMasterKeyMetadata(masterKeyPath, allowEnclaveComputations, signature);
+ } catch (DLLException e) {
+ DLLException.buildException(e.GetErrCode(), e.GetParam1(), e.GetParam2(), e.GetParam3());
+ return false;
+ }
+ }
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionJavaKeyStoreProvider.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionJavaKeyStoreProvider.java
index 41d012b65..2ffc5125d 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionJavaKeyStoreProvider.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionJavaKeyStoreProvider.java
@@ -16,6 +16,7 @@
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
+import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
@@ -303,7 +304,6 @@ private byte[] rsaSignHashedData(byte[] dataToSign,
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_EncryptionFailed"));
Object[] msgArgs = {e.getMessage()};
throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
-
}
return signedHash;
@@ -314,7 +314,52 @@ private byte[] getLittleEndianBytesFromShort(short value) {
byteBuffer.order(ByteOrder.LITTLE_ENDIAN);
byte[] byteValue = byteBuffer.putShort(value).array();
return byteValue;
+ }
+
+ /*
+ * Verify signature against certificate
+ */
+ private boolean rsaVerifySignature(byte[] dataToVerify, byte[] signature,
+ CertificateDetails certificateDetails) throws SQLServerException {
+ try {
+ Signature sig = Signature.getInstance("SHA256withRSA");
+ sig.initSign((PrivateKey) certificateDetails.privateKey);
+ sig.update(dataToVerify);
+ byte[] signedHash = sig.sign();
+
+ sig.initVerify(certificateDetails.certificate.getPublicKey());
+ sig.update(dataToVerify);
+
+ return sig.verify(signedHash);
+
+ } catch (InvalidKeyException | NoSuchAlgorithmException | SignatureException e) {
+ MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_VerifySignatureFailed"));
+ Object[] msgArgs = {e.getMessage()};
+ throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
+ }
+ }
+
+ @Override
+ public boolean verifyColumnMasterKeyMetadata(String masterKeyPath, boolean allowEnclaveComputations,
+ byte[] signature) throws SQLServerException {
+
+ if (!allowEnclaveComputations)
+ return false;
+ KeyStoreProviderCommon.validateNonEmptyMasterKeyPath(masterKeyPath);
+ CertificateDetails certificateDetails = getCertificateDetails(masterKeyPath);
+
+ try {
+ MessageDigest md = MessageDigest.getInstance("SHA-256");
+ md.update(name.toLowerCase().getBytes(java.nio.charset.StandardCharsets.UTF_16LE));
+ md.update(masterKeyPath.toLowerCase().getBytes(java.nio.charset.StandardCharsets.UTF_16LE));
+ // value of allowEnclaveComputations is always true here
+ md.update("true".getBytes(java.nio.charset.StandardCharsets.UTF_16LE));
+ return rsaVerifySignature(md.digest(), signature, certificateDetails);
+
+ } catch (NoSuchAlgorithmException e) {
+ throw new SQLServerException(SQLServerException.getErrString("R_NoSHA256Algorithm"), e);
+ }
}
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionKeyStoreProvider.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionKeyStoreProvider.java
index 6fd8b845f..6a11025a8 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionKeyStoreProvider.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerColumnEncryptionKeyStoreProvider.java
@@ -62,4 +62,19 @@ public abstract byte[] decryptColumnEncryptionKey(String masterKeyPath, String e
public abstract byte[] encryptColumnEncryptionKey(String masterKeyPath, String encryptionAlgorithm,
byte[] columnEncryptionKey) throws SQLServerException;
+ /**
+ * Verify the signature is valid for the column master key
+ *
+ * @param masterKeyPath
+ * column master key path
+ * @param allowEnclaveComputations
+ * indicates whether the column master key supports enclave computations
+ * @param signature
+ * signature of the column master key metadata
+ * @return
+ * whether the signature is valid for the column master key
+ * @throws SQLServerException
+ * when an error occurs while verifying the signature
+ */
+ public abstract boolean verifyColumnMasterKeyMetadata (String masterKeyPath, boolean allowEnclaveComputations, byte[] signature) throws SQLServerException;
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java
index 2cfe72ca0..04366fa27 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerConnection.java
@@ -125,6 +125,8 @@ public class SQLServerConnection implements ISQLServerConnection, java.io.Serial
private ConcurrentLinkedQueue discardedPreparedStatementHandles = new ConcurrentLinkedQueue<>();
private AtomicInteger discardedPreparedStatementHandleCount = new AtomicInteger(0);
+ private SQLServerColumnEncryptionKeyStoreProvider keystoreProvider = null;
+
private boolean fedAuthRequiredByUser = false;
private boolean fedAuthRequiredPreLoginResponse = false;
private boolean federatedAuthenticationRequested = false;
@@ -627,14 +629,23 @@ boolean isColumnEncryptionSettingEnabled() {
return (columnEncryptionSetting.equalsIgnoreCase(ColumnEncryptionSetting.Enabled.toString()));
}
+ String enclaveAttestationUrl = null;
+ String enclaveAttestationProtocol = null;
+
String keyStoreAuthentication = null;
String keyStoreSecret = null;
String keyStoreLocation = null;
- private boolean serverSupportsColumnEncryption = false;
+ private ColumnEncryptionVersion serverColumnEncryptionVersion = ColumnEncryptionVersion.AE_NotSupported;
+
+ private String enclaveType = null;
boolean getServerSupportsColumnEncryption() {
- return serverSupportsColumnEncryption;
+ return (serverColumnEncryptionVersion.value() > ColumnEncryptionVersion.AE_NotSupported.value());
+ }
+
+ ColumnEncryptionVersion getServerColumnEncryptionVersion() {
+ return serverColumnEncryptionVersion;
}
private boolean serverSupportsDataClassification = false;
@@ -705,13 +716,13 @@ public static synchronized void registerColumnEncryptionKeyStoreProviders(
+ globalCustomColumnEncryptionKeyStoreProviders.size());
}
- static synchronized SQLServerColumnEncryptionKeyStoreProvider getGlobalSystemColumnEncryptionKeyStoreProvider(
+ synchronized SQLServerColumnEncryptionKeyStoreProvider getGlobalSystemColumnEncryptionKeyStoreProvider(
String providerName) {
return (null != globalSystemColumnEncryptionKeyStoreProviders && globalSystemColumnEncryptionKeyStoreProviders
.containsKey(providerName)) ? globalSystemColumnEncryptionKeyStoreProviders.get(providerName) : null;
}
- static synchronized String getAllGlobalCustomSystemColumnEncryptionKeyStoreProviders() {
+ synchronized String getAllGlobalCustomSystemColumnEncryptionKeyStoreProviders() {
return (null != globalCustomColumnEncryptionKeyStoreProviders) ? globalCustomColumnEncryptionKeyStoreProviders
.keySet().toString() : null;
}
@@ -725,7 +736,7 @@ synchronized String getAllSystemColumnEncryptionKeyStoreProviders() {
return keyStores;
}
- static synchronized SQLServerColumnEncryptionKeyStoreProvider getGlobalCustomColumnEncryptionKeyStoreProvider(
+ synchronized SQLServerColumnEncryptionKeyStoreProvider getGlobalCustomColumnEncryptionKeyStoreProvider(
String providerName) {
return (null != globalCustomColumnEncryptionKeyStoreProviders && globalCustomColumnEncryptionKeyStoreProviders
.containsKey(providerName)) ? globalCustomColumnEncryptionKeyStoreProviders.get(providerName) : null;
@@ -737,6 +748,35 @@ synchronized SQLServerColumnEncryptionKeyStoreProvider getSystemColumnEncryption
.containsKey(providerName)) ? systemColumnEncryptionKeyStoreProvider.get(providerName) : null;
}
+ synchronized SQLServerColumnEncryptionKeyStoreProvider getColumnEncryptionKeyStoreProvider(
+ String providerName) throws SQLServerException {
+
+ // Check for the connection provider first.
+ keystoreProvider = getSystemColumnEncryptionKeyStoreProvider(providerName);
+
+ // There is no connection provider of this name, check for the global system providers.
+ if (null == keystoreProvider) {
+ keystoreProvider = getGlobalSystemColumnEncryptionKeyStoreProvider(providerName);
+ }
+
+ // There is no global system provider of this name, check for the global custom providers.
+ if (null == keystoreProvider) {
+ keystoreProvider = getGlobalCustomColumnEncryptionKeyStoreProvider(providerName);
+ }
+
+ // No provider was found of this name.
+ if (null == keystoreProvider) {
+ String systemProviders = getAllSystemColumnEncryptionKeyStoreProviders();
+ String customProviders = getAllGlobalCustomSystemColumnEncryptionKeyStoreProviders();
+ MessageFormat form = new MessageFormat(
+ SQLServerException.getErrString("R_UnrecognizedKeyStoreProviderName"));
+ Object[] msgArgs = {providerName, systemProviders, customProviders};
+ throw new SQLServerException(form.format(msgArgs), null);
+ }
+
+ return keystoreProvider;
+ }
+
private String trustedServerNameAE = null;
private static Map> columnEncryptionTrustedMasterKeyPaths = new HashMap<>();
@@ -1422,6 +1462,38 @@ Connection connectInternal(Properties propsIn,
}
columnEncryptionSetting = ColumnEncryptionSetting.valueOfString(sPropValue).toString();
+ sPropKey = SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_URL.toString();
+ sPropValue = activeConnectionProperties.getProperty(sPropKey);
+ if (null != sPropValue) {
+ enclaveAttestationUrl = sPropValue;
+ }
+
+ sPropKey = SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_PROTOCOL.toString();
+ sPropValue = activeConnectionProperties.getProperty(sPropKey);
+ if (null != sPropValue) {
+ enclaveAttestationProtocol = sPropValue;
+ if (!AttestationProtocol.isValidAttestationProtocol(enclaveAttestationProtocol)) {
+ if (connectionlogger.isLoggable(Level.SEVERE)) {
+ connectionlogger.severe(toString() + " "
+ + SQLServerException.getErrString("R_enclaveInvalidAttestationProtocol"));
+ }
+ throw new SQLServerException(SQLServerException.getErrString("R_enclaveInvalidAttestationProtocol"),
+ null);
+ }
+ }
+
+ // both enclaveAttestationUrl must be enclaveAttestationProtocol specified
+ if ((null != enclaveAttestationUrl && !enclaveAttestationUrl.isEmpty()
+ && (null == enclaveAttestationProtocol || enclaveAttestationProtocol.isEmpty()))
+ || (null != enclaveAttestationProtocol && !enclaveAttestationProtocol.isEmpty()
+ && (null == enclaveAttestationUrl || enclaveAttestationUrl.isEmpty()))) {
+ if (connectionlogger.isLoggable(Level.SEVERE)) {
+ connectionlogger.severe(
+ toString() + " " + SQLServerException.getErrString("R_enclaveNoAttestationProtocol"));
+ }
+ throw new SQLServerException(SQLServerException.getErrString("R_enclaveNoAttestationProtocol"), null);
+ }
+
sPropKey = SQLServerDriverStringProperty.KEY_STORE_AUTHENTICATION.toString();
sPropValue = activeConnectionProperties.getProperty(sPropKey);
if (null != sPropValue) {
@@ -3015,12 +3087,13 @@ final class ConnectionCommand extends UninterruptableTDSCommand {
}
final boolean doExecute() throws SQLServerException {
- startRequest(TDS.PKT_QUERY).writeString(sql);
+ TDSWriter tdsWriter = startRequest(TDS.PKT_QUERY);
+ tdsWriter.sendEnclavePackage(null, null);
+ tdsWriter.writeString(sql);
TDSParser.parse(startResponse(), getLogContext());
return true;
}
}
-
executeCommand(new ConnectionCommand(sql, logContext));
}
@@ -3540,9 +3613,13 @@ int writeAEFeatureRequest(boolean write, /* if false just calculates the length
int len = 6; // (1byte = featureID, 4bytes = featureData length, 1 bytes = Version)
if (write) {
- tdsWriter.writeByte(TDS.TDS_FEATURE_EXT_AE); // FEATUREEXT_TCE
- tdsWriter.writeInt(1);
- tdsWriter.writeByte(TDS.MAX_SUPPORTED_TCE_VERSION);
+ tdsWriter.writeByte(TDS.TDS_FEATURE_EXT_AE); // FEATUREEXT_TC
+ tdsWriter.writeInt(1); // length of version
+ if (null == enclaveAttestationUrl || enclaveAttestationUrl.isEmpty()) {
+ tdsWriter.writeByte(TDS.COLUMNENCRYPTION_VERSION1);
+ } else {
+ tdsWriter.writeByte(TDS.COLUMNENCRYPTION_VERSION2);
+ }
}
return len;
}
@@ -4553,13 +4630,29 @@ private void onFeatureExtAck(byte featureId, byte[] data) throws SQLServerExcept
throw new SQLServerException(SQLServerException.getErrString("R_InvalidAEVersionNumber"), null);
}
- byte supportedTceVersion = data[0];
- if (0 == supportedTceVersion || supportedTceVersion > TDS.MAX_SUPPORTED_TCE_VERSION) {
+ aeVersion = data[0];
+ if (TDS.COLUMNENCRYPTION_NOT_SUPPORTED == aeVersion || aeVersion > TDS.COLUMNENCRYPTION_VERSION2) {
throw new SQLServerException(SQLServerException.getErrString("R_InvalidAEVersionNumber"), null);
}
- serverSupportsColumnEncryption = true;
+ serverColumnEncryptionVersion = ColumnEncryptionVersion.AE_v1;
+
+ if (null != enclaveAttestationUrl) {
+ if (aeVersion < TDS.COLUMNENCRYPTION_VERSION2) {
+ throw new SQLServerException(SQLServerException.getErrString("R_enclaveNotSupported"), null);
+ } else {
+ serverColumnEncryptionVersion = ColumnEncryptionVersion.AE_v2;
+ enclaveType = new String(data, 2, data.length - 2, UTF_16LE);
+ }
+
+ if (!EnclaveType.isValidEnclaveType(enclaveType)) {
+ MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_enclaveTypeInvalid"));
+ Object[] msgArgs = {enclaveType};
+ throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
+ }
+ }
break;
+
}
case TDS.TDS_FEATURE_EXT_DATACLASSIFICATION: {
if (connectionlogger.isLoggable(Level.FINER)) {
@@ -4619,6 +4712,7 @@ final class DTCCommand extends UninterruptableTDSCommand {
final boolean doExecute() throws SQLServerException {
TDSWriter tdsWriter = startRequest(TDS.PKT_DTC);
+ tdsWriter.sendEnclavePackage(null, null);
tdsWriter.writeShort((short) requestType);
if (null == payload) {
@@ -5680,6 +5774,8 @@ public T unwrap(Class iface) throws SQLException {
private List openStatements;
private boolean originalUseFmtOnly;
+ int aeVersion = TDS.COLUMNENCRYPTION_NOT_SUPPORTED;
+
protected void beginRequestInternal() throws SQLException {
loggerExternal.entering(getClassNameLogging(), "beginRequest", this);
synchronized (this) {
@@ -6130,7 +6226,8 @@ final void unprepareUnreferencedPreparedStatementHandles(boolean force) {
try {
// Execute the batched set.
- try (Statement stmt = this.createStatement()) {
+ try (SQLServerStatement stmt = (SQLServerStatement) this.createStatement()) {
+ stmt.isInternalEncryptionQuery = true;
stmt.execute(sql.toString());
}
@@ -6369,6 +6466,28 @@ final synchronized void removeOpenStatement(ISQLServerStatement st) {
openStatements.remove(st);
}
}
+
+ boolean isAEv2() {
+ return (aeVersion >= TDS.COLUMNENCRYPTION_VERSION2);
+ }
+
+ ISQLServerEnclaveProvider enclaveProvider = new SQLServerVSMEnclaveProvider();
+
+ ArrayList initEnclaveParameters(String userSql, String preparedTypeDefinitions, Parameter[] params,
+ ArrayList parameterNames) throws SQLServerException {
+ if (!this.enclaveEstablished()) {
+ enclaveProvider.getAttestationParameters(false, this.enclaveAttestationUrl);
+ }
+ return enclaveProvider.createEnclaveSession(this, userSql, preparedTypeDefinitions, params, parameterNames);
+ }
+
+ boolean enclaveEstablished() {
+ return (null != enclaveProvider.getEnclaveSession());
+ }
+
+ byte[] generateEncalvePackage(String userSQL, ArrayList enclaveCEKs) throws SQLServerException {
+ return (enclaveCEKs.size() > 0) ? enclaveProvider.getEnclavePackage(userSQL, enclaveCEKs) : null;
+ }
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataColumn.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataColumn.java
index 218f58dbb..1cb840b3c 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataColumn.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataColumn.java
@@ -45,4 +45,35 @@ public String getColumnName() {
public int getColumnType() {
return javaSqlType;
}
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 31 * hash + javaSqlType;
+ hash = 31 * hash + precision;
+ hash = 31 * hash + scale;
+ hash = 31 * hash + numberOfDigitsIntegerPart;
+ hash = 31 * hash + (null != columnName ? columnName.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+
+ if (null != object && object.getClass() == SQLServerDataColumn.class) {
+ SQLServerDataColumn aSQLServerDataColumn = (SQLServerDataColumn) object;
+ if (hashCode() == aSQLServerDataColumn.hashCode()) {
+ // Compare objects to avoid collision
+ return ((null == columnName && null == aSQLServerDataColumn.columnName
+ || columnName.equals(aSQLServerDataColumn.columnName))
+ && javaSqlType == aSQLServerDataColumn.javaSqlType
+ && numberOfDigitsIntegerPart == aSQLServerDataColumn.numberOfDigitsIntegerPart
+ && precision == aSQLServerDataColumn.precision && scale == aSQLServerDataColumn.scale);
+ }
+ }
+ return false;
+ }
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java
index 64c523fd7..75397e02f 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataSource.java
@@ -358,6 +358,10 @@ public void setTrustStorePassword(String trustStorePassword) {
trustStorePassword);
}
+ String getTrustStorePassword() {
+ return getStringProperty(connectionProps, SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.toString(), null);
+ }
+
@Override
public void setHostNameInCertificate(String hostName) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.HOSTNAME_IN_CERTIFICATE.toString(), hostName);
@@ -478,11 +482,10 @@ public boolean getSendTimeAsDatetime() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.toString(),
SQLServerDriverBooleanProperty.SEND_TIME_AS_DATETIME.getDefaultValue());
}
-
+
@Override
public void setUseFmtOnly(boolean useFmtOnly) {
- setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.USE_FMT_ONLY.toString(),
- useFmtOnly);
+ setBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.USE_FMT_ONLY.toString(), useFmtOnly);
}
@Override
@@ -490,7 +493,7 @@ public boolean getUseFmtOnly() {
return getBooleanProperty(connectionProps, SQLServerDriverBooleanProperty.USE_FMT_ONLY.toString(),
SQLServerDriverBooleanProperty.USE_FMT_ONLY.getDefaultValue());
}
-
+
/**
* Sets whether string parameters are sent to the server in UNICODE format.
*
@@ -907,15 +910,38 @@ public void setKeyVaultProviderClientKey(String keyVaultProviderClientKey) {
keyVaultProviderClientKey);
}
+ @Override
+ public String getDomain() {
+ return getStringProperty(connectionProps, SQLServerDriverStringProperty.DOMAIN.toString(),
+ SQLServerDriverStringProperty.DOMAIN.getDefaultValue());
+ }
+
@Override
public void setDomain(String domain) {
setStringProperty(connectionProps, SQLServerDriverStringProperty.DOMAIN.toString(), domain);
}
@Override
- public String getDomain() {
- return getStringProperty(connectionProps, SQLServerDriverStringProperty.DOMAIN.toString(),
- SQLServerDriverStringProperty.DOMAIN.getDefaultValue());
+ public String getEnclaveAttestationUrl() {
+ return getStringProperty(connectionProps, SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_URL.toString(),
+ SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_URL.getDefaultValue());
+ }
+
+ @Override
+ public void setEnclaveAttestationUrl(String url) {
+ setStringProperty(connectionProps, SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_URL.toString(), url);
+ }
+
+ @Override
+ public String getEnclaveAttestationProtocol() {
+ return getStringProperty(connectionProps, SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_PROTOCOL.toString(),
+ SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_PROTOCOL.getDefaultValue());
+ }
+
+ @Override
+ public void setEnclaveAttestationProtocol(String protocol) {
+ setStringProperty(connectionProps, SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_PROTOCOL.toString(),
+ protocol);
}
/**
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java
index 8d59c0463..9f718d400 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDataTable.java
@@ -9,6 +9,7 @@
import java.text.MessageFormat;
import java.time.OffsetDateTime;
import java.time.OffsetTime;
+import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -334,4 +335,79 @@ public String getTvpName() {
public void setTvpName(String tvpName) {
this.tvpName = tvpName;
}
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 31 * hash + rowCount;
+ hash = 31 * hash + columnCount;
+ hash = 31 * hash + (null != columnMetadata ? columnMetadata.hashCode() : 0);
+ hash = 31 * hash + (null != columnNames ? columnNames.hashCode() : 0);
+ hash = 31 * hash + getRowsHashCode();
+ hash = 31 * hash + (null != tvpName ? tvpName.hashCode() : 0);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object object) {
+ if (this == object) {
+ return true;
+ }
+
+ if (null != object && object.getClass() == SQLServerDataTable.class) {
+ SQLServerDataTable aSQLServerDataTable = (SQLServerDataTable) object;
+ if (hashCode() == aSQLServerDataTable.hashCode()) {
+
+ // Compare objects to avoid collision
+ boolean equalColumnMetadata = columnMetadata.equals(aSQLServerDataTable.columnMetadata);
+ boolean equalColumnNames = columnNames.equals(aSQLServerDataTable.columnNames);
+ boolean equalRowData = compareRows(aSQLServerDataTable.rows);
+
+ return (rowCount == aSQLServerDataTable.rowCount && columnCount == aSQLServerDataTable.columnCount
+ && tvpName == aSQLServerDataTable.tvpName && equalColumnMetadata && equalColumnNames
+ && equalRowData);
+ }
+ }
+ return false;
+ }
+
+ private int getRowsHashCode() {
+ if (null == rows) {
+ return 0;
+ }
+ int h = 0;
+ for (Entry entry : rows.entrySet()) {
+ h += entry.getKey() ^ Arrays.hashCode(entry.getValue());
+ }
+ return h;
+ }
+
+ private boolean compareRows(Map otherRows) {
+ if (rows == otherRows) {
+ return true;
+ }
+ if (rows.size() != otherRows.size()) {
+ return false;
+ }
+ try {
+ for (Entry e : rows.entrySet()) {
+ Integer key = e.getKey();
+ Object[] value = e.getValue();
+ if (null == value) {
+ if (!(null == otherRows.get(key) && otherRows.containsKey(key))) {
+ return false;
+ }
+ } else {
+ if (!Arrays.equals(value, otherRows.get(key))) {
+ return false;
+ }
+ }
+ }
+ } catch (ClassCastException unused) {
+ return false;
+ } catch (NullPointerException unused) {
+ return false;
+ }
+ return true;
+ }
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java
index 36b254422..65880bdd2 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDatabaseMetaData.java
@@ -638,10 +638,10 @@ public java.sql.ResultSet getColumns(String catalog, String schema, String table
PreparedStatement pstmt = (SQLServerPreparedStatement) this.connection.prepareStatement(spColumnsSql);
pstmt.closeOnCompletion();
try {
- pstmt.setString(1, (null != table && !table.isEmpty()) ? table : "%");
- pstmt.setString(2, (null != schema && !schema.isEmpty()) ? schema : "%");
+ pstmt.setString(1, (null != table && !table.isEmpty()) ? EscapeIDName(table) : "%");
+ pstmt.setString(2, (null != schema && !schema.isEmpty()) ? EscapeIDName(schema) : "%");
pstmt.setString(3, (null != catalog && !catalog.isEmpty()) ? catalog : this.connection.getCatalog());
- pstmt.setString(4, (null != col && !col.isEmpty()) ? col : "%");
+ pstmt.setString(4, (null != col && !col.isEmpty()) ? EscapeIDName(col) : "%");
pstmt.setInt(5, 2);// show sparse columns
pstmt.setInt(6, 3);// odbc version
@@ -677,11 +677,11 @@ public java.sql.ResultSet getColumns(String catalog, String schema, String table
*/
try (PreparedStatement storedProcPstmt = this.connection
.prepareStatement("EXEC sp_columns_100 ?,?,?,?,?,?;")) {
- storedProcPstmt.setString(1, (null != table && !table.isEmpty()) ? table : "%");
- storedProcPstmt.setString(2, (null != schema && !schema.isEmpty()) ? schema : "%");
+ storedProcPstmt.setString(1, (null != table && !table.isEmpty()) ? EscapeIDName(table) : "%");
+ storedProcPstmt.setString(2, (null != schema && !schema.isEmpty()) ? EscapeIDName(schema) : "%");
storedProcPstmt.setString(3,
(null != catalog && !catalog.isEmpty()) ? catalog : this.connection.getCatalog());
- storedProcPstmt.setString(4, (null != col && !col.isEmpty()) ? col : "%");
+ storedProcPstmt.setString(4, (null != col && !col.isEmpty()) ? EscapeIDName(col) : "%");
storedProcPstmt.setInt(5, 2);// show sparse columns
storedProcPstmt.setInt(6, 3);// odbc version
@@ -1011,7 +1011,7 @@ private ResultSet executeSPFkeys(String[] procParams) throws SQLException, SQLTi
"END as UPDATE_RULE, " + "CASE s.delete_referential_action " + "WHEN 1 THEN 0 " + "WHEN 0 THEN 3 "
+ "WHEN 2 THEN 2 " + "WHEN 3 THEN 4 " + "END as DELETE_RULE, " + "t.FK_NAME, " + "t.PK_NAME, "
+ "t.DEFERRABILITY " + "FROM " + tempTableName + " t "
- + "LEFT JOIN sys.foreign_keys s ON t.FK_NAME = s.name collate database_default;";
+ + "LEFT JOIN sys.foreign_keys s ON t.FK_NAME = s.name COLLATE database_default AND schema_id(t.FKTABLE_OWNER) = s.schema_id";
SQLServerCallableStatement cstmt = (SQLServerCallableStatement) connection.prepareCall(sql);
cstmt.closeOnCompletion();
for (int i = 0; i < 6; i++) {
@@ -1212,7 +1212,7 @@ public int getMaxUserNameLength() throws SQLServerException {
@Override
public String getNumericFunctions() throws SQLServerException {
checkClosed();
- return "ABS,ACOS,ASIN,ATAN,ATAN2,CEILING,COS,COT,DEGREES,EXP, FLOOR,LOG,LOG10,MOD,PI,POWER,RADIANS,RAND,ROUND,SIGN,SIN,SQRT,TAN,TRUNCATE";
+ return "ABS,ACOS,ASIN,ATAN,ATAN2,CEILING,COS,COT,DEGREES,EXP,FLOOR,LOG,LOG10,MOD,PI,POWER,RADIANS,RAND,ROUND,SIGN,SIN,SQRT,TAN,TRUNCATE";
}
private static final String[] getPrimaryKeysColumnNames = { /* 1 */ TABLE_CAT, /* 2 */ TABLE_SCHEM,
@@ -1470,7 +1470,7 @@ private static String createSqlKeyWords() {
@Override
public String getStringFunctions() throws SQLServerException {
checkClosed();
- return "ASCII,CHAR,CONCAT, DIFFERENCE,INSERT,LCASE,LEFT,LENGTH,LOCATE,LTRIM,REPEAT,REPLACE,RIGHT,RTRIM,SOUNDEX,SPACE,SUBSTRING,UCASE";
+ return "ASCII,CHAR,CONCAT,DIFFERENCE,INSERT,LCASE,LEFT,LENGTH,LOCATE,LTRIM,REPEAT,REPLACE,RIGHT,RTRIM,SOUNDEX,SPACE,SUBSTRING,UCASE";
}
@Override
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java
index b3fd86735..4e30fa3f9 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerDriver.java
@@ -113,6 +113,46 @@ static ColumnEncryptionSetting valueOfString(String value) throws SQLServerExcep
}
+enum AttestationProtocol {
+ HGS("HGS"); // only protocol supported currently
+
+ private final String protocol;
+
+ AttestationProtocol(String protocol) {
+ this.protocol = protocol;
+ }
+
+ static boolean isValidAttestationProtocol(String protocol) {
+ for (AttestationProtocol p : AttestationProtocol.values()) {
+ if (protocol.equalsIgnoreCase(p.toString())) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+
+enum EnclaveType {
+ VBS("VBS"); // only VBS type supported
+
+ private final String type;
+
+ EnclaveType(String type) {
+ this.type = type;
+ }
+
+ static boolean isValidEnclaveType(String type) {
+ for (EnclaveType t : EnclaveType.values()) {
+ if (type.equalsIgnoreCase(t.toString())) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
+
+
enum SSLProtocol {
TLS("TLS"),
TLS_V10("TLSv1"),
@@ -237,6 +277,7 @@ static ApplicationIntent valueOfString(String value) throws SQLServerException {
enum SQLServerDriverObjectProperty {
GSS_CREDENTIAL("gsscredential", null);
+
private final String name;
private final String defaultValue;
@@ -286,6 +327,8 @@ enum SQLServerDriverStringProperty {
AUTHENTICATION("authentication", SqlAuthentication.NotSpecified.toString()),
ACCESS_TOKEN("accessToken", ""),
COLUMN_ENCRYPTION("columnEncryptionSetting", ColumnEncryptionSetting.Disabled.toString()),
+ ENCLAVE_ATTESTATION_URL("enclaveAttestationUrl", ""),
+ ENCLAVE_ATTESTATION_PROTOCOL("enclaveAttestationProtocol", ""),
KEY_STORE_AUTHENTICATION("keyStoreAuthentication", ""),
KEY_STORE_SECRET("keyStoreSecret", ""),
KEY_STORE_LOCATION("keyStoreLocation", ""),
@@ -400,6 +443,10 @@ public final class SQLServerDriver implements java.sql.Driver {
SQLServerDriverStringProperty.COLUMN_ENCRYPTION.getDefaultValue(), false,
new String[] {ColumnEncryptionSetting.Disabled.toString(),
ColumnEncryptionSetting.Enabled.toString()}),
+ new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_URL.toString(),
+ SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_URL.getDefaultValue(), false, null),
+ new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_PROTOCOL.toString(),
+ SQLServerDriverStringProperty.ENCLAVE_ATTESTATION_PROTOCOL.getDefaultValue(), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverStringProperty.DATABASE_NAME.toString(),
SQLServerDriverStringProperty.DATABASE_NAME.getDefaultValue(), false, null),
new SQLServerDriverPropertyInfo(SQLServerDriverBooleanProperty.DISABLE_STATEMENT_POOLING.toString(),
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerKeyVaultAuthenticationCallback.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerKeyVaultAuthenticationCallback.java
index daa475b99..c7ac13f5c 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerKeyVaultAuthenticationCallback.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerKeyVaultAuthenticationCallback.java
@@ -22,5 +22,5 @@ public interface SQLServerKeyVaultAuthenticationCallback {
* - The scope of the authentication request.
* @return access token
*/
- public String getAccessToken(String authority, String resource, String scope);
+ String getAccessToken(String authority, String resource, String scope);
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerParameterMetaData.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerParameterMetaData.java
index 876495f44..555221ffa 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerParameterMetaData.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerParameterMetaData.java
@@ -289,8 +289,8 @@ private void checkClosed() throws SQLServerException {
try (SQLServerStatement s = (SQLServerStatement) con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
SQLServerResultSet rsProcedureMeta = s.executeQueryInternal(
- con.isKatmaiOrLater() ? "exec sp_sproc_columns_100 " + sProc + ", @ODBCVer=3"
- : "exec sp_sproc_columns " + sProc + ", @ODBCVer=3")) {
+ con.isKatmaiOrLater() ? "exec sp_sproc_columns_100 " + sProc + ", @ODBCVer=3, @fUsePattern=0"
+ : "exec sp_sproc_columns " + sProc + ", @ODBCVer=3, @fUsePattern=0")) {
// if rsProcedureMeta has next row, it means the stored procedure is found
if (rsProcedureMeta.next()) {
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java
index dba2b644f..c9d0f90e7 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerPreparedStatement.java
@@ -52,9 +52,6 @@ public class SQLServerPreparedStatement extends SQLServerStatement implements IS
*/
private static final long serialVersionUID = -6292257029445685221L;
- /** Flag to indicate that it is an internal query to retrieve encryption metadata. */
- boolean isInternalEncryptionQuery = false;
-
/** delimiter for multiple statements in a single batch */
@SuppressWarnings("unused")
private static final int BATCH_STATEMENT_DELIMITER_TDS_71 = 0x80;
@@ -292,6 +289,7 @@ final boolean doExecute() throws SQLServerException {
executedSqlDirectly ? TDS.PROCID_SP_UNPREPARE : TDS.PROCID_SP_CURSORUNPREPARE);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(null, null);
tdsWriter.writeRPCInt(null, handleToClose, false);
TDSParser.parse(startResponse(), getLogContext());
return true;
@@ -556,6 +554,14 @@ final void doExecutePreparedStatement(PrepStmtExecCmd command) throws SQLServerE
hasNewTypeDefinitions = buildPreparedStrings(inOutParam, false);
}
+ if (connection.isAEv2() && !isInternalEncryptionQuery) {
+ this.enclaveCEKs = connection.initEnclaveParameters(preparedSQL, preparedTypeDefinitions, inOutParam,
+ parameterNames);
+ encryptionMetadataIsRetrieved = true;
+ setMaxRowsAndMaxFieldSize();
+ hasNewTypeDefinitions = buildPreparedStrings(inOutParam, true);
+ }
+
if ((Util.shouldHonorAEForParameters(stmtColumnEncriptionSetting, connection)) && (0 < inOutParam.length)
&& !isInternalEncryptionQuery) {
@@ -564,7 +570,7 @@ final void doExecutePreparedStatement(PrepStmtExecCmd command) throws SQLServerE
getParameterEncryptionMetadata(inOutParam);
encryptionMetadataIsRetrieved = true;
- // maxRows is set to 0 when retreving encryption metadata,
+ // maxRows is set to 0 when retrieving encryption metadata,
// need to set it back
setMaxRowsAndMaxFieldSize();
}
@@ -704,6 +710,7 @@ private void buildServerCursorPrepExecParams(TDSWriter tdsWriter) throws SQLServ
tdsWriter.writeShort(TDS.PROCID_SP_CURSORPREPEXEC);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(preparedSQL, enclaveCEKs);
//
// IN (reprepare): Old handle to unprepare before repreparing
@@ -747,6 +754,7 @@ private void buildPrepExecParams(TDSWriter tdsWriter) throws SQLServerException
tdsWriter.writeShort(TDS.PROCID_SP_PREPEXEC);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(preparedSQL, enclaveCEKs);
//
// IN (reprepare): Old handle to unprepare before repreparing
@@ -774,6 +782,7 @@ private void buildExecSQLParams(TDSWriter tdsWriter) throws SQLServerException {
tdsWriter.writeShort(TDS.PROCID_SP_EXECUTESQL);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(preparedSQL, enclaveCEKs);
// No handle used.
resetPrepStmtHandle(false);
@@ -800,6 +809,7 @@ private void buildServerCursorExecParams(TDSWriter tdsWriter) throws SQLServerEx
tdsWriter.writeShort(TDS.PROCID_SP_CURSOREXECUTE);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2 */
+ tdsWriter.sendEnclavePackage(preparedSQL, enclaveCEKs);
// IN
assert hasPreparedStatementHandle();
@@ -832,6 +842,7 @@ private void buildExecParams(TDSWriter tdsWriter) throws SQLServerException {
tdsWriter.writeShort(TDS.PROCID_SP_EXECUTE);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2 */
+ tdsWriter.sendEnclavePackage(preparedSQL, enclaveCEKs);
// IN
assert hasPreparedStatementHandle();
@@ -1026,6 +1037,8 @@ private boolean reuseCachedHandle(boolean hasNewTypeDefinitions, boolean discard
return false;
}
+ private ArrayList enclaveCEKs;
+
private boolean doPrepExec(TDSWriter tdsWriter, Parameter[] params, boolean hasNewTypeDefinitions,
boolean hasExistingTypeDefinitions) throws SQLServerException {
@@ -2025,7 +2038,7 @@ public int[] executeBatch() throws SQLServerException, BatchUpdateException, SQL
bcOperation.setDestinationTableName(tableName);
bcOperation.setStmtColumnEncriptionSetting(this.getStmtColumnEncriptionSetting());
bcOperation.setDestinationTableMetadata(rs);
- bcOperation.writeToServer((ISQLServerBulkRecord) batchRecord);
+ bcOperation.writeToServer(batchRecord);
bcOperation.close();
updateCounts = new int[batchParamValues.size()];
for (int i = 0; i < batchParamValues.size(); ++i) {
@@ -2182,7 +2195,7 @@ public long[] executeLargeBatch() throws SQLServerException, BatchUpdateExceptio
bcOperation.setDestinationTableName(tableName);
bcOperation.setStmtColumnEncriptionSetting(this.getStmtColumnEncriptionSetting());
bcOperation.setDestinationTableMetadata(rs);
- bcOperation.writeToServer((ISQLServerBulkRecord) batchRecord);
+ bcOperation.writeToServer(batchRecord);
bcOperation.close();
updateCounts = new long[batchParamValues.size()];
for (int i = 0; i < batchParamValues.size(); ++i) {
@@ -2709,17 +2722,6 @@ final void doExecutePreparedStatementBatch(PrepStmtBatchExecCmd batchCommand) th
// Create the parameter array that we'll use for all the items in this batch.
Parameter[] batchParam = new Parameter[inOutParam.length];
- /*
- * TDSWriter tdsWriter = null; while (numBatchesExecuted < numBatches) { // Fill in the parameter values for
- * this batch Parameter paramValues[] = batchParamValues.get(numBatchesPrepared); assert paramValues.length ==
- * batchParam.length; System.arraycopy(paramValues, 0, batchParam, 0, paramValues.length); boolean
- * hasExistingTypeDefinitions = preparedTypeDefinitions != null; boolean hasNewTypeDefinitions =
- * buildPreparedStrings(batchParam, false); // Get the encryption metadata for the first batch only. if ((0 ==
- * numBatchesExecuted) && (Util.shouldHonorAEForParameters(stmtColumnEncriptionSetting, connection)) && (0 <
- * batchParam.length) && !isInternalEncryptionQuery && !encryptionMetadataIsRetrieved) {
- * getParameterEncryptionMetadata(batchParam);
- */
-
TDSWriter tdsWriter = null;
while (numBatchesExecuted < numBatches) {
// Fill in the parameter values for this batch
@@ -2730,12 +2732,30 @@ final void doExecutePreparedStatementBatch(PrepStmtBatchExecCmd batchCommand) th
boolean hasExistingTypeDefinitions = preparedTypeDefinitions != null;
boolean hasNewTypeDefinitions = buildPreparedStrings(batchParam, false);
+ if (!isInternalEncryptionQuery && connection.isAEv2()) {
+ this.enclaveCEKs = connection.initEnclaveParameters(preparedSQL, preparedTypeDefinitions, batchParam,
+ parameterNames);
+ encryptionMetadataIsRetrieved = true;
+
+ // fix an issue when inserting unicode into non-encrypted nchar column using setString() and AE is
+ // on on
+ // Connection
+ buildPreparedStrings(batchParam, true);
+
+ // Save the crypto metadata retrieved for the first batch. We will re-use these for the rest of the
+ // batches.
+ for (Parameter aBatchParam : batchParam) {
+ cryptoMetaBatch.add(aBatchParam.cryptoMeta);
+ }
+ }
+
// Get the encryption metadata for the first batch only.
if ((0 == numBatchesExecuted) && (Util.shouldHonorAEForParameters(stmtColumnEncriptionSetting, connection))
&& (0 < batchParam.length) && !isInternalEncryptionQuery && !encryptionMetadataIsRetrieved) {
getParameterEncryptionMetadata(batchParam);
- // fix an issue when inserting unicode into non-encrypted nchar column using setString() and AE is on on
+ // fix an issue when inserting unicode into non-encrypted nchar column using setString() and AE is
+ // on on
// Connection
buildPreparedStrings(batchParam, true);
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java
index cca3ff929..093a7a83f 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResource.java
@@ -188,6 +188,8 @@ protected Object[][] getContents() {
{"R_portNumberPropertyDescription", "The TCP port where an instance of SQL Server is listening."},
{"R_serverSpnPropertyDescription", "SQL Server SPN."},
{"R_columnEncryptionSettingPropertyDescription", "The column encryption setting."},
+ {"R_enclaveAttestationUrlPropertyDescription", "The enclave attestation URL."},
+ {"R_enclaveAttestationProtocolPropertyDescription", "The enclave attestation protocol."},
{"R_serverNameAsACEPropertyDescription",
"Translates the serverName from Unicode to ASCII Compatible Encoding (ACE), as defined by the ToASCII operation of RFC 3490."},
{"R_sendStringParametersAsUnicodePropertyDescription",
@@ -594,5 +596,25 @@ protected Object[][] getContents() {
{"R_invalidUserSQL", "An error occurred when attempting to parse user SQL. Please verify SQL syntax."},
{"R_invalidInsertValuesQuery",
"An error occurred when matching VALUES list to table columns. Please verify SQL syntax."},
- {"R_invalidValuesList", "An error occurred when reading VALUES list. Please verify SQL syntax."}};
+ {"R_invalidValuesList", "An error occurred when reading VALUES list. Please verify SQL syntax."},
+ {"R_enclaveNotSupported", "The SQL Server instance does not support enclave based computations."},
+ {"R_enclaveNoAttestationProtocol",
+ "The \"enclaveAttestationProtocol\" connection property must be specified with \"enclaveAttestationUrl\"."},
+ {"R_enclaveInvalidAttestationProtocol", "The \"enclaveAttestationProtocol\" is invalid."},
+ {"R_enclaveTypeInvalid", "The enclave type {0} is invalid or not supported by the driver."},
+ {"R_attestationUrlInvalid", "Unable to attest enclave specified by {0}."},
+ {"R_EnclaveResponseLengthError",
+ "More bytes from the server were received than expected when parsing Enclave Attestation response."},
+ {"R_EnclavePackageLengthError",
+ "More bytes from the server were received than expected when parsing Enclave Package."},
+ {"R_EnclavePKLengthError",
+ "More bytes from the server were received than expected when parsing Enclave PK."},
+ {"R_MalformedECDHPublicKey", "The ECDH public key from the server must be 104 bits in length."},
+ {"R_MalformedECDHHeader", "Unexpected values for ECDH public key header from the server."},
+ {"R_InvalidHealthCert",
+ " Enclave Attestation failed, the health report certificate provided in the enclave was not signed by the HGS."},
+ {"R_InvalidSignedStatement",
+ " Enclave Attestation failed, the statement bytes were not signed by the health certificate."},
+ {"R_InvalidDHKeySignature",
+ "Enclave Attestation failed, the DH Public Key signature can't be verified with the enclave PK."},};
};
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java
index ca043a8bc..4772519a9 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerResultSet.java
@@ -24,6 +24,8 @@
import java.sql.SQLXML;
import java.text.MessageFormat;
import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.Level;
@@ -153,6 +155,9 @@ final void setCurrentRowType(RowType rowType) {
/** Flag set to true if the current row was updated through this ResultSet object */
private boolean updatedCurrentRow = false;
+ // Column name hash map for caching.
+ private final Map columnNames = new HashMap<>();
+
final boolean getUpdatedCurrentRow() {
return updatedCurrentRow;
}
@@ -632,17 +637,22 @@ public void close() throws SQLServerException {
/**
* Finds a column index given a column name.
*
- * @param columnName
+ * @param userProvidedColumnName
* the name of the column
* @throws SQLServerException
* If any errors occur.
* @return the column index
*/
@Override
- public int findColumn(String columnName) throws SQLServerException {
- loggerExternal.entering(getClassNameLogging(), "findColumn", columnName);
+ public int findColumn(String userProvidedColumnName) throws SQLServerException {
+ loggerExternal.entering(getClassNameLogging(), "findColumn", userProvidedColumnName);
checkClosed();
+ Integer value = columnNames.get(userProvidedColumnName);
+ if (null != value) {
+ return value;
+ }
+
// In order to be as accurate as possible when locating column name
// indexes, as well as be deterministic when running on various client
// locales, we search for column names using the following scheme:
@@ -663,9 +673,9 @@ public int findColumn(String columnName) throws SQLServerException {
// Search using case-sensitive, non-locale specific (binary) compare.
// If the user supplies a true match for the column name, we will find it here.
- int i;
- for (i = 0; i < columns.length; i++) {
- if (columns[i].getColumnName().equals(columnName)) {
+ for (int i = 0; i < columns.length; i++) {
+ if (columns[i].getColumnName().equals(userProvidedColumnName)) {
+ columnNames.put(userProvidedColumnName, i + 1);
loggerExternal.exiting(getClassNameLogging(), "findColumn", i + 1);
return i + 1;
}
@@ -675,14 +685,15 @@ public int findColumn(String columnName) throws SQLServerException {
// Per JDBC spec, 27.3 "The driver will do a case-insensitive search for
// columnName in it's attempt to map it to the column's index".
// Use VM supplied String.equalsIgnoreCase to do the "case-insensitive search".
- for (i = 0; i < columns.length; i++) {
- if (columns[i].getColumnName().equalsIgnoreCase(columnName)) {
+ for (int i = 0; i < columns.length; i++) {
+ if (columns[i].getColumnName().equalsIgnoreCase(userProvidedColumnName)) {
+ columnNames.put(userProvidedColumnName, i + 1);
loggerExternal.exiting(getClassNameLogging(), "findColumn", i + 1);
return i + 1;
}
}
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_invalidColumnName"));
- Object[] msgArgs = {columnName};
+ Object[] msgArgs = {userProvidedColumnName};
SQLServerException.makeFromDriverError(stmt.connection, stmt, form.format(msgArgs), "07009", false);
return 0;
@@ -4715,6 +4726,7 @@ private void doInsertRowRPC(TDSCommand command, String tableName) throws SQLServ
tdsWriter.writeShort(TDS.PROCID_SP_CURSOR);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(null, null);
tdsWriter.writeRPCInt(null, serverCursorId, false);
tdsWriter.writeRPCInt(null, (int) TDS.SP_CURSOR_OP_INSERT, false);
tdsWriter.writeRPCInt(null, fetchBufferGetRow(), false);
@@ -4795,6 +4807,7 @@ private void doUpdateRowRPC(TDSCommand command) throws SQLServerException {
tdsWriter.writeShort(TDS.PROCID_SP_CURSOR);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(null, null);
tdsWriter.writeRPCInt(null, serverCursorId, false);
tdsWriter.writeRPCInt(null, TDS.SP_CURSOR_OP_UPDATE | TDS.SP_CURSOR_OP_SETPOSITION, false);
tdsWriter.writeRPCInt(null, fetchBufferGetRow(), false);
@@ -4873,6 +4886,7 @@ private void doDeleteRowRPC(TDSCommand command) throws SQLServerException {
tdsWriter.writeShort(TDS.PROCID_SP_CURSOR);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(null, null);
tdsWriter.writeRPCInt(null, serverCursorId, false);
tdsWriter.writeRPCInt(null, TDS.SP_CURSOR_OP_DELETE | TDS.SP_CURSOR_OP_SETPOSITION, false);
tdsWriter.writeRPCInt(null, fetchBufferGetRow(), false);
@@ -5445,6 +5459,7 @@ final boolean doExecute() throws SQLServerException {
tdsWriter.writeShort(TDS.PROCID_SP_CURSORFETCH);
tdsWriter.writeByte(TDS.RPC_OPTION_NO_METADATA);
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(null, null);
tdsWriter.writeRPCInt(null, serverCursorId, false);
tdsWriter.writeRPCInt(null, fetchType, false);
tdsWriter.writeRPCInt(null, startRow, false);
@@ -5620,6 +5635,7 @@ final boolean doExecute() throws SQLServerException {
tdsWriter.writeShort(TDS.PROCID_SP_CURSORCLOSE);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(null, null);
tdsWriter.writeRPCInt(null, serverCursorId, false);
TDSParser.parse(startResponse(), getLogContext());
return true;
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSecurityUtility.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSecurityUtility.java
index 45fa6c87b..ca5ecc67b 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSecurityUtility.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSecurityUtility.java
@@ -7,7 +7,9 @@
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
+import java.text.MessageFormat;
import java.util.Iterator;
+import java.util.List;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@@ -189,4 +191,28 @@ static byte[] decryptWithKey(byte[] cipherText, CryptoMetadata md,
return plainText;
}
+
+ /*
+ * Verify the signature for the CMK
+ */
+ static void verifyColumnMasterKeyMetadata(SQLServerConnection connection, String keyStoreName, String keyPath,
+ String serverName, boolean isEnclaveEnabled, byte[] CMKSignature) throws SQLServerException {
+
+ // check trusted key paths
+ Boolean[] hasEntry = new Boolean[1];
+ List trustedKeyPaths = SQLServerConnection.getColumnEncryptionTrustedMasterKeyPaths(serverName,
+ hasEntry);
+ if (hasEntry[0]) {
+ if ((null == trustedKeyPaths) || (0 == trustedKeyPaths.size()) || (!trustedKeyPaths.contains(keyPath))) {
+ MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_UntrustedKeyPath"));
+ Object[] msgArgs = {keyPath, serverName};
+ throw new SQLServerException(form.format(msgArgs), null);
+ }
+ }
+
+ if (!connection.getColumnEncryptionKeyStoreProvider(keyStoreName).verifyColumnMasterKeyMetadata(keyPath,
+ isEnclaveEnabled, CMKSignature)) {
+ throw new SQLServerException(SQLServerException.getErrString("R_VerifySignature"), null);
+ }
+ }
}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java
index f7c722e6b..29fc21e8e 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSpatialDatatype.java
@@ -94,19 +94,31 @@ abstract class SQLServerSpatialDatatype {
/**
* Serializes the Geogemetry/Geography instance to WKB.
*
- * @param noZM
- * flag to indicate if Z and M coordinates should be included
+ * @param excludeZMFromWKB
+ * flag to indicate if Z and M coordinates should be excluded from the WKB representation
* @param type
* Type of Spatial Datatype (Geometry/Geography)
*/
- protected void serializeToWkb(boolean noZM, SQLServerSpatialDatatype type) {
- ByteBuffer buf = ByteBuffer.allocate(determineWkbCapacity());
+ protected void serializeToWkb(boolean excludeZMFromWKB, SQLServerSpatialDatatype type) {
+ ByteBuffer buf = ByteBuffer.allocate(determineWkbCapacity(excludeZMFromWKB));
createSerializationProperties();
buf.order(ByteOrder.LITTLE_ENDIAN);
buf.putInt(srid);
buf.put(version);
- buf.put(serializationProperties);
+ if (excludeZMFromWKB) {
+ byte serializationPropertiesNoZM = serializationProperties;
+ if (hasZvalues) {
+ serializationPropertiesNoZM -= hasZvaluesMask;
+ }
+
+ if (hasMvalues) {
+ serializationPropertiesNoZM -= hasMvaluesMask;
+ }
+ buf.put(serializationPropertiesNoZM);
+ } else {
+ buf.put(serializationProperties);
+ }
if (!isSinglePoint && !isSingleLineSegment) {
buf.putInt(numberOfPoints);
@@ -124,7 +136,7 @@ protected void serializeToWkb(boolean noZM, SQLServerSpatialDatatype type) {
}
}
- if (!noZM) {
+ if (!excludeZMFromWKB) {
if (hasZvalues) {
for (int i = 0; i < numberOfPoints; i++) {
buf.putDouble(zValues[i]);
@@ -139,7 +151,11 @@ protected void serializeToWkb(boolean noZM, SQLServerSpatialDatatype type) {
}
if (isSinglePoint || isSingleLineSegment) {
- wkb = buf.array();
+ if (excludeZMFromWKB) {
+ wkbNoZM = buf.array();
+ } else {
+ wkb = buf.array();
+ }
return;
}
@@ -163,7 +179,7 @@ protected void serializeToWkb(boolean noZM, SQLServerSpatialDatatype type) {
}
}
- if (noZM) {
+ if (excludeZMFromWKB) {
wkbNoZM = buf.array();
} else {
wkb = buf.array();
@@ -1282,7 +1298,7 @@ protected void createSerializationProperties() {
}
}
- protected int determineWkbCapacity() {
+ protected int determineWkbCapacity(boolean excludeZMFromWKB) {
int totalSize = 0;
totalSize += 6; // SRID + version + SerializationPropertiesByte
@@ -1290,24 +1306,28 @@ protected int determineWkbCapacity() {
if (isSinglePoint || isSingleLineSegment) {
totalSize += 16 * numberOfPoints;
- if (hasZvalues) {
- totalSize += 8 * numberOfPoints;
- }
+ if (!excludeZMFromWKB) {
+ if (hasZvalues) {
+ totalSize += 8 * numberOfPoints;
+ }
- if (hasMvalues) {
- totalSize += 8 * numberOfPoints;
+ if (hasMvalues) {
+ totalSize += 8 * numberOfPoints;
+ }
}
return totalSize;
}
int pointSize = 16;
- if (hasZvalues) {
- pointSize += 8;
- }
+ if (!excludeZMFromWKB) {
+ if (hasZvalues) {
+ pointSize += 8;
+ }
- if (hasMvalues) {
- pointSize += 8;
+ if (hasMvalues) {
+ pointSize += 8;
+ }
}
totalSize += 12; // 4 bytes for 3 ints, each representing the number of points, shapes and figures
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java
index afd0a3e94..9c01b7f78 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerStatement.java
@@ -16,7 +16,6 @@
import java.sql.Statement;
import java.text.MessageFormat;
import java.util.ArrayList;
-import java.util.ListIterator;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.Vector;
@@ -821,6 +820,9 @@ final void doExecuteStatement(StmtExecCmd execCmd) throws SQLServerException {
// through regular Statement objects. We need to ensure that any such JDBC
// call syntax is rewritten here as SQL exec syntax.
String sql = ensureSQLSyntax(execCmd.sql);
+ if (!isInternalEncryptionQuery && connection.isAEv2()) {
+ execCmd.enclaveCEKs = connection.initEnclaveParameters(sql, null, null, null);
+ }
// If this request might be a query (as opposed to an update) then make
// sure we set the max number of rows and max field size for any ResultSet
@@ -849,6 +851,8 @@ final void doExecuteStatement(StmtExecCmd execCmd) throws SQLServerException {
TDSWriter tdsWriter = execCmd.startRequest(TDS.PKT_QUERY);
+ tdsWriter.sendEnclavePackage(sql, execCmd.enclaveCEKs);
+
tdsWriter.writeString(sql);
// If this is an INSERT statement and generated keys were requested
@@ -914,6 +918,11 @@ private void doExecuteStatementBatch(StmtBatchExecCmd execCmd) throws SQLServerE
// Make sure any previous maxRows limitation on the connection is removed.
connection.setMaxRows(0);
+ String batchStatementString = String.join(";", batchStatementBuffer);
+ if (connection.isAEv2()) {
+ execCmd.enclaveCEKs = connection.initEnclaveParameters(batchStatementString, null, null, null);
+ }
+
if (loggerExternal.isLoggable(Level.FINER) && Util.isActivityTraceOn()) {
loggerExternal.finer(toString() + " ActivityId: " + ActivityCorrelator.getNext().toString());
}
@@ -926,12 +935,8 @@ private void doExecuteStatementBatch(StmtBatchExecCmd execCmd) throws SQLServerE
TDSWriter tdsWriter = execCmd.startRequest(TDS.PKT_QUERY);
// Write the concatenated batch of statements, delimited by semicolons
- ListIterator batchIter = batchStatementBuffer.listIterator();
- tdsWriter.writeString(batchIter.next());
- while (batchIter.hasNext()) {
- tdsWriter.writeString(" ; ");
- tdsWriter.writeString(batchIter.next());
- }
+ tdsWriter.sendEnclavePackage(batchStatementString, execCmd.enclaveCEKs);
+ tdsWriter.writeString(batchStatementString);
// Start the response
ensureExecuteResultsReader(execCmd.startResponse(isResponseBufferingAdaptive));
@@ -1205,6 +1210,9 @@ public final void cancel() throws SQLServerException {
Vector sqlWarnings; // the SQL warnings chain
+ /** Flag to indicate that it is an internal query to retrieve encryption metadata. */
+ boolean isInternalEncryptionQuery;
+
@Override
public final SQLWarning getWarnings() throws SQLServerException {
loggerExternal.entering(getClassNameLogging(), "getWarnings");
@@ -2000,6 +2008,7 @@ private void doExecuteCursored(StmtExecCmd execCmd, String sql) throws SQLServer
tdsWriter.writeShort(TDS.PROCID_SP_CURSOROPEN);
tdsWriter.writeByte((byte) 0); // RPC procedure option 1
tdsWriter.writeByte((byte) 0); // RPC procedure option 2
+ tdsWriter.sendEnclavePackage(sql, execCmd.enclaveCEKs);
// OUT
tdsWriter.writeRPCInt(null, 0, true);
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSymmetricKeyCache.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSymmetricKeyCache.java
index ab839d20f..c16c0aec7 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSymmetricKeyCache.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerSymmetricKeyCache.java
@@ -125,37 +125,9 @@ SQLServerSymmetricKey getKey(EncryptionKeyInfo keyInfo, SQLServerConnection conn
// if ColumnEncryptionKeyCacheTtl is 0 no caching at all
if (!cache.containsKey(keyLookupValue)) {
-
- // Check for the connection provider first.
- SQLServerColumnEncryptionKeyStoreProvider provider = connection
- .getSystemColumnEncryptionKeyStoreProvider(keyInfo.keyStoreName);
-
- // There is no connection provider of this name, check for the global system providers.
- if (null == provider) {
- provider = SQLServerConnection
- .getGlobalSystemColumnEncryptionKeyStoreProvider(keyInfo.keyStoreName);
- }
-
- // There is no global system provider of this name, check for the global custom providers.
- if (null == provider) {
- provider = SQLServerConnection
- .getGlobalCustomColumnEncryptionKeyStoreProvider(keyInfo.keyStoreName);
- }
-
- // No provider was found of this name.
- if (null == provider) {
- String systemProviders = connection.getAllSystemColumnEncryptionKeyStoreProviders();
- String customProviders = SQLServerConnection
- .getAllGlobalCustomSystemColumnEncryptionKeyStoreProviders();
- MessageFormat form = new MessageFormat(
- SQLServerException.getErrString("R_UnrecognizedKeyStoreProviderName"));
- Object[] msgArgs = {keyInfo.keyStoreName, systemProviders, customProviders};
- throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
- }
-
byte[] plaintextKey;
- plaintextKey = provider.decryptColumnEncryptionKey(keyInfo.keyPath, keyInfo.algorithmName,
- keyInfo.encryptedKey);
+ plaintextKey = connection.getColumnEncryptionKeyStoreProvider(keyInfo.keyStoreName)
+ .decryptColumnEncryptionKey(keyInfo.keyPath, keyInfo.algorithmName, keyInfo.encryptedKey);
encryptionKey = new SQLServerSymmetricKey(plaintextKey);
/*
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerVSMEnclaveProvider.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerVSMEnclaveProvider.java
new file mode 100644
index 000000000..9ad90e981
--- /dev/null
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerVSMEnclaveProvider.java
@@ -0,0 +1,589 @@
+/*
+ * Microsoft JDBC Driver for SQL Server Copyright(c) Microsoft Corporation All rights reserved. This program is made
+ * available under the terms of the MIT License. See the LICENSE file in the project root for more information.
+ */
+
+package com.microsoft.sqlserver.jdbc;
+
+import static java.nio.charset.StandardCharsets.UTF_16LE;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.math.BigInteger;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.MessageDigest;
+import java.security.PublicKey;
+import java.security.SecureRandom;
+import java.security.Signature;
+import java.security.SignatureException;
+import java.security.cert.CertificateException;
+import java.security.cert.CertificateFactory;
+import java.security.cert.X509Certificate;
+import java.security.interfaces.ECPrivateKey;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECGenParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.MGF1ParameterSpec;
+import java.security.spec.PSSParameterSpec;
+import java.security.spec.RSAPublicKeySpec;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.crypto.KeyAgreement;
+
+
+/**
+ *
+ * Provides the implementation of the VSM Enclave Provider. The enclave provider encapsulates the client-side
+ * implementation details of the enclave attestation protocol.
+ *
+ */
+public class SQLServerVSMEnclaveProvider implements ISQLServerEnclaveProvider {
+
+ private VSMAttestationParameters vsmParams = null;
+ private AttestationResponse hgsResponse = null;
+ private String attestationURL = null;
+ private EnclaveSession enclaveSession = null;
+
+ @Override
+ public void getAttestationParameters(boolean createNewParameters, String url) throws SQLServerException {
+ if (null == vsmParams || createNewParameters) {
+ attestationURL = url;
+ vsmParams = new VSMAttestationParameters();
+ }
+ }
+
+ @Override
+ public ArrayList createEnclaveSession(SQLServerConnection connection, String userSql,
+ String preparedTypeDefinitions, Parameter[] params,
+ ArrayList parameterNames) throws SQLServerException {
+ ArrayList b = describeParameterEncryption(connection, userSql, preparedTypeDefinitions, params,
+ parameterNames);
+ if (null != hgsResponse && !connection.enclaveEstablished()) {
+ try {
+ enclaveSession = new EnclaveSession(hgsResponse.getSessionID(),
+ vsmParams.createSessionSecret(hgsResponse.getDHpublicKey()));
+ } catch (GeneralSecurityException e) {
+ SQLServerException.makeFromDriverError(connection, this, e.getLocalizedMessage(), "0", false);
+ }
+ }
+ return b;
+ }
+
+ @Override
+ public void invalidateEnclaveSession() {
+ enclaveSession = null;
+ vsmParams = null;
+ attestationURL = null;
+ }
+
+ @Override
+ public EnclaveSession getEnclaveSession() {
+ return enclaveSession;
+ }
+
+ @Override
+ public byte[] getEnclavePackage(String userSQL, ArrayList enclaveCEKs) throws SQLServerException {
+ if (null != enclaveSession) {
+ try {
+ ByteArrayOutputStream enclavePackage = new ByteArrayOutputStream();
+ enclavePackage.writeBytes(enclaveSession.getSessionID());
+ ByteArrayOutputStream keys = new ByteArrayOutputStream();
+ byte[] randomGUID = new byte[16];
+ SecureRandom.getInstanceStrong().nextBytes(randomGUID);
+ keys.writeBytes(randomGUID);
+ keys.writeBytes(ByteBuffer.allocate(8).putLong(enclaveSession.getCounter()).array());
+ keys.writeBytes(MessageDigest.getInstance("SHA-256").digest((userSQL).getBytes(UTF_16LE)));
+ for (byte[] b : enclaveCEKs) {
+ keys.writeBytes(b);
+ }
+ enclaveCEKs.clear();
+ SQLServerAeadAes256CbcHmac256EncryptionKey encryptedKey = new SQLServerAeadAes256CbcHmac256EncryptionKey(
+ enclaveSession.getSessionSecret(), SQLServerAeadAes256CbcHmac256Algorithm.algorithmName);
+ SQLServerAeadAes256CbcHmac256Algorithm algo = new SQLServerAeadAes256CbcHmac256Algorithm(encryptedKey,
+ SQLServerEncryptionType.Randomized, (byte) 0x1);
+ enclavePackage.writeBytes(algo.encryptData(keys.toByteArray()));
+ return enclavePackage.toByteArray();
+ } catch (GeneralSecurityException | SQLServerException e) {
+ SQLServerException.makeFromDriverError(null, this, e.getLocalizedMessage(), "0", false);
+ }
+ }
+ return null;
+ }
+
+ private AttestationResponse validateAttestationResponse(AttestationResponse ar) throws SQLServerException {
+ try {
+ byte[] attestationCerts = getAttestationCertificates();
+ ar.validateCert(attestationCerts);
+ ar.validateStatementSignature();
+ ar.validateDHPublicKey();
+ } catch (IOException | GeneralSecurityException e) {
+ SQLServerException.makeFromDriverError(null, this, e.getLocalizedMessage(), "0", false);
+ }
+ return ar;
+ }
+
+ private byte[] getAttestationCertificates() throws IOException {
+ java.net.URL url = new java.net.URL(attestationURL + "/attestationservice.svc/v2.0/signingCertificates/");
+ java.net.URLConnection con = url.openConnection();
+ String s = new String(con.getInputStream().readAllBytes());
+ // omit the square brackets that come with the JSON
+ String[] bytesString = s.substring(1, s.length() - 1).split(",");
+ byte[] certData = new byte[bytesString.length];
+ for (int i = 0; i < certData.length; i++) {
+ certData[i] = (byte) (Integer.parseInt(bytesString[i]));
+ }
+ return certData;
+ }
+
+ private ArrayList describeParameterEncryption(SQLServerConnection connection, String userSql,
+ String preparedTypeDefinitions, Parameter[] params,
+ ArrayList parameterNames) throws SQLServerException {
+ ArrayList enclaveRequestedCEKs = new ArrayList<>();
+ ResultSet rs = null;
+ try (PreparedStatement stmt = connection.prepareStatement("EXEC sp_describe_parameter_encryption ?,?,?")) {
+ ((SQLServerPreparedStatement) stmt).isInternalEncryptionQuery = true;
+ stmt.setNString(1, userSql);
+ if (preparedTypeDefinitions != null && preparedTypeDefinitions.length() != 0) {
+ stmt.setNString(2, preparedTypeDefinitions);
+ } else {
+ stmt.setNString(2, "");
+ }
+ stmt.setBytes(3, vsmParams.getBytes());
+ rs = ((SQLServerPreparedStatement) stmt).executeQueryInternal();
+
+ if (null == rs) {
+ // No results. Meaning no parameter.
+ // Should never happen.
+ return enclaveRequestedCEKs;
+ }
+
+ Map cekList = new HashMap<>();
+ CekTableEntry cekEntry = null;
+ boolean isRequestedByEnclave = false;
+ try {
+ while (rs.next()) {
+ int currentOrdinal = rs.getInt(DescribeParameterEncryptionResultSet1.KeyOrdinal.value());
+ if (!cekList.containsKey(currentOrdinal)) {
+ cekEntry = new CekTableEntry(currentOrdinal);
+ cekList.put(cekEntry.ordinal, cekEntry);
+ } else {
+ cekEntry = cekList.get(currentOrdinal);
+ }
+
+ String keyStoreName = rs.getString(DescribeParameterEncryptionResultSet1.ProviderName.value());
+ String algo = rs.getString(DescribeParameterEncryptionResultSet1.KeyEncryptionAlgorithm.value());
+ String keyPath = rs.getString(DescribeParameterEncryptionResultSet1.KeyPath.value());
+
+ int dbID = rs.getInt(DescribeParameterEncryptionResultSet1.DbId.value());
+ byte[] mdVer = rs.getBytes(DescribeParameterEncryptionResultSet1.KeyMdVersion.value());
+ int keyID = rs.getInt(DescribeParameterEncryptionResultSet1.KeyId.value());
+ byte[] encryptedKey = rs.getBytes(DescribeParameterEncryptionResultSet1.EncryptedKey.value());
+
+ cekEntry.add(encryptedKey, dbID, keyID,
+ rs.getInt(DescribeParameterEncryptionResultSet1.KeyVersion.value()), mdVer, keyPath,
+ keyStoreName, algo);
+
+ // servers supporting enclave computations should always return a boolean indicating whether the key
+ // is
+ // required by enclave or not.
+ if (ColumnEncryptionVersion.AE_v2.value() <= connection.getServerColumnEncryptionVersion()
+ .value()) {
+ isRequestedByEnclave = rs
+ .getBoolean(DescribeParameterEncryptionResultSet1.IsRequestedByEnclave.value());
+ }
+
+ if (isRequestedByEnclave) {
+ byte[] keySignature = rs
+ .getBytes(DescribeParameterEncryptionResultSet1.EnclaveCMKSignature.value());
+ String serverName = connection.getTrustedServerNameAE();
+ SQLServerSecurityUtility.verifyColumnMasterKeyMetadata(connection, keyStoreName, keyPath,
+ serverName, isRequestedByEnclave, keySignature);
+
+ // DBID(4) + MDVER(8) + KEYID(2) + CEK(32) = 46
+ ByteBuffer aev2CekEntry = ByteBuffer.allocate(46);
+ aev2CekEntry.order(ByteOrder.LITTLE_ENDIAN).putInt(dbID);
+ aev2CekEntry.put(mdVer);
+ aev2CekEntry.putShort((short) keyID);
+ aev2CekEntry.put(connection.getColumnEncryptionKeyStoreProvider(keyStoreName)
+ .decryptColumnEncryptionKey(keyPath, algo, encryptedKey));
+ enclaveRequestedCEKs.add(aev2CekEntry.array());
+ }
+ }
+ } catch (SQLException e) {
+ if (e instanceof SQLServerException) {
+ throw (SQLServerException) e;
+ } else {
+ throw new SQLServerException(SQLServerException.getErrString("R_UnableRetrieveParameterMetadata"),
+ null, 0, e);
+ }
+ }
+
+ // Process the second resultset.
+ if (!stmt.getMoreResults()) {
+ throw new SQLServerException(this, SQLServerException.getErrString("R_UnexpectedDescribeParamFormat"),
+ null, 0, false);
+ }
+
+ try {
+ rs = (SQLServerResultSet) stmt.getResultSet();
+ while (rs.next() && null != params) {
+ String paramName = rs.getString(DescribeParameterEncryptionResultSet2.ParameterName.value());
+ int paramIndex = parameterNames.indexOf(paramName);
+ int cekOrdinal = rs
+ .getInt(DescribeParameterEncryptionResultSet2.ColumnEncryptionKeyOrdinal.value());
+ cekEntry = cekList.get(cekOrdinal);
+
+ // cekEntry will be null if none of the parameters are encrypted.
+ if ((null != cekEntry) && (cekList.size() < cekOrdinal)) {
+ MessageFormat form = new MessageFormat(
+ SQLServerException.getErrString("R_InvalidEncryptionKeyOridnal"));
+ Object[] msgArgs = {cekOrdinal, cekEntry.getSize()};
+ throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
+ }
+ SQLServerEncryptionType encType = SQLServerEncryptionType
+ .of((byte) rs.getInt(DescribeParameterEncryptionResultSet2.ColumnEncrytionType.value()));
+ if (SQLServerEncryptionType.PlainText != encType) {
+ params[paramIndex].cryptoMeta = new CryptoMetadata(cekEntry, (short) cekOrdinal,
+ (byte) rs.getInt(
+ DescribeParameterEncryptionResultSet2.ColumnEncryptionAlgorithm.value()),
+ null, encType.value, (byte) rs.getInt(
+ DescribeParameterEncryptionResultSet2.NormalizationRuleVersion.value()));
+ // Decrypt the symmetric key.(This will also validate and throw if needed).
+ SQLServerSecurityUtility.decryptSymmetricKey(params[paramIndex].cryptoMeta, connection);
+ } else {
+ if (params[paramIndex].getForceEncryption()) {
+ MessageFormat form = new MessageFormat(SQLServerException
+ .getErrString("R_ForceEncryptionTrue_HonorAETrue_UnencryptedColumn"));
+ Object[] msgArgs = {userSql, paramIndex + 1};
+ SQLServerException.makeFromDriverError(connection, this, form.format(msgArgs), "0", true);
+ }
+ }
+ }
+ } catch (SQLException e) {
+ if (e instanceof SQLServerException) {
+ throw (SQLServerException) e;
+ } else {
+ throw new SQLServerException(SQLServerException.getErrString("R_UnableRetrieveParameterMetadata"),
+ null, 0, e);
+ }
+ }
+
+ // Process the third resultset.
+ if (connection.isAEv2() && stmt.getMoreResults()) {
+ rs = (SQLServerResultSet) stmt.getResultSet();
+ while (rs.next()) {
+ hgsResponse = new AttestationResponse(rs.getBytes(1));
+ // This validates and establishes the enclave session if valid
+ if (!connection.enclaveEstablished()) {
+ hgsResponse = validateAttestationResponse(hgsResponse);
+ }
+ }
+ }
+
+ // Null check for rs is done already.
+ rs.close();
+ } catch (SQLException e) {
+ if (e instanceof SQLServerException) {
+ throw (SQLServerException) e;
+ } else {
+ throw new SQLServerException(SQLServerException.getErrString("R_UnableRetrieveParameterMetadata"), null,
+ 0, e);
+ }
+ }
+ return enclaveRequestedCEKs;
+ }
+}
+
+
+class VSMAttestationParameters extends BaseAttestationRequest {
+
+ // Static byte[] for VSM ECDH
+ private static byte ECDH_MAGIC[] = {0x45, 0x43, 0x4b, 0x33, 0x30, 0x00, 0x00, 0x00};
+ // Type 3 is VSM, sent as Little Endian 0x30000000
+ private static byte ENCLAVE_TYPE[] = new byte[] {0x3, 0x0, 0x0, 0x0};
+ // VSM doesn't have a challenge
+ private static byte ENCLAVE_CHALLENGE[] = new byte[] {0x0, 0x0, 0x0, 0x0};
+ private static int ENCLAVE_LENGTH = 104;
+ private byte[] x;
+ private byte[] y;
+
+ VSMAttestationParameters() throws SQLServerException {
+ KeyPairGenerator kpg = null;
+ try {
+ kpg = KeyPairGenerator.getInstance("EC");
+ kpg.initialize(new ECGenParameterSpec("secp384r1"));
+ } catch (GeneralSecurityException e) {
+ SQLServerException.makeFromDriverError(null, kpg, e.getLocalizedMessage(), "0", false);
+ }
+ KeyPair kp = kpg.generateKeyPair();
+ ECPublicKey publicKey = (ECPublicKey) kp.getPublic();
+ privateKey = kp.getPrivate();
+ ECPoint w = publicKey.getW();
+ x = w.getAffineX().toByteArray();
+ y = w.getAffineY().toByteArray();
+
+ /*
+ * For some reason toByteArray doesn't have an Signum option like the constructor. Manually remove leading 00
+ * byte if it exists.
+ */
+ if (x[0] == 0 && x.length != 48) {
+ x = Arrays.copyOfRange(x, 1, x.length);
+ }
+ if (y[0] == 0 && y.length != 48) {
+ y = Arrays.copyOfRange(y, 1, y.length);
+ }
+ }
+
+ @Override
+ byte[] getBytes() {
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ os.writeBytes(ENCLAVE_TYPE);
+ os.writeBytes(ENCLAVE_CHALLENGE);
+ os.writeBytes(ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN).putInt(ENCLAVE_LENGTH).array());
+ os.writeBytes(ECDH_MAGIC);
+ os.writeBytes(x);
+ os.writeBytes(y);
+ return os.toByteArray();
+ }
+
+ byte[] createSessionSecret(byte[] serverResponse) throws GeneralSecurityException, SQLServerException {
+ if (serverResponse.length != ENCLAVE_LENGTH) {
+ SQLServerException.makeFromDriverError(null, this,
+ SQLServerResource.getResource("R_MalformedECDHPublicKey"), "0", false);
+ }
+ ByteBuffer sr = ByteBuffer.wrap(serverResponse);
+ byte[] magic = new byte[8];
+ sr.get(magic);
+ if (!Arrays.equals(magic, ECDH_MAGIC)) {
+ SQLServerException.makeFromDriverError(null, this, SQLServerResource.getResource("R_MalformedECDHHeader"),
+ "0", false);
+ }
+ byte[] x = new byte[48];
+ byte[] y = new byte[48];
+ sr.get(x);
+ sr.get(y);
+ /*
+ * Server returns X and Y coordinates, create a key using the point of the server and our key parameters.
+ * Public/Private key parameters are the same.
+ */
+ ECPublicKeySpec keySpec = new ECPublicKeySpec(new ECPoint(new BigInteger(1, x), new BigInteger(1, y)),
+ ((ECPrivateKey) privateKey).getParams());
+ KeyAgreement ka = KeyAgreement.getInstance("ECDH");
+ ka.init(privateKey);
+ // Generate a PublicKey from the above key specifications and do an agreement with our PrivateKey
+ ka.doPhase(KeyFactory.getInstance("EC").generatePublic(keySpec), true);
+ // Generate a Secret from the agreement and hash with SHA-256 to create Session Secret
+ return MessageDigest.getInstance("SHA-256").digest(ka.generateSecret());
+ }
+}
+
+
+@SuppressWarnings("unused")
+class AttestationResponse {
+ private int totalSize;
+ private int identitySize;
+ private int healthReportSize;
+ private int enclaveReportSize;
+
+ private byte[] enclavePK;
+ private byte[] healthReportCertificate;
+ private byte[] enclaveReportPackage;
+
+ private int sessionInfoSize;
+ private byte[] sessionID = new byte[8];
+ private int DHPKsize;
+ private int DHPKSsize;
+ private byte[] DHpublicKey;
+ private byte[] publicKeySig;
+
+ private X509Certificate healthCert;
+
+ AttestationResponse(byte[] b) throws SQLServerException {
+ /*-
+ * Parse the attestation response.
+ *
+ * Total Size of the response - 4B
+ * Size of the Identity - 4B
+ * Size of the HealthCert - 4B
+ * Size of the EnclaveReport - 4B
+ * Enclave PK - identitySize bytes
+ * Health Certificate - healthReportSize bytes
+ * Enclave Report Package - enclaveReportSize bytes
+ * Session Info Size - 4B
+ * Session ID - 8B
+ * DH Public Key Size - 4B
+ * DH Public Key Signature Size - 4B
+ * DH Public Key - DHPKsize bytes
+ * DH Public Key Signature - DHPKSsize bytes
+ */
+ ByteBuffer response = ByteBuffer.wrap(b).order(ByteOrder.LITTLE_ENDIAN);
+ this.totalSize = response.getInt();
+ this.identitySize = response.getInt();
+ this.healthReportSize = response.getInt();
+ this.enclaveReportSize = response.getInt();
+
+ enclavePK = new byte[identitySize];
+ healthReportCertificate = new byte[healthReportSize];
+ enclaveReportPackage = new byte[enclaveReportSize];
+
+ response.get(enclavePK, 0, identitySize);
+ response.get(healthReportCertificate, 0, healthReportSize);
+ response.get(enclaveReportPackage, 0, enclaveReportSize);
+
+ this.sessionInfoSize = response.getInt();
+ response.get(sessionID, 0, 8);
+ this.DHPKsize = response.getInt();
+ this.DHPKSsize = response.getInt();
+
+ DHpublicKey = new byte[DHPKsize];
+ publicKeySig = new byte[DHPKSsize];
+
+ response.get(DHpublicKey, 0, DHPKsize);
+ response.get(publicKeySig, 0, DHPKSsize);
+
+ if (0 != response.remaining()) {
+ SQLServerException.makeFromDriverError(null, this,
+ SQLServerResource.getResource("R_EnclaveResponseLengthError"), "0", false);
+ }
+ // Create a X.509 certificate from the bytes
+ try {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ healthCert = (X509Certificate) cf.generateCertificate(new ByteArrayInputStream(healthReportCertificate));
+ } catch (CertificateException ce) {
+ SQLServerException.makeFromDriverError(null, this, ce.getLocalizedMessage(), "0", false);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ void validateCert(byte[] b) throws SQLServerException {
+ try {
+ CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ Collection certs = (Collection) cf
+ .generateCertificates(new ByteArrayInputStream(b));
+ for (X509Certificate cert : certs) {
+ try {
+ healthCert.verify(cert.getPublicKey());
+ return;
+ } catch (SignatureException e) {
+ // Doesn't match, but continue looping through the rest of the certificates
+ }
+ }
+ } catch (GeneralSecurityException e) {
+ SQLServerException.makeFromDriverError(null, this, e.getLocalizedMessage(), "0", false);
+ }
+ SQLServerException.makeFromDriverError(null, this, SQLServerResource.getResource("R_InvalidHealthCert"), "0",
+ false);
+ }
+
+ void validateStatementSignature() throws SQLServerException, GeneralSecurityException {
+ /*-
+ * Parse the Enclave Report Package fields.
+ *
+ * Package Size - 4B
+ * Version - 4B
+ * Signature Scheme - 4B
+ * Signed Statement Bytes Size - 4B
+ * Signature Size - 4B
+ * Reserved - 4B
+ * Signed Statement - signedStatementSize bytes contains:
+ * Report Size - 4B
+ * Report Version - 4B
+ * Enclave Data - 64B
+ * Enclave Identity - 152B
+ * ??? - 720B
+ * Signature Blob - signatureSize bytes
+ */
+ ByteBuffer enclaveReportPackageBuffer = ByteBuffer.wrap(enclaveReportPackage).order(ByteOrder.LITTLE_ENDIAN);
+ int packageSize = enclaveReportPackageBuffer.getInt();
+ int version = enclaveReportPackageBuffer.getInt();
+ int signatureScheme = enclaveReportPackageBuffer.getInt();
+ int signedStatementSize = enclaveReportPackageBuffer.getInt();
+ int signatureSize = enclaveReportPackageBuffer.getInt();
+ int reserved = enclaveReportPackageBuffer.getInt();
+
+ byte[] signedStatement = new byte[signedStatementSize];
+ enclaveReportPackageBuffer.get(signedStatement, 0, signedStatementSize);
+ byte[] signatureBlob = new byte[signatureSize];
+ enclaveReportPackageBuffer.get(signatureBlob, 0, signatureSize);
+
+ if (enclaveReportPackageBuffer.remaining() != 0) {
+ SQLServerException.makeFromDriverError(null, this,
+ SQLServerResource.getResource("R_EnclavePackageLengthError"), "0", false);
+ }
+
+ Signature sig = Signature.getInstance("RSASSA-PSS");
+ PSSParameterSpec pss = new PSSParameterSpec("SHA-256", "MGF1", MGF1ParameterSpec.SHA256, 32, 1);
+ sig.setParameter(pss);
+ sig.initVerify(healthCert);
+ sig.update(signedStatement);
+ if (!sig.verify(signatureBlob)) {
+ SQLServerException.makeFromDriverError(null, this,
+ SQLServerResource.getResource("R_InvalidSignedStatement"), "0", false);
+ }
+ }
+
+ void validateDHPublicKey() throws SQLServerException, GeneralSecurityException {
+ /*-
+ * Java doesn't directly support PKCS1 padding for RSA keys. Parse the key bytes and create a RSAPublicKeySpec
+ * with the exponent and modulus.
+ *
+ * Static string "RSA1" - 4B (Unused)
+ * Bit count - 4B (Unused)
+ * Public Exponent Length - 4B
+ * Public Modulus Length - 4B
+ * Prime 1 - 4B (Unused)
+ * Prime 2 - 4B (Unused)
+ * Exponent - publicExponentLength bytes
+ * Modulus - publicModulusLength bytes
+ */
+ ByteBuffer enclavePKBuffer = ByteBuffer.wrap(enclavePK).order(ByteOrder.LITTLE_ENDIAN);
+ byte[] rsa1 = new byte[4];
+ enclavePKBuffer.get(rsa1);
+ int bitCount = enclavePKBuffer.getInt();
+ int publicExponentLength = enclavePKBuffer.getInt();
+ int publicModulusLength = enclavePKBuffer.getInt();
+ int prime1 = enclavePKBuffer.getInt();
+ int prime2 = enclavePKBuffer.getInt();
+ byte[] exponent = new byte[publicExponentLength];
+ enclavePKBuffer.get(exponent);
+ byte[] modulus = new byte[publicModulusLength];
+ enclavePKBuffer.get(modulus);
+ if (enclavePKBuffer.remaining() != 0) {
+ SQLServerException.makeFromDriverError(null, this, SQLServerResource.getResource("R_EnclavePKLengthError"),
+ "0", false);
+ }
+ RSAPublicKeySpec spec = new RSAPublicKeySpec(new BigInteger(1, modulus), new BigInteger(1, exponent));
+ KeyFactory factory = KeyFactory.getInstance("RSA");
+ PublicKey pub = factory.generatePublic(spec);
+ Signature sig = Signature.getInstance("SHA256withRSA");
+ sig.initVerify(pub);
+ sig.update(DHpublicKey);
+ if (!sig.verify(publicKeySig)) {
+ SQLServerException.makeFromDriverError(null, this, SQLServerResource.getResource("R_InvalidDHKeySignature"),
+ "0", false);
+ }
+ }
+
+ byte[] getDHpublicKey() {
+ return DHpublicKey;
+ }
+
+ byte[] getSessionID() {
+ return sessionID;
+ }
+}
diff --git a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAConnection.java b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAConnection.java
index 958ffa365..fe1067775 100644
--- a/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAConnection.java
+++ b/src/main/java/com/microsoft/sqlserver/jdbc/SQLServerXAConnection.java
@@ -52,6 +52,22 @@ public final class SQLServerXAConnection extends SQLServerPooledConnection imple
controlConnectionProperties.setProperty(SQLServerDriverStringProperty.PASSWORD.toString(), pwd);
}
+ // Add truststore password property for creating the control connection. This will be removed again
+ String trustStorePassword = ds.getTrustStorePassword();
+ if (null == trustStorePassword) {
+ // trustStorePassword can either come from the connection string or added via
+ // SQLServerXADataSource::setTrustStorePassword.
+ // if trustStorePassword is null at this point, then check the connection string.
+ Properties urlProps = Util.parseUrl(ds.getURL(), xaLogger);
+ trustStorePassword = urlProps.getProperty(SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.toString());
+ }
+
+ // if trustStorePassword is still null, it wasn't provided. Do not set the property as null to avoid NPE.
+ if (null != trustStorePassword) {
+ controlConnectionProperties.setProperty(SQLServerDriverStringProperty.TRUST_STORE_PASSWORD.toString(),
+ trustStorePassword);
+ }
+
if (xaLogger.isLoggable(Level.FINER))
xaLogger.finer("Creating an internal control connection for" + toString());
physicalControlConnection = null;
diff --git a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java
index ec7fefb12..2fb946725 100644
--- a/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java
+++ b/src/test/java/com/microsoft/sqlserver/jdbc/AlwaysEncrypted/AESetup.java
@@ -18,7 +18,9 @@
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
+import java.util.HashMap;
import java.util.LinkedList;
+import java.util.Map;
import java.util.Properties;
import org.junit.jupiter.api.AfterAll;
@@ -28,9 +30,12 @@
import org.opentest4j.TestAbortedException;
import com.microsoft.sqlserver.jdbc.RandomData;
+import com.microsoft.sqlserver.jdbc.RandomUtil;
+import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionAzureKeyVaultProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionJavaKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerColumnEncryptionKeyStoreProvider;
import com.microsoft.sqlserver.jdbc.SQLServerConnection;
+import com.microsoft.sqlserver.jdbc.SQLServerException;
import com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement;
import com.microsoft.sqlserver.jdbc.SQLServerStatement;
import com.microsoft.sqlserver.jdbc.SQLServerStatementColumnEncryptionSetting;
@@ -54,14 +59,76 @@ public class AESetup extends AbstractTest {
static String filePath = null;
static String thumbprint = null;
- static String keyPath = null;
+ static String javaKeyPath = null;
static String javaKeyAliases = null;
-
- static SQLServerColumnEncryptionKeyStoreProvider storeProvider = null;
+ static String windowsKeyPath = null;
+ static String applicationClientID = null;
+ static String applicationKey = null;
+ static String[] keyIDs = null;
+ static String cmkJks = null;
+ static String cmkWin = null;
+ static String cmkAkv = null;
+ static String cekJks = null;
+ static String cekWin = null;
+ static String cekAkv = null;
+
+ static boolean kspRegistered = false;
+ static SQLServerColumnEncryptionKeyStoreProvider jksProvider = null;
+ static SQLServerColumnEncryptionAzureKeyVaultProvider akvProvider = null;
static SQLServerStatementColumnEncryptionSetting stmtColEncSetting = null;
static String AETestConnectionString;
-
static Properties AEInfo;
+ static boolean isAEv2Supported = false;
+
+ public static final String tableName = RandomUtil.getIdentifier("AETest_");
+
+ public static final String CHAR_TABLE_AE = RandomUtil.getIdentifier("JDBCEncryptedChar");
+ public static final String BINARY_TABLE_AE = RandomUtil.getIdentifier("JDBCEncryptedBinary");
+ public static final String DATE_TABLE_AE = RandomUtil.getIdentifier("JDBCEncryptedDate");
+ public static final String NUMERIC_TABLE_AE = RandomUtil.getIdentifier("JDBCEncryptedNumeric");
+ public static final String SCALE_DATE_TABLE_AE = RandomUtil.getIdentifier("JDBCEncryptedScaleDate");
+
+ enum ColumnType {
+ PLAIN,
+ RANDOMIZED,
+ DETERMINISTIC
+ }
+
+ /*
+ * tables used in the tests {columnName, columnType}
+ */
+ static String binaryTable[][] = {{"Binary", "binary(20)"}, {"Varbinary", "varbinary(50)"},
+ {"VarbinaryMax", "varbinary(max)"}, {"Binary512", "binary(512)"}, {"Binary8000", "varbinary(8000)"},};
+
+ static String charTable[][] = {{"Char", "char(20) COLLATE Latin1_General_BIN2", "CHAR"},
+ {"Varchar", "varchar(50) COLLATE Latin1_General_BIN2", "CHAR"},
+ {"VarcharMax", "varchar(max) COLLATE Latin1_General_BIN2", "LONGVARCHAR"},
+ {"Nchar", "nchar(30) COLLATE Latin1_General_BIN2", "NCHAR"},
+ {"Nvarchar", "nvarchar(60) COLLATE Latin1_General_BIN2", "NCHAR"},
+ {"NvarcharMax", "nvarchar(max) COLLATE Latin1_General_BIN2", "LONGNVARCHAR"},
+ {"Uniqueidentifier", "uniqueidentifier", "GUID"},
+ {"Varchar8000", "varchar(8000) COLLATE Latin1_General_BIN2", "CHAR"},
+ {"Nvarchar4000", "nvarchar(4000) COLLATE Latin1_General_BIN2", "NCHAR"},};
+
+ static String dateTable[][] = {{"Date", "date"}, {"Datetime2Default", "datetime2"},
+ {"DatetimeoffsetDefault", "datetimeoffset"}, {"TimeDefault", "time"}, {"Datetime", "datetime"},
+ {"Smalldatetime", "smalldatetime"},};
+
+ static String dateScaleTable[][] = {{"Datetime2", "datetime2(2)"}, {"Time", "time(2)"},
+ {"Datetimeoffset", "datetimeoffset(2)"},};
+
+ static String numericTable[][] = {{"Bit", "bit"}, {"Tinyint", "tinyint"}, {"Smallint", "smallint"}, {"Int", "int"},
+ {"Bigint", "bigint"}, {"FloatDefault", "float"}, {"Float", "float(30)"}, {"Real", "real"},
+ {"DecimalDefault", "decimal"}, {"Decimal", "decimal(10,5)"}, {"NumericDefault", "numeric"},
+ {"Numeric", "numeric(8,2)"}, {"SmallMoney", "smallmoney"}, {"Money", "money"},
+ {"Decimal2", "decimal(28,4)"}, {"Numeric2", "numeric(28,4)"},};
+
+ // CREATE TABLE tableName (columns) NULL"
+ static String createSql = "CREATE TABLE %s (%s)";
+
+ // ENCRYPTED WITH (ENCRYPTION_TYPE = encryptionType, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256',
+ // COLUMN_ENCRYPTION_KEY = cekName
+ static String encryptSql = " ENCRYPTED WITH (ENCRYPTION_TYPE = %s, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = %s";
/**
* Create connection, statement and generate path of resource file
@@ -72,24 +139,92 @@ public class AESetup extends AbstractTest {
@BeforeAll
public static void setUpConnection() throws TestAbortedException, Exception {
AETestConnectionString = connectionString + ";sendTimeAsDateTime=false";
+ String tmpConnectionString = AETestConnectionString;
+ String enclaveAttestationUrl = TestUtils.getConfiguredProperty("enclaveAttestationUrl");
+ if (null != enclaveAttestationUrl) {
+ tmpConnectionString = TestUtils.addOrOverrideProperty(tmpConnectionString, "enclaveAttestationUrl",
+ enclaveAttestationUrl);
+ }
+ String enclaveAttestationProtocol = TestUtils.getConfiguredProperty("enclaveAttestationProtocol");
+ if (null != enclaveAttestationProtocol) {
+ tmpConnectionString = TestUtils.addOrOverrideProperty(tmpConnectionString, "enclaveAttestationProtocol",
+ enclaveAttestationProtocol);
+ }
+
+ // add enclave properties if AEv2 supported
+ try (Connection con = PrepUtil.getConnection(tmpConnectionString)) {
+ if (TestUtils.isAEv2(con)) {
+ isAEv2Supported = true;
+ AETestConnectionString = tmpConnectionString;
+ }
+ } catch (SQLServerException e) {
+ if (!e.getMessage().matches(TestUtils.formatErrorMsg("R_enclaveNotSupported"))) {
+ // ignore AEv2 not supported errors
+ fail(e.getMessage());
+ }
+ }
+
+ cmkJks = Constants.CMK_NAME + "_JKS";
+ cekJks = Constants.CEK_NAME + "_JKS";
+
readFromFile(Constants.JAVA_KEY_STORE_FILENAME, "Alias name");
- try (Connection con = PrepUtil.getConnection(AETestConnectionString); Statement stmt = con.createStatement()) {
- dropCEK(stmt);
- dropCMK(stmt);
+
+ javaKeyPath = TestUtils.getCurrentClassPath() + Constants.JKS_NAME;
+ applicationClientID = TestUtils.getConfiguredProperty("applicationClientID");
+ applicationKey = TestUtils.getConfiguredProperty("applicationKey");
+ String keyID = TestUtils.getConfiguredProperty("keyID");
+ if (null != keyID) {
+ keyIDs = keyID.split(";");
+ }
+
+ Map map = new HashMap();
+ if (null == jksProvider) {
+ jksProvider = new SQLServerColumnEncryptionJavaKeyStoreProvider(javaKeyPath,
+ Constants.JKS_SECRET.toCharArray());
+ map.put("My_KEYSTORE", jksProvider);
+ }
+
+ if (null == akvProvider && null != applicationClientID && null != applicationKey) {
+ akvProvider = new SQLServerColumnEncryptionAzureKeyVaultProvider(applicationClientID, applicationKey);
+ map.put(Constants.AZURE_KEY_VAULT_NAME, akvProvider);
+ }
+
+ if (!kspRegistered && (null != jksProvider || null != akvProvider)) {
+ SQLServerConnection.registerColumnEncryptionKeyStoreProviders(map);
+ kspRegistered = true;
+ }
+
+ dropAll();
+
+ // always test JKS
+ createCMK(cmkJks, Constants.JAVA_KEY_STORE_NAME, javaKeyAliases, Constants.CMK_SIGNATURE);
+ createCEK(cmkJks, cekJks, jksProvider);
+
+ if (null != akvProvider) {
+ cmkAkv = Constants.CMK_NAME + "_AKV";
+ cekAkv = Constants.CEK_NAME + "_AKV";
+
+ createCMK(cmkAkv, Constants.AZURE_KEY_VAULT_NAME, keyIDs[0], Constants.CMK_SIGNATURE_AKV);
+ createCEK(cmkAkv, cekAkv, akvProvider);
+ }
+
+ windowsKeyPath = TestUtils.getConfiguredProperty("windowsKeyPath");
+ if (null != windowsKeyPath) {
+ AETestConnectionString = TestUtils.addOrOverrideProperty(AETestConnectionString, "windowsKeyPath",
+ windowsKeyPath);
+ cmkWin = Constants.CMK_NAME + "_WIN";
+ cekWin = Constants.CEK_NAME + "_WIN";
+ createCMK(cmkWin, Constants.WINDOWS_KEY_STORE_NAME, windowsKeyPath, Constants.CMK_SIGNATURE);
+ createCEK(cmkWin, cekWin, null);
}
- keyPath = TestUtils.getCurrentClassPath() + Constants.JKS_NAME;
- storeProvider = new SQLServerColumnEncryptionJavaKeyStoreProvider(keyPath, Constants.JKS_SECRET.toCharArray());
stmtColEncSetting = SQLServerStatementColumnEncryptionSetting.Enabled;
AEInfo = new Properties();
AEInfo.setProperty("ColumnEncryptionSetting", Constants.ENABLED);
AEInfo.setProperty("keyStoreAuthentication", Constants.JAVA_KEY_STORE_SECRET);
- AEInfo.setProperty("keyStoreLocation", keyPath);
+ AEInfo.setProperty("keyStoreLocation", javaKeyPath);
AEInfo.setProperty("keyStoreSecret", Constants.JKS_SECRET);
-
- createCMK(Constants.JAVA_KEY_STORE_NAME, javaKeyAliases);
- createCEK(storeProvider);
}
/**
@@ -102,8 +237,19 @@ public static void setUpConnection() throws TestAbortedException, Exception {
public static void dropAll() throws Exception {
try (Statement stmt = connection.createStatement()) {
dropTables(stmt);
- dropCEK(stmt);
- dropCMK(stmt);
+
+ dropCEK(cekJks, stmt);
+ dropCMK(cmkJks, stmt);
+
+ if (null != cekWin) {
+ dropCEK(cekWin, stmt);
+ dropCMK(cmkWin, stmt);
+ }
+
+ if (null != cekAkv) {
+ dropCEK(cekAkv, stmt);
+ dropCMK(cmkAkv, stmt);
+ }
}
}
@@ -137,172 +283,26 @@ private static void readFromFile(String inputFile, String lookupValue) throws IO
}
/**
- * Create encrypted table for Binary
- *
- * @throws SQLException
- */
- protected static void createBinaryTable() throws SQLException {
- String sql = "create table " + AbstractSQLGenerator.escapeIdentifier(Constants.BINARY_TABLE_AE) + " ("
- + "PlainBinary binary(20) null,"
- + "RandomizedBinary binary(20) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicBinary binary(20) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainVarbinary varbinary(50) null,"
- + "RandomizedVarbinary varbinary(50) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicVarbinary varbinary(50) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainVarbinaryMax varbinary(max) null,"
- + "RandomizedVarbinaryMax varbinary(max) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicVarbinaryMax varbinary(max) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainBinary512 binary(512) null,"
- + "RandomizedBinary512 binary(512) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicBinary512 binary(512) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainBinary8000 varbinary(8000) null,"
- + "RandomizedBinary8000 varbinary(8000) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicBinary8000 varbinary(8000) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + ");";
-
- try (SQLServerConnection con = (SQLServerConnection) PrepUtil.getConnection(AETestConnectionString, AEInfo);
- SQLServerStatement stmt = (SQLServerStatement) con.createStatement()) {
- stmt.execute(sql);
- stmt.execute("DBCC FREEPROCCACHE");
- } catch (SQLException e) {
- fail(e.getMessage());
- }
- }
-
- /**
- * Create encrypted table for Char
- *
- * @throws SQLException
- */
- protected static void createCharTable() throws SQLException {
- String sql = "create table " + AbstractSQLGenerator.escapeIdentifier(Constants.CHAR_TABLE_AE) + " ("
- + "PlainChar char(20) null,"
- + "RandomizedChar char(20) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicChar char(20) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainVarchar varchar(50) null,"
- + "RandomizedVarchar varchar(50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicVarchar varchar(50) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainVarcharMax varchar(max) null,"
- + "RandomizedVarcharMax varchar(max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicVarcharMax varchar(max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainNchar nchar(30) null,"
- + "RandomizedNchar nchar(30) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicNchar nchar(30) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainNvarchar nvarchar(60) null,"
- + "RandomizedNvarchar nvarchar(60) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicNvarchar nvarchar(60) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainNvarcharMax nvarchar(max) null,"
- + "RandomizedNvarcharMax nvarchar(max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicNvarcharMax nvarchar(max) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainUniqueidentifier uniqueidentifier null,"
- + "RandomizedUniqueidentifier uniqueidentifier ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicUniqueidentifier uniqueidentifier ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainVarchar8000 varchar(8000) null,"
- + "RandomizedVarchar8000 varchar(8000) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicVarchar8000 varchar(8000) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainNvarchar4000 nvarchar(4000) null,"
- + "RandomizedNvarchar4000 nvarchar(4000) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicNvarchar4000 nvarchar(4000) COLLATE Latin1_General_BIN2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + ");";
-
- try (SQLServerConnection con = (SQLServerConnection) PrepUtil.getConnection(AETestConnectionString, AEInfo);
- SQLServerStatement stmt = (SQLServerStatement) con.createStatement()) {
- stmt.execute(sql);
- stmt.execute("DBCC FREEPROCCACHE");
- } catch (SQLException e) {
- fail(e.getMessage());
- }
- }
-
- /**
- * Create encrypted table for Date
+ * Create AE test tables
*
+ * @param tableName
+ * name of test table
+ * @param table
+ * 2d array containing table column definitions
* @throws SQLException
*/
- protected void createDateTable() throws SQLException {
- String sql = "create table " + AbstractSQLGenerator.escapeIdentifier(Constants.DATE_TABLE_AE) + " ("
- + "PlainDate date null,"
- + "RandomizedDate date ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDate date ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainDatetime2Default datetime2 null,"
- + "RandomizedDatetime2Default datetime2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDatetime2Default datetime2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainDatetimeoffsetDefault datetimeoffset null,"
- + "RandomizedDatetimeoffsetDefault datetimeoffset ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDatetimeoffsetDefault datetimeoffset ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainTimeDefault time null,"
- + "RandomizedTimeDefault time ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicTimeDefault time ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainDatetime datetime null,"
- + "RandomizedDatetime datetime ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDatetime datetime ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainSmalldatetime smalldatetime null,"
- + "RandomizedSmalldatetime smalldatetime ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicSmalldatetime smalldatetime ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + ");";
-
+ protected static void createTable(String tableName, String cekName, String table[][]) throws SQLException {
try (SQLServerConnection con = (SQLServerConnection) PrepUtil.getConnection(AETestConnectionString, AEInfo);
SQLServerStatement stmt = (SQLServerStatement) con.createStatement()) {
+ String sql = "";
+ for (int i = 0; i < table.length; i++) {
+ sql += ColumnType.PLAIN.name() + table[i][0] + " " + table[i][1] + " NULL,";
+ sql += ColumnType.DETERMINISTIC.name() + table[i][0] + " " + table[i][1]
+ + String.format(encryptSql, ColumnType.DETERMINISTIC.name(), cekName) + ") NULL,";
+ sql += ColumnType.RANDOMIZED.name() + table[i][0] + " " + table[i][1]
+ + String.format(encryptSql, ColumnType.RANDOMIZED.name(), cekName) + ") NULL,";
+ }
+ sql = String.format(createSql, AbstractSQLGenerator.escapeIdentifier(tableName), sql);
stmt.execute(sql);
stmt.execute("DBCC FREEPROCCACHE");
} catch (SQLException e) {
@@ -310,60 +310,33 @@ protected void createDateTable() throws SQLException {
}
}
- /**
- * Create encrypted table for Date with precision
- *
- * @throws SQLException
- */
- protected void createDatePrecisionTable(int scale) throws SQLException {
- String sql = "create table " + AbstractSQLGenerator.escapeIdentifier(Constants.DATE_TABLE_AE) + " ("
- // 1
- + "PlainDatetime2 datetime2(" + scale + ") null," + "RandomizedDatetime2 datetime2(" + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL," + "DeterministicDatetime2 datetime2(" + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- // 4
- + "PlainDatetime2Default datetime2 null,"
- + "RandomizedDatetime2Default datetime2 ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDatetime2Default datetime2 ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- // 7
- + "PlainDatetimeoffsetDefault datetimeoffset null,"
- + "RandomizedDatetimeoffsetDefault datetimeoffset ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDatetimeoffsetDefault datetimeoffset ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- // 10
- + "PlainTimeDefault time null,"
- + "RandomizedTimeDefault time ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicTimeDefault time ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- // 13
- + "PlainTime time(" + scale + ") null," + "RandomizedTime time(" + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL," + "DeterministicTime time(" + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- // 16
- + "PlainDatetimeoffset datetimeoffset(" + scale + ") null," + "RandomizedDatetimeoffset datetimeoffset("
- + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL," + "DeterministicDatetimeoffset datetimeoffset(" + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + ");";
-
+ protected static void createPrecisionTable(String tableName, String table[][], String cekName, int floatPrecision,
+ int precision, int scale) throws SQLException {
try (SQLServerConnection con = (SQLServerConnection) PrepUtil.getConnection(AETestConnectionString, AEInfo);
SQLServerStatement stmt = (SQLServerStatement) con.createStatement()) {
+ String sql = "";
+ for (int i = 0; i < table.length; i++) {
+ if ("float" == table[i][1]) {
+ sql += ColumnType.PLAIN.name() + table[i][0] + "Precision " + table[i][1] + "(" + floatPrecision
+ + ") NULL,";
+ sql += ColumnType.RANDOMIZED.name() + table[i][0] + "Precision " + table[i][1] + "("
+ + floatPrecision + ") " + String.format(encryptSql, ColumnType.RANDOMIZED.name(), cekName)
+ + ") NULL,";
+ sql += ColumnType.DETERMINISTIC.name() + table[i][0] + "Precision " + table[i][1] + "("
+ + floatPrecision + ") "
+ + String.format(encryptSql, ColumnType.DETERMINISTIC.name(), cekName) + ") NULL,";
+ } else {
+ sql += ColumnType.PLAIN.name() + table[i][0] + "Precision " + table[i][1] + "(" + precision + ","
+ + scale + ") NULL,";
+ sql += ColumnType.RANDOMIZED.name() + table[i][0] + "Precision " + table[i][1] + "(" + precision
+ + "," + scale + ") " + String.format(encryptSql, ColumnType.RANDOMIZED.name(), cekName)
+ + ") NULL,";
+ sql += ColumnType.DETERMINISTIC.name() + table[i][0] + "Precision " + table[i][1] + "(" + precision
+ + "," + scale + ") " + String.format(encryptSql, ColumnType.DETERMINISTIC.name(), cekName)
+ + ") NULL,";
+ }
+ }
+ sql = String.format(createSql, AbstractSQLGenerator.escapeIdentifier(tableName), sql);
stmt.execute(sql);
stmt.execute("DBCC FREEPROCCACHE");
} catch (SQLException e) {
@@ -371,188 +344,27 @@ protected void createDatePrecisionTable(int scale) throws SQLException {
}
}
- /**
- * Create encrypted table for Date with scale
- *
- * @throws SQLException
- */
- protected static void createDateScaleTable() throws SQLException {
- String sql = "create table " + AbstractSQLGenerator.escapeIdentifier(Constants.SCALE_DATE_TABLE_AE) + " ("
-
- + "PlainDatetime2 datetime2(2) null,"
- + "RandomizedDatetime2 datetime2(2) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDatetime2 datetime2(2) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainTime time(2) null,"
- + "RandomizedTime time(2) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicTime time(2) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainDatetimeoffset datetimeoffset(2) null,"
- + "RandomizedDatetimeoffset datetimeoffset(2) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDatetimeoffset datetimeoffset(2) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + ");";
-
+ protected static void createScaleTable(String tableName, String table[][], String cekName,
+ int scale) throws SQLException {
try (SQLServerConnection con = (SQLServerConnection) PrepUtil.getConnection(AETestConnectionString, AEInfo);
SQLServerStatement stmt = (SQLServerStatement) con.createStatement()) {
- stmt.execute(sql);
- stmt.execute("DBCC FREEPROCCACHE");
- } catch (SQLException e) {
- fail(e.getMessage());
- }
- }
+ String sql = "";
+ for (int i = 0; i < table.length; i++) {
- /**
- * Create encrypted table for Numeric
- *
- * @throws SQLException
- */
- protected static void createNumericTable() throws SQLException {
- String sql = "create table " + AbstractSQLGenerator.escapeIdentifier(Constants.NUMERIC_TABLE_AE) + " ("
- + "PlainBit bit null,"
- + "RandomizedBit bit ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicBit bit ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainTinyint tinyint null,"
- + "RandomizedTinyint tinyint ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicTinyint tinyint ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainSmallint smallint null,"
- + "RandomizedSmallint smallint ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicSmallint smallint ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainInt int null,"
- + "RandomizedInt int ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicInt int ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainBigint bigint null,"
- + "RandomizedBigint bigint ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicBigint bigint ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainFloatDefault float null,"
- + "RandomizedFloatDefault float ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicFloatDefault float ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainFloat float(30) null,"
- + "RandomizedFloat float(30) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicFloat float(30) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainReal real null,"
- + "RandomizedReal real ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicReal real ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainDecimalDefault decimal null,"
- + "RandomizedDecimalDefault decimal ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDecimalDefault decimal ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainDecimal decimal(10,5) null,"
- + "RandomizedDecimal decimal(10,5) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDecimal decimal(10,5) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainNumericDefault numeric null,"
- + "RandomizedNumericDefault numeric ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicNumericDefault numeric ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainNumeric numeric(8,2) null,"
- + "RandomizedNumeric numeric(8,2) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicNumeric numeric(8,2) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainSmallMoney smallmoney null,"
- + "RandomizedSmallMoney smallmoney ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicSmallMoney smallmoney ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainMoney money null,"
- + "RandomizedMoney money ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicMoney money ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainDecimal2 decimal(28,4) null,"
- + "RandomizedDecimal2 decimal(28,4) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicDecimal2 decimal(28,4) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainNumeric2 numeric(28,4) null,"
- + "RandomizedNumeric2 numeric(28,4) ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
- + "DeterministicNumeric2 numeric(28,4) ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + ");";
-
- try (SQLServerConnection con = (SQLServerConnection) PrepUtil.getConnection(AETestConnectionString, AEInfo);
- SQLServerStatement stmt = (SQLServerStatement) con.createStatement()) {
- stmt.execute(sql);
- stmt.execute("DBCC FREEPROCCACHE");
- } catch (SQLException e) {
- fail(e.getMessage());
- }
- }
+ sql += ColumnType.PLAIN.name() + table[i][0] + "Scale " + table[i][1] + "(" + scale + ") NULL,";
+ sql += ColumnType.RANDOMIZED.name() + table[i][0] + "Scale " + table[i][1] + "(" + scale + ") "
+ + String.format(encryptSql, ColumnType.RANDOMIZED.name(), cekName) + ") NULL,";
+ sql += ColumnType.DETERMINISTIC.name() + table[i][0] + "Scale " + table[i][1] + "(" + scale + ") "
+ + String.format(encryptSql, ColumnType.DETERMINISTIC.name(), cekName) + ") NULL,";
- /**
- * Create encrypted table for Numeric with precision
- *
- * @throws SQLException
- */
- protected void createNumericPrecisionTable(int floatPrecision, int precision, int scale) throws SQLException {
- String sql = "create table " + AbstractSQLGenerator.escapeIdentifier(Constants.NUMERIC_TABLE_AE) + " ("
- + "PlainFloat float(" + floatPrecision + ") null," + "RandomizedFloat float(" + floatPrecision
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL," + "DeterministicFloat float(" + floatPrecision
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainDecimal decimal(" + precision + "," + scale + ") null," + "RandomizedDecimal decimal("
- + precision + "," + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL," + "DeterministicDecimal decimal(" + precision + "," + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL,"
-
- + "PlainNumeric numeric(" + precision + "," + scale + ") null," + "RandomizedNumeric numeric("
- + precision + "," + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL," + "DeterministicNumeric numeric(" + precision + "," + scale
- + ") ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
- + Constants.CEK_NAME + ") NULL"
-
- + ");";
+ sql += ColumnType.PLAIN.name() + table[i][0] + " " + table[i][1] + " NULL,";
+ sql += ColumnType.RANDOMIZED.name() + table[i][0] + " " + table[i][1]
+ + String.format(encryptSql, ColumnType.RANDOMIZED.name(), cekName) + ") NULL,";
+ sql += ColumnType.DETERMINISTIC.name() + table[i][0] + " " + table[i][1]
+ + String.format(encryptSql, ColumnType.DETERMINISTIC.name(), cekName) + ") NULL,";
+ }
- try (SQLServerConnection con = (SQLServerConnection) PrepUtil.getConnection(AETestConnectionString, AEInfo);
- SQLServerStatement stmt = (SQLServerStatement) con.createStatement()) {
+ sql = String.format(createSql, AbstractSQLGenerator.escapeIdentifier(tableName), sql);
stmt.execute(sql);
stmt.execute("DBCC FREEPROCCACHE");
} catch (SQLException e) {
@@ -673,13 +485,15 @@ protected static LinkedList