libdigidocpp
main_test-1.cpp
Go to the documentation of this file.
1 /*
2  * libdigidocpp
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  */
19 
20 #include "log.h"
21 #include "BDoc.h"
22 #include "BDocException.h"
23 #include "Conf.h"
24 #include "Document.h"
25 #include "crypto/crypt/RSACrypt.h"
26 #include "crypto/Digest.h"
29 #include "crypto/crypt/RSACrypt.h"
30 #include "crypto/ocsp/OCSP.h"
35 #include "crypto/signer/SignException.h"
36 #include "SignatureException.h"
37 #include "io/IOException.h"
38 #include "io/ZipSerialize.h"
39 #include "util/File.h"
40 #include "xml/OpenDocument_manifest.hxx"
41 
42 #include <openssl/objects.h>
43 #include <openssl/pem.h>
44 #include <openssl/ssl.h>
45 
46 #include <iostream>
47 
48 #include <xercesc/parsers/XercesDOMParser.hpp>
49 #include <xercesc/dom/DOM.hpp>
50 #include <xercesc/util/XMLString.hpp>
51 #include <xercesc/util/PlatformUtils.hpp>
52 
53 
54 //using namespace std;
55 //using namespace xercesc;
56 
57 
58 #include <xsec/canon/XSECC14n20010315.hpp>
59 #include <xsec/utils/XSECPlatformUtils.hpp>
60 
61 using namespace digidoc;
62 
63 
64 int testException(int argc, char* argv[]);
65 int testUtil(int argc, char* argv[]);
66 int testZipSerialize(int argc, char* argv[]);
67 int testBDOC(int argc, char* argv[]);
68 int testOCSP(int argc, char* argv[]);
69 int testOpenBDocBES(int argc, char* argv[]);
70 int testShowCertInfo(const digidoc::Signature* signature);
71 int testSignBDocBES(int argc, char* argv[]);
72 int testSignBDocTM(int argc, char* argv[]);
73 int testPKCS11Signer(int argc, char* argv[]);
74 int testC14N(int argc, char* argv[]);
75 int testCanon(int argc, char* argv[]);
77 int testTMValidate();
78 int testRSASigner(int argc, char* argv[]);
79 int testX509Verify(int argc, char* argv[]);
80 
81 
82 
87 {
88 
89  public:
90  PKCS11ConsolePinSigner(const std::string& driver) throw(SignException);
91  virtual ~PKCS11ConsolePinSigner();
92 
93  protected:
94  virtual PKCS11Signer::PKCS11Cert selectSigningCertificate(std::vector<PKCS11Signer::PKCS11Cert> certificates) throw(SignException);
95  virtual std::string getPin(PKCS11Signer::PKCS11Cert certificate) throw(SignException);
96 
97  private:
98  void printPKCS11Cert(const PKCS11Signer::PKCS11Cert& cert);
99 
100 };
101 
102 
109 int main(int argc, char* argv[])
110 {
111  /*
112  SSL_load_error_strings();
113  SSL_library_init(); //OpenSSL_add_ssl_algorithms(); // makro kutsub välja SSL_library_init()
114  //OpenSSL_add_all_digests();
115  OPENSSL_config(NULL);
116 
117  xercesc::XMLPlatformUtils::Initialize();
118  XSECPlatformUtils::Initialise();
119 
120 
121  */
122 
124 
127 
128  try
129  {
130  /*
131  digidoc::SHA1Digest d;
132  unsigned char b[1] = { 0 };
133  d.update(&b[0], 0);
134  std::vector<unsigned char> sha1 = d.getDigest();
135  DEBUG("sha1.size() = %d", sha1.size())
136  xml_schema::Base64Binary bin(&sha1[0], 20);
137  std::cout << bin.encode();
138  */
139 
140 
141  //std::vector<std::string> files = digidoc::util::File::listFiles("/home/janari/projects/smartlink/digidoc/tmp/aaaa", false, true, false);
142  //DEBUG("------------------------------------------------------------------------------------")
143  //for(std::vector<std::string>::const_iterator iter = files.begin(); iter != files.end(); iter++)
144  //{
145  // DEBUG("%s", iter->c_str())
146  //}
147  //DEBUG("------------------------------------------------------------------------------------")
148 
149  //X509Cert cert(X509Cert::loadX509("/home/janari/projects/smartlink/digidoc/test/data/cert/cert+priv_key.pem"));
150  //X509Cert cert(X509Cert::loadX509("/home/janari/projects/smartlink/digidoc/etc/certs/sk-test.pem"));
151  //DEBUG("cert.getSerial() = %ld", cert.getSerial());
152 
153  //testRSASigner(argc, argv);
154  //test();
155  //return testOCSP(argc, argv);
156  //return testSignBDocBES(argc, argv);
157  //return testSignBDocTM(argc, argv);
158  //return testSignBDocBES(argc, argv);
159  //return testC14N(argc, argv);
160  //return testCanon(argc, argv);
161  //return testOpenBDocBES(argc, argv);
162  //return testOCSP(argc, argv);
163  //return testTMValidate();
164  return testX509Verify(argc, argv);
165  }
166  catch(const digidoc::BDocException& e)
167  {
168  ERR("Caught BDocException: %s", e.getMsg().c_str());
169  }
170  catch(const digidoc::SignException& e)
171  {
172  ERR("Caught SignException: %s", e.getMsg().c_str());
173  }
174  catch(const digidoc::OCSPException& e)
175  {
176  ERR("Caught OCSPException: %s", e.getMsg().c_str());
177  }
178  catch(const digidoc::IOException& e)
179  {
180  ERR("Caught IOException: %s", e.getMsg().c_str());
181  }
182  catch(const digidoc::Exception& e)
183  {
184  ERR("Caught Exception: %s", e.getMsg().c_str());
185  }
186  catch(...)
187  {
188  ERR("Caught unknown exception");
189  }
190 
191  /*
192  XSECPlatformUtils::Terminate();
193  xercesc::XMLPlatformUtils::Terminate();
194  */
195 
197 
198  return -1;
199 }
200 
201 int testX509Verify(int argc, char* argv[])
202 {
203  try
204  {
205 
206  EstEIDConsolePinSigner signer(digidoc::Conf::getInstance()->getPKCS11DriverPath());
207  X509 * x = signer.getCert();
208  X509Cert cert(x);
209 
210  //DirectoryX509CertStore dirStore(digidoc::Conf::getInstance()->getCertStorePath());
211 
212  //X509_STORE * store = dirStore.getCertStore(); X509_STORE_scope t(&store);
213 
214  int r = cert.verify();
215  if(r)
216  {
217  INFO("Cert OK");
218  }
219  return r;
220  }
221  catch(const IOException& e)
222  {
223  ERR("Caught IOException: %s", e.getMsg().c_str());
224  return -1;
225  }
226 
227 }
228 
235 int testException(int argc, char* argv[])
236 {
237  /*
238  digidoc::IOException ioe(__FILE__, __LINE__, "IOE");
239  digidoc::BDocException be(__FILE__, __LINE__, "BE", ioe);
240 
241  DEBUG("be.hasCause(); %i", be.hasCause())
242  if(be.hasCause())
243  {
244  DEBUG("%s", be.getCause().getMsg().c_str())
245  }
246 
247  digidoc::BDocException e(be);
248  DEBUG("e = 0x%X", (unsigned int)&e);
249  DEBUG("be = 0x%X", (unsigned int)&be);
250  DEBUG("%s", e.getCause().getMsg().c_str())
251  */
252 
253  return 0;
254 }
255 
262 int testUtil(int argc, char* argv[])
263 {
264  //bool exists = digidoc::Util::File::fileExists("/tmp/Security.zip");
265  //bool exists = digidoc::Util::File::directoryExists("/home/janari/");
266  //DEBUG("exists = %d", exists);
267 
268  //std::string dir = digidoc::Util::File::directory("/home/janari/projects");
269  //std::string str = digidoc::Util::File::tempFileName();
270  //std::string str = digidoc::Util::File::path("/tmp/asaasasasx/", "sssssx\\sssx/kkkkx\\text.txt");
271  //std::string str = digidoc::Util::File::path("\\ffff\\dddd/jjj", "sssssx\\sssx/kkkkx\\text.txt");
272  //DEBUG("str = '%s'", str.c_str())
273  //unsigned long size = digidoc::Util::File::fileSize("/tmp/CHIFFR~1-1.ZIP");
274  //DEBUG("size = %lu", size)
275  //digidoc::Util::File::createDirectory("/tmp/test-003/test/blaaah/hjhjh/ddd/");
276  //digidoc::Util::File::moveFile("/tmp/BDoc-1.0.pdf___", "/tmp/BDoc-1.0.pdf");
277  //digidoc::Util::File::copyFile("/tmp/BDoc-1.0.pdf", "/tmp/BDoc-1.0.pdf__");
278  /*
279  std::vector<std::string> files = digidoc::Util::File::listFiles("/tmp", true);
280  DEBUG("--------------------------------------------------------------------------------------")
281  for(std::vector<std::string>::const_iterator iter = files.begin(); iter != files.end(); iter++)
282  {
283  DEBUG("%s", iter->c_str())
284  }
285  DEBUG("--------------------------------------------------------------------------------------")
286  */
287 
288  return 0;
289 }
290 
297 int testZipSerialize(int argc, char* argv[])
298 {
299  /*
300  try
301  {
302  digidoc::ZipSerialize zip("digidoc.zip");
303 
304  //zip.extract();
305 
306  zip.addFile("test.txt", "mimetype");
307  zip.addFile("document.doc", "document.doc");
308  zip.addFile("META-INF/test.txt", "mimetype");
309  zip.save();
310  }
311  catch(const digidoc::IOException e)
312  {
313  ERROR("Caught IOException: %s", e.getMsg().c_str());
314  }
315  catch(const digidoc::Exception e)
316  {
317  ERROR("Caught Exception: %s", e.getMsg().c_str());
318  }
319  catch(...)
320  {
321  ERROR("Caught unknown exception");
322  }
323  */
324 
325  return 0;
326 }
327 
334 int testBDOC(int argc, char* argv[])
335 {
336  /*
337  try
338  {
339  digidoc::BDoc bdoc;
340  std::auto_ptr<digidoc::ISerialize> serializer(new digidoc::ZipSerialize("digidoc.zip"));
341  //bdoc.readFrom(serializer);
342 
343  digidoc::Document doc_001("document1.doc", "word");
344  digidoc::Document doc_002("document2.doc", "word");
345  digidoc::Document doc_003("document3.doc", "word");
346 
347  bdoc.addDocument(doc_001);
348  bdoc.addDocument(doc_002);
349  bdoc.addDocument(doc_003);
350 
351  digidoc::Signature* sig_001 = new digidoc::Signature("META-INF/signature1.xml", "signature/bdoc-1.0/BES");
352  digidoc::Signature* sig_002 = new digidoc::Signature("META-INF/signature2.xml", "signature/bdoc-1.0/TS");
353  digidoc::Signature* sig_003 = new digidoc::Signature("META-INF/signature3.xml", "signature/bdoc-1.0/TM");
354  digidoc::Signature* sig_004 = new digidoc::Signature("META-INF/signature4.xml", "signature/bdoc-1.0/BES");
355 
356  bdoc.addSignature(sig_001);
357  bdoc.addSignature(sig_002);
358  bdoc.addSignature(sig_003);
359  bdoc.addSignature(sig_004);
360 
361  //for(unsigned int i = 0; i < bdoc.documentCount(); i++)
362  //{
363  // digidoc::Document doc = bdoc.getDocument(i);
364  // std::string msg;
365  // msg += doc.getFullPath() + std::string(" :: ") + doc.getMediaType() + std::string("\n");
366  // printf(msg.c_str());
367  //}
368 
369  //bdoc.save();
370  bdoc.saveTo(serializer);
371 
372  //bdoc.getDocument(100);
373  }
374  catch(const digidoc::BDocException e)
375  {
376  ERROR("Caught BDocException: %s", e.getMsg().c_str());
377  }
378  catch(const digidoc::IOException e)
379  {
380  ERROR("Caught IOException: %s", e.getMsg().c_str());
381  }
382  catch(const digidoc::Exception e)
383  {
384  ERROR("Caught Exception: %s", e.getMsg().c_str());
385  }
386  catch(...)
387  {
388  ERROR("Caught unknown exception");
389  }
390  */
391 
392  return 0;
393 }
394 
395 
396 #include <openssl/ssl.h>
397 #include <openssl/conf.h>
398 
399 
400 typedef struct pw_cb_data
401  {
402  const void *password;
403  const char *prompt_info;
404  } PW_CB_DATA;
405 
406 
407 #define FORMAT_PEM 3
408 
409 
410 STACK_OF(X509) *load_certs(BIO *err, const char *file, int format,
411  const char *pass, ENGINE *e, const char *cert_descrip)
412  {
413  BIO *certs;
414  int i;
415  STACK_OF(X509) *othercerts = NULL;
416  STACK_OF(X509_INFO) *allcerts = NULL;
417  X509_INFO *xi;
419 
420  cb_data.password = pass;
421  cb_data.prompt_info = file;
422 
423  if((certs = BIO_new(BIO_s_file())) == NULL)
424  {
425  //ERR_print_errors(err);
426  goto end;
427  }
428 
429  if (file == NULL)
430  BIO_set_fp(certs,stdin,BIO_NOCLOSE);
431  else
432  {
433  if (BIO_read_filename(certs,file) <= 0)
434  {
435  BIO_printf(err, "Error opening %s %s\n",
436  cert_descrip, file);
437  //ERR_print_errors(err);
438  goto end;
439  }
440  }
441 
442  if (format == FORMAT_PEM)
443  {
444  othercerts = sk_X509_new_null();
445  if(!othercerts)
446  {
447  sk_X509_free(othercerts);
448  othercerts = NULL;
449  goto end;
450  }
451  allcerts = PEM_X509_INFO_read_bio(certs, NULL,
452  NULL/*(pem_password_cb *)password_callback*/, &cb_data);
453  for(i = 0; i < sk_X509_INFO_num(allcerts); i++)
454  {
455  xi = sk_X509_INFO_value (allcerts, i);
456  if (xi->x509)
457  {
458  sk_X509_push(othercerts, xi->x509);
459  xi->x509 = NULL;
460  }
461  }
462  goto end;
463  }
464  else {
465  BIO_printf(err,"bad input format specified for %s\n",
466  cert_descrip);
467  goto end;
468  }
469 end:
470  if (othercerts == NULL)
471  {
472  BIO_printf(err,"unable to load certificates\n");
473  //ERR_print_errors(err);
474  }
475  if (allcerts) sk_X509_INFO_pop_free(allcerts, X509_INFO_free);
476  if (certs != NULL) BIO_free(certs);
477  return(othercerts);
478  }
479 
480 
487 int testOCSP(int argc, char* argv[])
488 {
489  try
490  {
491  /*
492  SSL_load_error_strings();
493  SSL_library_init(); //OpenSSL_add_ssl_algorithms(); // makro kutsub välja SSL_library_init()
494  //OpenSSL_add_all_digests();
495  OPENSSL_config(NULL);
496  */
497 
498  //FILE* pCertFile = fopen("/home/janari/projects/smartlink/digidoc/tmp/php_ocsp_check/etc/test_ocsp_2006.cer", "r");
499  //FILE* pCertFile = fopen("etc/certs/test_ocsp_2006.cer", "r");
500  FILE* pCertFile = fopen("etc/certs/mari-liis.mannik.pem", "r");
501  X509* cert = PEM_read_X509(pCertFile, NULL, NULL, NULL);
502  fclose(pCertFile);
503 
504  //FILE* pIssuerFile = fopen("/home/janari/projects/smartlink/digidoc/tmp/php_ocsp_check/etc/sk-test.pem", "r");
505  FILE* pIssuerFile = fopen("etc/certs/sk-test.pem", "r");
506  X509* issuer = PEM_read_X509(pIssuerFile, NULL, NULL, NULL);
507  fclose(pIssuerFile);
508 
509  //FILE* pIStoreFile = fopen("/home/janari/projects/smartlink/digidoc/tmp/php_ocsp_check/etc/sk-test-ocsp-responder-2005.pem", "r");
510  //X509* responderCert = PEM_read_X509(pIStoreFile, NULL, NULL, NULL);
511  //fclose(pIStoreFile);
512  //BIO* bio_err = BIO_new_fp(stderr, BIO_NOCLOSE);
513  //ENGINE* e = NULL;
514  //STACK_OF(X509)* ocspCerts = load_certs(bio_err, "/home/janari/projects/smartlink/digidoc/tmp/php_ocsp_check/etc/sk-test-ocsp-responder-2005.pem", FORMAT_PEM, NULL, e, "validator certificate");
515  //STACK_OF(X509)* ocspCerts = load_certs(bio_err, "etc/certs/sk-test-ocsp-responder-2005.pem", FORMAT_PEM, NULL, e, "validator certificate");
516 
517  digidoc::OCSP ocsp("http://www.openxades.org/cgi-bin/ocsp.cgi");
518  //ocsp.setOCSPCerts(ocspCerts);
519  std::vector<unsigned char> nonce(20);
520  ocsp.setMaxAge(5);
521  std::vector<unsigned char> ocspResponseDER;
522  tm producedAt;
523  digidoc::OCSP::CertStatus status = ocsp.checkCert(cert, issuer, nonce, ocspResponseDER, producedAt);
524 
525  if(status == digidoc::OCSP::GOOD) { DEBUG("OCSP status: GOOD"); }
526  else if(status == digidoc::OCSP::REVOKED) { DEBUG("OCSP status: REVOKED"); }
527  else if(status == digidoc::OCSP::UNKNOWN) { DEBUG("OCSP status: UNKNOWN"); }
528  }
529  catch(const digidoc::OCSPException& e)
530  {
531  ERR("Caught OCSPException: %s", e.getMsg().c_str());
532  }
533  catch(const digidoc::IOException& e)
534  {
535  ERR("Caught IOException: %s", e.getMsg().c_str());
536  }
537  catch(const digidoc::Exception& e)
538  {
539  ERR("Caught Exception: %s", e.getMsg().c_str());
540  }
541  catch(...)
542  {
543  ERR("Caught unknown exception");
544  }
545 
546  return 0;
547 }
548 
549 
550 X509* selectSignCertificate(std::vector<digidoc::PKCS11Signer::PKCS11Cert> certificates)
551 {
552  INFO("selectSignCertificate(certificates.size() = %d)", certificates.size());
553 
554  for(std::vector<digidoc::PKCS11Signer::PKCS11Cert>::const_iterator iter = certificates.begin(); iter != certificates.end(); iter++)
555  {
556  DEBUG("token label: %s", iter->token.label.c_str());
557  DEBUG("token manufacturer: %s", iter->token.manufacturer.c_str());
558  DEBUG("token model: %s", iter->token.model.c_str());
559  DEBUG("token serial Nr: %s", iter->token.serialNr.c_str());
560  DEBUG("label: %s", iter->label.c_str());
561  DEBUG("cert: 0x%X", (unsigned int)(iter->cert));
562  DEBUG("--------------------------------------------------------------------");
563  }
564 
565  return certificates[0].cert;
566 }
567 
569 {
570  INFO("getPin(certificate = { token = {label = '%s'}})", certificate.token.label.c_str());
571  return "0090";
572 }
573 
580 int testPKCS11Signer(int argc, char* argv[])
581 {
582  try
583  {
584  PKCS11ConsolePinSigner signer("/usr/lib/opensc-pkcs11.so");
585  //digidoc::PKCS11Signer signer("C:\\dev\\tools\\Copy of opensc-0.11.6\\src\\pkcs11\\opensc-pkcs11.dll", selectSignCertificate, getPin);
586 
587  digidoc::SignatureProductionPlace spp("Tallinn", "Harjumaa", "12345", "Estonia");
588  signer.setSignatureProductionPlace(spp);
589 
590  digidoc::SignerRole role("chief o'brian");
591  signer.setSignerRole(role);
592 
593  //X509* cert = signer.getCert();
594  //DEBUG("cert = 0x%X", (unsigned int)cert);
595 
596  digidoc::Signer::Digest digest = { NID_sha1, (unsigned char*)"ABCDEFGHIJ0123456789", 20 };
597  digidoc::Signer::Signature signature = { new unsigned char[256], 256 };
598  memset(signature.signature, 0, signature.length);
599  //digidoc::Signer::Signature signature = { NULL, 0 };
600  try { signer.sign(digest, signature); } catch(const digidoc::SignException& ) {}
601 
602  DEBUG("----------------------------------------------------------------------------------------------------");
603  DEBUG("Digest: type = %d, digest = %s, length = %d", digest.type, (char*)digest.digest, digest.length);
604  DEBUG("Signature: signature = 0x%X, length = %d", (unsigned int)signature.signature, signature.length);
605 
606  //DEBUG("%u", (signature.signature)[0])
607  DEBUG("signature.signature[100] = %u", (signature.signature)[100]);
608  DEBUG("signature.signature[127] = %u", (signature.signature)[127]);
609  DEBUG("signature.signature[128] = %u", (signature.signature)[128]);
610  }
611  catch(const digidoc::SignException& e)
612  {
613  ERR("Caught SignException: %s", e.getMsg().c_str());
614  }
615  catch(const digidoc::Exception& e)
616  {
617  ERR("Caught Exception: %s", e.getMsg().c_str());
618  }
619  catch(...)
620  {
621  ERR("Caught unknown exception");
622  }
623 
624  return 0;
625 }
626 
633 int testSignBDoc(digidoc::Signature::Type signingType, int argc, char* argv[])
634 {
635  try
636  {
637  //FILE* pCertFile = fopen("/home/janari/projects/smartlink/digidoc/tmp/php_ocsp_check/etc/sk-test.pem", "r");
638  //X509* x509 = PEM_read_X509(pCertFile, NULL, NULL, NULL);
639  //fclose(pCertFile);
640  //digidoc::DummySigner signer(x509);
641 
642  PKCS11ConsolePinSigner signer("/usr/lib/opensc-pkcs11.so");
643  digidoc::SignatureProductionPlace spp("Tallinn", "Harjumaa", "12345", "Estonia");
644 
645  digidoc::SignerRole role("chief o'brian");
646  signer.setSignerRole(role);
647  signer.setSignatureProductionPlace(spp);
648 
649  //X509* cert = signer.getCert();
650  //DEBUG("cert = 0x%X", (unsigned int)cert);
651 
652  //std::auto_ptr<digidoc::ISerialize> serializer(new digidoc::ZipSerialize("/home/janari/projects/smartlink/digidoc/tmp/digidoc.zip"));
653  digidoc::BDoc bdoc;
654  //bdoc.readFrom(serializer);
655 
656  if(argc == 3)
657  {
658  DEBUG("args: %s %s", argv[1], argv[2]);
659  digidoc::Document doc_001(argv[1], argv[2]);
660  bdoc.addDocument(doc_001);
661  }
662  else
663  {
664  digidoc::Document doc_001("/proc/cpuinfo", "text/txt");
665  bdoc.addDocument(doc_001);
666  }
667 
668  bdoc.sign(&signer, signingType);
669 
670  // save/print out the signature created.
671  digidoc::Signature* sig = const_cast<digidoc::Signature*>(bdoc.getSignature(bdoc.signatureCount() - 1));
672  sig->saveToXml();
673 
674  //sig->validateOnline();
675 
676  //bdoc.saveTo(serializer);
677  }
678  catch(const digidoc::SignException& e)
679  {
680  ERR("Caught SignException: %s", e.getMsg().c_str());
681  }
682  catch(const digidoc::Exception& e)
683  {
684  ERR("Caught Exception: %s", e.getMsg().c_str());
685  }
686  catch(...)
687  {
688  ERR("Caught unknown exception");
689  }
690 
691  return 0;
692 }
693 
694 int testSignBDocBES(int argc, char* argv[])
695 {
696  return testSignBDoc(digidoc::Signature::BES, argc, argv);
697 }
698 
699 int testSignBDocTM(int argc, char* argv[])
700 {
701  return testSignBDoc(digidoc::Signature::TM, argc, argv);
702 }
703 
710 int testOpenBDocBES(int argc, char* argv[])
711 {
712  const std::string fileName("/home/janari/projects/smartlink/digidoc/test/data/bdoc/BES.bdoc");
713  DEBUG(fileName.c_str());
714 
715  //testSignBDocBES();
716  //testBDOC(argc, argv);
717  //testPKCS11Signer(argc, argv);
718 
719  std::auto_ptr<digidoc::ISerialize> serializer(new digidoc::ZipSerialize(fileName));
720  std::auto_ptr<digidoc::BDoc> bdoc(new digidoc::BDoc(serializer));
721 
722  size_t sigCount = bdoc->signatureCount();
723  for ( size_t sig = 0; sig < sigCount; sig++ )
724  {
725  const digidoc::Signature* signature = bdoc->getSignature(sig);
726  std::cout << "Signature[" << sig << "]:" << std::endl;
727 
728  try
729  {
730  signature->validateOffline();
731  std::cout << "\tofflineValid[true]" << std::endl;
732  }
733  catch (digidoc::SignatureException& e)
734  {
735  dumpException(e);
736  }
737 
738  digidoc::SignatureProductionPlace productionPlace = signature->getProductionPlace();
739  std::cout << "\tSignatureProductionPlace:" << std::endl;
740  std::cout << "\t\tcity[" << productionPlace.city << "]" << std::endl;
741  std::cout << "\t\tstateOrProvince[" << productionPlace.stateOrProvince << "]" << std::endl;
742  std::cout << "\t\tpostalCode[" << productionPlace.postalCode << "]" << std::endl;
743  std::cout << "\t\tcountryName[" << productionPlace.countryName << "]" << std::endl;
744 
745  digidoc::SignerRole signerRole = signature->getSignerRole();
746  std::cout << "\tClaimedRoles:" << std::endl;
747  for ( digidoc::SignerRole::TRoles::const_iterator it = signerRole.claimedRoles.begin()
748  ; it != signerRole.claimedRoles.end()
749  ; it++ )
750  {
751  std::cout << "\t\tClaimedRole[" << (*it) << "]" << std::endl;
752  }
753 
754  std::cout << "\tSigningTime:" << std::endl;
755  std::cout << "\t\ttime[" << signature->getSigningTime() << "]" << std::endl;
756 
757  // certs
758  testShowCertInfo(signature);
759  }
760 
761 
762 
763 
764  return 0;
765 };
766 
768 {
769  try
770  {
771  PKCS11ConsolePinSigner signer("/usr/lib/opensc-pkcs11.so");
772  digidoc::SignatureProductionPlace spp("Tallinn", "Harjumaa", "12345", "Estonia");
773 
774  digidoc::SignerRole role("chief o'brian");
775  signer.setSignerRole(role);
776  signer.setSignatureProductionPlace(spp);
777 
778  digidoc::BDoc bdoc;
779 
780  digidoc::Document doc_001("/proc/cpuinfo", "text/txt");
781  bdoc.addDocument(doc_001);
782 
783 
784  bdoc.sign(&signer, digidoc::Signature::TM);
785 
786  // save/print out the signature created.
787  digidoc::Signature* sig = const_cast<digidoc::Signature*>(bdoc.getSignature(bdoc.signatureCount() - 1));
788  //sig->saveToXml();
789 
790  sig->validateOffline();
791  }
792  catch(const digidoc::SignException& e)
793  {
794  ERR("Caught SignException: %s", e.getMsg().c_str());
795  }
796  catch(const digidoc::Exception& e)
797  {
798  ERR("Caught Exception: %s", e.getMsg().c_str());
799  }
800  catch(...)
801  {
802  ERR("Caught unknown exception");
803  }
804 
805  return 0;
806 
807 }
808 
809 
810 int testCanon(int argc, char* argv[])
811 {
812  try {
813  xercesc::XMLPlatformUtils::Initialize();
814  }
815  catch (const xercesc::XMLException& toCatch) {
816  char* message = xercesc::XMLString::transcode(toCatch.getMessage());
817  std::cout << "Error during initialization! :\n"
818  << message << "\n";
819  xercesc::XMLString::release(&message);
820  return 1;
821  }
822 
823  xercesc::XercesDOMParser* parser = new xercesc::XercesDOMParser();
824  parser->setValidationScheme(xercesc::XercesDOMParser::Val_Always);
825  parser->setDoNamespaces(true); // optional
826 
827  //xercesc::ErrorHandler* errHandler = /*(xercesc::ErrorHandler*)*/ new xercesc::HandlerBase();
828  //parser->setErrorHandler(errHandler);
829 
830  //char* xmlFile = "tmp/META-INF/signature1.xml";
831  //char* xmlFile = "tmp/bdocTM/META-INF/signature0.xml";
832  char* xmlFile = "tmp/javalib07/META-INF/signature1.xml";
833 
834  xercesc::DOMDocument *doc = 0;
835 
836  try {
837  parser->parse(xmlFile);
838  std::cout << "Parsed" << std::endl;
839  doc = parser->getDocument();
840  std::cout << "Got document" << std::endl;
841 
842 
843  //xercesc::DOMNode* signedPropsNode = doc->getFirstChild()->getLastChild()->getFirstChild()->getFirstChild();
844 
845  //xercesc::DOMNodeList* list = doc->getElementsByTagName(xercesc::XMLString::transcode("SignedInfo"));
846 
847  xercesc::DOMNodeList* list =doc->getElementsByTagNameNS(xercesc::XMLString::transcode("http://www.w3.org/2000/09/xmldsig#"),
848  xercesc::XMLString::transcode("SignedInfo"));
849 
850  xercesc::DOMNode* node = list->item(0);
851  //node->getNodeName();
852  std::cout << "Got node" << std::endl;
853 
854 
855  XSECC14n20010315 canonicalizer(doc, node);
856  //canonicalizer.setCommentsProcessing(true);
857  canonicalizer.setUseNamespaceStack(true);
858  canonicalizer.setExclusive();
859  //canonicalizer.setStartNode(node);
860 
861  std::cout << "Got canon" << std::endl;
862 
863  //canonicalizer.XPathSelectNodes("//SignedInfo");
864 
865  std::vector<unsigned char> c14n;
866  unsigned char buffer[1024];
867  int bytes = 0;
868  std::cout << "Getting data" << std::endl;
869  while((bytes = canonicalizer.outputBuffer(buffer, 1024)) > 0)
870  {
871  // XXX: use memcopy instead?
872  for(int i = 0; i < bytes; i++)
873  {
874  c14n.push_back(buffer[i]);
875  }
876  }
877 
878  INFO("c14n = '%s'", std::string(reinterpret_cast<char*>(&c14n[0]), c14n.size()).c_str() );
879  // return c14n;
880 
881  std::auto_ptr<Digest> sha1 = Digest::create(digidoc::Digest::URI_SHA1);
882  sha1->update(c14n);
883 
884  std::vector<unsigned char> hash = sha1->getDigest();
885 
886  DEBUGMEM("Digest", &hash[0], hash.size());
887 
888  }
889  catch (const xercesc::XMLException& toCatch) {
890  char* message = xercesc::XMLString::transcode(toCatch.getMessage());
891  std::cout << "Exception message is: \n"
892  << message << "\n";
893  xercesc::XMLString::release(&message);
894  return -1;
895  }
896  catch (const xercesc::DOMException& toCatch) {
897  char* message = xercesc::XMLString::transcode(toCatch.msg);
898  std::cout << "Exception message is: \n"
899  << message << "\n";
900  xercesc::XMLString::release(&message);
901  return -1;
902  }
903  catch (...) {
904  std::cout << "Unexpected Exception \n" ;
905  return -1;
906  }
907 
908  delete parser;
909  //delete errHandler;
910  return 0;
911 
912 }
913 
920 int testC14N(int argc, char* argv[])
921 {
922  try
923  {
924  //xercesc::XMLPlatformUtils::Initialize();
925  //XSECPlatformUtils::Initialise();
926 
927  DEBUG("POS[10]");
928  std::string fileName = "/home/janari/projects/smartlink/digidoc/tmp/example_container/META-INF/manifest.xml";
929  xml_schema::Properties properties;
930  properties.schema_location("urn:oasis:names:tc:opendocument:xmlns:manifest:1.0", digidoc::Conf::getInstance()->getManifestXsdPath());
931  std::auto_ptr<digidoc::manifest::Manifest> manifest(digidoc::manifest::manifest(fileName, xml_schema::Flags::keep_dom, properties));
932 
933  DEBUG("POS[20]");
934 
935  xercesc::DOMNode* pNode = manifest->_node();
936  /*
937  //xercesc::DOMDocument* pDoc = new xercesc::DOMDocument();
938  //xercesc::DOMDocument* pDoc = NULL;
939  DEBUG("POS[21]")
940 
941  //DEBUG("POS[22] :: DOMImplementation::getImplementation() = 0x%X", (unsigned int)xercesc::DOMImplementation::getImplementation())
942  //xercesc::DOMDocument* pDoc = xercesc::DOMImplementation::getImplementation()->createDocument();
943 
944  const XMLCh ls_id [] = {xercesc::chLatin_L, xercesc::chLatin_S, xercesc::chNull};
945  DEBUG("POS[22]")
946  xercesc::DOMImplementation* impl = xercesc::DOMImplementationRegistry::getDOMImplementation(ls_id);
947  DEBUG("POS[23] :: impl = 0x%X", (unsigned int)impl)
948 
949 
950  xercesc::DOMDocument* pDoc = xercesc::DOMImplementationRegistry::getDOMImplementation(ls_id)->createDocument();
951 
952  DEBUG("POS[26] :: pNode = 0x%X", (unsigned int)pNode)
953  //pDoc->adoptNode(pNode);
954  pDoc->importNode(pNode, true);
955  */
956 
957  DEBUG("POS[30]");
958  //DEBUG("POS[31] :: pNode->getOwnerDocument() = 0x%X", (unsigned int)pNode->getOwnerDocument())
959  XSECC14n20010315 canon(pNode->getOwnerDocument() /*pDoc*/);
960  canon.setCommentsProcessing(true);
961  canon.setUseNamespaceStack(true);
962 
963  canon.setStartNode(manifest->file_entry()[0]._node());
964 
965  DEBUG("POS[40]");
966  char buffer[512];
967  int res = canon.outputBuffer((unsigned char *) buffer, 128);
968  DEBUG("POS[41] :: res = %d", res);
969  while(res != 0)
970  {
971  buffer[res] = '\0';
972  std::cout << buffer;
973  res = canon.outputBuffer((unsigned char *) buffer, 128);
974  }
975 
976  std::cout << std::endl;
977  DEBUG("POS[60]");
978 
979 
980  //XSECPlatformUtils::Terminate();
981  //xercesc::XMLPlatformUtils::Terminate();
982  }
983  catch(const xercesc::DOMException& e)
984  {
985  ERR("xercesc::DOMException: %s", XMLString::transcode(e.getMessage()));
986  }
987  catch(const xercesc::XMLException& e)
988  {
989  ERR("xercesc::DOMException: %s", XMLString::transcode(e.getMessage()));
990  }
991  catch(const xml_schema::Exception& e)
992  {
993  std::ostringstream oss;
994  oss << e;
995  ERR("xml_schema::Exception: %s", oss.str().c_str());
996  }
997 
998 
999  return 0;
1000 }
1001 
1002 int testRSASigner(int argc, char* argv[])
1003 {
1004  try
1005  {
1006  // Self signed certificate with private key can be creates with the following command:
1007  // openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout cert.pem -out cert.pem
1008 
1009  // Load X.509 cert and RSA private key.
1010  std::string keyPath = "/home/janari/projects/smartlink/digidoc/test/data/cert/cert+priv_key.pem";
1011  X509* signingCert = X509Cert::loadX509(keyPath); X509_scope signingCertScope(&signingCert);
1012  RSA* privateKey = RSACrypt::loadRSAPrivateKey(keyPath); RSA_scope privateKeyScope(&privateKey);
1013 
1014  RSASigner signer(signingCert, privateKey);
1015 
1016  //X509* cert = signer.getCert();
1017  //DEBUG("cert = 0x%X", (unsigned int)cert);
1018 
1019  digidoc::Signer::Digest digest = { NID_sha1, (unsigned char*)"ABCDEFGHIJ0123456789", 20 };
1020  digidoc::Signer::Signature signature = { new unsigned char[256], 256 };
1021  memset(signature.signature, 0, signature.length);
1022  try { signer.sign(digest, signature); } catch(const digidoc::SignException& ) {}
1023 
1024  DEBUG("----------------------------------------------------------------------------------------------------");
1025  DEBUG("Digest: type = %d, digest = %s, length = %d", digest.type, (char*)digest.digest, digest.length);
1026  DEBUG("Signature: signature = 0x%X, length = %d", (unsigned int)signature.signature, signature.length);
1027 
1028  DEBUGMEM("", signature.signature, signature.length);
1029  }
1030  catch(const digidoc::SignException& e)
1031  {
1032  ERR("Caught SignException: %s", e.getMsg().c_str());
1033  }
1034  catch(const digidoc::IOException& e)
1035  {
1036  ERR("Caught IOException: %s", e.getMsg().c_str());
1037  }
1038  catch(const digidoc::Exception& e)
1039  {
1040  ERR("Caught Exception: %s", e.getMsg().c_str());
1041  }
1042  catch(...)
1043  {
1044  ERR("Caught unknown exception");
1045  }
1046 
1047  return 0;
1048 }
1049 
1050 
1052 {
1053  digidoc::X509Cert cert(signature->getSigningCertificate());
1054 
1055  std::cout << "\tCertificateInfo:" << std::endl;
1056  std::cout << "\t\tserial[" << cert.getSerial() << "]" << std::endl;
1057  std::cout << "\t\tissuerName[" << cert.getIssuerName() << "]" << std::endl;
1058 
1059  return 0;
1060 }
1061 
1062 std::string indent(size_t level, char character = ' ')
1063 {
1064  std::string str;
1065  str.resize(level, character);
1066  return str;
1067 }
1068 
1070  , std::stringstream& addTo
1071  , size_t depth
1072  )
1073 {
1074  addTo << indent(depth)
1075  << "Exception[" << e.getMsg() << "]"
1076  << std::endl;
1077 
1078  if ( e.hasCause() )
1079  {
1080  digidoc::Exception::Causes causedBy = e.getCauses();
1081 
1082  addTo << indent(depth + 1) << "Caused by:" << std::endl;
1083  for ( digidoc::Exception::Causes::const_iterator it = causedBy.begin()
1084  ; it != causedBy.end()
1085  ; it++ )
1086  {
1087  getExceptionMsg(*it, addTo, depth + 1); // recurse
1088  }
1089 
1090  }
1091 }
1092 
1094 {
1095  std::stringstream stream;
1096  getExceptionMsg(e, stream, 0);
1097  std::cout << stream.str() << std::endl;
1098 }
1099 
1100 
1101 
1106  : PKCS11Signer(driver)
1107 {
1108 }
1109 
1111 {
1112 }
1113 
1118  std::vector<PKCS11Signer::PKCS11Cert> certificates) throw(SignException)
1119 {
1120  // Print available certificates.
1121  DEBUG("Available certificates:\n");
1122  for(std::vector<PKCS11Signer::PKCS11Cert>::const_iterator iter = certificates.begin(); iter != certificates.end(); iter++)
1123  {
1124  printPKCS11Cert(*iter);
1125  }
1126 
1127  // 0 - Isikutuvastus, 1 - Allkirjastamine
1128  PKCS11Signer::PKCS11Cert cert = certificates[0];
1129  DEBUG("Selected certificate: %s", cert.token.label.c_str());
1130  return cert;
1131 }
1132 
1142 {
1143  char pin[16];
1144  size_t pinMax = 16;
1145 
1146 #if defined(_WIN32)
1147  {
1148  printf("Please enter PIN for token '%s' or <enter> to cancel: ", certificate.token.label.c_str());
1149  size_t i = 0;
1150  char c;
1151  while(i < pinMax && (c = getch()) != '\r')
1152  {
1153  pin[i++] = c;
1154  }
1155  }
1156 #else
1157  char prompt[1024];
1158  snprintf(prompt, sizeof(prompt), "Please enter PIN for token '%s' or <enter> to cancel: ", certificate.token.label.c_str());
1159  char* p = getpass(prompt);
1160  strncpy(pin, p, pinMax);
1161 #endif
1162 
1163  pin[pinMax-1] = '\0';
1164 
1165  std::string result(pin);
1166  if(result.empty())
1167  {
1168  THROW_SIGNEXCEPTION("PIN acquisition canceled.");
1169  }
1170 
1171  return result;
1172  //return "0090";
1173  //return "01497";
1174 }
1175 
1182 {
1183  DEBUG("-------------------------------------------------------");
1184  DEBUG(" token label: %s", cert.token.label.c_str());
1185  DEBUG(" token manufacturer: %s", cert.token.manufacturer.c_str());
1186  DEBUG(" token model: %s", cert.token.model.c_str());
1187  DEBUG(" token serial Nr: %s", cert.token.serialNr.c_str());
1188  DEBUG(" label: %s", cert.label.c_str());
1189 }