Skip to content

Commit f887414

Browse files
committed
OpenSSH key parsing: minor clean-ups in new AEAD code paths
Guard against corrupted key files with excessive or negative key data lengths (AEAD encryption only; other code paths were already guarding against this.) Avoid an extra copy of decrypted key data if no MAC is used by the cipher.
1 parent 752faa5 commit f887414

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/openssh/OpenSSHKeyPairResourceParser.java

+8-1
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public Collection<KeyPair> extractKeyPairs(
154154

155155
CipherFactory cipherSpec = BuiltinCiphers.resolveFactory(cipher);
156156
if (cipherSpec == null || !cipherSpec.isSupported()) {
157-
throw new NoSuchAlgorithmException("Unsupported cipher: " + cipher);
157+
throw new NoSuchAlgorithmException("Unsupported cipher: " + cipher + " for encrypted key in " + resourceKey);
158158
}
159159

160160
byte[] encryptedData;
@@ -164,6 +164,13 @@ public Collection<KeyPair> extractKeyPairs(
164164
// to follow the payload data.
165165
int authTokenLength = cipherSpec.getAuthenticationTagSize();
166166
int encryptedLength = KeyEntryResolver.decodeInt(stream);
167+
if (encryptedLength < 0) {
168+
throw new StreamCorruptedException(
169+
"Key length " + encryptedLength + " negative for encrypted key in " + resourceKey);
170+
} else if (encryptedLength > MAX_PRIVATE_KEY_DATA_SIZE) {
171+
throw new StreamCorruptedException("Key length " + encryptedLength + " > allowed maximum "
172+
+ MAX_PRIVATE_KEY_DATA_SIZE + " for encrypted key in " + resourceKey);
173+
}
167174
encryptedData = new byte[encryptedLength + authTokenLength];
168175
IoUtils.readFully(stream, encryptedData);
169176
} else {

sshd-common/src/main/java/org/apache/sshd/common/config/keys/loader/openssh/kdf/BCryptKdfOptions.java

+6
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@ public byte[] decodePrivateKeyBytes(
137137
int macLength = cipherSpec.getAuthenticationTagSize();
138138
cipher.init(Cipher.Mode.Decrypt, kv, iv);
139139
cipher.update(sensitive, 0, sensitive.length - macLength);
140+
if (macLength == 0) {
141+
// Avoid an extra copy
142+
byte[] result = sensitive;
143+
sensitive = null; // Don't clear in finalization
144+
return result;
145+
}
140146
return Arrays.copyOf(sensitive, sensitive.length - macLength);
141147
} catch (RuntimeException e) {
142148
Throwable t = ExceptionUtils.peelException(e);

0 commit comments

Comments
 (0)