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

AE setup #337

Merged
merged 4 commits into from
Jun 16, 2017
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
15 changes: 12 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
sudo: required
sudo: required

language: java
jdk:
Expand All @@ -18,8 +18,17 @@ env:
cache:
directories:
- $HOME/.m2


before_install:
- mkdir AE_Certificates

install:
- cd AE_Certificates
- openssl req -newkey rsa:2048 -x509 -keyout cakey.pem -out cacert.pem -days 3650 -subj "/C=US/ST=WA/L=Redmond/O=Microsoft Corporation/OU=SQL Server/CN=JDBC Driver" -nodes
- openssl pkcs12 -export -in cacert.pem -inkey cakey.pem -out identity.p12 -password pass:password
- keytool -importkeystore -destkeystore clientcert.jks -deststorepass password -srckeystore identity.p12 -srcstoretype PKCS12 -srcstorepass password
- keytool -list -v -keystore clientcert.jks -storepass "password" > JavaKeyStore.txt
- cd ..
- mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -Pbuild41
- mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -Pbuild42

Expand All @@ -36,4 +45,4 @@ script:

#after_success:
# instead of after success we are using && operator for conditional submitting coverage report.
# - bash <(curl -s https://codecov.io/bash)
# - bash <(curl -s https://codecov.io/bash)
11 changes: 11 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,25 @@ install:
- ps: choco pack
- ps: choco install jce -fdv -s . -y -failonstderr
- ps: cd..
- ps: mkdir AE_Certificates
- ps: cd AE_Certificates
- ps: $cert = New-SelfSignedCertificate -dns "AlwaysEncryptedCert" -CertStoreLocation Cert:CurrentUser\My
- ps: $pwd = ConvertTo-SecureString -String "password" -Force -AsPlainText
- ps: $path = 'cert:\CurrentUser\My\' + $cert.thumbprint
- ps: $certificate = Export-PfxCertificate -cert $path -FilePath cert.pfx -Password $pwd
- ps: Get-ChildItem -path cert:\CurrentUser\My > certificate.txt

cache:
- C:\Users\appveyor\.m2 -> pom.xml

build_script:
- keytool -importkeystore -srckeystore cert.pfx -srcstoretype pkcs12 -destkeystore clientcert.jks -deststoretype JKS -srcstorepass password -deststorepass password
- keytool -list -v -keystore clientcert.jks -storepass "password" > JavaKeyStore.txt
- cd..
- mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -Pbuild41
- mvn install -DskipTests=true -Dmaven.javadoc.skip=true -B -V -Pbuild42

test_script:
- mvn test -B -Pbuild41
- mvn test -B -Pbuild42

