Skip to content

Commit

Permalink
Merge branch 'main' into ignoreSystemJaas
Browse files Browse the repository at this point in the history
  • Loading branch information
tkyc authored Sep 27, 2023
2 parents 39ec87b + 2799c6c commit f753702
Show file tree
Hide file tree
Showing 47 changed files with 885 additions and 485 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/)

## [12.4.0] Stable Release
### Fixed issues
- Revert #2051 (Big decimal precision) / #2116 (Fix for bigDecimal values between 0 and 1 having too high of a precision) [#2176](https://github.com/microsoft/mssql-jdbc/pull/2176)
- Fixed server certificate validation for encrypt=strict [#2174](https://github.com/microsoft/mssql-jdbc/pull/2174)
- Fixed issues identified by SonarQube [#2145](https://github.com/microsoft/mssql-jdbc/pull/2145)

## [12.3.1] Preview Release
### Added
- Added a case to throw XAER_RMFAIL on connection reset for XA transactions [2118](https://github.com/microsoft/mssql-jdbc/pull/2118)
Expand Down
29 changes: 13 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,13 @@ The Microsoft JDBC Driver for SQL Server is a Type 4 JDBC driver that provides d

We hope you enjoy using the Microsoft JDBC Driver for SQL Server.

SQL Server Team
Microsoft JDBC driver for SQL Server Team

## Take our survey

Let us know how you think we're doing.

<a href="https://aka.ms/mssqljdbcsurvey"><img style="float: right;" height="67" width="156" src="https://sqlchoice.blob.core.windows.net/sqlchoice/static/images/survey.png"></a>
<a href="https://aka.ms/mssqljdbcsurvey"><img style="float: right;" height="50" width="125" src="https://img.shields.io/badge/Survey-70B244"></a>

## Status of Most Recent Builds
| Azure Pipelines (Windows) | Azure Pipelines (Linux) | Azure Pipelines (MacOS) |
Expand All @@ -28,10 +28,7 @@ Let us know how you think we're doing.
What's coming next? We will look into adding a more comprehensive set of tests, improving our javadocs, and start developing the next set of features.

## Get Started
* [**Ubuntu + SQL Server + Java**](https://www.microsoft.com/en-us/sql-server/developer-get-started/java/ubuntu)
* [**Red Hat + SQL Server + Java**](https://www.microsoft.com/en-us/sql-server/developer-get-started/java/rhel)
* [**Mac + SQL Server + Java**](https://www.microsoft.com/en-us/sql-server/developer-get-started/java/mac)
* [**Windows + SQL Server + Java**](https://www.microsoft.com/en-us/sql-server/developer-get-started/java/windows)
[**Getting started with SQL Server and Java**](https://github.com/AzureSQLDB/sql-driver-examples/blob/main/examples/sql/drivers/java-driver-example.md)

## Build
### Prerequisites
Expand Down Expand Up @@ -82,7 +79,7 @@ We're now on the Maven Central Repository. Add the following to your POM file to
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.2.0.jre11</version>
<version>12.4.0.jre11</version>
</dependency>
```
The driver can be downloaded from [Microsoft](https://aka.ms/downloadmssqljdbc).
Expand All @@ -93,7 +90,7 @@ To get the latest version of the driver, add the following to your POM file:
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.2.0.jre11</version>
<version>12.4.0.jre11</version>
</dependency>
```

Expand Down Expand Up @@ -128,7 +125,7 @@ Projects that require either of the two features need to explicitly declare the
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.2.0.jre11</version>
<version>12.4.0.jre11</version>
<scope>compile</scope>
</dependency>

Expand All @@ -146,7 +143,7 @@ Projects that require either of the two features need to explicitly declare the
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.2.0.jre11</version>
<version>12.4.0.jre11</version>
<scope>compile</scope>
</dependency>

Expand All @@ -173,7 +170,7 @@ When setting 'useFmtOnly' property to 'true' for establishing a connection or cr
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.2.0.jre11</version>
<version>12.4.0.jre11</version>
</dependency>

<dependency>
Expand Down Expand Up @@ -213,7 +210,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, 8.2, 8.4, 9.2, 9.4, 10.2, 11.2, 12.2. Preview versions have an odd minor version. For example, 6.1, 6.3, 6.5, 7.1, 7.3, 8.1, 9.1, 10.1, 11.1, 12.1, 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, 8.2, 8.4, 9.2, 9.4, 10.2, 11.2, 12.2, 12.4. Preview versions have an odd minor version. For example, 6.1, 6.3, 6.5, 7.1, 7.3, 8.1, 9.1, 10.1, 11.1, 12.1, 12.3, and so on.

## Contributors
Special thanks to everyone who has contributed to the project.
Expand All @@ -229,13 +226,13 @@ Here are our Top 15 contributors from the community:
- simon04 (Simon Legner)
- gstojsic
- cosmofrit
- harawata- shayaantx
- (Iwao AVE!)
- nsidhaye (Nikhil Sidhaye)
- mmimica (Milan Mimica)
- harawata (Iwao AVE!)
- rPraml (Roland Praml)
- laeubi (Christoph Laubrich)
- worldtiki (Daniel Albuquerque)
- shayaantx
- mfriesen (Mike Friesen)
- mnhubspot


## License
Expand Down
5 changes: 3 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@

apply plugin: 'java'

version = '12.4.0-SNAPSHOT'
version = '12.5.0-SNAPSHOT'
def releaseExt = '-preview'
def jreVersion = ""
def testOutputDir = file("build/classes/java/test")
def archivesBaseName = 'mssql-jdbc'
Expand Down Expand Up @@ -85,7 +86,7 @@ if(hasProperty('buildProfile') && buildProfile == "jre8") {
}
}

jar.archiveFileName = "${archivesBaseName}-${version}.${jreVersion}-preview.jar"
jar.archiveFileName = "${archivesBaseName}-${version}.${jreVersion}${releaseExt}.jar"
jar {
manifest {
attributes 'Title': "Microsoft JDBC Driver ${archiveVersion} for SQL Server",
Expand Down
21 changes: 11 additions & 10 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
<version>12.4.0-SNAPSHOT</version>
<version>12.5.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>Microsoft JDBC Driver for SQL Server</name>
<description>
Expand Down Expand Up @@ -37,7 +37,8 @@
xSQLv11 - - - - - - For tests not compatible with SQL Server 2012 - - - -
xSQLv12 - - - - - - For tests not compatible with SQL Server 2008 R2 - 2014
xSQLv14 - - - - - - For tests not compatible with SQL Server 2016 - 2017
xSQLv15 - - - - - - For tests not compatible with SQL Server 2019 - - - -
xSQLv15 - - - - - - For tests not compatible with SQL Server 2019 - - - -
xSQLv16 - - - - - - For tests not compatible with SQL Server 2022 - - - -
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
Expand All @@ -53,22 +54,22 @@
<releaseExt>-preview</releaseExt>
<!-- Driver Dependencies -->
<org.osgi.core.version>6.0.0</org.osgi.core.version>
<azure-security-keyvault-keys.version>4.6.1</azure-security-keyvault-keys.version>
<azure-security-keyvault-keys.version>4.6.4</azure-security-keyvault-keys.version>
<azure-identity.version>1.9.0</azure-identity.version>
<msal.version>1.13.8</msal.version>
<osgi.jdbc.version>1.1.0</osgi.jdbc.version>
<antlr-runtime.version>4.9.3</antlr-runtime.version>
<com.google.code.gson.version>2.10.1</com.google.code.gson.version>
<bcprov-jdk15on.version>1.70</bcprov-jdk15on.version>
<bcpkix-jdk15on.version>1.70</bcpkix-jdk15on.version>
<bcprov-jdk18on.version>1.76</bcprov-jdk18on.version>
<bcpkix-jdk18on.version>1.76</bcpkix-jdk18on.version>
<!-- JUnit Test Dependencies -->
<junit.platform.version>[1.3.2, 1.9.0]</junit.platform.version>
<junit.jupiter.version>5.8.2</junit.jupiter.version>
<hikaricp.version>3.4.2</hikaricp.version>
<dbcp2.version>2.7.0</dbcp2.version>
<slf4j.nop.version>1.7.30</slf4j.nop.version>
<gemini.mock.version>2.1.0.RELEASE</gemini.mock.version>
<h2.version>2.1.214</h2.version>
<h2.version>2.2.220</h2.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>${project.build.sourceEncoding}</project.reporting.outputEncoding>
<enforcer.skip>false</enforcer.skip>
Expand Down Expand Up @@ -114,15 +115,15 @@
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>${bcprov-jdk15on.version}</version>
<artifactId>bcprov-jdk18on</artifactId>
<version>${bcprov-jdk18on.version}</version>
<optional>true</optional>
</dependency>
<!-- dependencies for Client Certificate Authentication -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>${bcpkix-jdk15on.version}</version>
<artifactId>bcpkix-jdk18on</artifactId>
<version>${bcpkix-jdk18on.version}</version>
<optional>true</optional>
</dependency>
<!-- dependencies provided by an OSGi-Framework -->
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/microsoft/sqlserver/jdbc/DataTypes.java
Original file line number Diff line number Diff line change
Expand Up @@ -1115,7 +1115,7 @@ private DataTypes() {
static final void throwConversionError(String fromType, String toType) throws SQLServerException {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_unsupportedConversionFromTo"));
Object[] msgArgs = {fromType, toType};
SQLServerException.makeFromDriverError(null, null, form.format(msgArgs), null, true);
SQLServerException.makeFromDriverError(null, null, form.format(msgArgs), SQLState.ERROR_IN_ASSIGNMENT.getSQLStateCode(), true);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -1693,7 +1693,7 @@ else if (con.getTrustManagerClass() != null) {
// Otherwise, we'll validate the certificate using a real TrustManager obtained
// from the a security provider that is capable of validating X.509 certificates.
else {
if (isTDS8) {
if (isTDS8 && serverCert != null) {
if (logger.isLoggable(Level.FINEST))
logger.finest(toString() + " Verify server certificate for TDS 8");

Expand Down
31 changes: 2 additions & 29 deletions src/main/java/com/microsoft/sqlserver/jdbc/Parameter.java
Original file line number Diff line number Diff line change
Expand Up @@ -531,36 +531,9 @@ private void setTypeDefinition(DTV dtv) {
param.typeDefinition = SSType.DECIMAL.toString() + "(" + valueLength + "," + scale + ")";
}
} else {
if (dtv.getJavaType() == JavaType.BIGDECIMAL && null != dtv.getSetterValue()) {
String[] plainValueArray
= ((BigDecimal) dtv.getSetterValue()).abs().toPlainString().split("\\.");

// Precision is computed as opposed to using BigDecimal.precision(). This is because the
// BigDecimal method can lead to inaccurate results.
int calculatedPrecision;

// If the string array has two parts, e.g .the input was a decimal, check if the first
// part is a 0. For BigDecimals with leading zeroes, the leading zero does not count towards
// precision. For all other decimals, we include the integer portion as part of the precision
// When the string array has just one part, we only look at that part to compute precision.
if (plainValueArray.length == 2) {
if (plainValueArray[0].length() == 1 && (Integer.parseInt(plainValueArray[0]) == 0)) {
calculatedPrecision = plainValueArray[1].length();
} else {
calculatedPrecision = plainValueArray[0].length() + plainValueArray[1].length();
}
} else {
calculatedPrecision = plainValueArray[0].length();
}

param.typeDefinition = SSType.DECIMAL.toString() + "(" + calculatedPrecision + "," +
(plainValueArray.length == 2 ? plainValueArray[1].length() : 0) + ")";
} else {
param.typeDefinition = SSType.DECIMAL.toString() + "("
+ SQLServerConnection.MAX_DECIMAL_PRECISION + "," + scale + ")";
}
param.typeDefinition = SSType.DECIMAL.toString() + "("
+ SQLServerConnection.MAX_DECIMAL_PRECISION + "," + scale + ")";
}

break;

case MONEY:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

final class SQLJdbcVersion {
static final int MAJOR = 12;
static final int MINOR = 4;
static final int MINOR = 5;
static final int PATCH = 0;
static final int BUILD = 0;
/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -281,9 +281,8 @@ static void validateServerNameInCertificate(X509Certificate cert, String hostNam
*/
static void validateServerCerticate(X509Certificate cert, String certFile) throws CertificateException {
try (InputStream is = fileToStream(certFile)) {
if (!CertificateFactory.getInstance("X509").generateCertificate(is).getPublicKey()
.equals(cert.getPublicKey())) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_publicKeyMismatch"));
if (!CertificateFactory.getInstance("X509").generateCertificate(is).equals(cert)) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_serverCertError"));
Object[] msgArgs = {certFile};
throw new CertificateException(form.format(msgArgs));
}
Expand Down Expand Up @@ -353,8 +352,7 @@ static KeyManager[] readPKCS8Certificate(String certPath, String keyPath,
}

private static KeyManager[] readPKCS12Certificate(String certPath,
String keyPassword) throws NoSuchAlgorithmException, CertificateException, IOException,
UnrecoverableKeyException, KeyStoreException, SQLServerException {
String keyPassword) throws NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, KeyStoreException, SQLServerException {

KeyStore keyStore = loadPKCS12KeyStore(certPath, keyPassword);
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(SUN_X_509);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ public byte[] decryptColumnEncryptionKey(String masterKeyPath, String encryption
// Validate the signature
if (!azureKeyVaultVerifySignature(dataToVerify, signature, masterKeyPath)) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_CEKSignatureNotMatchCMK"));
Object[] msgArgs = {masterKeyPath};
Object[] msgArgs = {Util.byteToHexDisplayString(signature), masterKeyPath};
throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
}

Expand Down Expand Up @@ -876,6 +876,9 @@ public boolean verifyColumnMasterKeyMetadata(String masterKeyPath, boolean allow
return cmkMetadataSignatureVerificationCache.get(key);
}

byte[] signedHash = null;
boolean isValid = false;

try {
MessageDigest md = MessageDigest.getInstance(SHA_256);
md.update(name.toLowerCase().getBytes(java.nio.charset.StandardCharsets.UTF_16LE));
Expand All @@ -889,19 +892,65 @@ public boolean verifyColumnMasterKeyMetadata(String masterKeyPath, boolean allow
}

// Sign the hash
byte[] signedHash = azureKeyVaultSignHashedData(dataToVerify, masterKeyPath);
signedHash = azureKeyVaultSignHashedData(dataToVerify, masterKeyPath);
if (null == signedHash) {
throw new SQLServerException(SQLServerException.getErrString("R_SignedHashLengthError"), null);
}

// Validate the signature
boolean isValid = azureKeyVaultVerifySignature(dataToVerify, signature, masterKeyPath);
isValid = azureKeyVaultVerifySignature(dataToVerify, signature, masterKeyPath);
cmkMetadataSignatureVerificationCache.put(key, isValid);
} catch (NoSuchAlgorithmException e) {
throw new SQLServerException(SQLServerException.getErrString("R_NoSHA256Algorithm"), e);
} catch (SQLServerException e) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_SignatureNotMatch"));
Object[] msgArgs = {Util.byteToHexDisplayString(signature),
(signedHash != null) ? Util.byteToHexDisplayString(signedHash) : " ", masterKeyPath,
": " + e.getMessage()};
throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
}

if (!isValid) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_SignatureNotMatch"));
Object[] msgArgs = {Util.byteToHexDisplayString(signature), Util.byteToHexDisplayString(signedHash),
masterKeyPath, ""};
throw new SQLServerException(this, form.format(msgArgs), null, 0, false);
}
return isValid;
}

public byte[] signColumnMasterKeyMetadata(String masterKeyPath,
boolean allowEnclaveComputations) throws SQLServerException {
if (!allowEnclaveComputations) {
return null;
}

KeyStoreProviderCommon.validateNonEmptyMasterKeyPath(masterKeyPath);

byte[] signedHash = null;
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);
}

return isValid;
// Sign the hash
signedHash = azureKeyVaultSignHashedData(dataToVerify, masterKeyPath);
} catch (NoSuchAlgorithmException e) {
throw new SQLServerException(SQLServerException.getErrString("R_NoSHA256Algorithm"), e);
}

if (null == signedHash) {
throw new SQLServerException(SQLServerException.getErrString("R_SignedHashLengthError"), null);
}

return signedHash;
}

private static List<String> getTrustedEndpoints() {
Expand Down
Loading

0 comments on commit f753702

Please sign in to comment.