Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow validate signatures with TimeStampValidationData #455

Merged
merged 1 commit into from
May 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 7 additions & 13 deletions src/SignatureXAdES_B.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ namespace digidoc

static Base64Binary toBase64(const vector<unsigned char> &v)
{
return Base64Binary(v.data(), v.size());
return {v.data(), v.size()};
}

}
Expand Down Expand Up @@ -339,7 +339,7 @@ SignatureXAdES_B::SignatureXAdES_B(istream &sigdata, ASiContainer *bdoc, bool re
if(!usp->archiveTimeStamp().empty())
THROW("ArchiveTimeStamp is not supported");
if(!usp->timeStampValidationData().empty())
THROW("TimeStampValidationData is not supported");
WARN("TimeStampValidationData is not supported");
}
}

Expand Down Expand Up @@ -600,7 +600,7 @@ void SignatureXAdES_B::validate(const string &policy) const
uri.erase(0, 1);
signatureref.insert({ uri, mimeinfo["#"+ref.id().get()] });
}
};
}
if(!signedInfoFound)
EXCEPTION_ADD(exception, "SignedProperties not found");

Expand Down Expand Up @@ -628,7 +628,7 @@ void SignatureXAdES_B::validate(const string &policy) const
}
else
EXCEPTION_ADD(exception, "Manifest datafile not listed in signature references %s", file->fileName().c_str());
};
}
}

if(bdoc->dataFiles().empty())
Expand Down Expand Up @@ -958,14 +958,8 @@ void SignatureXAdES_B::setSigningTime(const struct tm &signingTime)
*/
void SignatureXAdES_B::setSignatureValue(const vector<unsigned char> &signatureValue)
{
// Make copy of current signature value id.
string id = signature->signatureValue().id().get();

// Set new signature value.
signature->signatureValue(toBase64(signatureValue));

// Set signature value id back to its old value.
signature->signatureValue().id(id);
SignatureValueType buffer = toBase64(signatureValue);
signature->signatureValue().swap(buffer);
sigdata_.clear();
}