7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,13 @@
<include>**/*.csv</include>
</includes>
</testResource>
<testResource>
<directory>AE_Certificates</directory>
<includes>
<include>**/*.txt</include>
<include>**/*.jks</include>
</includes>
</testResource>
</testResources>

<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
/*
* 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.AlwaysEncrypted;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.xml.bind.DatatypeConverter;

import org.junit.jupiter.api.BeforeAll;
import org.junit.platform.runner.JUnitPlatform;
import org.junit.runner.RunWith;
import org.opentest4j.TestAbortedException;

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.testframework.AbstractTest;
import com.microsoft.sqlserver.testframework.DBConnection;
import com.microsoft.sqlserver.testframework.Utils;
import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.Assumptions.assumeTrue;

/**
* Setup for Always Encrypted test
* This test will work on Appveyor and Travis-ci as java key store gets created from the .yml scripts. Users on their local machine should create the
* keystore manually and save the alias name in JavaKeyStore.txt file. For local test purposes, put this in the target/test-classes directory
*
*/
@RunWith(JUnitPlatform.class)
public class AESetup extends AbstractTest {

static String javaKeyStoreInputFile = "JavaKeyStore.txt";
static String keyStoreName = "MSSQL_JAVA_KEYSTORE";
static String jksName = "clientcert.jks";
static String filePath = null;
static String thumbprint = null;
static SQLServerConnection con = null;
static Statement stmt = null;
static String cmkName = "JDBC_CMK";
static String cekName = "JDBC_CEK";
static String keyPath = null;
static String javaKeyAliases = null;
static String OS = System.getProperty("os.name").toLowerCase();
static SQLServerColumnEncryptionKeyStoreProvider storeProvider = null;
static String secretstrJks = "password";
static String numericTable = "numericTable";

/**
* Create connection, statement and generate path of resource file
* @throws Exception
* @throws TestAbortedException
*/
@BeforeAll
static void setUpConnection() throws TestAbortedException, Exception {
assumeTrue(13 <= new DBConnection(connectionString).getServerVersion(),
"Aborting test case as SQL Server version is not compatible with Always encrypted ");

readFromFile(javaKeyStoreInputFile, "Alias name");
con = (SQLServerConnection) DriverManager.getConnection(connectionString);
stmt = con.createStatement();
Utils.dropTableIfExists(numericTable, stmt);
dropCEK();
dropCMK();
con.close();


keyPath = Utils.getCurrentClassPath() + jksName;
storeProvider = new SQLServerColumnEncryptionJavaKeyStoreProvider(keyPath, secretstrJks.toCharArray());
Properties info = new Properties();
info.setProperty("ColumnEncryptionSetting", "Enabled");
info.setProperty("keyStoreAuthentication", "JavaKeyStorePassword");
info.setProperty("keyStoreLocation", keyPath);
info.setProperty("keyStoreSecret", secretstrJks);
con = (SQLServerConnection) DriverManager.getConnection(connectionString, info);
stmt = con.createStatement();
createCMK(keyStoreName, javaKeyAliases);
}

/**
* Read the alias from file which is created during creating jks
* If the jks and alias name in JavaKeyStore.txt does not exists, will not run!
* @param inputFile
* @param lookupValue
* @throws IOException
*/
private static void readFromFile(String inputFile,
String lookupValue) throws IOException {
BufferedReader buffer = null;
filePath = Utils.getCurrentClassPath();
try {
File f = new File(filePath + inputFile);
assumeTrue(f.exists(), "Aborting test case since no java key store and alias name exists!");
buffer = new BufferedReader(new FileReader(f));
String readLine = "";
String[] linecontents;

while ((readLine = buffer.readLine()) != null) {
if (readLine.trim().contains(lookupValue)) {
linecontents = readLine.split(" ");
javaKeyAliases = linecontents[2];
break;
}
}

}
catch (IOException e) {
fail(e.toString());;
}
finally{
if (null != buffer){
buffer.close();
}
}

}

/**
* Creating numeric table
*/
static void createNumericTable() {
String sql = "create table " + numericTable + " (" + "PlainSmallint smallint null,"
+ "RandomizedSmallint smallint ENCRYPTED WITH (ENCRYPTION_TYPE = RANDOMIZED, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
+ cekName + ") NULL,"
+ "DeterministicSmallint smallint ENCRYPTED WITH (ENCRYPTION_TYPE = DETERMINISTIC, ALGORITHM = 'AEAD_AES_256_CBC_HMAC_SHA_256', COLUMN_ENCRYPTION_KEY = "
+ cekName + ") NULL" + ");";

try {
stmt.execute(sql);
}
catch (SQLException e) {
fail(e.toString());
}
}

/**
* Create column master key
* @param keyStoreName
* @param keyPath
* @throws SQLException
*/
private static void createCMK(String keyStoreName,
String keyPath) throws SQLException {
String sql = " if not exists (SELECT name from sys.column_master_keys where name='" + cmkName + "')" + " begin" + " CREATE COLUMN MASTER KEY "
+ cmkName + " WITH (KEY_STORE_PROVIDER_NAME = '" + keyStoreName + "', KEY_PATH = '" + keyPath + "')" + " end";
stmt.execute(sql);
}

/**
* Create column encryption key
* @param storeProvider
* @param certStore
* @throws SQLException
*/
static void createCEK(SQLServerColumnEncryptionKeyStoreProvider storeProvider) throws SQLException {
String letters = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
byte[] valuesDefault = letters.getBytes();
String cekSql = null;
byte[] key = storeProvider.encryptColumnEncryptionKey(javaKeyAliases, "RSA_OAEP", valuesDefault);
cekSql = "CREATE COLUMN ENCRYPTION KEY " + cekName + " WITH VALUES " + "(COLUMN_MASTER_KEY = " + cmkName
+ ", ALGORITHM = 'RSA_OAEP', ENCRYPTED_VALUE = 0x" + DatatypeConverter.printHexBinary(key) + ")" + ";";
stmt.execute(cekSql);
}

/**
* Dropping column encryption key
* @throws SQLServerException
* @throws SQLException
*/
static void dropCEK() throws SQLServerException, SQLException {
String cekSql = " if exists (SELECT name from sys.column_encryption_keys where name='" + cekName + "')" + " begin"
+ " drop column encryption key " + cekName + " end";
stmt.execute(cekSql);
}

/**
* Dropping column master key
* @throws SQLServerException
* @throws SQLException
*/
static void dropCMK() throws SQLServerException, SQLException {
String cekSql = " if exists (SELECT name from sys.column_master_keys where name='" + cmkName + "')" + " begin" + " drop column master key "
+ cmkName + " end";
stmt.execute(cekSql);
}
}
Loading