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

SNOW-618478: support passing private key as base64 encoded string (private_key_base64) as alternative to (private_key_file) #1810

Closed
wants to merge 1 commit into from

Conversation

ets
Copy link
Contributor

@ets ets commented Jul 2, 2024

Overview

SNOW-618478

  1. What GitHub issue is this PR addressing? Make sure that there is an accompanying issue to your PR.

    SNOW-618478: Unable to authenticate with a private key by using spring datasource properties #1053

  2. Fill out the following pre-review checklist:

    • I am adding a new automated test(s) to verify correctness of my new code
    • [] I am adding new logging messages
      - None were added but a few log messages were tweaked for clarity
    • I am modifying authorization mechanisms
    • I am adding new credentials
    • I am modifying OCSP code
    • I am adding a new dependency or upgrading an existing one
    • I am adding new public/protected component not marked with @SnowflakeJdbcInternalApi (note that public/protected methods/fields in classes marked with this annotation are already internal)
  3. Please describe how your code solves the related issue.

    Please write a short description of how your code change solves the related issue.

There are currently only two options for passing a privateKey for authentication purposes. The key can be supplied as a fully instantiated PrivateKey object or a path to a private key file can be supplied and the PrivateKey object will be extracted. Neither option supports the usecase where the calling code needs to pass the privateKey as a String.

As the GitHub issue documents, there are several scenarios where passing the privateKey as a String is required (Hikari pool only accepts property values of type String, Spark.read if you don't want to push the file to every executor, etc..). This PR adds a new session property "private_key_base64" which complements the existing "private_key_file". The new logic ensures that only one of private_key_base64, private_key_file, or private_key are not null. Then it extracts, decrypts, and instantiates the needed private_key as appropriate.

The PR piggy-backs upon the existing tests for private_key_file and adds variants that instead leverage private_key_base64 to demonstrate expected behavior.

@ets ets requested a review from a team as a code owner July 2, 2024 16:10
Copy link

github-actions bot commented Jul 2, 2024

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@ets
Copy link
Contributor Author

ets commented Jul 2, 2024

I have read the CLA Document and I hereby sign the CLA

@ets
Copy link
Contributor Author

ets commented Jul 2, 2024

recheck

src/main/java/net/snowflake/client/core/SessionUtil.java Outdated Show resolved Hide resolved
+ privateKeyBase64;

try (Connection connection = DriverManager.getConnection(uri, properties)) {}
// test with incorrect password for private key
Copy link
Collaborator

Choose a reason for hiding this comment

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

let's make it a separate test - the same also in other sections below

}

// test with invalid public/private key combo (using 1st public key with 2nd private key)
try (Connection connection = getConnection();
Copy link
Collaborator

Choose a reason for hiding this comment

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

can we create a method for adding public key and reuse it?

}
}

// This will only work with JDBC driver versions higher than 3.15.1
Copy link
Collaborator

Choose a reason for hiding this comment

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

it will work in version higher than 3.17.0 probably

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not my insight... this comment exists above testPrivateKeyInConnectionStringWithBouncyCastle and if it does apply there then it also should apply here.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Still we wants to have LatestIT tests marked with comment with version

@@ -891,6 +950,146 @@ public void testPrivateKeyInConnectionStringWithBouncyCastle() throws SQLExcepti
testPrivateKeyInConnectionString();
}

@Test
Copy link
Collaborator

Choose a reason for hiding this comment

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

please add a comment about version when the test will work > 3.17.0 probably

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not clear on the ask here. I assume the version limitation is based upon historical support for BouncyCastle - right?

System.setProperty(SecurityUtil.ENABLE_BOUNCYCASTLE_PROVIDER_JVM, "true");

So if that was introduced in 3.15.1 as the existing comment on testPrivateKeyInConnectionStringWithBouncyCastle suggests..then it should apply equally to the new testPrivateKeyBase64InConnectionStringWithBouncyCastle

Right?

Copy link
Collaborator

Choose a reason for hiding this comment

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

On each our test added to classes ...LatestIT we add comment to mark from which version this test is correct. Currently the last released version is 3.17.0 so above newly added test that use new connection property you added there should be comment e.g. in other tests

@ets
Copy link
Contributor Author

ets commented Jul 5, 2024

Hey @sfc-gh-dprzybysz thanks for reviewing this one. I knocked out most of your asks but see my feedback on the proposed changes to ConnectionLatestIt where I've introduced a couple test methods that are carbon copies of testPrivatekKeyFileXXX equivalents. I'm thinking we should keep those more or less in sync with respect to design - agreed?

@josecsotomorales
Copy link

Hey SF folks, any timeline of when this PR will be merged and released? This currently blocks several users of Spark and Hikari from using Key Pair Auth properly.

}

/**
* Helper function to generate a JWT token
Copy link
Collaborator

Choose a reason for hiding this comment

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

please add link in javadoc to function above

import java.util.Map;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
Copy link
Collaborator

Choose a reason for hiding this comment

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

it should still fail on checkstyle, please run mvn -P check-style validate

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.*;
Copy link
Collaborator

Choose a reason for hiding this comment

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

here also the checkstyle check will fail

@@ -891,6 +950,146 @@ public void testPrivateKeyInConnectionStringWithBouncyCastle() throws SQLExcepti
testPrivateKeyInConnectionString();
}

@Test
Copy link
Collaborator

Choose a reason for hiding this comment

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

On each our test added to classes ...LatestIT we add comment to mark from which version this test is correct. Currently the last released version is 3.17.0 so above newly added test that use new connection property you added there should be comment e.g. in other tests

properties.put("port", parameters.get("port"));
try (Connection connection = DriverManager.getConnection(uri, properties)) {}

// PKCS #1
Copy link
Collaborator

Choose a reason for hiding this comment

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

@ets could you split the test into smaller ones?

}
}

// This will only work with JDBC driver versions higher than 3.15.1
Copy link
Collaborator

Choose a reason for hiding this comment

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

Still we wants to have LatestIT tests marked with comment with version

@sfc-gh-dprzybysz
Copy link
Collaborator

@ets Please also rebase your change when you will be addressing the comments

@ets
Copy link
Contributor Author

ets commented Aug 9, 2024

@sfc-gh-dprzybysz I see that you got to the open items here before me. Are there any remaining that you'd like me to look into or is this PR ready for next steps now?

…ew session property key "private_key_base64"

Rename private key password variable for clarity
Add deprecation to private key file password
@sfc-gh-mkubik
Copy link
Contributor

Merged with #1847

@github-actions github-actions bot locked and limited conversation to collaborators Sep 3, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants