Esempio n. 1
0
/// Check that SignedInfo contains exactly one Reference to every document,
/// plus one Reference to the SignedProperties
/// @throws SignatureException on a problem in signature
void digidoc::SignatureBES::checkReferences() const throw(SignatureException)
{
    dsig::SignedInfoType& signedInfo = signature->signedInfo();
    dsig::SignedInfoType::ReferenceSequence& refSeq = signedInfo.reference();

    if ( refSeq.size() != (bdoc.documentCount() + 1) )
    {
        // we require exactly one ref to every document, plus one ref to the SignedProperties
        THROW_SIGNATUREEXCEPTION("Number of references in SignedInfo is invalid: found %d, expected %d"
                                 , refSeq.size(), bdoc.documentCount() + 1);

    }

    // check reference to SignedProperties
    bool gotSignatureRef = false; // remember to ensure, it exists only once
    for ( dsig::SignedInfoType::ReferenceSequence::const_iterator itRef = refSeq.begin()
            ; itRef != refSeq.end()
            ; itRef++
        )
    {
        const dsig::ReferenceType& refType = (*itRef);

        if ( isReferenceToSigProps(refType) )
        {
            // the one and only reference to SignedProperties
            if ( gotSignatureRef )
            {
                THROW_SIGNATUREEXCEPTION("SignedInfo element refers to more than one SignedProperties");
            }
            gotSignatureRef = true; // remember this, we don't expect any more of those

            checkReferenceToSigProps(refType);
        } // else: skip, checked elsewhere
    }

    if ( !gotSignatureRef )
    {
        THROW_SIGNATUREEXCEPTION("SignedInfo does not contain reference to SignedProperties");
    }

    // check refs to documents
    checkReferencesToDocs(refSeq);

}
Esempio n. 2
0
void bdoc::Signature::checkReferencesToDocs(
    dsig::SignedInfoType::ReferenceSequence& refSeq) const
{
    _bdoc->checkDocumentsBegin();

    for (dsig::SignedInfoType::ReferenceSequence::const_iterator
            itRef = refSeq.begin(); itRef != refSeq.end(); itRef++) {

        const dsig::ReferenceType& refType = (*itRef);

        if (!isReferenceToSigProps(refType)) {
            const dsig::ReferenceType::URIOptional&
            uriOpt = refType.uRI();
            if (!uriOpt.present()) {
                THROW_STACK_EXCEPTION(
                    "Document reference is missing "
                    "attribute 'URI'");
            }
            std::string docRefUri(uriOpt.get());

            // file names in manifest do not have '/' at front
            if (!docRefUri.empty() && docRefUri[0] == '/') {
                docRefUri.erase(0, 1);
            }

            const dsig::DigestMethodType&
            digestMethod = refType.digestMethod();

            const dsig::DigestMethodType::AlgorithmType&
            algorithmType = digestMethod.algorithm();

            const dsig::DigestValueType&
            digestValueType = refType.digestValue();

            _bdoc->checkDocument(
                docRefUri, algorithmType, digestValueType);
        }
    }

    if (!_bdoc->checkDocumentsResult()) {
        THROW_STACK_EXCEPTION("Document references didn't match");
    }
}
Esempio n. 3
0
void bdoc::Signature::checkReferences()
{
    dsig::SignedInfoType& signedInfo = _sign->signedInfo();
    dsig::SignedInfoType::ReferenceSequence&
    refSeq = signedInfo.reference();

    if (refSeq.size() != (_bdoc->documentCount() + 1)) {
        // we require exactly one ref to every document,
        // plus one ref to the SignedProperties
        THROW_STACK_EXCEPTION(
            "Number of references in SignedInfo is invalid: "
            "found %d, expected %d",
            refSeq.size(), _bdoc->documentCount() + 1);
    }

    bool gotSignatureRef = false;
    for (dsig::SignedInfoType::ReferenceSequence::const_iterator
            itRef = refSeq.begin(); itRef != refSeq.end(); itRef++) {

        const dsig::ReferenceType& refType = (*itRef);

        if (isReferenceToSigProps(refType)) {
            // the one and only reference to SignedProperties
            if (gotSignatureRef) {
                THROW_STACK_EXCEPTION(
                    "SignedInfo element refers to more "
                    "than one SignedProperties");
            }
            gotSignatureRef = true;
            checkReferenceToSigProps(refType);
        }
    }

    if (!gotSignatureRef) {
        THROW_STACK_EXCEPTION(
            "SignedInfo does not contain reference to "
            "SignedProperties");
    }

    checkReferencesToDocs(refSeq);
}
Esempio n. 4
0
/**
 * Offline check on every SignedInfo reference to a document.
 * @throws SignatureException on error in references
 */
void digidoc::SignatureBES::checkReferencesToDocs(dsig::SignedInfoType::ReferenceSequence& refSeq)
const throw(SignatureException)
{
    // copy documents to a list for removal on every successful find
    std::vector< size_t > docNumberList;
    size_t docCount = bdoc.documentCount();
    for ( size_t i = 0; i != docCount; i++ )
    {
        docNumberList.push_back( i );
    }

    // loop over references
    for ( dsig::SignedInfoType::ReferenceSequence::const_iterator itRef = refSeq.begin()
            ; itRef != refSeq.end()
            ; itRef++
        )
    {
        const dsig::ReferenceType& refType = (*itRef);

        if ( !isReferenceToSigProps(refType) )
        {

            // get document URI
            const dsig::ReferenceType::URIOptional& uriOpt = refType.uRI();
            if ( !uriOpt.present() )
            {
                THROW_SIGNATUREEXCEPTION("Document reference is missing attribute 'URI'");
            }
            std::string docRefUri(uriOpt.get());

            // file names in manifest do not have '/' at front
            if ( !docRefUri.empty() && docRefUri[0] == '/' )
            {
                docRefUri.erase( 0, 1 );
            }

            // find the matching document from container
            bool foundDoc = false;
            for ( std::vector< size_t >::iterator itDocs = docNumberList.begin()
                    ; itDocs != docNumberList.end(); itDocs++ )
            {
                Document doc = bdoc.getDocument( *itDocs );

                std::string documentFileName = util::File::fileName( doc.getPath() );
                if ( digidoc::util::String::toUriFormat(documentFileName) == docRefUri )
                {
                    foundDoc = true;
                    docNumberList.erase( itDocs ); // remove from list to detect duplicate refs
                    checkDocumentRefDigest( doc, documentFileName, refType );
                    break; // we modified docNumberList so get out of here
                }

            }

            if ( !foundDoc )
            {
                THROW_SIGNATUREEXCEPTION("Referenced Document '%s' not found in BDoc container", docRefUri.c_str());
            }

        } // else: skip, checked elsewhere
    }

    if ( !docNumberList.empty() )
    {
        // that's actually coder's bug - fix it
        THROW_SIGNATUREEXCEPTION("BDoc document list does not match the references block in signature");
    }
}