Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues detected by SonarQube #1739

Merged
merged 4 commits into from
Jan 24, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 22 additions & 21 deletions src/main/java/com/microsoft/sqlserver/jdbc/AE.java
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ short getOrdinal() {
encryptionKeyInfo = null;
}

boolean IsAlgorithmInitialized() {
boolean isAlgorithmInitialized() {
return null != cipherAlgorithm;
}
}
Expand All @@ -234,17 +234,17 @@ boolean IsAlgorithmInitialized() {
// We expect the server to return the fields in the resultset in the same order as mentioned below.
// If the server changes the below order, then transparent parameter encryption will break.
enum DescribeParameterEncryptionResultSet1 {
KeyOrdinal,
DbId,
KeyId,
KeyVersion,
KeyMdVersion,
EncryptedKey,
ProviderName,
KeyPath,
KeyEncryptionAlgorithm,
IsRequestedByEnclave,
EnclaveCMKSignature;
KEYORDINAL,
DBID,
KEYID,
KEYVERSION,
KEYMDVERSION,
ENCRYPTEDKEY,
PROVIDERNAME,
KEYPATH,
KEYENCRYPTIONALGORITHM,
ISREQUESTEDBYENCLAVE,
ENCLAVECMKSIGNATURE;

int value() {
// Column indexing starts from 1;
Expand All @@ -257,23 +257,24 @@ int value() {
// We expect the server to return the fields in the resultset in the same order as mentioned below.
// If the server changes the below order, then transparent parameter encryption will break.
enum DescribeParameterEncryptionResultSet2 {
ParameterOrdinal,
ParameterName,
ColumnEncryptionAlgorithm,
ColumnEncrytionType,
ColumnEncryptionKeyOrdinal,
NormalizationRuleVersion;
PARAMETERORDINAL,
PARAMETERNAME,
COLUMNENCRYPTIONALGORITHM,
COLUMNENCRYPTIONTYPE,
COLUMNENCRYPTIONKEYORDINAL,
NORMALIZATIONRULEVERSION;

int value() {
// Column indexing starts from 1;
return ordinal() + 1;
}
}


enum ColumnEncryptionVersion {
AE_NotSupported,
AE_v1,
AE_v2;
AE_NOTSUPPORTED,
AE_V1,
AE_V2;

int value() {
// Column indexing starts from 1;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

package com.microsoft.sqlserver.jdbc;

import java.lang.reflect.Array;
import java.text.MessageFormat;
import java.util.logging.Level;

Expand All @@ -25,12 +24,12 @@ class FedAuthDllInfo {
* Encapsulation of the JNI native calls for trusted authentication.
*/
final class AuthenticationJNI extends SSPIAuthentication {
private static final int maximumpointersize = 128; // we keep the SNI_Sec pointer
private static final int MAXPOINTERSIZE = 128; // we keep the SNI_Sec pointer
private static boolean enabled = false;
private static java.util.logging.Logger authLogger = java.util.logging.Logger
.getLogger("com.microsoft.sqlserver.jdbc.internals.AuthenticationJNI");
private static int sspiBlobMaxlen = 0;
private byte[] sniSec = new byte[maximumpointersize];
private byte[] sniSec = new byte[MAXPOINTERSIZE];
private int[] sniSecLen = {0};
private final String dnsName;
private final int port;
Expand Down
36 changes: 25 additions & 11 deletions src/main/java/com/microsoft/sqlserver/jdbc/IOBuffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -5645,15 +5645,6 @@ void writeRPCByteArray(String sName, byte bValue[], boolean bOut, JDBCType jdbcT
collation = null;
} else
switch (jdbcType) {
case BINARY:
case VARBINARY:
case LONGVARBINARY:
case BLOB:
default:
tdsType = (isShortValue || usePLP) ? TDSType.BIGVARBINARY : TDSType.IMAGE;
collation = null;
break;

case CHAR:
case VARCHAR:
case LONGVARCHAR:
Expand All @@ -5671,6 +5662,15 @@ void writeRPCByteArray(String sName, byte bValue[], boolean bOut, JDBCType jdbcT
if (null == collation)
collation = con.getDatabaseCollation();
break;

case BINARY:
case VARBINARY:
case LONGVARBINARY:
case BLOB:
default:
tdsType = (isShortValue || usePLP) ? TDSType.BIGVARBINARY : TDSType.IMAGE;
collation = null;
break;
}

writeRPCNameValType(sName, bOut, tdsType);
Expand Down Expand Up @@ -6366,6 +6366,13 @@ byte[] writeEncryptedScaledTemporal(GregorianCalendar cal, int subSecondNanos, i
System.arraycopy(encodedNanoBytes, 0, encodedBytesForEncryption, 0, encodedNanoBytes.length);
}
}

if (encodedBytesForEncryption == null) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_NullValue"));
Object[] msgArgs1 = {"encodedBytesForEncryption"};
throw new SQLServerException(form.format(msgArgs1), null);
}

// Copy the 3 byte date value
System.arraycopy(encodedBytes, 0, encodedBytesForEncryption, (encodedBytesForEncryption.length - 3), 3);

Expand All @@ -6388,6 +6395,12 @@ byte[] writeEncryptedScaledTemporal(GregorianCalendar cal, int subSecondNanos, i
}
}

if (encodedBytesForEncryption == null) {
MessageFormat form = new MessageFormat(SQLServerException.getErrString("R_NullValue"));
Object[] msgArgs1 = {"encodedBytesForEncryption"};
throw new SQLServerException(form.format(msgArgs1), null);
}

// Copy the 3 byte date value
System.arraycopy(encodedBytes, 0, encodedBytesForEncryption, (encodedBytesForEncryption.length - 5), 3);
// Copy the 2 byte minutesOffset value
Expand Down Expand Up @@ -6949,7 +6962,7 @@ synchronized final boolean readPacket() throws SQLServerException {
lastPacket = newPacket;

// When logging, append the payload to the log buffer and write out the whole thing.
if (tdsChannel.isLoggingPackets()) {
if (tdsChannel.isLoggingPackets() && logBuffer != null) {
System.arraycopy(newPacket.payload, 0, logBuffer, TDS.PACKET_HEADER_SIZE, newPacket.payloadLength);
tdsChannel.logPacket(logBuffer, 0, packetLength,
this.toString() + " received Packet:" + packetNum + " (" + newPacket.payloadLength + " bytes)");
Expand Down Expand Up @@ -7542,7 +7555,8 @@ protected void interrupt() throws Exception {
} else {
// If the timer wasn't canceled before it ran out of
// time then interrupt the registered command.
command.interrupt(SQLServerException.getErrString("R_queryTimedOut"));
if (null != command)
command.interrupt(SQLServerException.getErrString("R_queryTimedOut"));
}
} catch (SQLServerException e) {
// Request failed to time out and SQLServerConnection does not exist
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,59 +180,61 @@ default ResultSet executeSDPEv1(PreparedStatement stmt, String userSql,
* if error
*/
default void processSDPEv1(String userSql, String preparedTypeDefinitions, Parameter[] params,
ArrayList<String> parameterNames, SQLServerConnection connection, SQLServerStatement sqlServerStatement, PreparedStatement stmt, ResultSet rs,
ArrayList<byte[]> enclaveRequestedCEKs) throws SQLException {
ArrayList<String> parameterNames, SQLServerConnection connection, SQLServerStatement sqlServerStatement,
PreparedStatement stmt, ResultSet rs, ArrayList<byte[]> enclaveRequestedCEKs) throws SQLException {
Map<Integer, CekTableEntry> cekList = new HashMap<>();
CekTableEntry cekEntry = null;
boolean isRequestedByEnclave = false;
SQLServerStatement statement = (SQLServerStatement) ((SQLServerPreparedStatement) stmt);

if (null != sqlServerStatement && sqlServerStatement.hasColumnEncryptionKeyStoreProvidersRegistered()) {
statement.registerColumnEncryptionKeyStoreProvidersOnStatement(sqlServerStatement.statementColumnEncryptionKeyStoreProviders);
statement.registerColumnEncryptionKeyStoreProvidersOnStatement(
sqlServerStatement.statementColumnEncryptionKeyStoreProviders);
}

while (rs.next()) {
int currentOrdinal = rs.getInt(DescribeParameterEncryptionResultSet1.KeyOrdinal.value());
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());
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());
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()),
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()) {
if (ColumnEncryptionVersion.AE_V2.value() <= connection.getServerColumnEncryptionVersion().value()) {
isRequestedByEnclave = rs
.getBoolean(DescribeParameterEncryptionResultSet1.IsRequestedByEnclave.value());
.getBoolean(DescribeParameterEncryptionResultSet1.ISREQUESTEDBYENCLAVE.value());
}

if (isRequestedByEnclave) {
byte[] keySignature = rs.getBytes(DescribeParameterEncryptionResultSet1.EnclaveCMKSignature.value());
byte[] keySignature = rs.getBytes(DescribeParameterEncryptionResultSet1.ENCLAVECMKSIGNATURE.value());
String serverName = connection.getTrustedServerNameAE();
SQLServerSecurityUtility.verifyColumnMasterKeyMetadata(connection, statement, keyStoreName, keyPath, serverName,
isRequestedByEnclave, keySignature);
SQLServerSecurityUtility.verifyColumnMasterKeyMetadata(connection, statement, 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);

SQLServerColumnEncryptionKeyStoreProvider provider = SQLServerSecurityUtility.getColumnEncryptionKeyStoreProvider(keyStoreName, connection, statement);
SQLServerColumnEncryptionKeyStoreProvider provider = SQLServerSecurityUtility
.getColumnEncryptionKeyStoreProvider(keyStoreName, connection, statement);
aev2CekEntry.put(provider.decryptColumnEncryptionKey(keyPath, algo, encryptedKey));
enclaveRequestedCEKs.add(aev2CekEntry.array());
}
Expand All @@ -244,35 +246,36 @@ default void processSDPEv1(String userSql, String preparedTypeDefinitions, Param
0, false);
}

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_InvalidEncryptionKeyOrdinal"));
Object[] msgArgs = {cekOrdinal, cekEntry.getSize()};
throw new SQLServerException(null, 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, statement);
} else {
if (params[paramIndex].getForceEncryption()) {
try (ResultSet rs2 = stmt.getResultSet()) {
while (rs2.next() && null != params) {
String paramName = rs2.getString(DescribeParameterEncryptionResultSet2.PARAMETERNAME.value());
int paramIndex = parameterNames.indexOf(paramName);
int cekOrdinal = rs2.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_ForceEncryptionTrue_HonorAETrue_UnencryptedColumn"));
Object[] msgArgs = {userSql, paramIndex + 1};
SQLServerException.makeFromDriverError(null, connection, form.format(msgArgs), "0", true);
SQLServerException.getErrString("R_InvalidEncryptionKeyOrdinal"));
Object[] msgArgs = {cekOrdinal, cekEntry.getSize()};
throw new SQLServerException(null, form.format(msgArgs), null, 0, false);
}
SQLServerEncryptionType encType = SQLServerEncryptionType
.of((byte) rs2.getInt(DescribeParameterEncryptionResultSet2.COLUMNENCRYPTIONTYPE.value()));
if (SQLServerEncryptionType.PlainText != encType) {
params[paramIndex].cryptoMeta = new CryptoMetadata(cekEntry, (short) cekOrdinal,
(byte) rs2.getInt(DescribeParameterEncryptionResultSet2.COLUMNENCRYPTIONALGORITHM.value()),
null, encType.value,
(byte) rs2.getInt(DescribeParameterEncryptionResultSet2.NORMALIZATIONRULEVERSION.value()));
// Decrypt the symmetric key.(This will also validate and throw if needed).
SQLServerSecurityUtility.decryptSymmetricKey(params[paramIndex].cryptoMeta, connection, statement);
} else {
if (params[paramIndex].getForceEncryption()) {
MessageFormat form = new MessageFormat(
SQLServerException.getErrString("R_ForceEncryptionTrue_HonorAETrue_UnencryptedColumn"));
Object[] msgArgs = {userSql, paramIndex + 1};
SQLServerException.makeFromDriverError(null, connection, form.format(msgArgs), "0", true);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ void updateSessionState(TDSReader tdsReader, short sessionStateId, int sessionSt
} else {
// Not a first time state update hence if only there is a transition in state do we update the count.
if (fRecoverable != sessionStateDelta[sessionStateId].isRecoverable()) {
if(fRecoverable)
if (fRecoverable)
unRecoverableSessionStateCount.decrementAndGet();
else
unRecoverableSessionStateCount.incrementAndGet();
Expand Down Expand Up @@ -424,6 +424,9 @@ public void run() {
Thread.sleep(con.getRetryInterval() * 1000);
}
} catch (InterruptedException ie) {
// re-interrupt thread
Thread.currentThread().interrupt();

this.eReceived = new SQLServerException(SQLServerException.getErrString("R_queryTimedOut"),
SQLState.STATEMENT_CANCELED, DriverError.NOT_SET, null);
keepRetrying = false;
Expand Down
28 changes: 14 additions & 14 deletions src/main/java/com/microsoft/sqlserver/jdbc/ParameterUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ static int scanSQLForChar(char ch, String sql, int offset) {

while (offset < len) {
switch (chTmp = sql.charAt(offset++)) {
case '[':
chTmp = ']';
case '\'':
case '"':
chQuote = chTmp;
while (offset < len) {
if (sql.charAt(offset++) == chQuote) {
if (len == offset || sql.charAt(offset) != chQuote)
break;

++offset;
}
}
break;
case '/':
if (offset == len)
break;
Expand Down Expand Up @@ -102,20 +116,6 @@ static int scanSQLForChar(char ch, String sql, int offset) {
if (ch == chTmp)
return offset - 1;
break;
case '[':
chTmp = ']';
case '\'':
case '"':
chQuote = chTmp;
while (offset < len) {
if (sql.charAt(offset++) == chQuote) {
if (len == offset || sql.charAt(offset) != chQuote)
break;

++offset;
}
}
break;
}
}

Expand Down
Loading