poppler/Form.cc | 60 ---
poppler/Object.h | 12 ++-
2 files changed, 42 insertions(+), 30 deletions(-)
New commits:
commit dcefd7a232ba17af878b95efaa4ffaf147d095b7
Author: Adrian Johnson
Date: Fri Jan 8 16:49:25 2016 +1030
check all byte ranges in signature dictionary
diff --git a/poppler/Form.cc b/poppler/Form.cc
index d94757a..910c179 100644
--- a/poppler/Form.cc
+++ b/poppler/Form.cc
@@ -1473,48 +1473,51 @@ SignatureInfo
*FormFieldSignature::validateSignature(bool doVerifyCert, bool for
return signature_info;
}
- if (!byte_range.isArray() || signature == NULL) {
+ if (signature == NULL) {
+error(errSyntaxError, 0, "Invalid or missing Signature string");
return signature_info;
}
- Object r2, r3, r4;
- NSSCMSVerificationStatus sig_val_state;
- SECErrorCodes cert_val_state;
-
- byte_range.arrayGet(1, );
- byte_range.arrayGet(2, );
- byte_range.arrayGet(3, );
-
- Goffset fileLength = doc->getBaseStream()->getLength();
- Goffset r_values[3];
-
- r_values[0] = r2.isInt64() ? r2.getInt64() : r2.getInt();
- r_values[1] = r3.isInt64() ? r3.getInt64() : r3.getInt();
- r_values[2] = r4.isInt64() ? r4.getInt64() : r4.getInt();
+ if (!byte_range.isArray()) {
+error(errSyntaxError, 0, "Invalid or missing ByteRange array");
+return signature_info;
+ }
- if (r_values[0] <= 0 || r_values[1] <= 0 || r_values[2] <= 0 || r_values[1]
<= r_values[0] ||
-r_values[1] + r_values[2] > fileLength)
- {
- error(errSyntaxError, 0, "Illegal values in ByteRange array");
- return signature_info;
+ int arrayLen = byte_range.arrayGetLength();
+ if (arrayLen < 2) {
+error(errSyntaxError, 0, "Too few elements in ByteRange array");
+return signature_info;
}
+ NSSCMSVerificationStatus sig_val_state;
+ SECErrorCodes cert_val_state;
const int signature_len = signature->getLength();
-
unsigned char *signatureuchar = (unsigned char *)gmalloc(signature_len);
memcpy(signatureuchar, signature->getCString(), signature_len);
SignatureHandler signature_handler(signatureuchar, signature_len);
- //Read the 2 slices of data that are signed
- doc->getBaseStream()->setPos(0);
- Goffset block_len = r_values[0];
+ Goffset fileLength = doc->getBaseStream()->getLength();
+ for (int i = 0; i < arrayLen/2; i++) {
+Object offsetObj, lenObj;
+byte_range.arrayGet(i*2, );
+byte_range.arrayGet(i*2+1, );
+
+if (!offsetObj.isIntOrInt64() || !lenObj.isIntOrInt64()) {
+ error(errSyntaxError, 0, "Illegal values in ByteRange array");
+ return signature_info;
+}
- hashSignedDataBlock(_handler, block_len);
+Goffset offset = offsetObj.getIntOrInt64();
+Goffset len = lenObj.getIntOrInt64();
- doc->getBaseStream()->setPos(r_values[1]);
- block_len = r_values[2];
+if (offset < 0 || offset >= fileLength || len < 0 || len > fileLength ||
offset + len > fileLength) {
+ error(errSyntaxError, 0, "Illegal values in ByteRange array");
+ return signature_info;
+}
- hashSignedDataBlock(_handler, block_len);
+doc->getBaseStream()->setPos(offset);
+hashSignedDataBlock(_handler, len);
+ }
sig_val_state = signature_handler.validateSignature();
signature_info->setSignatureValStatus(SignatureHandler::NSS_SigTranslate(sig_val_state));
@@ -1534,7 +1537,6 @@ SignatureInfo *FormFieldSignature::validateSignature(bool
doVerifyCert, bool for
#endif
return signature_info;
-
}
#ifdef DEBUG_FORMS
diff --git a/poppler/Object.h b/poppler/Object.h
index 1b06a3c..b9cae28 100644
--- a/poppler/Object.h
+++ b/poppler/Object.h
@@ -50,7 +50,14 @@
abort(); \
}
-#define OBJECT_3TYPES_CHECK(wanted_type1, wanted_type2, wanted_type3) \
+#define OBJECT_2TYPES_CHECK(wanted_type1, wanted_type2) \
+if (unlikely(type != wanted_type1) && unlikely(type != wanted_type2)) { \
+error(errInternal, 0, "Call to Object where the object was type {0:d},
" \
+ "not the expected type {1:d} or {2:d}", type, wanted_type1,
wanted_type2); \
+abort(); \
+}
+
+#define OBJECT_3TYPES_CHECK(wanted_type1, wanted_type2, wanted_type3) \
if (unlikely(type != wanted_type1) && unlikely(type != wanted_type2) &&
unlikely(type != wanted_type3)) { \
error(errInternal, 0, "Call to Object where the object was type {0:d},
" \
"not the expected type {1:d}, {2:d} or {3:d}", type,
wanted_type1, wanted_type2, wanted_type3); \
@@ -181,6 +188,7 @@ public:
GBool isEOF() { return type == objEOF; }
GBool isNone() { return type == objNone; }
GBool isInt64() { return type == objInt64; }
+ GBool isIntOrInt64() { return type == objInt || type == objInt64; }
// Special type checking.
GBool isName(const char *nameA)
@@ -213,6 +221,8 @@ public:
int getRefGen() { OBJECT_TYPE_CHECK(objRef); return ref.gen; }
char *getCmd() { OBJECT_TYPE_CHECK(objCmd); return cmd; }
long