Expand Down Expand Up @@ -1160,7 +1154,7 @@ vector<string> SignatureXAdES_B::signerRoles() const
getSignedSignatureProperties().signerRole();
const SignedSignaturePropertiesType::SignerRoleV2Optional &roleV2Opt =
getSignedSignatureProperties().signerRoleV2();
const ClaimedRolesListType::ClaimedRoleSequence &claimedRoleSequence = [&]() -> ClaimedRolesListType::ClaimedRoleSequence const {
const ClaimedRolesListType::ClaimedRoleSequence &claimedRoleSequence = [&]() -> ClaimedRolesListType::ClaimedRoleSequence {
// return elements from SignerRole element or SignerRoleV2 when available
if(roleOpt.present() && roleOpt->claimedRoles().present())
return roleOpt->claimedRoles()->claimedRole();
Expand Down
68 changes: 26 additions & 42 deletions src/SignatureXAdES_T.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include "ASiC_E.h"
#include "Conf.h"
#include "crypto/Digest.h"
#include "crypto/OpenSSLHelpers.h"
#include "crypto/TS.h"
#include "crypto/X509Cert.h"
#include "util/DateTime.h"
Expand All @@ -41,11 +40,11 @@ using namespace std;

void SignatureXAdES_T::createUnsignedSignatureProperties()
{
if(qualifyingProperties().unsignedProperties().present())
if(qualifyingProperties().unsignedProperties())
return;
UnsignedPropertiesType usProp;
usProp.unsignedSignatureProperties(UnsignedSignaturePropertiesType());
qualifyingProperties().unsignedProperties(usProp);
qualifyingProperties().unsignedProperties(make_unique<UnsignedPropertiesType>());
qualifyingProperties().unsignedProperties()
->unsignedSignatureProperties(make_unique<UnsignedSignaturePropertiesType>());
}

vector<unsigned char> SignatureXAdES_T::messageImprint() const
Expand Down Expand Up @@ -81,15 +80,16 @@ void SignatureXAdES_T::extendSignatureProfile(const std::string &profile)

TS tsa(CONF(TSUrl), calc, " Profile: " + profile);
vector<unsigned char> der = tsa;
UnsignedSignaturePropertiesType::SignatureTimeStampType ts;
ts.id(id() + Log::format("-T%lu", (unsigned long)unsignedSignatureProperties().signatureTimeStamp().size()));
ts.canonicalizationMethod(signature->signedInfo().canonicalizationMethod());
ts.encapsulatedTimeStamp().push_back(EncapsulatedPKIDataType(Base64Binary(der.data(), der.size())));
unsignedSignatureProperties().signatureTimeStamp().push_back(ts);
unsignedSignatureProperties().contentOrder().push_back(
UnsignedSignaturePropertiesType::ContentOrderType(
UnsignedSignaturePropertiesType::signatureTimeStampId,
unsignedSignatureProperties().signatureTimeStamp().size() - 1));
auto &usp = unsignedSignatureProperties();
auto ts = make_unique<UnsignedSignaturePropertiesType::SignatureTimeStampType>();
ts->id(id() + Log::format("-T%zu", usp.signatureTimeStamp().size()));
ts->canonicalizationMethod(signature->signedInfo().canonicalizationMethod());
ts->encapsulatedTimeStamp().push_back(make_unique<EncapsulatedPKIDataType>(
Base64Binary(der.data(), der.size(), der.size(), false)));
usp.signatureTimeStamp().push_back(move(ts));
usp.contentOrder().emplace_back(UnsignedSignaturePropertiesType::ContentOrderType(
UnsignedSignaturePropertiesType::signatureTimeStampId,
unsignedSignatureProperties().signatureTimeStamp().size() - 1));
sigdata_.clear();
}

Expand All @@ -104,7 +104,7 @@ TS SignatureXAdES_T::tsFromBase64() const
return {};
const GenericTimeStampType::EncapsulatedTimeStampType &bin =
ts.encapsulatedTimeStamp().front();
return TS((const unsigned char*)bin.data(), bin.size());
return {(const unsigned char*)bin.data(), bin.size()};
} catch(const Exception &) {}
return {};
}
Expand All @@ -114,26 +114,16 @@ void SignatureXAdES_T::validate(const std::string &policy) const
Exception exception(EXCEPTION_PARAMS("Signature validation"));
try {
SignatureXAdES_B::validate(policy);
if(profile().find(ASiC_E::ASIC_TS_PROFILE) == string::npos)
return;
} catch(const Exception &e) {
if(profile().find(ASiC_E::ASIC_TS_PROFILE) == string::npos)
throw;
for(const Exception &ex: e.causes())
exception.addCause(ex);
}
if(profile().find(ASiC_E::ASIC_TS_PROFILE) == string::npos)
{
if(!exception.causes().empty())
throw exception;
return;
}

