aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafal Stanczak2018-06-17 09:02:34 -0400
committerDawid Pakula2018-06-19 10:32:15 -0400
commitd8ea0d3492dfb7cf275d6e06aec3686bc305d0b9 (patch)
tree45dd7be86dc881803a377608f56ef2ee717c9255
parentec639ea4665a7611d7af4b4dacab0b0203742108 (diff)
downloadorg.eclipse.pdt-d8ea0d3492dfb7cf275d6e06aec3686bc305d0b9.tar.gz
org.eclipse.pdt-d8ea0d3492dfb7cf275d6e06aec3686bc305d0b9.tar.xz
org.eclipse.pdt-d8ea0d3492dfb7cf275d6e06aec3686bc305d0b9.zip
Bug 535976 - Reading of PHAR signature is done wrongly
The signature should be analyzed from the end of file (like in phar.c from php-source). Analyzing from end-position of last entry can cause wrong digest bytes comparation (eg. when signatureLen==25). Change-Id: Ic49727cb9c0d0a16790e7d907bc1c7befff3d48a Signed-off-by: Rafal Stanczak <rafal@pregusia.pl>
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharFile.java39
-rw-r--r--plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharUtil.java36
2 files changed, 52 insertions, 23 deletions
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharFile.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharFile.java
index 27f28ec7d..74432b3bb 100644
--- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharFile.java
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharFile.java
@@ -183,31 +183,42 @@ public class PharFile {
if (signatureLength < 24) {
throw new PharException(Messages.Phar_Signature_Corrupted);
} else {
-
- bis.skip(signatureLength - 8);
- buffer = new byte[4];
- read(bis, buffer);
boolean found = false;
+ byte[] signatureData = new byte[signatureLength];
+ bis.read(signatureData);
+
+ // checking phar signature should be done from the end of file
+ // like done in phar.c (from php source)
+ // especially reading digest from signature begining is wrong in some cases
+
+ if (!PharUtil.byteArrayEquals(signatureData, PharConstants.GBMB, signatureData.length - 4)) {
+ throw new PharException(Messages.Phar_Signature_Corrupted);
+ }
+
+ byte[] digestFlags = Arrays.copyOfRange(signatureData, signatureData.length - 8,
+ signatureData.length - 4);
+
for (Iterator<Digest> iterator = Digest.DIGEST_MAP.values().iterator(); iterator.hasNext();) {
Digest digest = iterator.next();
- if (PharUtil.byteArrayEquals(digest.getBitMap(), buffer)) {
- if (digest.getDigest().digest().length != signatureLength - 8
- || !PharUtil.checkSignature(file, digest, signatureEntry.getPosition())) {
+ if (PharUtil.byteArrayEquals(digest.getBitMap(), digestFlags)) {
+ int digestLen = digest.getDigest().digest().length;
+ if (signatureData.length - 8 < digestLen) {
+ throw new PharException(Messages.Phar_Signature_Corrupted);
+ }
+ byte[] digestData = Arrays.copyOfRange(signatureData, signatureData.length - 8 - digestLen,
+ signatureData.length - 8);
+
+ if (!PharUtil.checkSignature(file, (int) (file.length() - 8 - digestLen), digest, digestData)) {
throw new PharException(Messages.Phar_Signature_Corrupted);
- } else {
- found = true;
- break;
}
+ found = true;
+ break;
}
}
if (!found) {
throw new PharException(Messages.Phar_Signature_Unsupported);
}
- read(bis, buffer);
- if (!PharUtil.byteArrayEquals(PharConstants.GBMB, buffer)) {
- throw new PharException(Messages.Phar_Signature_End);
- }
}
pharEntryList.add(signatureEntry);
pharEntryMap.put(signatureEntry.getName(), signatureEntry);
diff --git a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharUtil.java b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharUtil.java
index a6f659d3f..44f3f9f2d 100644
--- a/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharUtil.java
+++ b/plugins/org.eclipse.php.core/src/org/eclipse/php/internal/core/phar/PharUtil.java
@@ -179,7 +179,27 @@ public class PharUtil {
}
- public static boolean checkSignature(File file, Digest digest, int end) throws IOException {
+ public static boolean byteArrayEquals(byte[] b1, byte[] b2, int offset) {
+ if (b1 == null)
+ return false;
+ if (b2 == null)
+ return false;
+ if (offset < 0)
+ return false;
+ if (offset == 0)
+ return byteArrayEquals(b1, b2);
+ if (offset + b2.length > b1.length)
+ return false;
+
+ for (int i = 0; i < b2.length; ++i) {
+ if (b1[offset + i] != b2[i])
+ return false;
+ }
+
+ return true;
+ }
+
+ public static boolean checkSignature(File file, int fileEnd, Digest digest, byte[] digestData) throws IOException {
MessageDigest messageDigest = digest.getDigest();
messageDigest.reset();
int length = 0;
@@ -189,8 +209,8 @@ public class PharUtil {
int n;
int size = 4096;
byte[] readBuffer;
- if (end < size) {
- readBuffer = new byte[end];
+ if (fileEnd < size) {
+ readBuffer = new byte[fileEnd];
} else {
readBuffer = new byte[4096];
}
@@ -204,16 +224,14 @@ public class PharUtil {
// } else {
messageDigest.update(readBuffer, 0, n);
// }
- if (length == end) {
+ if (length == fileEnd) {
break;
}
- if (length + readBuffer.length > end) {
- readBuffer = new byte[end - length];
+ if (length + readBuffer.length > fileEnd) {
+ readBuffer = new byte[fileEnd - length];
}
}
- readBuffer = new byte[contentStream.available() - 8];
- contentStream.read(readBuffer);
- if (PharUtil.byteArrayEquals(messageDigest.digest(), readBuffer)) {
+ if (PharUtil.byteArrayEquals(messageDigest.digest(), digestData)) {
return true;
}
} finally {