33 using namespace digidoc;
35 #if defined(__APPLE__)
36 # define LIBDIGIDOC_NAME "libdigidoc.dylib"
38 # define LIBDIGIDOC_NAME "digidoc.dll"
40 # define LIBDIGIDOC_NAME "libdigidoc.so.2"
49 , f_calculateDataFileSizeAndDigest(0)
50 , f_cleanupConfigStore(0)
51 , f_convertStringToTimestamp(0)
52 , f_createOrReplacePrivateConfigItem(0)
53 , f_createSignedDoc(0)
54 , f_DataFile_delete(0)
56 , f_ddocPrepareSignature(0)
57 , f_ddocSaxReadSignedDocFromFile(0)
58 , f_ddocSigInfo_GetOCSPRespondersCert(0)
59 , f_ddocSigInfo_GetSignatureValue_Value(0)
60 , f_ddocSigInfo_GetSignersCert(0)
61 , f_ddocSigInfo_SetSignatureValue(0)
62 , f_getCountOfDataFiles(0)
63 , f_getCountOfSignatures(0)
69 , f_finalizeDigiDocLib(0)
70 , f_hasUnreadErrors(0)
72 , f_initConfigStore(0)
73 , f_notarizeSignature(0)
74 , f_ddocSaxExtractDataFile(0)
76 , f_SignatureInfo_delete(0)
79 , f_verifySignatureAndNotary(0)
80 #ifndef LINKED_LIBDIGIDOC
105 #ifndef LINKED_LIBDIGIDOC
131 #ifdef LINKED_LIBDIGIDOC
200 #ifndef LINKED_LIBDIGIDOC
207 {
return h ? (
void*)GetProcAddress(
h, symbol ) : 0; }
210 {
if(
h ) FreeLibrary(
h );
h = 0; }
218 {
return h ? dlsym(
h, symbol ) : 0; }
221 {
if(
h ) dlclose(
h );
h = 0; }
235 for( std::vector<SignatureDDOC*>::const_iterator
i =
signatures.begin();
245 for( std::vector<SignatureDDOC*>::const_iterator
i =
signatures.begin();
250 for(
int i = 0;
i < count; ++
i )
262 case ERR_OCSP_CERT_REVOKED:
264 case ERR_OCSP_CERT_UNKNOWN:
266 case ERR_OCSP_RESP_NOT_TRUSTED:
268 case ERR_OCSP_CERT_NOTFOUND:
270 case ERR_OCSP_UNAUTHORIZED:
274 case ERR_SIGNERS_CERT_NOT_TRUSTED:
277 throwError<T>( msg, line, err );
284 throwError<BDocException>(
"DDoc library not loaded", line );
286 throwError<BDocException>(
"Document not open", line );
292 std::stringstream ddoc;
296 const char *errorClass[] = {
"NO_ERRORS",
"TECHNICAL",
"USER",
"LIBRARY"};
301 <<
" (" << e->fileName <<
":" << e->line
305 T
e( __FILE__, line, ddoc.str() );
314 lib->f_SignatureInfo_delete( doc, sig->szId );
315 throwCodeError<BDocException>( err, msg, line );
328 throw SignatureException( __FILE__, __LINE__,
"Null pointer in SignatureDDOC constructor" );
333 throw SignatureException( __FILE__, __LINE__,
"Null pointer in SignatureDDOC constructor" );
340 s.
signature = (
unsigned char*)value->pMem;
345 if(
d->
sig->sigProdPlace.szCity )
346 l.
city =
d->
sig->sigProdPlace.szCity;
347 if(
d->
sig->sigProdPlace.szStateOrProvince )
349 if(
d->
sig->sigProdPlace.szPostalCode )
351 if(
d->
sig->sigProdPlace.szCountryName )
356 for(
int i = 0;
i <
d->
sig->signerRole.nClaimedRoles; ++
i )
362 setSigningTime( xml_schema::DateTime( ts.year, ts.mon, ts.day, ts.hour, ts.min, ts.sec, ts.tz, 0 ) );
375 std::ostringstream s;
385 NotaryInfo *n =
d->
sig->pNotary;
387 return std::vector<unsigned char>();
390 (
char*)n->mbufOcspResponse.pMem, (
char*)n->mbufOcspResponse.pMem + n->mbufOcspResponse.nLen ) );
408 NotaryInfo *n =
d->
sig->pNotary;
409 if( !n || !n->timeProduced )
411 Timestamp ts = { 0, 0, 0, 0, 0, 0, 0 };
413 return util::date::xsd2string( xml_schema::DateTime( ts.year, ts.mon, ts.day, ts.hour, ts.min, ts.sec, ts.tz, 0 ) );
421 NotaryInfo *n =
d->
sig->pNotary;
422 return n ? std::string( (
const char*)n->mbufRespId.pMem, n->mbufRespId.nLen ) : std::string();
431 NotaryInfo *n = d->sig->pNotary;
434 data.resize( n->mbufOcspDigest.nLen );
435 std::copy( (
unsigned char*)n->mbufOcspDigest.pMem,
436 (
unsigned char*)n->mbufOcspDigest.pMem + n->mbufOcspDigest.nLen, data.begin() );
437 if( n->szDigestType )
438 digestMethodUri = n->szDigestType;
454 d->
priv->
throwCodeError<SignatureException>( err,
"Failed to validate signature", __LINE__ );
501 d->throwError<
BDocException>(
"DDoc library not loaded", __LINE__ );
516 case ERR_OCSP_CERT_REVOKED:
517 case ERR_OCSP_CERT_UNKNOWN:
520 err = ERR_DIGIDOC_PARSE;
530 for(
int i = 0;
i < count; ++
i )
535 doc.
getFilePath().c_str(), data->szId, CHARSET_UTF_8 );
560 d->throwDocOpenError( __LINE__ );
563 int err = d->lib->f_DataFile_new( &data, d->doc, 0, document.getFilePath().c_str(),
564 CONTENT_EMBEDDED_BASE64, document.getMediaType().c_str(), 0, 0, 0, 0, CHARSET_UTF_8 );
565 d->throwCodeError<
BDocException>( err,
"Failed to add file '" + document.getFilePath() +
"'" , __LINE__ );
567 err = d->lib->f_calculateDataFileSizeAndDigest(
568 d->doc, data->szId, document.getFilePath().c_str(), DIGEST_SHA1 );
569 d->throwCodeError<
BDocException>( err,
"Failed calculate file digest and size", __LINE__ );
570 d->documents.push_back(
571 Document( document.getFileName(), document.getFilePath(), document.getMediaType(), data->szId ) );
584 ofs <<
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
585 ofs <<
"<SignedDoc format=\"DIGIDOC-XML\" version=\"1.3\" xmlns=\"http://www.sk.ee/DigiDoc/v1.3.0#\">\n";
586 for(std::vector<unsigned char>::const_iterator
i = signature.begin();
i != signature.end(); ++
i)
588 ofs <<
"</SignedDoc>";
592 SignedDoc *sigDoc = 0;
593 int err = d->lib->f_ddocSaxReadSignedDocFromFile( &sigDoc, fileName.c_str(), 0, 0 );
594 d->throwCodeError<
BDocException>( err,
"Failed to sign document", __LINE__ );
596 SignatureInfo **signatures = (SignatureInfo**)realloc( d->doc->pSignatures,
597 (d->doc->nSignatures + sigDoc->nSignatures) *
sizeof(
void *));
600 d->lib->f_SignedDoc_free( sigDoc );
601 d->throwError<
BDocException>(
"Failed to sign document", __LINE__ );
604 d->doc->pSignatures = signatures;
605 for(
int i = 0;
i < sigDoc->nSignatures; ++
i )
607 d->doc->pSignatures[d->doc->nSignatures +
i] = sigDoc->pSignatures[
i];
608 sigDoc->pSignatures[
i] = 0;
610 ((
char*)d->doc->pSignatures[d->doc->nSignatures +
i]->pDocs[0]->szDigest)[0] = 0x0A;
612 d->doc->nSignatures += sigDoc->nSignatures;
613 sigDoc->nSignatures = 0;
615 d->lib->f_SignedDoc_free( sigDoc );
638 d->throwDocOpenError( __LINE__ );
640 if(
id >= d->documents.size() )
642 std::ostringstream s;
643 s <<
"Incorrect document id " <<
id <<
", there are only ";
644 s << d->documents.size() <<
" documents in container.";
648 return d->documents[id];
660 d->throwDocOpenError( __LINE__ );
662 if(
id >= d->signatures.size() )
664 std::ostringstream s;
665 s <<
"Incorrect signature id " <<
id <<
", there are only ";
666 s << d->signatures.size() <<
" signatures in container.";
670 return d->signatures[id];
683 d->throwDocOpenError( __LINE__ );
685 if(
id >= d->documents.size() )
687 std::ostringstream s;
688 s <<
"Incorrect document id " <<
id <<
", there are only ";
689 s << d->documents.size() <<
" documents in container.";
692 if( !d->signatures.empty() )
695 "Can not remove document from container which has signatures, "
696 "remove all signatures before removing document.", __LINE__ );
699 int err = d->lib->f_DataFile_delete( d->doc, d->doc->pDataFiles[
id]->szId );
700 d->throwCodeError<
BDocException>( err,
"Failed to delete file", __LINE__ );
701 d->documents.erase( d->documents.begin() + id );
712 d->throwDocOpenError( __LINE__ );
714 if(
id >= d->signatures.size() )
716 std::ostringstream s;
717 s <<
"Incorrect signature id " <<
id <<
", there are only ";
718 s << d->signatures.size() <<
" signatures in container.";
722 int err = d->lib->f_SignatureInfo_delete( d->doc, d->doc->pSignatures[
id]->szId );
723 d->throwCodeError<
BDocException>( err,
"Failed to remove signature", __LINE__ );
739 d->
throwCodeError<BDocException>( err,
"Failed to save document", __LINE__ );
753 d->throwDocOpenError( __LINE__ );
754 int err = d->lib->f_createSignedDoc( d->doc, d->filename.c_str(), path.c_str() );
755 d->throwCodeError<
BDocException>( err,
"Failed to save document", __LINE__ );
768 d->throwDocOpenError( __LINE__ );
770 if( !signer->getCert() )
771 throw BDocException( __FILE__, __LINE__,
"Failed to sign document, Certificate cannot be NULL" );
776 x509 = X509_dup( signer->getCert() );
780 throw BDocException( __FILE__, __LINE__,
"Failed to sign document", e );
783 std::ostringstream role;
785 for( SignerRole::TRoles::const_iterator
i = r.begin();
i != r.end(); ++
i )
788 if( i + 1 != r.end() )
793 SignatureInfo *info = 0;
794 int err = d->lib->f_ddocPrepareSignature( d->doc, &info, role.str().c_str(), l.
city.c_str(),
796 d->throwSignError( info, err,
"Failed to sign document", __LINE__ );
805 d->lib->f_SignatureInfo_delete( d->doc, info->szId );
806 throw BDocException( __FILE__, __LINE__,
"Failed to sign document", e );
808 std::vector<unsigned char> buf1(size);
811 std::vector<unsigned char> buf2(
812 (
unsigned char*)info->pSigInfoRealDigest->mbufDigestValue.pMem,
813 (
unsigned char*)info->pSigInfoRealDigest->mbufDigestValue.pMem + info->pSigInfoRealDigest->mbufDigestValue.nLen );
818 signer->sign( digest, signatureSha1Rsa );
822 d->lib->f_SignatureInfo_delete( d->doc, info->szId );
823 throw BDocException( __FILE__, __LINE__,
"Failed to sign document", e );
825 err = d->lib->f_ddocSigInfo_SetSignatureValue( info, (
const char*)signatureSha1Rsa.
signature, signatureSha1Rsa.
length );
826 d->throwSignError( info, err,
"Failed to sign document", __LINE__ );
831 d->lib->f_createOrReplacePrivateConfigItem( 0,
"USE_PROXY",
"true" );
832 d->lib->f_createOrReplacePrivateConfigItem( 0,
"DIGIDOC_PROXY_HOST", c->
getProxyHost().c_str() );
833 d->lib->f_createOrReplacePrivateConfigItem( 0,
"DIGIDOC_PROXY_PORT", c->
getProxyPort().c_str() );
834 d->lib->f_createOrReplacePrivateConfigItem( 0,
"DIGIDOC_PROXY_USER", c->
getProxyUser().c_str() );
835 d->lib->f_createOrReplacePrivateConfigItem( 0,
"DIGIDOC_PROXY_PASS", c->
getProxyPass().c_str() );
838 d->lib->f_createOrReplacePrivateConfigItem( 0,
"USE_PROXY",
"false" );
841 d->lib->f_createOrReplacePrivateConfigItem( 0,
"SIGN_OCSP",
"false" );
844 d->lib->f_createOrReplacePrivateConfigItem( 0,
"SIGN_OCSP",
"true" );
845 d->lib->f_createOrReplacePrivateConfigItem( 0,
"DIGIDOC_PKCS_FILE",
847 d->lib->f_createOrReplacePrivateConfigItem( 0,
"DIGIDOC_PKCS_PASSWD",
851 err = d->lib->f_notarizeSignature( d->doc, info );
852 d->throwSignError( info, err,
"Failed to sign document", __LINE__ );
854 err = d->lib->f_verifySignatureAndNotary( d->doc, info, d->filename.c_str() );
855 d->throwSignError( info, err,
"Failed to sign document", __LINE__ );
870 d->throwDocOpenError( __LINE__ );
872 DataFile *data = d->lib->f_getDataFile( d->doc,
id );
875 std::ostringstream s;
876 s <<
"Incorrect document id " <<
id <<
", there are only ";
877 s << d->lib->f_getCountOfDataFiles( d->doc ) <<
" documents in container.";
879 return std::vector<unsigned char>();
882 return std::vector<unsigned char>( (
unsigned char*)data->mbufDigest.pMem,
883 (
unsigned char*)data->mbufDigest.pMem + data->mbufDigest.nLen );