-
Notifications
You must be signed in to change notification settings - Fork 24.9k
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
solved issue "certutil: large passwords not set" #30944 #36689
Changes from 5 commits
9f2be48
51cfd77
c0943be
de70a40
1da475e
2e58e7a
6fe7e60
b885cae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -91,6 +91,7 @@ public class CertificateTool extends LoggingAwareMultiCommand { | |
private static final String DEFAULT_CA_ZIP = "elastic-stack-ca.zip"; | ||
private static final String DEFAULT_CA_P12 = "elastic-stack-ca.p12"; | ||
private static final BouncyCastleProvider BC_PROV = new BouncyCastleProvider(); | ||
private static final Integer MAX_SIZE_PW_BUFFER_OLDER_SSL = 50; | ||
|
||
static final String DEFAULT_CERT_NAME = "instance"; | ||
|
||
|
@@ -336,8 +337,7 @@ CAInfo getCAInfo(Terminal terminal, OptionSet options, Environment env) throws E | |
private CAInfo loadPkcs12CA(Terminal terminal, OptionSet options, Environment env) throws Exception { | ||
Path path = resolvePath(options, caPkcs12PathSpec); | ||
char[] passwordOption = getChars(caPasswordSpec.value(options)); | ||
|
||
Map<Certificate, Key> keys = withPassword("CA (" + path + ")", passwordOption, | ||
Map<Certificate, Key> keys = withPassword("CA (" + path + ")", false, passwordOption, | ||
terminal, password -> CertParsingUtils.readPkcs12KeyPairs(path, password, a -> password)); | ||
|
||
if (keys.size() != 1) { | ||
|
@@ -381,7 +381,7 @@ CAInfo generateCA(Terminal terminal, OptionSet options) throws Exception { | |
return new CAInfo(caCert, keyPair.getPrivate(), true, password); | ||
} | ||
if (options.has(caPasswordSpec)) { | ||
return withPassword("CA Private key", null, terminal, p -> new CAInfo(caCert, keyPair.getPrivate(), true, p.clone())); | ||
return withPassword("CA Private key",false, null, terminal, p -> new CAInfo(caCert, keyPair.getPrivate(), true, p.clone())); | ||
} | ||
return new CAInfo(caCert, keyPair.getPrivate(), true, null); | ||
} | ||
|
@@ -527,7 +527,8 @@ static void writeCAInfo(ZipOutputStream outputStream, CAInfo info, Terminal term | |
final String dirName = createCaDirectory(outputStream); | ||
final String fileName = dirName + "ca.p12"; | ||
outputStream.putNextEntry(new ZipEntry(fileName)); | ||
withPassword("Generated CA", info.password, terminal, caPassword -> { | ||
|
||
withPassword("Generated CA", false, info.password, terminal, caPassword -> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this needs to be |
||
writePkcs12(fileName, outputStream, "ca", info.certAndKey, null, caPassword, null); | ||
return null; | ||
}); | ||
|
@@ -546,17 +547,19 @@ static void writePkcs12(String fileName, OutputStream output, String alias, Cert | |
char[] password, Terminal terminal) throws Exception { | ||
final KeyStore pkcs12 = KeyStore.getInstance("PKCS12"); | ||
pkcs12.load(null); | ||
withPassword(fileName, password, terminal, p12Password -> { | ||
if (isAscii(p12Password)) { | ||
pkcs12.setKeyEntry(alias, pair.key, p12Password, new Certificate[]{pair.cert}); | ||
if (caCert != null) { | ||
pkcs12.setCertificateEntry("ca", caCert); | ||
|
||
|
||
withPassword(fileName, true, password, terminal, p12Password -> { | ||
if (isAscii(p12Password)) { | ||
pkcs12.setKeyEntry(alias, pair.key, p12Password, new Certificate[]{pair.cert}); | ||
if (caCert != null) { | ||
pkcs12.setCertificateEntry("ca", caCert); | ||
} | ||
pkcs12.store(output, p12Password); | ||
return null; | ||
} else { | ||
throw new UserException(ExitCodes.CONFIG, "PKCS#12 passwords must be plain ASCII"); | ||
} | ||
pkcs12.store(output, p12Password); | ||
return null; | ||
} else { | ||
throw new UserException(ExitCodes.CONFIG, "PKCS#12 passwords must be plain ASCII"); | ||
} | ||
}); | ||
} | ||
} | ||
|
@@ -794,7 +797,8 @@ void generateAndWriteSignedCertificates(Path output, boolean writeZipFile, Optio | |
final String keyFileName = entryBase + ".key"; | ||
outputStream.putNextEntry(new ZipEntry(keyFileName)); | ||
if (usePassword) { | ||
withPassword(keyFileName, outputPassword, terminal, password -> { | ||
|
||
withPassword(keyFileName, false, outputPassword, terminal, password -> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this one needs to be |
||
pemWriter.writeObject(pair.key, getEncrypter(password)); | ||
return null; | ||
}); | ||
|
@@ -923,15 +927,29 @@ private static PEMEncryptor getEncrypter(char[] password) { | |
return new JcePEMEncryptorBuilder("DES-EDE3-CBC").setProvider(BC_PROV).build(password); | ||
} | ||
|
||
private static <T, E extends Exception> T withPassword(String description, char[] password, Terminal terminal, | ||
private static <T, E extends Exception> T withPassword(String description, boolean long_size, char[] password, Terminal terminal, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Rather than |
||
CheckedFunction<char[], T, E> body) throws E { | ||
if (password == null) { | ||
char[] promptedValue = terminal.readSecret("Enter password for " + description + " : "); | ||
try { | ||
return body.apply(promptedValue); | ||
} finally { | ||
Arrays.fill(promptedValue, (char) 0); | ||
while(long_size){ | ||
if(promptedValue.length > MAX_SIZE_PW_BUFFER_OLDER_SSL){ | ||
if(terminal.promptYesNo("Your password exceeds a length of 50 characters. Versions of OpenSSL older than 1.1.0 will not be able to use this certificate. Do you want to continue?", true)){ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Having through about this a bit more, I think the prompt is going to be annoying rather than helpful. Sorry for messing things around like this, but sometimes things become clearer during the review cycle. |
||
long_size = false; | ||
|
||
} else { | ||
promptedValue = terminal.readSecret("Enter password for " + description + " : "); | ||
if(promptedValue.length <= MAX_SIZE_PW_BUFFER_OLDER_SSL) | ||
long_size = false; | ||
} | ||
} else { | ||
long_size = false; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The formatting of thise code (spaces around brackets etc) is different to the way the rest of this source code is formatted. By the time we get to the end of this review process, we'll want to have it formatted in the same style as the surrounding code. |
||
} | ||
try { | ||
return body.apply(promptedValue); | ||
} finally { | ||
Arrays.fill(promptedValue, (char) 0); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The We need to only perform this check/warning if the password is being applied to a new file. |
||
} else { | ||
return body.apply(password); | ||
} | ||
|
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.
This one should be
true
.We want to check the password length any time we're generating a new private key.