Commit b56a697c authored by Albert Astals Cid's avatar Albert Astals Cid

Improvements to the previous Signature commit

 * Remove FormWidgetSignature::setFormSignatureType, the API was weird,
make it be an output parameter of getCheckedSignature

 * include cleanup

 * Make validation time mandatory, marking to use -1 for *now*

 * Remove setFormSignatureType noone uses

 * Fix compilation wihtout NSS3

 * Don't static cast between NSS3 HASH_HashType and poppler-qt5 HashAlgorithm

 * Actually pass validationTime down in FormFieldSignature::validate

 * Add since markers to poppler-qt5 functions/enums

 * Fix spacing

 * Remove SignatureValidationInfo::signingDateTime that returns
QDateTime, having two functions that return the same is a bit confusing,
and we're not filling the timezone info anyway, so let it be a time_t
parent a81700df
......@@ -33,7 +33,6 @@
#include <string.h>
#include "goo/gmem.h"
#include "goo/GooString.h"
#include "goo/GooList.h"
#include "Error.h"
#include "Object.h"
#include "Array.h"
......@@ -439,7 +438,6 @@ FormWidgetSignature::FormWidgetSignature(PDFDoc *docA, Object *aobj, unsigned nu
FormWidget(docA, aobj, num, ref, p)
{
type = formSignature;
file_size = 0;
}
SignatureInfo *FormWidgetSignature::validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime)
......@@ -451,7 +449,7 @@ std::vector<Goffset> FormWidgetSignature::getSignedRangeBounds()
{
Object* obj = static_cast<FormFieldSignature*>(field)->getByteRange();
std::vector<Goffset> range_vec;
if (obj && obj->isArray())
if (obj->isArray())
{
if (obj->arrayGetLength() == 4)
{
......@@ -472,7 +470,7 @@ std::vector<Goffset> FormWidgetSignature::getSignedRangeBounds()
return range_vec;
}
GooString* FormWidgetSignature::getCheckedSignature()
GooString* FormWidgetSignature::getCheckedSignature(Goffset *checkedFileSize)
{
Goffset start = 0;
Goffset end = 0;
......@@ -485,7 +483,7 @@ GooString* FormWidgetSignature::getCheckedSignature()
if (end >= start+6)
{
BaseStream* stream = doc->getBaseStream();
file_size = stream->getLength();
*checkedFileSize = stream->getLength();
Goffset len = end-start;
stream->setPos(end-1);
int c2 = stream->lookChar();
......@@ -498,7 +496,7 @@ GooString* FormWidgetSignature::getCheckedSignature()
// encoding or (0x80 + n) for ASN1 DER definite length encoding
// where n is the number of subsequent "length bytes" which big-endian
// encode the length of the content of the SEQUENCE following them.
if (len <= std::numeric_limits<int>::max() && file_size > end && c1 == '<' && c2 == '>')
if (len <= std::numeric_limits<int>::max() && *checkedFileSize > end && c1 == '<' && c2 == '>')
{
GooString gstr;
++start;
......@@ -1488,7 +1486,7 @@ GooString *FormFieldChoice::getSelectedChoice() {
//------------------------------------------------------------------------
FormFieldSignature::FormFieldSignature(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents)
: FormField(docA, dict, ref, parent, usedParents, formSignature),
signature_type(adbe_pkcs7_detached), byte_range(),
signature_type(adbe_pkcs7_detached),
signature(nullptr), signature_info(nullptr)
{
signature = NULL;
......@@ -1575,11 +1573,6 @@ FormSignatureType FormWidgetSignature::signatureType()
return static_cast<FormFieldSignature*>(field)->signature_type;
}
void FormWidgetSignature::setFormSignatureType(FormSignatureType type)
{
static_cast<FormFieldSignature*>(field)->signature_type = type;
}
SignatureInfo *FormFieldSignature::validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime)
{
#ifdef ENABLE_NSS3
......
......@@ -28,11 +28,9 @@
#include "Object.h"
#include "Annot.h"
#include <list>
#include <set>
#include <vector>
class GooList;
class GooString;
class Array;
class Dict;
......@@ -263,22 +261,17 @@ public:
void updateWidgetAppearance() override;
FormSignatureType signatureType();
void setFormSignatureType(FormSignatureType type);
SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime = -1);
// Use -1 for now as validationTime
SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime);
// returns a list with the boundaries of the signed ranges
// the elements of the list are of type Goffset
std::vector<Goffset> getSignedRangeBounds();
// checks the length encoding of the signature and returns the hex encoded signature
// if the check passed otherwise a nullptr is returned
GooString* getCheckedSignature();
// this method only gives the correct file size if getCheckedSignature()
// has been called before
Goffset getCheckedFileSize() const { return file_size; }
protected:
Goffset file_size;
// if the check passed (and the checked file size as output parameter in checkedFileSize)
// otherwise a nullptr is returned
GooString* getCheckedSignature(Goffset *checkedFileSize);
};
//------------------------------------------------------------------------
......@@ -521,7 +514,8 @@ class FormFieldSignature: public FormField {
public:
FormFieldSignature(PDFDoc *docA, Object *dict, const Ref& ref, FormField *parent, std::set<int> *usedParents);
SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime = -1);
// Use -1 for now as validationTime
SignatureInfo *validateSignature(bool doVerifyCert, bool forceRevalidation, time_t validationTime);
~FormFieldSignature();
Object* getByteRange() { return &byte_range; }
......
......@@ -6,7 +6,7 @@
//
// Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com>
// Copyright 2015 André Esser <bepandre@hotmail.com>
// Copyright 2015 Albert Astals Cid <aacid@kde.org>
// Copyright 2015, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
//
//========================================================================
......@@ -42,7 +42,8 @@ public:
void setSignature(unsigned char *, int);
void updateHash(unsigned char * data_block, int data_len);
NSSCMSVerificationStatus validateSignature();
SECErrorCodes validateCertificate(time_t validation_time = -1);
// Use -1 as validation_time for now
SECErrorCodes validateCertificate(time_t validation_time);
//Translate NSS error codes
static SignatureValidationStatus NSS_SigTranslate(NSSCMSVerificationStatus nss_code);
......
......@@ -7,6 +7,7 @@
// Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com>
// Copyright 2015 André Esser <bepandre@hotmail.com>
// Copyright 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
// Copyright 2017 Albert Astals Cid <aacid@kde.org>
//
//========================================================================
......@@ -17,7 +18,11 @@
#include <stdlib.h>
#include <string.h>
#include <hasht.h>
#ifdef ENABLE_NSS3
#include <hasht.h>
#else
static const int HASH_AlgNULL = -1;
#endif
/* Constructor & Destructor */
......
......@@ -6,7 +6,7 @@
//
// Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com>
// Copyright 2015 André Esser <bepandre@hotmail.com>
// Copyright 2015 Albert Astals Cid <aacid@kde.org>
// Copyright 2015, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
//
//========================================================================
......@@ -49,7 +49,7 @@ public:
CertificateValidationStatus getCertificateValStatus();
const char *getSignerName();
const char *getSubjectDN();
int getHashAlgorithm();
int getHashAlgorithm(); // Returns a NSS3 HASH_HashType or -1 if compiled without NSS3
time_t getSigningTime();
bool isSubfilterSupported() { return sig_subfilter_supported; }
......
......@@ -38,18 +38,9 @@
#include <math.h>
#include <ctype.h>
enum HASH_HashType
{
HASH_AlgNULL = 0,
HASH_AlgMD2 = 1,
HASH_AlgMD5 = 2,
HASH_AlgSHA1 = 3,
HASH_AlgSHA256 = 4,
HASH_AlgSHA384 = 5,
HASH_AlgSHA512 = 6,
HASH_AlgSHA224 = 7,
HASH_AlgTOTAL
};
#ifdef ENABLE_NSS3
#include <hasht.h>
#endif
namespace {
......@@ -513,7 +504,27 @@ QString SignatureValidationInfo::signerSubjectDN() const
SignatureValidationInfo::HashAlgorithm SignatureValidationInfo::hashAlgorithm() const
{
Q_D(const SignatureValidationInfo);
return static_cast<HashAlgorithm>(d->hash_algorithm);
#ifdef ENABLE_NSS3
switch (d->hash_algorithm)
{
case HASH_AlgMD2:
return HashAlgorithmMd2;
case HASH_AlgMD5:
return HashAlgorithmMd5;
case HASH_AlgSHA1:
return HashAlgorithmSha1;
case HASH_AlgSHA256:
return HashAlgorithmSha256;
case HASH_AlgSHA384:
return HashAlgorithmSha384;
case HASH_AlgSHA512:
return HashAlgorithmSha512;
case HASH_AlgSHA224:
return HashAlgorithmSha224;
}
#endif
return HashAlgorithmUnknown;
}
time_t SignatureValidationInfo::signingTime() const
......@@ -522,11 +533,6 @@ time_t SignatureValidationInfo::signingTime() const
return d->signing_time;
}
QDateTime SignatureValidationInfo::signingDateTime() const
{
return QDateTime::fromTime_t(signingTime());
}
QByteArray SignatureValidationInfo::signature() const
{
Q_D(const SignatureValidationInfo);
......@@ -581,7 +587,7 @@ FormField::FormType FormFieldSignature::type() const
{
return FormField::FormSignature;
}
FormFieldSignature::SignatureType FormFieldSignature::signatureType() const
{
SignatureType sigType = AdbePkcs7detached;
......@@ -609,7 +615,8 @@ SignatureValidationInfo FormFieldSignature::validate(ValidateOptions opt) const
SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& validationTime) const
{
FormWidgetSignature* fws = static_cast<FormWidgetSignature*>(m_formData->fm);
SignatureInfo* si = fws->validateSignature(opt & ValidateVerifyCertificate, opt & ValidateForceRevalidation);
const time_t validationTimeT = validationTime.isValid() ? validationTime.toTime_t() : -1;
SignatureInfo* si = fws->validateSignature(opt & ValidateVerifyCertificate, opt & ValidateForceRevalidation, validationTimeT);
SignatureValidationInfoPrivate* priv = new SignatureValidationInfoPrivate;
switch (si->getSignatureValStatus()) {
case SIGNATURE_VALID:
......@@ -664,7 +671,7 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
priv->hash_algorithm = si->getHashAlgorithm();
priv->signing_time = si->getSigningTime();
std::vector<Goffset> ranges = fws->getSignedRangeBounds();
const std::vector<Goffset> ranges = fws->getSignedRangeBounds();
if (!ranges.empty())
{
for (Goffset bound : ranges)
......@@ -672,11 +679,10 @@ SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& v
priv->range_bounds.append(bound);
}
}
GooString* checkedSignature = fws->getCheckedSignature();
GooString* checkedSignature = fws->getCheckedSignature(&priv->docLength);
if (priv->range_bounds.size() == 4 && checkedSignature)
{
priv->signature = QByteArray::fromHex(checkedSignature->getCString());
priv->docLength = fws->getCheckedFileSize();
}
delete checkedSignature;
......
......@@ -405,19 +405,19 @@ namespace Poppler {
};
/**
* The hash algorithme of the signature
The hash algorithm of the signature
\since 0.58
*/
enum HashAlgorithm
{
HashAlgNULL = 0,
HashAlgMD2 = 1,
HashAlgMD5 = 2,
HashAlgSHA1 = 3,
HashAlgSHA256 = 4,
HashAlgSHA384 = 5,
HashAlgSHA512 = 6,
HashAlgSHA224 = 7,
HashAlgTOTAL
HashAlgorithmUnknown,
HashAlgorithmMd2,
HashAlgorithmMd5,
HashAlgorithmSha1,
HashAlgorithmSha256,
HashAlgorithmSha384,
HashAlgorithmSha512,
HashAlgorithmSha224
};
/// \cond PRIVATE
......@@ -442,11 +442,13 @@ namespace Poppler {
/**
The signer subject distinguished name associated with the signature.
\since 0.58
*/
QString signerSubjectDN() const;
/**
The the hash algorithm used for the signature.
\since 0.58
*/
HashAlgorithm hashAlgorithm() const;
......@@ -454,21 +456,23 @@ namespace Poppler {
The signing time associated with the signature.
*/
time_t signingTime() const;
QDateTime signingDateTime() const;
/**
Get the signature binary data.
\since 0.58
*/
QByteArray signature() const;
/**
Get the bounds of the ranges of the document which are signed.
\since 0.58
*/
QList<qint64> signedRangeBounds() const;
/**
Checks whether the signature authenticates the total document
except for the signature itself.
\since 0.58
*/
bool signsTotalDocument() const;
......@@ -489,14 +493,15 @@ namespace Poppler {
class POPPLER_QT5_EXPORT FormFieldSignature : public FormField {
public:
/**
The types of signature fields.
*/
enum SignatureType {
AdbePkcs7sha1,
AdbePkcs7detached,
EtsiCAdESdetached
};
/**
The types of signature fields.
\since 0.58
*/
enum SignatureType {
AdbePkcs7sha1,
AdbePkcs7detached,
EtsiCAdESdetached
};
/**
The validation options of this signature.
......@@ -513,14 +518,26 @@ namespace Poppler {
FormType type() const override;
SignatureType signatureType() const;
/**
The signature type
\since 0.58
*/
SignatureType signatureType() const;
/**
Validate the signature.
Validate the signature with now as validation time.
Reset signature validatation info of scoped instance.
*/
SignatureValidationInfo validate(ValidateOptions opt) const;
/**
Validate the signature with @p validationTime as validation time.
Reset signature validatation info of scoped instance.
\since 0.58
*/
SignatureValidationInfo validate(int opt, const QDateTime& validationTime) const;
private:
......
......@@ -6,7 +6,7 @@
//
// Copyright 2015 André Guerreiro <aguerreiro1985@gmail.com>
// Copyright 2015 André Esser <bepandre@hotmail.com>
// Copyright 2015 Albert Astals Cid <aacid@kde.org>
// Copyright 2015, 2017 Albert Astals Cid <aacid@kde.org>
// Copyright 2016 Markus Kilås <digital@markuspage.com>
// Copyright 2017 Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
//
......@@ -19,7 +19,7 @@
#include <stddef.h>
#include <string.h>
#include <time.h>
#include "goo/GooList.h"
#include <hasht.h>
#include "parseargs.h"
#include "Object.h"
#include "Array.h"
......@@ -30,20 +30,6 @@
#include "GlobalParams.h"
#include "SignatureInfo.h"
enum HASH_HashType
{
HASH_AlgNULL = 0,
HASH_AlgMD2 = 1,
HASH_AlgMD5 = 2,
HASH_AlgSHA1 = 3,
HASH_AlgSHA256 = 4,
HASH_AlgSHA384 = 5,
HASH_AlgSHA512 = 6,
HASH_AlgSHA224 = 7,
HASH_AlgTOTAL
};
const char * getReadableSigState(SignatureValidationStatus sig_vs)
{
switch(sig_vs) {
......@@ -169,7 +155,7 @@ int main(int argc, char *argv[])
}
for (unsigned int i = 0; i < sigCount; i++) {
sig_info = sig_widgets.at(i)->validateSignature(!dontVerifyCert, false);
sig_info = sig_widgets.at(i)->validateSignature(!dontVerifyCert, false, -1 /* now */);
printf("Signature #%u:\n", i+1);
printf(" - Signer Certificate Common Name: %s\n", sig_info->getSignerName());
printf(" - Signer full Distinguished Name: %s\n", sig_info->getSubjectDN());
......@@ -222,8 +208,9 @@ int main(int argc, char *argv[])
int i = 0;
printf(" - Signed Ranges: [%lld - %lld], [%lld - %lld]\n",
ranges[0], ranges[1], ranges[2], ranges[3]);
GooString* signature = sig_widgets.at(i)->getCheckedSignature();
if (signature && sig_widgets.at(i)->getCheckedFileSize() == ranges[3])
Goffset checked_file_size;
GooString* signature = sig_widgets.at(i)->getCheckedSignature(&checked_file_size);
if (signature && checked_file_size == ranges[3])
{
printf(" - Total document signed\n");
delete signature;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment