Handle UTF-8 values in the keystore (#39496)
* Handle UTF8 values in the keystore Our current implementation uses CharBuffer#array to get the chars that were decoded from the UTF-8 bytes. The backing array of CharBuffer is created in CharsetDecoder#decode and gets an initial length that is the same as the length of the ByteBuffer it decodes, hence the number of UTF-8 bytes. This works fine for the first 128 characters where each one needs one bytes, but for the next UTF-8 characters (other latin alphabets Greek, Cyrillic etc.) where we need 2 to 4 bytes per character, this backing char array has a larger size than the number of the actual chars this CharBuffer contains. Calling `array()` on it will return a char array that can potentially have extra null chars so the SecureString we get from the KeystoreWrapper, is not the same as the one we entered. This commit changes the behavior to use Arrays#copyOfRange to get the necessary chars from the CharBuffer and adds a test with random ( maybe not printable ) UTF-8 strings
This commit is contained in:
parent
e9fa7767ec
commit
8dc8fc507d
|
@ -532,7 +532,7 @@ public class KeyStoreWrapper implements SecureSettings {
|
|||
}
|
||||
ByteBuffer byteBuffer = ByteBuffer.wrap(entry.bytes);
|
||||
CharBuffer charBuffer = StandardCharsets.UTF_8.decode(byteBuffer);
|
||||
return new SecureString(charBuffer.array());
|
||||
return new SecureString(Arrays.copyOfRange(charBuffer.array(), charBuffer.position(), charBuffer.limit()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
package org.elasticsearch.common.settings;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.CharArrayWriter;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
|
@ -133,6 +134,19 @@ public class AddStringKeyStoreCommandTests extends KeyStoreCommandTestCase {
|
|||
assertSecureString("foo", "secret value 2");
|
||||
}
|
||||
|
||||
public void testAddUtf8String() throws Exception {
|
||||
KeyStoreWrapper.create().save(env.configFile(), new char[0]);
|
||||
final int stringSize = randomIntBetween(8, 16);
|
||||
try (CharArrayWriter secretChars = new CharArrayWriter(stringSize)) {
|
||||
for (int i = 0; i < stringSize; i++) {
|
||||
secretChars.write((char) randomIntBetween(129, 2048));
|
||||
}
|
||||
setInput(secretChars.toString());
|
||||
execute("-x", "foo");
|
||||
assertSecureString("foo", secretChars.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void testMissingSettingName() throws Exception {
|
||||
createKeystore("");
|
||||
terminal.addTextInput("");
|
||||
|
|
Loading…
Reference in New Issue