-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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
Add secure file setting to keystore #24001
Conversation
Some systems like GCE rely on a plaintext file containing credentials. Rather than extract the information out of that credentials file and store each peace individually in the keystore, it is cleaner to just store the entire file. This commit adds support to the keystore wrapper for secure file settings. These are settings that contain an entire file that would normally be stored on the local filesystem. Retrieving the file returns an input stream to the file contents. This also adds a `add-file` command to the keystore cli. In order to support both strings and files as values for settings, the metadata format of the keystore has also been updated (with backcompat) to keep a map of setting name to type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some minors, no need for another review
String secretKeyAlgo = input.readString(); | ||
String stringKeyAlgo = input.readString(); | ||
final String fileKeyAlgo; | ||
if (formatVersion >= 2) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we get a constant here instead of the plain number
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what that would help with. We have a constant for the min version supported, as well as the current version. I could create a constant for "v1" and "v2", but how is reading a constant name different than seeing the version directly here? It would just mean 2
is in the name, so not really different?
Enumeration<String> aliases = keystore.get().aliases(); | ||
while (aliases.hasMoreElements()) { | ||
settingNames.add(aliases.nextElement()); | ||
if (formatVersion == 1) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here please add a nice constant that is human readable
// TODO: in the future if we ever change any algorithms used above, we need | ||
// to create a new KeyStore here instead of using the existing one, so that | ||
// the encoded material inside the keystore is updated | ||
assert type.equals(NEW_KEYSTORE_TYPE); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please give us messages for the assertions
KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) entry; | ||
PBEKeySpec keySpec = (PBEKeySpec) fileFactory.getKeySpec(secretKeyEntry.getSecretKey(), PBEKeySpec.class); | ||
// The PBE keyspec gives us chars, we first convert to bytes, then decode base64 inline. | ||
char[] chars = keySpec.getPassword(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so these are all 1 byte chars here in the password?
@Override | ||
public void close() throws IOException { | ||
super.close(); | ||
Arrays.fill(bytes, (byte)0); // wipe our second copy when the stream is exhausted |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nice
bytes = Base64.getEncoder().encode(bytes); | ||
char[] chars = new char[bytes.length]; | ||
for (int i = 0; i < chars.length; ++i) { | ||
chars[i] = (char)bytes[i]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
again 1 byte chars? maybe leave a comment about this here and above?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I already had a comment above. I copied it down to here as well:
// PBE only stores the lower 8 bits, so this narrowing is ok
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks good to me other than the minors Simon commented on
Some systems like GCE rely on a plaintext file containing credentials. Rather than extract the information out of that credentials file and store each peace individually in the keystore, it is cleaner to just store the entire file. This commit adds support to the keystore wrapper for secure file settings. These are settings that contain an entire file that would normally be stored on the local filesystem. Retrieving the file returns an input stream to the file contents. This also adds a `add-file` command to the keystore cli. In order to support both strings and files as values for settings, the metadata format of the keystore has also been updated (with backcompat) to keep a map of setting name to type.
Some systems like GCE rely on a plaintext file containing credentials.
Rather than extract the information out of that credentials file and
store each peace individually in the keystore, it is cleaner to just
store the entire file.
This commit adds support to the keystore wrapper for secure file
settings. These are settings that contain an entire file that would
normally be stored on the local filesystem. Retrieving the file returns
an input stream to the file contents. This also adds a
add-file
command to the keystore cli.