/* poppler-form.h: qt interface to poppler
 * Copyright (C) 2007-2008, 2011, Pino Toscano <pino@kde.org>
 * Copyright (C) 2008, 2011, 2012, 2015-2019 Albert Astals Cid <aacid@kde.org>
 * Copyright (C) 2011 Carlos Garcia Campos <carlosgc@gnome.org>
 * Copyright (C) 2012, Adam Reichold <adamreichold@myopera.com>
 * Copyright (C) 2016, Hanno Meyer-Thurow <h.mth@web.de>
 * Copyright (C) 2017, Hans-Ulrich Jüttner <huj@froreich-bioscientia.de>
 * Copyright (C) 2018, Andre Heinecke <aheinecke@intevation.de>
 * Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info@kdab.com>. Work sponsored by the LiMux project of the city of Munich
 * Copyright (C) 2018 Chinmoy Ranjan Pradhan <chinmoyrp65@protonmail.com>
 * Copyright (C) 2018 Oliver Sander <oliver.sander@tu-dresden.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "poppler-qt5.h"

#include <QtCore/QSizeF>

#include <Form.h>
#include <Object.h>
#include <Link.h>
#include <SignatureInfo.h>
#include <CertificateInfo.h>

#include "poppler-form.h"
#include "poppler-page-private.h"
#include "poppler-private.h"
#include "poppler-annotation-helper.h"

#include <math.h>
#include <ctype.h>

#ifdef ENABLE_NSS3
  #include <hasht.h>
#endif

namespace {

Qt::Alignment formTextAlignment(::FormWidget *fm)
{
  Qt::Alignment qtalign = Qt::AlignLeft;
  switch (fm->getField()->getTextQuadding())
  {
    case quaddingCentered:
      qtalign = Qt::AlignHCenter;
      break;
    case quaddingRightJustified:
      qtalign = Qt::AlignRight;
      break;
    case quaddingLeftJustified:
      qtalign = Qt::AlignLeft;
  }
  return qtalign;
}

}

namespace Poppler {

FormField::FormField(FormFieldData &dd)
  : m_formData(&dd)
{
  const int rotation = m_formData->page->getRotate();
  // reading the coords
  double left, top, right, bottom;
  m_formData->fm->getRect(&left, &bottom, &right, &top);
  // build a normalized transform matrix for this page at 100% scale
  GfxState gfxState( 72.0, 72.0, m_formData->page->getCropBox(), rotation, true );
  const double * gfxCTM = gfxState.getCTM();
  double MTX[6];
  double pageWidth = m_formData->page->getCropWidth();
  double pageHeight = m_formData->page->getCropHeight();
  // landscape and seascape page rotation: be sure to use the correct (== rotated) page size
  if (((rotation / 90) % 2) == 1)
    qSwap(pageWidth, pageHeight);
  for ( int i = 0; i < 6; i+=2 )
  {
    MTX[i] = gfxCTM[i] / pageWidth;
    MTX[i+1] = gfxCTM[i+1] / pageHeight;
  }
  QPointF topLeft;
  XPDFReader::transform( MTX, qMin( left, right ), qMax( top, bottom ), topLeft );
  QPointF bottomRight;
  XPDFReader::transform( MTX, qMax( left, right ), qMin( top, bottom ), bottomRight );
  m_formData->box = QRectF(topLeft, QSizeF(bottomRight.x() - topLeft.x(), bottomRight.y() - topLeft.y()));
}

FormField::~FormField()
{
  delete m_formData;
  m_formData = nullptr;
}

QRectF FormField::rect() const
{
  return m_formData->box;
}

int FormField::id() const
{
  return m_formData->fm->getID();
}

QString FormField::name() const
{
  QString name;
  if (const GooString *goo = m_formData->fm->getPartialName())
  {
    name = QString::fromLatin1(goo->c_str());
  }
  return name;
}

void FormField::setName(const QString &name) const
{
  GooString * goo = QStringToGooString( name );
  m_formData->fm->setPartialName(*goo);
  delete goo;
}

QString FormField::fullyQualifiedName() const
{
  QString name;
  if (GooString *goo = m_formData->fm->getFullyQualifiedName())
  {
    name = UnicodeParsedString(goo);
  }
  return name;
}

QString FormField::uiName() const
{
  QString name;
  if (const GooString *goo = m_formData->fm->getAlternateUiName())
  {
    name = QString::fromLatin1(goo->c_str());
  }
  return name;
}

bool FormField::isReadOnly() const
{
  return m_formData->fm->isReadOnly();
}

void FormField::setReadOnly(bool value)
{
  m_formData->fm->setReadOnly(value);
}

bool FormField::isVisible() const
{
  return !(m_formData->fm->getWidgetAnnotation()->getFlags() & Annot::flagHidden);
}

void FormField::setVisible(bool value)
{
  unsigned int flags = m_formData->fm->getWidgetAnnotation()->getFlags();
  if (value) {
    flags &= ~Annot::flagHidden;
  } else {
    flags |= Annot::flagHidden;
  }
  m_formData->fm->getWidgetAnnotation()->setFlags(flags);
}

Link* FormField::activationAction() const
{
  Link* action = nullptr;
  if (::LinkAction *act = m_formData->fm->getActivationAction())
  {
    action = PageData::convertLinkActionToLink(act, m_formData->doc, QRectF());
  }
  return action;
}

Link *FormField::additionalAction(AdditionalActionType type) const
{
  Annot::FormAdditionalActionsType actionType = Annot::actionFieldModified;
  switch ( type )
  {
      case FieldModified:  actionType = Annot::actionFieldModified; break;
      case FormatField:    actionType = Annot::actionFormatField; break;
      case ValidateField:  actionType = Annot::actionValidateField; break;
      case CalculateField: actionType = Annot::actionCalculateField; break;

  }

  Link* action = nullptr;
  if (::LinkAction *act = m_formData->fm->getAdditionalAction(actionType))
  {
    action = PageData::convertLinkActionToLink(act, m_formData->doc, QRectF());
  }
  return action;
}

Link *FormField::additionalAction(Annotation::AdditionalActionType type) const
{
  ::AnnotWidget *w = m_formData->fm->getWidgetAnnotation();
  if (!w)
  {
    return nullptr;
  }

  const Annot::AdditionalActionsType actionType = toPopplerAdditionalActionType(type);

  Link* action = nullptr;
  if (::LinkAction *act = w->getAdditionalAction(actionType))
  {
    action = PageData::convertLinkActionToLink(act, m_formData->doc, QRectF());
  }
  return action;
}

FormFieldButton::FormFieldButton(DocumentData *doc, ::Page *p, ::FormWidgetButton *w)
  : FormField(*new FormFieldData(doc, p, w))
{
}

FormFieldButton::~FormFieldButton()
{
}

FormFieldButton::FormType FormFieldButton::type() const
{
  return FormField::FormButton;
}

FormFieldButton::ButtonType FormFieldButton::buttonType() const
{
  FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm);
  switch (fwb->getButtonType())
  {
    case formButtonCheck:
      return FormFieldButton::CheckBox;
      break;
    case formButtonPush:
      return FormFieldButton::Push;
      break;
    case formButtonRadio:
      return FormFieldButton::Radio;
      break;
  }
  return FormFieldButton::CheckBox;
}

QString FormFieldButton::caption() const
{
  FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm);
  QString ret;
  if (fwb->getButtonType() == formButtonPush)
  {
    Dict *dict = m_formData->fm->getObj()->getDict();
    Object obj1 = dict->lookup("MK");
    if (obj1.isDict())
    {
      AnnotAppearanceCharacs appearCharacs(obj1.getDict());
      if (appearCharacs.getNormalCaption())
      {
        ret = UnicodeParsedString(appearCharacs.getNormalCaption());
      }
    }
  }
  else
  {
    if (const char *goo = fwb->getOnStr())
    {
      ret = QString::fromUtf8(goo);
    }
  }
  return ret;
}

bool FormFieldButton::state() const
{
  FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm);
  return fwb->getState();
}

void FormFieldButton::setState( bool state )
{
  FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm);
  fwb->setState((bool)state);
}

QList<int> FormFieldButton::siblings() const
{
  FormWidgetButton* fwb = static_cast<FormWidgetButton*>(m_formData->fm);
  ::FormFieldButton* ffb = static_cast< ::FormFieldButton* >(fwb->getField());
  if (fwb->getButtonType() == formButtonPush)
    return QList<int>();

  QList<int> ret;
  for (int i = 0; i < ffb->getNumSiblings(); ++i)
  {
    ::FormFieldButton* sibling = static_cast< ::FormFieldButton* >(ffb->getSibling(i));
    for (int j = 0; j < sibling->getNumWidgets(); ++j)
    {
        FormWidget *w = sibling->getWidget(j);
        if (w) ret.append(w->getID());
    }
  }

  return ret;
}


FormFieldText::FormFieldText(DocumentData *doc, ::Page *p, ::FormWidgetText *w)
  : FormField(*new FormFieldData(doc, p, w))
{
}

FormFieldText::~FormFieldText()
{
}

FormField::FormType FormFieldText::type() const
{
  return FormField::FormText;
}

FormFieldText::TextType FormFieldText::textType() const
{
  FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm);
  if (fwt->isFileSelect())
    return FormFieldText::FileSelect;
  else if (fwt->isMultiline())
    return FormFieldText::Multiline;
  return FormFieldText::Normal;
}

QString FormFieldText::text() const
{
  const GooString *goo = static_cast<FormWidgetText*>(m_formData->fm)->getContent();
  return UnicodeParsedString(goo);
}

void FormFieldText::setText( const QString& text )
{
  FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm);
  GooString * goo = QStringToUnicodeGooString( text );
  fwt->setContent( goo );
  delete goo;
}

bool FormFieldText::isPassword() const
{
  FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm);
  return fwt->isPassword();
}

bool FormFieldText::isRichText() const
{
  FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm);
  return fwt->isRichText();
}

int FormFieldText::maximumLength() const
{
  FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm);
  const int maxlen = fwt->getMaxLen();
  return maxlen > 0 ? maxlen : -1;
}

Qt::Alignment FormFieldText::textAlignment() const
{
  return formTextAlignment(m_formData->fm);
}

bool FormFieldText::canBeSpellChecked() const
{
  FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm);
  return !fwt->noSpellCheck();
}

double FormFieldText::getFontSize() const
{
  FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm);
  return fwt->getTextFontSize();
}

void FormFieldText::setFontSize(int fontSize)
{
  FormWidgetText* fwt = static_cast<FormWidgetText*>(m_formData->fm);
  fwt->setTextFontSize(fontSize);
}

FormFieldChoice::FormFieldChoice(DocumentData *doc, ::Page *p, ::FormWidgetChoice *w)
  : FormField(*new FormFieldData(doc, p, w))
{
}

FormFieldChoice::~FormFieldChoice()
{
}

FormFieldChoice::FormType FormFieldChoice::type() const
{
  return FormField::FormChoice;
}

FormFieldChoice::ChoiceType FormFieldChoice::choiceType() const
{
  FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm);
  if (fwc->isCombo())
    return FormFieldChoice::ComboBox;
  return FormFieldChoice::ListBox;
}

QStringList FormFieldChoice::choices() const
{
  FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm);
  QStringList ret;
  int num = fwc->getNumChoices();
  ret.reserve(num);
  for (int i = 0; i < num; ++i)
  {
    ret.append(UnicodeParsedString(fwc->getChoice(i)));
  }
  return ret;
}

bool FormFieldChoice::isEditable() const
{
  FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm);
  return fwc->isCombo() ? fwc->hasEdit() : false;
}

bool FormFieldChoice::multiSelect() const
{
  FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm);
  return !fwc->isCombo() ? fwc->isMultiSelect() : false;
}

QList<int> FormFieldChoice::currentChoices() const
{
  FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm);
  int num = fwc->getNumChoices();
  QList<int> choices;
  for ( int i = 0; i < num; ++i )
    if ( fwc->isSelected( i ) )
      choices.append( i );
  return choices;
}

void FormFieldChoice::setCurrentChoices( const QList<int> &choice )
{
  FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm);
  fwc->deselectAll();
  for ( int i = 0; i < choice.count(); ++i )
    fwc->select( choice.at( i ) );
}

QString FormFieldChoice::editChoice() const
{
  FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm);
  
  if ( fwc->isCombo() && fwc->hasEdit() )
    return UnicodeParsedString(fwc->getEditChoice());
  else
    return QString();
}

void FormFieldChoice::setEditChoice(const QString& text)
{
  FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm);
  
  if ( fwc->isCombo() && fwc->hasEdit() )
  {
    GooString* goo = QStringToUnicodeGooString( text );
    fwc->setEditChoice( goo );
    delete goo;
  }
}

Qt::Alignment FormFieldChoice::textAlignment() const
{
  return formTextAlignment(m_formData->fm);
}

bool FormFieldChoice::canBeSpellChecked() const
{
  FormWidgetChoice* fwc = static_cast<FormWidgetChoice*>(m_formData->fm);
  return !fwc->noSpellCheck();
}

class CertificateInfoPrivate
{
public:
  struct EntityInfo
  {
    QString common_name;
    QString email_address;
    QString org_name;
    QString distinguished_name;
  };

  EntityInfo issuer_info;
  EntityInfo subject_info;
  QByteArray certificate_der;
  QByteArray serial_number;
  QByteArray public_key;
  QDateTime validity_start;
  QDateTime validity_end;
  int public_key_type;
  int public_key_strength;
  int ku_extensions;
  int version;
  bool is_self_signed;
  bool is_null;
};

CertificateInfo::CertificateInfo(CertificateInfoPrivate* priv)
  : d_ptr( priv )
{
}

CertificateInfo::CertificateInfo(const CertificateInfo &other)
 : d_ptr( other.d_ptr )
{
}

CertificateInfo::~CertificateInfo() = default;

CertificateInfo &CertificateInfo::operator=(const CertificateInfo &other)
{
  if ( this != &other )
    d_ptr = other.d_ptr;

  return *this;
}

bool CertificateInfo::isNull() const
{
  Q_D(const CertificateInfo);
  return d->is_null;
}

int CertificateInfo::version() const
{
  Q_D(const CertificateInfo);
  return d->version;
}

QByteArray CertificateInfo::serialNumber() const
{
  Q_D(const CertificateInfo);
  return d->serial_number;
}

QString CertificateInfo::issuerInfo(EntityInfoKey key) const
{
  Q_D(const CertificateInfo);
  switch (key)
  {
    case CommonName:
      return d->issuer_info.common_name;
    case DistinguishedName:
      return d->issuer_info.distinguished_name;
    case EmailAddress:
      return d->issuer_info.email_address;
    case Organization:
      return d->issuer_info.org_name;
    default:
      return QString();
  }
}

QString CertificateInfo::subjectInfo(EntityInfoKey key) const
{
  Q_D(const CertificateInfo);
  switch (key)
  {
    case CommonName:
      return d->subject_info.common_name;
    case DistinguishedName:
      return d->subject_info.distinguished_name;
    case EmailAddress:
      return d->subject_info.email_address;
    case Organization:
      return d->subject_info.org_name;
    default:
      return QString();
  }
}

QDateTime CertificateInfo::validityStart() const
{
  Q_D(const CertificateInfo);
  return d->validity_start;
}

QDateTime CertificateInfo::validityEnd() const
{
  Q_D(const CertificateInfo);
  return d->validity_end;
}

CertificateInfo::KeyUsageExtensions CertificateInfo::keyUsageExtensions() const
{
  Q_D(const CertificateInfo);

  KeyUsageExtensions kuExtensions = KuNone;
  if (d->ku_extensions & KU_DIGITAL_SIGNATURE)
    kuExtensions |= KuDigitalSignature;
  if (d->ku_extensions & KU_NON_REPUDIATION)
    kuExtensions |= KuNonRepudiation;
  if (d->ku_extensions & KU_KEY_ENCIPHERMENT)
    kuExtensions |= KuKeyEncipherment;
  if (d->ku_extensions & KU_DATA_ENCIPHERMENT)
    kuExtensions |= KuDataEncipherment;
  if (d->ku_extensions & KU_KEY_AGREEMENT)
    kuExtensions |= KuKeyAgreement;
  if (d->ku_extensions & KU_KEY_CERT_SIGN)
    kuExtensions |= KuKeyCertSign;
  if (d->ku_extensions & KU_CRL_SIGN)
    kuExtensions |= KuClrSign;
  if (d->ku_extensions & KU_ENCIPHER_ONLY)
    kuExtensions |= KuEncipherOnly;

  return kuExtensions;
}

QByteArray CertificateInfo::publicKey() const
{
  Q_D(const CertificateInfo);
  return d->public_key;
}

CertificateInfo::PublicKeyType CertificateInfo::publicKeyType() const
{
  Q_D(const CertificateInfo);
  switch (d->public_key_type)
  {
    case RSAKEY:
      return RsaKey;
    case DSAKEY:
      return DsaKey;
    case ECKEY:
      return EcKey;
    default:
      return OtherKey;
  }
}

int CertificateInfo::publicKeyStrength() const
{
  Q_D(const CertificateInfo);
  return d->public_key_strength;
}

bool CertificateInfo::isSelfSigned() const
{
  Q_D(const CertificateInfo);
  return d->is_self_signed;
}

QByteArray CertificateInfo::certificateData() const
{
  Q_D(const CertificateInfo);
  return d->certificate_der;
}

class SignatureValidationInfoPrivate {
public:
	SignatureValidationInfoPrivate(CertificateInfo &&ci)
		: cert_info(ci)
	{
	}

	SignatureValidationInfo::SignatureStatus signature_status;
	SignatureValidationInfo::CertificateStatus certificate_status;
	CertificateInfo cert_info;

	QByteArray signature;
	QString signer_name;
	QString signer_subject_dn;
	QString location;
	QString reason;
	int hash_algorithm;
	time_t signing_time;
	QList<qint64> range_bounds;
	qint64 docLength;
};


SignatureValidationInfo::SignatureValidationInfo(SignatureValidationInfoPrivate* priv)
  : d_ptr(priv)
{
}

SignatureValidationInfo::SignatureValidationInfo(const SignatureValidationInfo &other)
 : d_ptr( other.d_ptr )
{
}

SignatureValidationInfo::~SignatureValidationInfo()
{
}

SignatureValidationInfo::SignatureStatus SignatureValidationInfo::signatureStatus() const
{
  Q_D(const SignatureValidationInfo);
  return d->signature_status;
}

SignatureValidationInfo::CertificateStatus SignatureValidationInfo::certificateStatus() const
{
  Q_D(const SignatureValidationInfo);
  return d->certificate_status;
}

QString SignatureValidationInfo::signerName() const
{
  Q_D(const SignatureValidationInfo);
  return d->signer_name;
}

QString SignatureValidationInfo::signerSubjectDN() const
{
  Q_D(const SignatureValidationInfo);
  return d->signer_subject_dn;
}

QString SignatureValidationInfo::location() const
{
  Q_D(const SignatureValidationInfo);
  return d->location;
}

QString SignatureValidationInfo::reason() const
{
  Q_D(const SignatureValidationInfo);
  return d->reason;
}

SignatureValidationInfo::HashAlgorithm SignatureValidationInfo::hashAlgorithm() const
{
#ifdef ENABLE_NSS3
  Q_D(const SignatureValidationInfo);

  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
{
  Q_D(const SignatureValidationInfo);
  return d->signing_time;
}

QByteArray SignatureValidationInfo::signature() const
{
  Q_D(const SignatureValidationInfo);
  return d->signature;
}

QList<qint64> SignatureValidationInfo::signedRangeBounds() const
{
  Q_D(const SignatureValidationInfo);
  return d->range_bounds;
}

bool SignatureValidationInfo::signsTotalDocument() const
{
  Q_D(const SignatureValidationInfo);
  if (d->range_bounds.size() == 4 && d->range_bounds.value(0) == 0 &&
      d->range_bounds.value(1) >= 0 &&
      d->range_bounds.value(2) > d->range_bounds.value(1) &&
      d->range_bounds.value(3) >= d->range_bounds.value(2))
  {
    // The range from d->range_bounds.value(1) to d->range_bounds.value(2) is
    // not authenticated by the signature and should only contain the signature
    // itself padded with 0 bytes. This has been checked in readSignature().
    // If it failed, d->signature is empty.
    // A potential range after d->range_bounds.value(3) would be also not
    // authenticated. Therefore d->range_bounds.value(3) should coincide with
    // the end of the document.
    if (d->docLength == d->range_bounds.value(3) && !d->signature.isEmpty())
      return true;
  }
  return false;
}

CertificateInfo SignatureValidationInfo::certificateInfo() const
{
  Q_D(const SignatureValidationInfo);
  return d->cert_info;
}

SignatureValidationInfo &SignatureValidationInfo::operator=(const SignatureValidationInfo &other)
{
  if ( this != &other )
    d_ptr = other.d_ptr;

  return *this;
}

FormFieldSignature::FormFieldSignature(DocumentData *doc, ::Page *p, ::FormWidgetSignature *w)
  : FormField(*new FormFieldData(doc, p, w))
{
}

FormFieldSignature::~FormFieldSignature()
{
}

FormField::FormType FormFieldSignature::type() const
{
  return FormField::FormSignature;
}

FormFieldSignature::SignatureType FormFieldSignature::signatureType() const
{
  SignatureType sigType = AdbePkcs7detached;
  FormWidgetSignature* fws = static_cast<FormWidgetSignature*>(m_formData->fm);
  switch (fws->signatureType())
  {
    case adbe_pkcs7_sha1:
      sigType = AdbePkcs7sha1;
      break;
    case adbe_pkcs7_detached:
      sigType = AdbePkcs7detached;
      break;
    case ETSI_CAdES_detached:
      sigType = EtsiCAdESdetached;
      break;
  }
  return sigType;
}

SignatureValidationInfo FormFieldSignature::validate(ValidateOptions opt) const
{
  return validate(opt, QDateTime());
}

SignatureValidationInfo FormFieldSignature::validate(int opt, const QDateTime& validationTime) const
{
  FormWidgetSignature* fws = static_cast<FormWidgetSignature*>(m_formData->fm);
  const time_t validationTimeT = validationTime.isValid() ? validationTime.toTime_t() : -1;
  SignatureInfo* si = fws->validateSignature(opt & ValidateVerifyCertificate, opt & ValidateForceRevalidation, validationTimeT);

  // get certificate info
  const X509CertificateInfo *ci = si->getCertificateInfo();
  CertificateInfoPrivate* certPriv = new CertificateInfoPrivate;
  certPriv->is_null = true;
  if (ci)
  {
    certPriv->version = ci->getVersion();
    certPriv->ku_extensions = ci->getKeyUsageExtensions();

    const GooString &certSerial = ci->getSerialNumber();
    certPriv->serial_number = QByteArray(certSerial.c_str(), certSerial.getLength());

    const X509CertificateInfo::EntityInfo &issuerInfo = ci->getIssuerInfo();
    certPriv->issuer_info.common_name = issuerInfo.commonName.c_str();
    certPriv->issuer_info.distinguished_name = issuerInfo.distinguishedName.c_str();
    certPriv->issuer_info.email_address = issuerInfo.email.c_str();
    certPriv->issuer_info.org_name = issuerInfo.organization.c_str();

    const X509CertificateInfo::EntityInfo &subjectInfo = ci->getSubjectInfo();
    certPriv->subject_info.common_name = subjectInfo.commonName.c_str();
    certPriv->subject_info.distinguished_name = subjectInfo.distinguishedName.c_str();
    certPriv->subject_info.email_address = subjectInfo.email.c_str();
    certPriv->subject_info.org_name = subjectInfo.organization.c_str();

    X509CertificateInfo::Validity certValidity = ci->getValidity();
    certPriv->validity_start = QDateTime::fromTime_t(certValidity.notBefore, Qt::UTC);
    certPriv->validity_end = QDateTime::fromTime_t(certValidity.notAfter, Qt::UTC);

    const X509CertificateInfo::PublicKeyInfo &pkInfo = ci->getPublicKeyInfo();
    certPriv->public_key = QByteArray(pkInfo.publicKey.c_str(), pkInfo.publicKey.getLength());
    certPriv->public_key_type = static_cast<int>(pkInfo.publicKeyType);
    certPriv->public_key_strength = pkInfo.publicKeyStrength;

    const GooString &certDer = ci->getCertificateDER();
    certPriv->certificate_der = QByteArray(certDer.c_str(), certDer.getLength());

    certPriv->is_null = false;
  }

  SignatureValidationInfoPrivate* priv = new SignatureValidationInfoPrivate(CertificateInfo(certPriv));
  switch (si->getSignatureValStatus()) {
    case SIGNATURE_VALID:
      priv->signature_status = SignatureValidationInfo::SignatureValid;
      break;
    case SIGNATURE_INVALID:
      priv->signature_status = SignatureValidationInfo::SignatureInvalid;
      break;
    case SIGNATURE_DIGEST_MISMATCH:
      priv->signature_status = SignatureValidationInfo::SignatureDigestMismatch;
      break;
    case SIGNATURE_DECODING_ERROR:
      priv->signature_status = SignatureValidationInfo::SignatureDecodingError;
      break;
    default:
    case SIGNATURE_GENERIC_ERROR:
      priv->signature_status = SignatureValidationInfo::SignatureGenericError;
      break;
    case SIGNATURE_NOT_FOUND:
      priv->signature_status = SignatureValidationInfo::SignatureNotFound;
      break;
    case SIGNATURE_NOT_VERIFIED:
      priv->signature_status = SignatureValidationInfo::SignatureNotVerified;
      break;
  }
  switch (si->getCertificateValStatus()) {
    case CERTIFICATE_TRUSTED:
      priv->certificate_status = SignatureValidationInfo::CertificateTrusted;
      break;
    case CERTIFICATE_UNTRUSTED_ISSUER:
      priv->certificate_status = SignatureValidationInfo::CertificateUntrustedIssuer;
      break;
    case CERTIFICATE_UNKNOWN_ISSUER:
      priv->certificate_status = SignatureValidationInfo::CertificateUnknownIssuer;
      break;
    case CERTIFICATE_REVOKED:
      priv->certificate_status = SignatureValidationInfo::CertificateRevoked;
      break;
    case CERTIFICATE_EXPIRED:
      priv->certificate_status = SignatureValidationInfo::CertificateExpired;
      break;
    default:
    case CERTIFICATE_GENERIC_ERROR:
      priv->certificate_status = SignatureValidationInfo::CertificateGenericError;
      break;
    case CERTIFICATE_NOT_VERIFIED:
      priv->certificate_status = SignatureValidationInfo::CertificateNotVerified;
      break;
  }
  priv->signer_name = si->getSignerName();
  priv->signer_subject_dn = si->getSubjectDN();
  priv->hash_algorithm = si->getHashAlgorithm();
  priv->location = si->getLocation();
  priv->reason = si->getReason();

  priv->signing_time = si->getSigningTime();
  const std::vector<Goffset> ranges = fws->getSignedRangeBounds();
  if (!ranges.empty())
  {
    for (Goffset bound : ranges)
    {
      priv->range_bounds.append(bound);
    }
  }
  GooString* checkedSignature = fws->getCheckedSignature(&priv->docLength);
  if (priv->range_bounds.size() == 4 && checkedSignature)
  {
    priv->signature = QByteArray::fromHex(checkedSignature->c_str());
  }
  delete checkedSignature;

  return SignatureValidationInfo(priv);
}

}
