Skip to content

Commit

Permalink
Fix the issue where the validity of the encoded strkey is not verifie…
Browse files Browse the repository at this point in the history
…d in certain scenarios. (#541)
  • Loading branch information
overcat authored Sep 27, 2023
1 parent 904cd16 commit 19eb5a1
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
As this project is pre 1.0, breaking changes may happen for minor version bumps. A breaking change will get clearly notified in this log.

## Pending
* Fix issues where the validity of the encoded strkey is not verified in certain scenarios. ([#541](https://github.com/stellar/java-stellar-sdk/pull/541))
* Fix the issue of javadocJar not including documentation. ([#539](https://github.com/stellar/java-stellar-sdk/pull/539))
* Publish sourcesJar to the GitHub Release page. ([#539](https://github.com/stellar/java-stellar-sdk/pull/539))

Expand Down
15 changes: 13 additions & 2 deletions src/main/java/org/stellar/sdk/StrKey.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Optional;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base32OutputStream;
import org.apache.commons.codec.binary.StringUtils;
import org.stellar.sdk.xdr.AccountID;
import org.stellar.sdk.xdr.CryptoKeyType;
import org.stellar.sdk.xdr.MuxedAccount;
Expand Down Expand Up @@ -139,7 +140,8 @@ public static MuxedAccount encodeToXDRMuxedAccount(String data) {
}

public static VersionByte decodeVersionByte(String data) {
byte[] decoded = base32Codec.decode(data);
byte[] dataBytes = StringUtils.getBytesUtf8(data);
byte[] decoded = base32decode(dataBytes);
byte decodedVersionByte = decoded[0];
Optional<VersionByte> versionByteOptional = VersionByte.findByValue(decodedVersionByte);
if (!versionByteOptional.isPresent()) {
Expand Down Expand Up @@ -300,7 +302,7 @@ protected static byte[] decodeCheck(VersionByte versionByte, char[] encoded) {
}
}

byte[] decoded = base32Codec.decode(bytes);
byte[] decoded = base32decode(bytes);
byte decodedVersionByte = decoded[0];
byte[] payload = Arrays.copyOfRange(decoded, 0, decoded.length - 2);
byte[] data = Arrays.copyOfRange(payload, 1, payload.length);
Expand Down Expand Up @@ -424,4 +426,13 @@ private static char[] bytesToChars(byte[] data) {
}
return chars;
}

private static byte[] base32decode(byte[] data) {
// Apache commons codec Base32 class will auto remove the illegal characters, this is
// what we don't want, so we need to check the data before decoding
if (!base32Codec.isInAlphabet(data, false)) {
throw new IllegalArgumentException("Invalid base32 encoded string");
}
return base32Codec.decode(data);
}
}
89 changes: 88 additions & 1 deletion src/test/java/org/stellar/sdk/StrKeyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -333,7 +333,7 @@ public void testEncodeAccountIdToMuxed() {

@Test
public void testEncodeToXDRMuxedAccountInvalidAddress() {

// https://github.com/stellar/go/blob/2b876cd781b6dd0c218dcdd4f300900f87b3889e/strkey/main_test.go#L86
try {
StrKey.encodeToXDRMuxedAccount("XBU2RRGLXH3E5CQHTD3ODLDF2BWDCYUSSBLLZ5GNW7JXHDIYKXZWGTOG");
fail();
Expand All @@ -347,5 +347,92 @@ public void testEncodeToXDRMuxedAccountInvalidAddress() {
} catch (FormatException e) {
assertEquals("Checksum invalid", e.getMessage());
}

try {
StrKey.encodeToXDRMuxedAccount(
"MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUR");
fail();
} catch (IllegalArgumentException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount("GA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVSGZA");
fail();
} catch (IllegalArgumentException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount("G47QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVP2I");
fail();
} catch (FormatException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount(
"MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLKA");
fail();
} catch (IllegalArgumentException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount(
"M47QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUQ");
fail();
} catch (FormatException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount(
"M47QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUQ");
fail();
} catch (FormatException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount(
"MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUK");
fail();
} catch (FormatException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount(
"MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAACJUO");
fail();
} catch (FormatException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount("");
fail();
} catch (IllegalArgumentException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount("SBCVMMCBEDB64TVJZFYJOJAERZC4YVVUOE6SYR2Y76CBTENGUSGWRRVO");
fail();
} catch (FormatException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount(
"MCEO75Y6YKE53HM6N46IJYH3LK3YYFZ4QWGNUKCSSIQSH3KOAD7BEAAAAAAAAAAAPNT2W___");
fail();
} catch (IllegalArgumentException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount(
"MDWZCOEQRODFCH6ISYQPWY67L3ULLWS5ISXYYL5GH43W7YFMTLB64AAAAAAAAAAAAHGLW===");
fail();
} catch (IllegalArgumentException ignored) {
}

try {
StrKey.encodeToXDRMuxedAccount(
" MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK");
fail();
} catch (IllegalArgumentException ignored) {
}
}
}

0 comments on commit 19eb5a1

Please sign in to comment.