Skip to content

Commit

Permalink
OF-2883: Add fallback to older style base64 encoding for security.xml
Browse files Browse the repository at this point in the history
In Openfire 4.9.0, the base64 encoder was changed. This causes a compatibility issue with security.xml files that
were generated by older values, that use the 'MIME' type of decoding (with linebreaks) that's not used in later versions.
While persisting data in 'security.xml', linebreaks are replaced by white space.

With the changes in this commit, the decoder checks for white space, and uses the older-style type of decoding when found.
  • Loading branch information
guusdk committed Feb 13, 2025
1 parent 3ca33a2 commit d4ad8bb
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 3 deletions.
15 changes: 13 additions & 2 deletions xmppserver/src/main/java/org/jivesoftware/util/AesEncryptor.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017-2024 Ignite Realtime Foundation. All rights reserved.
* Copyright (C) 2017-2025 Ignite Realtime Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -25,6 +25,7 @@
import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.security.Security;
import java.util.Base64;

/**
* Utility class providing symmetric AES encryption/decryption. To strengthen
Expand Down Expand Up @@ -97,7 +98,17 @@ public String decrypt(String value) {
@Override
public String decrypt(String value, byte[] iv) {
if (value == null) { return null; }
byte [] bytes = cipher(java.util.Base64.getDecoder().decode(value), getKey(), iv == null ? INIT_PARM : iv, Cipher.DECRYPT_MODE);

// OF-2883: In Openfire 4.9.0, the base64 encoder was changed. This causes a compatibility issue with security.xml files that
// were generated by older values, that use the 'MIME' type of decoding (with linebreaks) that's not used in later versions.
// While persisting data in 'security.xml', linebreaks are replaced by white space.
final Base64.Decoder decoder;
if (value.length() > 76 && Character.isWhitespace(value.charAt(76))) {
decoder = Base64.getMimeDecoder(); // Value saved by older version of Openfire.
} else {
decoder = Base64.getDecoder();
}
byte [] bytes = cipher(decoder.decode(value), getKey(), iv == null ? INIT_PARM : iv, Cipher.DECRYPT_MODE);
if (bytes == null) { return null; }
return new String(bytes, StandardCharsets.UTF_8);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (C) 2017-2023 Ignite Realtime Foundation. All rights reserved.
* Copyright (C) 2017-2025 Ignite Realtime Foundation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -101,4 +101,43 @@ public void testEncryptionWithKeyAndBadIV() {

}

/**
* Tests decoding a Base64 value stored as would be stored in security.xml by versions of Openfire prior to 4.9.0.
*
* @see <a href="https://igniterealtime.atlassian.net/browse/OF-2883">OF-2883: Base64 decoding issue preventing startup (after upgrade to 4.9.0)</a>
*/
@Test
public void testBase64DecodeValuePriorTo490()
{
// Setup text fixture.
final String unencoded = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod";
final String base64encoded = "PwwA2Ejt1HDS0xwbEg4qMzk/E9fDA1aA6TdL2zBPMVtwW9C2UnUafAmm/twRZxY89euheVg0rxoQ Vfo5to825asMcx/bJNPY136oZstULDU=";

// Execute system under test.
final AesEncryptor encryptor = new AesEncryptor();
final String result = encryptor.decrypt(base64encoded);

// Verify results.
assertEquals(unencoded, result);
}

/**
* Tests decoding a Base64 value stored as would be stored in security.xml by versions of Openfire 4.9.0 and later.
*
* @see <a href="https://igniterealtime.atlassian.net/browse/OF-2883">OF-2883: Base64 decoding issue preventing startup (after upgrade to 4.9.0)</a>
*/
@Test
public void testBase64DecodeValuePastTo490()
{
// Setup test fixture.
final String unencoded = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod";
final String base64encoded = "PwwA2Ejt1HDS0xwbEg4qMzk/E9fDA1aA6TdL2zBPMVtwW9C2UnUafAmm/twRZxY89euheVg0rxoQVfo5to825asMcx/bJNPY136oZstULDU=";

// Execute system under test.
final AesEncryptor encryptor = new AesEncryptor();
final String result = encryptor.decrypt(base64encoded);

// Verify results.
assertEquals(unencoded, result);
}
}

0 comments on commit d4ad8bb

Please sign in to comment.