[poppler] Branch 'signatureHandling' - poppler/Form.cc poppler/Object.h
Adrian Johnson
ajohnson at kemper.freedesktop.org
Thu Jan 14 14:19:58 PST 2016
poppler/Form.cc | 60 ++++++++++++++++++++++++++++---------------------------
poppler/Object.h | 12 ++++++++++-
2 files changed, 42 insertions(+), 30 deletions(-)
New commits:
commit dcefd7a232ba17af878b95efaa4ffaf147d095b7
Author: Adrian Johnson <ajohnson at redneon.com>
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, &r2);
- byte_range.arrayGet(2, &r3);
- byte_range.arrayGet(3, &r4);
-
- 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, &offsetObj);
+ byte_range.arrayGet(i*2+1, &lenObj);
+
+ if (!offsetObj.isIntOrInt64() || !lenObj.isIntOrInt64()) {
+ error(errSyntaxError, 0, "Illegal values in ByteRange array");
+ return signature_info;
+ }
- hashSignedDataBlock(&signature_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(&signature_handler, block_len);
+ doc->getBaseStream()->setPos(offset);
+ hashSignedDataBlock(&signature_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 long getInt64() { OBJECT_TYPE_CHECK(objInt64); return int64g; }
+ long long getIntOrInt64() { OBJECT_2TYPES_CHECK(objInt, objInt64);
+ return type == objInt ? intg : int64g; }
// Array accessors.
int arrayGetLength();
More information about the poppler
mailing list