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

Remove RSA Public Key #21

Merged
merged 6 commits into from
Oct 19, 2018
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@
*.iml
.idea
target/
profile.json
113 changes: 111 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<description>Snowflake Ingest SDK</description>
<url>https://www.snowflake.net/</url>


<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
Expand All @@ -39,6 +40,8 @@
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<shadeBase>net.snowflake.ingest.internal</shadeBase>
<jacoco.skip.instrument>true</jacoco.skip.instrument>
<jacoco.version>0.8.1</jacoco.version>
</properties>

<build>
Expand Down Expand Up @@ -206,6 +209,36 @@
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>target/jacoco-ut.exec</destFile>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>target/jacoco-ut.exec</dataFile>
<outputDirectory>target/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
<configuration>
<skip>${jacoco.skip.instrument}</skip>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
Expand All @@ -221,6 +254,14 @@
<scope>test</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-ext-jdk15on -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk15on</artifactId>
<version>1.60</version>
<scope>test</scope>
</dependency>


<!-- Jose4J provides token authentication for GS -->
<dependency>
Expand All @@ -234,14 +275,14 @@
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.8.4</version>
<version>2.9.6</version>
</dependency>

<!-- Jackson Databind api -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.4</version>
<version>2.9.6</version>
</dependency>


Expand Down Expand Up @@ -287,4 +328,72 @@

</dependencies>

<profiles>
<profile>
<id>travisIT</id>
<activation>
<property>
<name>travisIT</name>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
</goals>
<configuration>
<argLine>
@{argLine} -Djava.util.logging.config.file=travis_it_logging.properties
</argLine>
</configuration>
</execution>
<execution>
<id>verify_travis_it</id>
<phase>verify</phase>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco.version}</version>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<destFile>target/jacoco-ut.exec</destFile>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<dataFile>target/jacoco-ut.exec</dataFile>
<outputDirectory>target/jacoco-ut</outputDirectory>
</configuration>
</execution>
</executions>
<configuration>
<skip>${jacoco.skip.instrument}</skip>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>

</project>
13 changes: 13 additions & 0 deletions profile.json.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"user": "user name",
"account": "account name",
"private_key": "PEM Private Key",
"port": 443,
"host": "account_name.snowflakecomputing.com",
"schema": "schema",
"scheme": "https",
"database": "database name",
"connect_string": "jdbc:snowflake://account_name.snowflakecomputing.com:443",
"ssl": "on",
"warehouse": "warehouse name"
}
119 changes: 108 additions & 11 deletions src/main/java/net/snowflake/ingest/SimpleIngestManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,14 @@

import java.io.IOException;
import java.net.URISyntaxException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.util.Collections;
import java.util.List;
import java.util.Set;
Expand Down Expand Up @@ -217,10 +224,11 @@ private void init(String account, String user, String pipe,
* Snowflake DB
*
* @param account The account into which we're loading
* @param user the user performing this load
* @param pipe the fully qualified name of the pipe
* @param user the user performing this load
* @param pipe the fully qualified name of the pipe
* @param keyPair the KeyPair we'll use to sign JWT tokens
*/
@Deprecated
public SimpleIngestManager(String account, String user, String pipe,
KeyPair keyPair)
{
Expand All @@ -232,30 +240,119 @@ public SimpleIngestManager(String account, String user, String pipe,
}


/**
* Constructs a SimpleIngestManager for a given user in a specific account
* In addition, this also takes takes the target table and source stage
* Finally, it also requires a valid private key registered with
* Snowflake DB
*
* @param account The account into which we're loading
* @param user the user performing this load
* @param pipe the fully qualified name of the pipe
* @param privateKey the private key we'll use to sign JWT tokens
* @throws NoSuchAlgorithmException if can't create
* key factory by using RSA algorithm
* @throws InvalidKeySpecException if private key or public key is
* invalid
*/
public SimpleIngestManager(String account, String user, String pipe,
PrivateKey privateKey)
throws InvalidKeySpecException, NoSuchAlgorithmException
{
KeyPair keyPair = createKeyPairFromPrivateKey(privateKey);

//call our initializer method
init(account, user, pipe, keyPair);

//create the request builder
this.builder = new RequestBuilder(account, user, keyPair);
}


/**
* Constructs a SimpleIngestManager for a given user in a specific account
* In addition, this also takes takes the target table and source stage
* Finally, it also requires a valid KeyPair object registered with
* Snowflake DB
*
* @param account the account into which we're loading
* @param user the user performing this load
* @param pipe the fully qualified name of the pipe
* @param keyPair the KeyPair we'll use to sign JWT tokens
* @param account the account into which we're loading
* @param user the user performing this load
* @param pipe the fully qualified name of the pipe
* @param keyPair the KeyPair we'll use to sign JWT tokens
* @param schemeName http or https
* @param hostName the hostname
* @param port the port number
*/
@Deprecated
public SimpleIngestManager(String account, String user, String pipe,
KeyPair keyPair, String schemeName,
String hostName, int port)
{
//call our initializer method
init(account, user, pipe, keyPair);

//make the request builder we'll use to build messages to the service
builder = new RequestBuilder(account, user, keyPair,
schemeName, hostName, port);
}

/**
* Constructs a SimpleIngestManager for a given user in a specific account
* In addition, this also takes takes the target table and source stage
* Finally, it also requires a valid private key registered with
* Snowflake DB
*
* @param account the account into which we're loading
* @param user the user performing this load
* @param pipe the fully qualified name of the pipe
* @param privateKey the private key we'll use to sign JWT tokens
* @param schemeName http or https
* @param hostName the hostname
* @param port the port number
* @param hostName the hostname
* @param port the port number
* @throws NoSuchAlgorithmException if can't create key factory by using
* RSA algorithm
* @throws InvalidKeySpecException if private key or public key is invalid
*/
public SimpleIngestManager(String account, String user, String pipe,
KeyPair keyPair, String schemeName,
String hostName, int port)
PrivateKey privateKey, String schemeName,
String hostName, int port)
throws NoSuchAlgorithmException, InvalidKeySpecException
{
KeyPair keyPair = createKeyPairFromPrivateKey(privateKey);
//call our initializer method
init(account, user, pipe, keyPair);

//make the request builder we'll use to build messages to the service
builder = new RequestBuilder(account, user, keyPair,
schemeName, hostName, port);
schemeName, hostName, port);

}

/**
* generate key pair object from private key
*
* @param privateKey private key
* @return a key pair object
* @throws NoSuchAlgorithmException if can't create key factory by using
* RSA algorithm
* @throws InvalidKeySpecException if private key or public key is invalid
*/
private KeyPair createKeyPairFromPrivateKey(PrivateKey privateKey) throws
NoSuchAlgorithmException, InvalidKeySpecException
{
if(!(privateKey instanceof RSAPrivateCrtKey))
throw new IllegalArgumentException("Input private key is not a RSA private key");

KeyFactory kf = KeyFactory.getInstance("RSA");

//generate public key from private key
RSAPrivateCrtKey privk = (RSAPrivateCrtKey) privateKey;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Throw proper user error in case user is passing in a PrivateKey not instancesof RSAPrivateCrtKey

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a checker

if(!(privateKey instanceof RSAPrivateCrtKey))
throw new IllegalArgumentException("Input private key is not a RSA private key");

RSAPublicKeySpec publicKeySpec = new RSAPublicKeySpec(privk.getModulus(),
privk.getPublicExponent());
PublicKey publicK = kf.generatePublic(publicKeySpec);

//create key pairs
return new KeyPair(publicK, privateKey);
}


Expand Down
Loading