try {
const QualifyingPropertiesType::UnsignedPropertiesOptional &uProps = qualifyingProperties().unsignedProperties();
if(!uProps.present())
THROW_MAIN(exception, "QualifyingProperties must contain UnsignedProperties");
if(uProps->unsignedDataObjectProperties().present())
EXCEPTION_ADD(exception, "unexpected UnsignedDataObjectProperties in Signature");
if(!uProps->unsignedSignatureProperties().present())
THROW_MAIN(exception, "UnsignedProperties must contain UnsignedSignatureProperties");

const UnsignedSignaturePropertiesType::SignatureTimeStampSequence &tseq =
unsignedSignatureProperties().signatureTimeStamp();
if(tseq.empty())
Expand All @@ -148,11 +138,11 @@ void SignatureXAdES_T::validate(const std::string &policy) const
THROW("Missing EncapsulatedTimeStamp");
if(etseq.size() > 1)
THROW("More than one EncapsulatedTimeStamp is not supported");
const GenericTimeStampType::EncapsulatedTimeStampType &bin = etseq.front();

string canonicalizationMethod;
if(ts.canonicalizationMethod().present())
if(ts.canonicalizationMethod())
canonicalizationMethod = ts.canonicalizationMethod()->algorithm();

const GenericTimeStampType::EncapsulatedTimeStampType &bin = etseq.front();
TS tsa((const unsigned char*)bin.data(), bin.size());
Digest calc(tsa.digestMethod());
calcDigestOnNode(&calc, URI_ID_DSIG, "SignatureValue", {}, canonicalizationMethod);
Expand All @@ -178,15 +168,9 @@ void SignatureXAdES_T::validate(const std::string &policy) const

UnsignedSignaturePropertiesType &SignatureXAdES_T::unsignedSignatureProperties() const
{
QualifyingPropertiesType::UnsignedPropertiesOptional &unsignedPropsOptional =
qualifyingProperties().unsignedProperties();
if(!unsignedPropsOptional.present())
if(!qualifyingProperties().unsignedProperties())
THROW("QualifyingProperties block 'UnsignedProperties' is missing.");

UnsignedPropertiesType::UnsignedSignaturePropertiesOptional &unsignedSigProps =
unsignedPropsOptional->unsignedSignatureProperties();
if(!unsignedSigProps.present())
THROW("QualifyingProperties block 'UnsignedSignatureProperties' is missing.");

return unsignedSigProps.get();
if(!qualifyingProperties().unsignedProperties()->unsignedSignatureProperties())
THROW("UnsignedProperties block 'UnsignedSignatureProperties' is missing.");
return qualifyingProperties().unsignedProperties()->unsignedSignatureProperties().get();
}
59 changes: 30 additions & 29 deletions src/xml/UnsignedSignaturePropertiesType.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,7 @@ using namespace xsd::cxx::xml::dom;
#endif

UnsignedSignaturePropertiesType::UnsignedSignaturePropertiesType()
: UnsignedSignaturePropertiesTypeBase()
, ArchiveTimeStampV141_(this)
: ArchiveTimeStampV141_(this)
, TimeStampValidationData_(this)
{
}
Expand All @@ -49,31 +48,35 @@ UnsignedSignaturePropertiesType::UnsignedSignaturePropertiesType(
}

UnsignedSignaturePropertiesType::UnsignedSignaturePropertiesType(const DOMElement &e, Flags f, Container *c)
: UnsignedSignaturePropertiesTypeBase(e, f, c)
: UnsignedSignaturePropertiesTypeBase(e, f | Flags::base, c)
, ArchiveTimeStampV141_(this)
, TimeStampValidationData_(this)
{
xsd::cxx::xml::dom::parser<char> p(e, true, false, true);
parser<char> p(e, true, false, true);
for (; p.more_content(); p.next_content(false))
{
const DOMElement &i(p.cur_element());
const xsd::cxx::xml::qualified_name<char> n(xsd::cxx::xml::dom::name<char>(i));
parse(p, f);
if(!p.more_content())
break;
const DOMElement &i = p.cur_element();
const xsd::cxx::xml::qualified_name<char> n = name<char>(i);
if(n.name() == "ArchiveTimeStamp" && n.namespace_() == "http://uri.etsi.org/01903/v1.4.1#")
{
ArchiveTimeStampV141_.push_back(xadesv141::ArchiveTimeStampTraits::create(i, f, this));
content_order_.push_back(ContentOrderType(archiveTimeStampV141Id, ArchiveTimeStampV141_.size () - 1));
continue;
}
else if(n.name() == "TimeStampValidationData" && n.namespace_() == "http://uri.etsi.org/01903/v1.4.1#")
if(n.name() == "TimeStampValidationData" && n.namespace_() == "http://uri.etsi.org/01903/v1.4.1#")
{
TimeStampValidationData_.push_back(xadesv141::TimeStampValidationDataTraits::create(i, f, this));
content_order_.push_back(ContentOrderType(timeStampValidationDataId, TimeStampValidationData_.size () - 1));
continue;
}
break;
}
}

UnsignedSignaturePropertiesType::~UnsignedSignaturePropertiesType()
{
}
UnsignedSignaturePropertiesType::~UnsignedSignaturePropertiesType() = default;

UnsignedSignaturePropertiesType* UnsignedSignaturePropertiesType::_clone(Flags f, Container *c) const
{
Expand Down Expand Up @@ -106,56 +109,54 @@ void digidoc::xades::operator<< (DOMElement &e, const UnsignedSignaturePropertie
const char XADES141_NS[] = "http://uri.etsi.org/01903/v1.4.1#";
e << static_cast<const Type&>(i);

for(UnsignedSignaturePropertiesType::ContentOrderConstIterator
b(i.contentOrder().begin()), n(i.contentOrder().end());
b != n; ++b)
for(const UnsignedSignaturePropertiesType::ContentOrderType &b: i.contentOrder())
{
switch (b->id)
switch (b.id)
{
case UnsignedSignaturePropertiesType::counterSignatureId:
create_element("CounterSignature", XADES_NS, e) << i.counterSignature()[b->index];
create_element("CounterSignature", XADES_NS, e) << i.counterSignature()[b.index];
continue;
case UnsignedSignaturePropertiesType::signatureTimeStampId:
create_element("SignatureTimeStamp", XADES_NS, e) << i.signatureTimeStamp()[b->index];
create_element("SignatureTimeStamp", XADES_NS, e) << i.signatureTimeStamp()[b.index];
continue;
case UnsignedSignaturePropertiesType::completeCertificateRefsId:
create_element("CompleteCertificateRefs", XADES_NS, e) << i.completeCertificateRefs()[b->index];
create_element("CompleteCertificateRefs", XADES_NS, e) << i.completeCertificateRefs()[b.index];
continue;
case UnsignedSignaturePropertiesType::completeRevocationRefsId:
create_element("CompleteRevocationRefs", XADES_NS, e) << i.completeRevocationRefs()[b->index];
create_element("CompleteRevocationRefs", XADES_NS, e) << i.completeRevocationRefs()[b.index];
continue;
case UnsignedSignaturePropertiesType::attributeCertificateRefsId:
create_element("AttributeCertificateRefs", XADES_NS, e) << i.attributeCertificateRefs()[b->index];
create_element("AttributeCertificateRefs", XADES_NS, e) << i.attributeCertificateRefs()[b.index];
continue;
case UnsignedSignaturePropertiesType::attributeRevocationRefsId:
create_element("AttributeRevocationRefs", XADES_NS, e) << i.attributeRevocationRefs()[b->index];
create_element("AttributeRevocationRefs", XADES_NS, e) << i.attributeRevocationRefs()[b.index];
continue;
case UnsignedSignaturePropertiesType::sigAndRefsTimeStampId:
create_element("SigAndRefsTimeStamp", XADES_NS, e) << i.sigAndRefsTimeStamp()[b->index];
create_element("SigAndRefsTimeStamp", XADES_NS, e) << i.sigAndRefsTimeStamp()[b.index];
continue;
case UnsignedSignaturePropertiesType::refsOnlyTimeStampId:
create_element("RefsOnlyTimeStamp", XADES_NS, e) << i.refsOnlyTimeStamp()[b->index];
create_element("RefsOnlyTimeStamp", XADES_NS, e) << i.refsOnlyTimeStamp()[b.index];
continue;
case UnsignedSignaturePropertiesType::certificateValuesId:
create_element("CertificateValues", XADES_NS, e) << i.certificateValues()[b->index];
create_element("CertificateValues", XADES_NS, e) << i.certificateValues()[b.index];
continue;
case UnsignedSignaturePropertiesType::revocationValuesId:
create_element("RevocationValues", XADES_NS, e) << i.revocationValues()[b->index];
create_element("RevocationValues", XADES_NS, e) << i.revocationValues()[b.index];
continue;
case UnsignedSignaturePropertiesType::attrAuthoritiesCertValuesId:
create_element("AttrAuthoritiesCertValues", XADES_NS, e) << i.attrAuthoritiesCertValues()[b->index];
create_element("AttrAuthoritiesCertValues", XADES_NS, e) << i.attrAuthoritiesCertValues()[b.index];
continue;
case UnsignedSignaturePropertiesType::attributeRevocationValuesId:
create_element("AttributeRevocationValues", XADES_NS, e) << i.attributeRevocationValues()[b->index];
create_element("AttributeRevocationValues", XADES_NS, e) << i.attributeRevocationValues()[b.index];
continue;
case UnsignedSignaturePropertiesType::archiveTimeStampId:
create_element("ArchiveTimeStamp", XADES_NS, e) << i.archiveTimeStamp()[b->index];
create_element("ArchiveTimeStamp", XADES_NS, e) << i.archiveTimeStamp()[b.index];
continue;
case UnsignedSignaturePropertiesType::archiveTimeStampV141Id:
create_element("ArchiveTimeStamp", XADES141_NS, e) << i.archiveTimeStampV141()[b->index];
create_element("ArchiveTimeStamp", XADES141_NS, e) << i.archiveTimeStampV141()[b.index];
continue;
case UnsignedSignaturePropertiesType::timeStampValidationDataId:
create_element("TimeStampValidationData", XADES141_NS, e) << i.timeStampValidationData()[b->index];
create_element("TimeStampValidationData", XADES141_NS, e) << i.timeStampValidationData()[b.index];
continue;
default: break;
}
Expand Down
20 changes: 10 additions & 10 deletions src/xml/UnsignedSignaturePropertiesType.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,25 +24,25 @@

namespace digidoc {
namespace xadesv141 {
typedef xades::XAdESTimeStampType ArchiveTimeStampType;
typedef xsd::cxx::tree::sequence<ArchiveTimeStampType> ArchiveTimeStampSequence;
typedef xsd::cxx::tree::traits<ArchiveTimeStampType, char> ArchiveTimeStampTraits;
using ArchiveTimeStampType = xades::XAdESTimeStampType;
using ArchiveTimeStampSequence = xsd::cxx::tree::sequence<ArchiveTimeStampType>;
using ArchiveTimeStampTraits = xsd::cxx::tree::traits<ArchiveTimeStampType, char>;

typedef xsd::cxx::tree::sequence<ValidationDataType> TimeStampValidationData;
typedef xsd::cxx::tree::traits<ValidationDataType, char> TimeStampValidationDataTraits;
using TimeStampValidationData = xsd::cxx::tree::sequence<ValidationDataType>;
using TimeStampValidationDataTraits = xsd::cxx::tree::traits<ValidationDataType, char>;
}
namespace xades {

class UnsignedSignaturePropertiesType: public UnsignedSignaturePropertiesTypeBase
class UnsignedSignaturePropertiesType final: public UnsignedSignaturePropertiesTypeBase
{
public:

UnsignedSignaturePropertiesType();
UnsignedSignaturePropertiesType(const xercesc::DOMElement &e, xml_schema::Flags f = 0, xml_schema::Container *c = 0);
UnsignedSignaturePropertiesType(const UnsignedSignaturePropertiesType &x, xml_schema::Flags f = 0, xml_schema::Container *c = 0);
virtual ~UnsignedSignaturePropertiesType();
UnsignedSignaturePropertiesType(const xercesc::DOMElement &e, xml_schema::Flags f = {}, xml_schema::Container *c = nullptr);
UnsignedSignaturePropertiesType(const UnsignedSignaturePropertiesType &x, xml_schema::Flags f = {}, xml_schema::Container *c = nullptr);
~UnsignedSignaturePropertiesType() final;

virtual UnsignedSignaturePropertiesType* _clone(xml_schema::Flags f = 0, xml_schema::Container *c = 0) const;
UnsignedSignaturePropertiesType* _clone(xml_schema::Flags f = {}, xml_schema::Container *c = nullptr) const final;

const xadesv141::ArchiveTimeStampSequence& archiveTimeStampV141() const;
xadesv141::ArchiveTimeStampSequence& archiveTimeStampV141();
Expand Down