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"); } }
/** * 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"); } }