/* * 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.fips; import java.sql.Connection; import java.util.Properties; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import org.junit.platform.runner.JUnitPlatform; import org.junit.runner.RunWith; import com.microsoft.sqlserver.jdbc.SQLServerDataSource; import com.microsoft.sqlserver.jdbc.SQLServerException; import com.microsoft.sqlserver.jdbc.StringUtils; import com.microsoft.sqlserver.testframework.PrepUtil; import com.microsoft.sqlserver.testframework.Utils; /** * Test class for testing FIPS property settings. */ @RunWith(JUnitPlatform.class) public class FipsTest { private static String connectionString; private static String[] dataSourceProps; @BeforeAll public static void init() { connectionString = Utils.getConfiguredProperty("mssql_jdbc_test_connection_properties"); dataSourceProps = getDataSourceProperties(); } /** * Test after setting TrustServerCertificate as true. * * @throws Exception */ @Test public void fipsTrustServerCertificateTest() throws Exception { try { Properties props = buildConnectionProperties(); props.setProperty("TrustServerCertificate", "true"); Connection con = PrepUtil.getConnection(connectionString, props); Assertions.fail("It should fail as we are not passing appropriate params"); } catch (SQLServerException e) { Assertions.assertTrue( e.getMessage().contains("Could not enable FIPS due to either encrypt is not true or using trusted certificate settings."), "Should create exception for invalid TrustServerCertificate value"); } } /** * Test after passing encrypt as false. * * @throws Exception */ @Test public void fipsEncryptTest() throws Exception { try { Properties props = buildConnectionProperties(); props.setProperty("encrypt", "false"); Connection con = PrepUtil.getConnection(connectionString, props); Assertions.fail("It should fail as we are not passing appropriate params"); } catch (SQLServerException e) { Assertions.assertTrue( e.getMessage().contains("Could not enable FIPS due to either encrypt is not true or using trusted certificate settings."), "Should create exception for invalid encrypt value"); } } /** * Test after removing FIPS PROVIDER * * @throws Exception */ @Test public void fipsProviderTest() throws Exception { try { Properties props = buildConnectionProperties(); props.remove("fipsProvider"); props.setProperty("trustStore", "/SOME_PATH"); Connection con = PrepUtil.getConnection(connectionString, props); Assertions.fail("It should fail as we are not passing appropriate params"); } catch (SQLServerException e) { Assertions.assertTrue(e.getMessage().contains("Could not enable FIPS due to invalid FIPSProvider or TrustStoreType"), "Should create exception for invalid FIPSProvider"); } } /** * Test after removing fips, encrypt & trustStore it should work appropriately. * * @throws Exception */ @Test public void fipsPropertyTest() throws Exception { Properties props = buildConnectionProperties(); props.remove("fips"); props.remove("trustStoreType"); props.remove("encrypt"); Connection con = PrepUtil.getConnection(connectionString, props); Assertions.assertTrue(!StringUtils.isEmpty(con.getSchema())); con.close(); con = null; } /** * Tests after removing all FIPS related properties. * * @throws Exception */ @Test public void fipsDataSourcePropertyTest() throws Exception { SQLServerDataSource ds = new SQLServerDataSource(); setDataSourceProperties(ds); ds.setFIPS(false); ds.setFIPSProvider(""); ds.setEncrypt(false); ds.setTrustStoreType("JKS"); Connection con = ds.getConnection(); Assertions.assertTrue(!StringUtils.isEmpty(con.getSchema())); con.close(); con = null; } /** * Test after removing encrypt in FIPS Data Source. */ @Test public void fipsDatSourceEncrypt() { try { SQLServerDataSource ds = new SQLServerDataSource(); setDataSourceProperties(ds); ds.setEncrypt(false); Connection con = ds.getConnection(); Assertions.fail("It should fail as we are not passing appropriate params"); } catch (SQLServerException e) { Assertions.assertTrue( e.getMessage().contains("Could not enable FIPS due to either encrypt is not true or using trusted certificate settings."), "Should create exception for invalid encrypt value"); } } /** * Test after removing FIPS PROVIDER * * @throws Exception */ @Test public void fipsDataSourceProviderTest() throws Exception { try { SQLServerDataSource ds = new SQLServerDataSource(); setDataSourceProperties(ds); ds.setFIPSProvider(""); ds.setTrustStore("/SOME_PATH"); Connection con = ds.getConnection(); Assertions.fail("It should fail as we are not passing appropriate params"); } catch (SQLServerException e) { Assertions.assertTrue(e.getMessage().contains("Could not enable FIPS due to invalid FIPSProvider or TrustStoreType"), "Should create exception for invalid FIPSProvider"); } } /** * Test after setting TrustServerCertificate as true. * * @throws Exception */ @Test public void fipsDataSourceTrustServerCertificateTest() throws Exception { try { SQLServerDataSource ds = new SQLServerDataSource(); setDataSourceProperties(ds); ds.setTrustServerCertificate(true); Connection con = ds.getConnection(); Assertions.fail("It should fail as we are not passing appropriate params"); } catch (SQLServerException e) { Assertions.assertTrue( e.getMessage().contains("Could not enable FIPS due to either encrypt is not true or using trusted certificate settings."), "Should create exception for invalid TrustServerCertificate value"); } } /** * Setting appropriate data source properties including FIPS * @param ds */ private void setDataSourceProperties(SQLServerDataSource ds) { ds.setServerName(dataSourceProps[0]); if (dataSourceProps[1] != null && StringUtils.isInteger(dataSourceProps[1])) { ds.setPortNumber(Integer.valueOf(dataSourceProps[1])); } ds.setUser(dataSourceProps[2]); ds.setPassword(dataSourceProps[3]); ds.setDatabaseName(dataSourceProps[4]); // Set all properties for FIPS ds.setFIPS(true); ds.setEncrypt(true); ds.setTrustServerCertificate(false); ds.setIntegratedSecurity(false); ds.setTrustStoreType("PKCS12"); ds.setFIPSProvider("BCFIPS"); } /** * Build Connection properties for FIPS * * @return */ private Properties buildConnectionProperties() { Properties connectionProps = new Properties(); connectionProps.setProperty("encrypt", "true"); connectionProps.setProperty("integratedSecurity", "false"); // In case of false we need to pass keystore etc. which is not passing by default. connectionProps.setProperty("TrustServerCertificate", "false"); // For New Code connectionProps.setProperty("trustStoreType", "PKCS12"); connectionProps.setProperty("fipsProvider", "BCFIPS"); connectionProps.setProperty("fips", "true"); return connectionProps; } /** * It will return String array. [dbServer,username,password,dbname/database] * * -ea -Dmssql_jdbc_test_connection_properties=jdbc:sqlserver://SQL-2K16-01.galaxy.ad;userName=sa;password=Moonshine4me;database=test; * -Djava.library.path=C:\Downloads\sqljdbc_6.0.7728.100_enu.tar\sqljdbc_6.0\enu\auth\x64 * * @param connectionProperty * @return */ private static String[] getDataSourceProperties() { String[] params = connectionString.split(";"); String[] dataSoureParam = new String[5]; for (String strParam : params) { if (strParam.startsWith("jdbc:sqlserver")) { dataSoureParam[0] = strParam.replace("jdbc:sqlserver://", ""); String[] hostPort = dataSoureParam[0].split(":"); dataSoureParam[0] = hostPort[0]; if (hostPort.length > 1) { dataSoureParam[1] = hostPort[1]; } } // Actually this is specifically did for Travis. else if(strParam.startsWith("port")) { strParam = strParam.toLowerCase(); if(strParam.startsWith("portnumber")) { dataSoureParam[1] = strParam.replace("portnumber=", ""); } else { dataSoureParam[1] = strParam.replace("port=", ""); } } else if (strParam.startsWith("user")) { strParam = strParam.toLowerCase(); if (strParam.startsWith("username")) { dataSoureParam[2] = strParam.replace("username=", ""); } else { dataSoureParam[2] = strParam.replace("user=", ""); } } else if (strParam.startsWith("password")) { dataSoureParam[3] = strParam.replace("password=", ""); } else if (strParam.startsWith("database")) { strParam = strParam.toLowerCase(); if (strParam.startsWith("databasename")) { dataSoureParam[4] = strParam.replace("databasename=", ""); } else { dataSoureParam[4] = strParam.replace("database=", ""); } } } return dataSoureParam; } }