summaryrefslogtreecommitdiff
path: root/libdigidoc/cdigidoc.c
diff options
context:
space:
mode:
Diffstat (limited to 'libdigidoc/cdigidoc.c')
-rw-r--r--libdigidoc/cdigidoc.c2559
1 files changed, 2559 insertions, 0 deletions
diff --git a/libdigidoc/cdigidoc.c b/libdigidoc/cdigidoc.c
new file mode 100644
index 0000000..49e0988
--- /dev/null
+++ b/libdigidoc/cdigidoc.c
@@ -0,0 +1,2559 @@
+//==================================================
+// FILE: digidoc.c
+// PROJECT: Digi Doc
+// DESCRIPTION: Utility program to demonstrate the
+// functionality of DigiDocLib
+// AUTHOR: Veiko Sinivee, S|E|B IT Partner Estonia
+//==================================================
+// Copyright (C) AS Sertifitseerimiskeskus
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+// GNU Lesser General Public Licence is available at
+// http://www.gnu.org/copyleft/lesser.html
+//==========< HISTORY >=============================
+// 12.01.2004 Veiko Sinivee
+// Creation
+//==================================================
+
+#include "config.h"
+#include <libdigidoc/DigiDocDefs.h>
+#include <libdigidoc/DigiDocLib.h>
+#include <libdigidoc/DigiDocConfig.h>
+#include <libdigidoc/DigiDocPKCS11.h>
+#include <libdigidoc/DigiDocSAXParser.h>
+#include <libdigidoc/DigiDocParser.h>
+#include <libdigidoc/DigiDocEncSAXParser.h>
+#include <libdigidoc/DigiDocEnc.h>
+#include <libdigidoc/DigiDocEncGen.h>
+#include <libdigidoc/DigiDocConvert.h>
+#include <libdigidoc/DigiDocDebug.h>
+#include <libdigidoc/DigiDocCert.h>
+#include <libdigidoc/DigiDocObj.h>
+#include <libdigidoc/DigiDocGen.h>
+#include <libdigidoc/DigiDocService.h>
+#include <libdigidoc/DigiDocDfExtract.h>
+
+#ifdef WIN32
+ #define snprintf _snprintf
+ #include <wchar.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <openssl/objects.h>
+#include <sys/stat.h>
+#include <time.h>
+
+//==========< global constants >====================
+
+// programm arguments
+char* p_szInFile = 0;
+char* p_szInEncFile = 0;
+char* p_szInDecFile = 0;
+char* p_szOutFile = 0;
+char* p_szConfigFile = 0;
+int p_parseMode = 1, g_nLibErrors = 0;
+
+int g_cgiMode = 1; // 1=output in CGI mode, 0=normal e.g. human readable mode
+char* g_szOutputSeparator = 0;
+char *errorClass[] = {"NO_ERRORS", "TECHNICAL", "USER", "LIBRARY"};
+char* g_szProgNameVer = "cdigidoc/"DIGIDOC_VERSION;
+
+//==========< forward defs >========================
+
+void printErrorsAndWarnings(SignedDoc* pSigDoc);
+
+//==========< helper functions for argument handling >====================
+
+
+
+//--------------------------------------------------
+// Handles one argument
+//--------------------------------------------------
+int checkArguments(int argc, char** argv, int* pCounter, char** dest)
+{
+ int nLen = 0;
+
+ if(argc > (*pCounter)+1 && argv[(*pCounter)+1][0] != '-') {
+ nLen = strlen(argv[(*pCounter)+1]) * 2;
+ ddocConvertInput((const char*)argv[(*pCounter)+1], dest);
+ (*pCounter)++;
+ }
+ return nLen;
+}
+
+//--------------------------------------------------
+// checks the existence of one command line argument
+//--------------------------------------------------
+int hasCmdLineArg(int argc, char** argv, const char* argName)
+{
+ int i;
+
+ for(i = 1; i < argc; i++) {
+ if(argv[i] != NULL && argv[i][0] == '-' &&
+ !strcmp(argv[i], argName)) {
+ return i;
+ }
+ }
+ return 0;
+}
+
+//--------------------------------------------------
+// Returns the value of one command line argument
+//--------------------------------------------------
+int checkCmdLineArg(int argc, char** argv, const char* argName, char** dest)
+{
+ int i;
+
+ *dest = 0; // mark as not found
+ for(i = 1; i < argc; i++) {
+ if(argv[i] != NULL && argv[i][0] == '-' &&
+ !strcmp(argv[i], argName)) {
+ if((i + 1 < argc) && (argv[i+1][0] != '-')) {
+ ddocConvertInput((const char*)argv[i+1], dest);
+ return 0;
+ }
+ else
+ return ERR_BAD_PARAM;
+ }
+ }
+ return 0; // not found but no error
+}
+
+//--------------------------------------------------
+// prints usage statement
+//--------------------------------------------------
+void printUsage()
+{
+ fprintf(stderr, "USAGE: cdigidoc <command(s)> [-in <input-file>] [-out <output-file>] [-config <config-file>]\n");
+ fprintf(stderr, "COMMANDS:\n");
+ fprintf(stderr, "\t[-new] \n");
+ fprintf(stderr, "\t-check-cert <-cerificate-file-name (PEM format)>\n");
+ fprintf(stderr, "\t-add <file-name> <mime-type> [<content-type>] [<charset>]\n");
+ fprintf(stderr, "\t-verify \n");
+ fprintf(stderr, "\t-sign <pin> [[[<manifest>] [<city> <state> <zip> <country>]] [slot(0)] [ocsp(1)] [PKCS11/CNG/PKCS12] [pkcs12-file-name]]\n");
+ fprintf(stderr, "\t-extract <doc-id> <file-name> [<charset>] [<file-name-charset>]\n");
+ fprintf(stderr, "\t-encrypt <file-name>\n");
+ fprintf(stderr, "\t-encrypt-sk <file-name>\n");
+ fprintf(stderr, "\t-encrecv <cert-file> [<recipient>] [<keyname>] [<carried-key-name>]\n");
+ fprintf(stderr, "\t-decrypt <file-name> <pin1> [pkcs12-file] [slot(0)]\n");
+ fprintf(stderr, "\t-decrypt-sk <file-name> <pin1> [pkcs12-file] [slot(0)]\n");
+ fprintf(stderr, "\t-denc-list <file-name>\n");
+ fprintf(stderr, "\t-encrypt-file <in-file-name> <out-file-name> [<in-file-mime-type>]\n");
+ fprintf(stderr, "\t-decrypt-file <in-file-name> <out-file-name> <pin1> [pkcs12-file]\n");
+
+ fprintf(stderr, "\t-calc-sign <cert-file> [<manifest>] [<city> <state> <zip> <country>]\n");
+ fprintf(stderr, "\t-add-sign-value <sign-value-file> <sign-id>\n");
+ fprintf(stderr, "\t-del-sign <sign-id>\n");
+ fprintf(stderr, "\t-get-confirmation <sign-id>\n");
+
+ fprintf(stderr, "\t-mid-sign <phone-no> <per-code> [[<country>(EE)] [<lang>(EST)] [<service>(Testing)] [<manifest>] [<city> <state> <zip>]]\n");
+ fprintf(stderr, "\t-mid-test <input-data-file> <input-mime-type> <output-ddoc> <phone-no> <per-code> [<service> (Testimine)]\n");
+
+ fprintf(stderr, "\t-in-mem <file-name>\n");
+ fprintf(stderr, "\t-add-mem <file-name> <mime-type> [<content-type>]\n");
+ fprintf(stderr, "\t-out-mem <file-name>\n");
+ fprintf(stderr, "\t-extract-mem <doc-id> <file-name>\n");
+
+ fprintf(stderr, "OPTIONS:\n");
+ fprintf(stderr, "\t-cgimode [<ouput-separator] - output in CGI mode\n");
+ fprintf(stderr, "\t-consolemode - output in console (not cgi) mode\n");
+ fprintf(stderr, "\t-SAX - use SAX parser\n");
+ fprintf(stderr, "\t-libraryerrors - show all errors sent by library\n");
+ fprintf(stderr, "\t-XRDR - use XmlReader parser\n");
+}
+
+//--------------------------------------------------
+// Checks program runtime arguments
+//--------------------------------------------------
+int checkProgArguments(int argc, char** argv)
+{
+ int err = ERR_OK;
+
+ // -?, -help -> print usage
+ if(!err && (hasCmdLineArg(argc, argv, "-?") ||
+ hasCmdLineArg(argc, argv, "-help")))
+ printUsage();
+ // -in <input-file>
+ if(!err)
+ if((err = checkCmdLineArg(argc, argv, "-in", &p_szInFile)) != ERR_OK)
+ addError(err, __FILE__, __LINE__, "Missing or invalid input file name");
+ // -in-mem <input-file>
+ if(!err && hasCmdLineArg(argc, argv, "-in-mem")) {
+ if((err = checkCmdLineArg(argc, argv, "-in-mem", &p_szInFile)) != ERR_OK)
+ addError(err, __FILE__, __LINE__, "Missing or invalid input file name");
+ p_parseMode = 3;
+ }
+ // -SAX -> use Sax parser (default)
+ if(!err)
+ if(hasCmdLineArg(argc, argv, "-SAX"))
+ p_parseMode = 1;
+ // -SAX -> use Sax parser (default)
+ if(!err)
+ if(hasCmdLineArg(argc, argv, "-XRDR"))
+ p_parseMode = 2;
+ // -libraryerrors
+ if(!err)
+ if(hasCmdLineArg(argc, argv, "-libraryerrors"))
+ g_nLibErrors = 1;
+ // -out <out-file>
+ if(!err)
+ if((err = checkCmdLineArg(argc, argv, "-out", &p_szOutFile)) != ERR_OK)
+ addError(err, __FILE__, __LINE__, "Missing or invalid output file name");
+ if(!err && hasCmdLineArg(argc, argv, "-out-mem")) {
+ if((err = checkCmdLineArg(argc, argv, "-out-mem", &p_szOutFile)) != ERR_OK)
+ addError(err, __FILE__, __LINE__, "Missing or invalid output file name");
+ p_parseMode = 3;
+ }
+ // -encrypt <encryption-input-file>
+ if(!err && hasCmdLineArg(argc, argv, "-encrypt"))
+ if((err = checkCmdLineArg(argc, argv, "-encrypt", &p_szInEncFile)) != ERR_OK)
+ addError(err, __FILE__, __LINE__, "Missing or invalid encrypt input file name");
+ // -encrypt-sk <encryption-input-file>
+ if(!err && hasCmdLineArg(argc, argv, "-encrypt-sk"))
+ if((err = checkCmdLineArg(argc, argv, "-encrypt-sk", &p_szInEncFile)) != ERR_OK)
+ addError(err, __FILE__, __LINE__, "Missing or invalid encrypt input file name");
+ // -config <config-file>
+ if(!err)
+ if((err = checkCmdLineArg(argc, argv, "-config", &p_szConfigFile)) != ERR_OK)
+ addError(err, __FILE__, __LINE__, "Missing or invalid configuration file name");
+ // -CGI -> use CGI output mode
+ if(!err)
+ if(hasCmdLineArg(argc, argv, "-cgimode")) {
+ g_cgiMode = 1;
+ if((err = checkCmdLineArg(argc, argv, "-cgimode", &g_szOutputSeparator)) != ERR_OK)
+ addError(err, __FILE__, __LINE__, "Missing or invalid cgi output separator");
+ if(!g_szOutputSeparator || !g_szOutputSeparator[0] || err) {
+ g_szOutputSeparator = strdup("|");
+ err = ERR_OK;
+ }
+ }
+ if(hasCmdLineArg(argc, argv, "-consolemode")) {
+ g_cgiMode = 0;
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// reads various statusflags from config file
+//--------------------------------------------------
+void readConfigParams()
+{
+ int n = 0;
+ const char* s = 0;
+
+ // check if we are in CGI mode
+ n = ConfigItem_lookup_bool("DIGIDOC_CGI_MODE", 0);
+ if(!g_cgiMode && n)
+ g_cgiMode = n;
+
+ s = ConfigItem_lookup("DIGIDOC_CGI_SEPARATOR");
+ if(!g_szOutputSeparator && s)
+ g_szOutputSeparator = (char*)strdup(s);
+ if(!g_szOutputSeparator || !g_szOutputSeparator[0]) {
+ if(g_szOutputSeparator) free(g_szOutputSeparator);
+ g_szOutputSeparator = strdup("|");
+ }
+}
+
+
+//==========< command handlers >====================
+
+//--------------------------------------------------
+// Creates a new signed doc
+//--------------------------------------------------
+int cmdNew(SignedDoc** ppSigDoc, const char* pFormat, const char* pVersion)
+{
+ int err = ERR_OK;
+ const char* format = pFormat, *version = pVersion;
+
+ if(!p_szOutFile) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "No output file specified");
+ return err;
+ }
+ if(!format)
+ format = "DIGIDOC-XML";
+ if(!version)
+ version = "1.3";
+ if(format && version) {
+ err = SignedDoc_new(ppSigDoc, format, version);
+ RETURN_IF_NOT(err == ERR_OK, err);
+ } else {
+ err = ERR_UNSUPPORTED_FORMAT;
+ addError(err, __FILE__, __LINE__, "Error finding new document format or version");
+ }
+ return err;
+}
+
+
+
+//--------------------------------------------------
+// Adds a DataFile to signed doc
+//--------------------------------------------------
+int cmdAddDataFile(SignedDoc** ppSigDoc, const char* file,
+ const char* mime, const char* content, const char* charset)
+{
+ int err = ERR_OK, l1;
+ DataFile *pDataFile;
+ char *p = 0, buf1[300];
+
+ // if there was no new command then implicitly create a new document
+ if(!(*ppSigDoc)) {
+ err = cmdNew(ppSigDoc, NULL, NULL);
+ RETURN_IF_NOT(err == ERR_OK, err);
+ }
+ // convert to UTF-8
+ err = ddocConvertInput(file, &p);
+ l1 = sizeof(buf1);
+ getFullFileName(p, buf1, l1);
+ freeLibMem(p);
+ // add a file
+ err = DataFile_new(&pDataFile, *ppSigDoc, NULL, buf1,
+ content, mime, 0, NULL, 0, NULL, charset);
+ if(!err)
+ err = calculateDataFileSizeAndDigest(*ppSigDoc, pDataFile->szId, buf1, DIGEST_SHA1);
+
+ RETURN_IF_NOT(err == ERR_OK, err);
+ return err;
+}
+
+//--------------------------------------------------
+// Create digidoc and adds datafiles
+//--------------------------------------------------
+int runAddCmds(int argc, char** argv, SignedDoc** ppSigDoc)
+{
+ int err = ERR_OK, i;
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // create new digidoc
+ if(!strcmp(argv[i], "-new")) {
+ char* format = NULL;
+ char* version = NULL;
+ // optional content and charset
+ checkArguments(argc, argv, &i, &format);
+ checkArguments(argc, argv, &i, &version);
+ //printf("format: %s version: %s\n", format, version);
+ err = cmdNew(ppSigDoc, format, version);
+ freeLibMem(format);
+ freeLibMem(version);
+ RETURN_IF_NOT(err == ERR_OK, err);
+ }
+ // add a DataFile
+ if(!strcmp(argv[i], "-add")) {
+ if(argc > i+2 && argv[i+1][0] != '-' && argv[i+2][0] != '-') {
+ char* file = argv[i+1];
+ char* mime = argv[i+2];
+ char* content = NULL;
+ char* charset = NULL;
+ i += 2;
+ // optional content and charset
+ checkArguments(argc, argv, &i, &content);
+ checkArguments(argc, argv, &i, &charset);
+ err = cmdAddDataFile(ppSigDoc, (const char*)file, (const char*)mime,
+ (const char*)(content ? content : CONTENT_EMBEDDED_BASE64),
+ (const char*)(charset ? charset : CHARSET_UTF_8));
+ freeLibMem(content);
+ freeLibMem(charset);
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <file> and <mime-type> arguments of -add command");
+ }
+ }
+
+ }
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// Adds a DataFile to signed doc
+//--------------------------------------------------
+int cmdAddDataFileFromMem(SignedDoc** ppSigDoc, const char* file,
+ const char* mime, const char* content)
+{
+ int err = ERR_OK;
+ DataFile *pDf = NULL;
+ DigiDocMemBuf mbuf1;
+
+ mbuf1.pMem = 0;
+ mbuf1.nLen = 0;
+
+ // if there was no new command then implicitly create a new document
+ if(!(*ppSigDoc)) {
+ err = cmdNew(ppSigDoc, NULL, NULL);
+ RETURN_IF_NOT(err == ERR_OK, err);
+ }
+ err = ddocReadFile(file, &mbuf1);
+ if(!err)
+ err = createDataFileInMemory(&pDf, *ppSigDoc, NULL, file, content, mime, mbuf1.pMem, mbuf1.nLen);
+ ddocMemBuf_free(&mbuf1);
+ return err;
+}
+
+//--------------------------------------------------
+// Create digidoc and adds datafiles
+//--------------------------------------------------
+int runAddMemCmds(int argc, char** argv, SignedDoc** ppSigDoc)
+{
+ int err = ERR_OK, i;
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // add a DataFile
+ if(!strcmp(argv[i], "-add-mem")) {
+ if(argc > i+2 && argv[i+1][0] != '-' && argv[i+2][0] != '-') {
+ char* file = argv[i+1];
+ char* mime = argv[i+2];
+ char* content = NULL;
+ i += 2;
+ // optional content and charset
+ checkArguments(argc, argv, &i, &content);
+ err = cmdAddDataFileFromMem(ppSigDoc, (const char*)file, (const char*)mime,
+ (const char*)(content ? content : CONTENT_EMBEDDED_BASE64));
+ freeLibMem(content);
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <file> and <mime-type> arguments of -add-mem command");
+ }
+ }
+
+ }
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// Create digidoc and adds datafiles
+//--------------------------------------------------
+/*int runAddSignValue(int argc, char** argv, SignedDoc** ppSigDoc)
+{
+ int err = ERR_OK, i;
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // create new digidoc
+ if(!strcmp(argv[i], "-addsignvalue")) {
+ char* infile = NULL;
+ char* sigid = NULL;
+ char* sigvalf = NULL;
+ checkArguments(argc, argv, &i, &infile);
+ checkArguments(argc, argv, &i, &sigid);
+ checkArguments(argc, argv, &i, &sigvalf);
+ err = cmdReadDigiDoc(ppSigDoc, 0, 1);
+
+ }
+ // add a DataFile
+ if(!strcmp(argv[i], "-addsignvalue")) {
+ if(argc > i+2 && argv[i+1][0] != '-' && argv[i+2][0] != '-') {
+ char* file = argv[i+1];
+ char* mime = argv[i+2];
+ char* content = CONTENT_EMBEDDED_BASE64;
+ char* charset = CHARSET_UTF_8;
+ i += 2;
+ // optional content and charset
+ checkArguments(argc, argv, &i, &content);
+ checkArguments(argc, argv, &i, &charset);
+ err = cmdAddDataFile(ppSigDoc, (const char*)file, (const char*)mime,
+ (const char*)content, (const char*)charset);
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <in-digidoc> and <sig-id> or <sign-value-file> arguments of -addsignvalue command");
+ }
+
+ }
+ }
+ return err;
+}*/
+
+//--------------------------------------------------
+// Add ecryption recipients
+//--------------------------------------------------
+int runRecipientCmds(int argc, char** argv, DEncEncryptedData** ppEncData)
+{
+ int err = ERR_OK, i, rb = 0;
+ DEncEncryptedKey* pEncKey = 0;
+ X509* pCert = 0;
+ DigiDocMemBuf mbuf1;
+
+ mbuf1.pMem = 0;
+ mbuf1.nLen = 0;
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // add a recipients key
+ if(!strcmp(argv[i], "-encrecv")) {
+ if(argc > i+1 && argv[i+1][0] != '-') {
+ char* certfile = argv[i+1];
+ char* recipient = NULL;
+ char* keyname = NULL;
+ char* carriedkeyname = NULL;
+ char* id = NULL;
+ i++;
+ if(!(*ppEncData))
+ err = dencEncryptedData_new(ppEncData, DENC_XMLNS_XMLENC, DENC_ENC_METHOD_AES128, 0, 0, 0);
+ if(!err) {
+ err = dencMetaInfo_SetLibVersion(*ppEncData);
+ if(!err) {
+ err = dencMetaInfo_SetFormatVersion(*ppEncData);
+ if(!err) {
+ // optional arguments
+ checkArguments(argc, argv, &i, &recipient);
+ checkArguments(argc, argv, &i, &keyname);
+ checkArguments(argc, argv, &i, &carriedkeyname);
+ err = ReadCertificate(&pCert, certfile);
+ if(!err) {
+ if(!recipient) {
+ ddocCertGetSubjectCN(pCert, &mbuf1);
+ recipient = (char*)mbuf1.pMem;
+ rb = 1;
+ }
+ err = dencEncryptedKey_new(*ppEncData, &pEncKey, pCert,
+ DENC_ENC_METHOD_RSA1_5,
+ id, recipient, keyname, carriedkeyname);
+ if(rb) recipient = NULL; // was not malloc separately from mbuf1
+ }
+ }
+ }
+ }
+ ddocMemBuf_free(&mbuf1);
+ freeLibMem(recipient);
+ freeLibMem(keyname);
+ freeLibMem(carriedkeyname);
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <cert-file> argument of -encrecv command");
+ }
+ }
+ }
+ }
+ return err;
+}
+
+
+unsigned char* findFileExt(unsigned char* szFileName)
+{
+ int i = 0;
+
+ if(szFileName && strlen(szFileName) > 0) {
+ for(i = strlen(szFileName)-1; (i > 0) && (szFileName[i] != '.'); i--);
+ if(szFileName[i] == '.')
+ return szFileName + i + 1;
+ }
+ return 0;
+}
+
+int checkOldFormatVer(SignedDoc* pSigDoc)
+{
+ if(!pSigDoc || !pSigDoc->szFormat || !pSigDoc->szFormatVer) {
+ addError(ERR_BAD_PARAM, __FILE__, __LINE__, "Format or version not specified");
+ return ERR_BAD_PARAM;
+ }
+ if(!strcmp(pSigDoc->szFormat, SK_XML_1_NAME) ||
+ (!strcmp(pSigDoc->szFormat, DIGIDOC_XML_1_1_NAME) &&
+ (!strcmp(pSigDoc->szFormatVer, DIGIDOC_XML_1_1_VER) ||
+ !strcmp(pSigDoc->szFormatVer, DIGIDOC_XML_1_2_VER)))) {
+ SET_LAST_ERROR(ERR_OLD_VERSION);
+ return ERR_OLD_VERSION;
+ }
+ return ERR_OK;
+}
+
+//--------------------------------------------------
+// reads in a signed doc
+//--------------------------------------------------
+int cmdReadDigiDoc(SignedDoc** ppSigDoc, DEncEncryptedData** ppEncData, int nMode)
+{
+ int err = ERR_OK, e;
+ int nMaxDfLen;
+ unsigned char* pExt = 0;
+ if(!p_szInFile) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "No input file specified");
+ return err;
+ }
+ nMaxDfLen = ConfigItem_lookup_int("DATAFILE_MAX_CACHE", 0);
+ pExt = findFileExt(p_szInFile);
+ //printf("Read file: %s - ext: %s", p_szInFile, pExt);
+ if(pExt && strcmp(pExt, "cdoc") == 0) {
+ err = dencSaxReadEncryptedData(ppEncData, p_szInFile);
+ } else if(pExt && strcmp(pExt, "ddoc") == 0) {
+ switch(nMode) {
+ case 2: // new XMLReader interface
+ //err = ddocXRdrReadSignedDocFromFile(p_szInFile, CHARSET_ISO_8859_1, ppSigDoc, nMaxDfLen);
+ break;
+ case 1:
+ default:
+ err = ddocSaxReadSignedDocFromFile(ppSigDoc, p_szInFile, 0, nMaxDfLen);
+ }
+ } else {
+ err = ERR_FILE_READ;
+ }
+ e = checkOldFormatVer(*ppSigDoc);
+ if(!err && e) err = e;
+ printErrorsAndWarnings(*ppSigDoc);
+ return err;
+}
+
+//--------------------------------------------------
+// reads in a signed doc
+//--------------------------------------------------
+int cmdReadDigiDocFromMem(SignedDoc** ppSigDoc, DEncEncryptedData** ppEncData)
+{
+ int err = ERR_OK, e;
+ DigiDocMemBuf mbuf1;
+
+ mbuf1.pMem = 0;
+ mbuf1.nLen = 0;
+ if(!p_szInFile) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "No input file specified");
+ return err;
+ }
+ //nMaxDfLen = ConfigItem_lookup_int("DATAFILE_MAX_CACHE", 0);
+
+ if(strstr(p_szInFile, ".cdoc")) {
+ err = ddocReadFile(p_szInFile, &mbuf1);
+ if(!err)
+ err = dencSaxReadEncryptedDataFromMemory(ppEncData, &mbuf1);
+ } else {
+ err = ddocReadFile(p_szInFile, &mbuf1);
+ if(!err)
+ err = ddocSaxReadSignedDocFromMemory(ppSigDoc, mbuf1.pMem, mbuf1.nLen, mbuf1.nLen + 1);
+ }
+ ddocMemBuf_free(&mbuf1);
+ e = checkOldFormatVer(*ppSigDoc);
+ printErrorsAndWarnings(*ppSigDoc);
+ if(!err && e) err = e;
+ return err;
+}
+
+//--------------------------------------------------
+// writes a digidoc in file
+//--------------------------------------------------
+int cmdWrite(SignedDoc* pSigDoc, DEncEncryptedData* pEncData)
+{
+ int err = ERR_OK;
+ FILE* hFile;
+#ifdef WIN32
+ wchar_t *convFileName = 0;
+ int l1 = 0;
+#endif
+
+ if(!p_szOutFile) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "No output file specified");
+ return err;
+ }
+ if(pSigDoc)
+ err = createSignedDoc(pSigDoc, p_szInFile, p_szOutFile);
+ if(pEncData) {
+ if(pEncData->nDataStatus == DENC_DATA_STATUS_ENCRYPTED_AND_NOT_COMPRESSED ||
+ pEncData->nDataStatus == DENC_DATA_STATUS_ENCRYPTED_AND_COMPRESSED) {
+ err = dencGenEncryptedData_writeToFile(pEncData, p_szOutFile);
+ } else {
+#ifdef WIN32
+ err = utf82unicode((const char*)p_szOutFile, (char**)&convFileName, &l1);
+ ddocDebug(3, "cmdWrite", "Writing file: %s, conv-file: %s len: %d", p_szOutFile, convFileName, l1);
+ if((hFile = _wfopen(convFileName, L"wb")) != NULL) {
+#else
+ if((hFile = fopen(p_szOutFile, "wb")) != NULL) {
+#endif
+ fwrite((pEncData)->mbufEncryptedData.pMem, 1,
+ (pEncData)->mbufEncryptedData.nLen, hFile);
+ fclose(hFile);
+ }
+ else
+ err = ERR_FILE_WRITE;
+ }
+ }
+ if (err)
+ addError(err, __FILE__, __LINE__, "Error writing file\n");
+ return err;
+}
+
+//--------------------------------------------------
+// writes a digidoc in file
+//--------------------------------------------------
+int cmdWriteMem(SignedDoc* pSigDoc, DEncEncryptedData* pEncData)
+{
+ int err = ERR_OK;
+ DigiDocMemBuf mbuf1;
+
+ mbuf1.pMem = 0;
+ mbuf1.nLen = 0;
+ if(!p_szOutFile) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "No output file specified");
+ return err;
+ }
+ if(pSigDoc) {
+ err = createSignedDocInMemory(pSigDoc, NULL, &mbuf1);
+ if(!err)
+ err = ddocWriteFile(p_szOutFile, &mbuf1);
+ }
+ if(pEncData) {
+ if(pEncData->nDataStatus == DENC_DATA_STATUS_ENCRYPTED_AND_NOT_COMPRESSED ||
+ pEncData->nDataStatus == DENC_DATA_STATUS_ENCRYPTED_AND_COMPRESSED) {
+ err = dencGenEncryptedData_toXML(pEncData, &mbuf1);
+ if(!err)
+ err = ddocWriteFile(p_szOutFile, &mbuf1);
+ } else {
+ err = ddocWriteFile(p_szOutFile, &(pEncData->mbufEncryptedData));
+ }
+ }
+ ddocMemBuf_free(&mbuf1);
+ if (err)
+ addError(err, __FILE__, __LINE__, "Error writing file\n");
+ return err;
+}
+
+
+//-----------------------------------------
+// prints certificate info
+//-----------------------------------------
+void printCertificateInfo(SignedDoc* pSigDoc, X509* pCert)
+{
+ int err, p;
+ char buf1[500];
+ PolicyIdentifier* pPolicies;
+ DigiDocMemBuf mbuf;
+ int nPols;
+
+ mbuf.pMem = 0;
+ mbuf.nLen = 0;
+ // serial number
+ err = ReadCertSerialNumber(buf1, sizeof(buf1), pCert);
+ if(g_cgiMode)
+ fprintf(stdout, "\nX509Certificate%s%s", g_szOutputSeparator, buf1);
+ else
+ fprintf(stdout, "\nX509Certificate nr: %s", buf1);
+ // issuer
+ err = ddocCertGetIssuerDN(pCert, &mbuf);
+ if(g_cgiMode)
+ fprintf(stdout, "%s%s", g_szOutputSeparator, (char*)mbuf.pMem);
+ else
+ fprintf(stdout, "\n\tIssuer: %s", (char*)mbuf.pMem);
+ ddocMemBuf_free(&mbuf);
+ // subject
+ err = ddocCertGetSubjectDN(pCert, &mbuf);
+ if(g_cgiMode)
+ fprintf(stdout, "%s%s", g_szOutputSeparator, (char*)mbuf.pMem);
+ else
+ fprintf(stdout, "\n\tSubject: %s", (char*)mbuf.pMem);
+ ddocMemBuf_free(&mbuf);
+ // ValidFrom
+ memset(buf1, 0, sizeof(buf1));
+ err = getCertNotBefore(pSigDoc, pCert, buf1, sizeof(buf1));
+ if(g_cgiMode)
+ fprintf(stdout, "%s%s", g_szOutputSeparator, buf1);
+ else
+ fprintf(stdout, "\n\tNotBefore: %s", buf1);
+ // ValidTo
+ memset(buf1, 0, sizeof(buf1));
+ err = getCertNotAfter(pSigDoc, pCert, buf1, sizeof(buf1));
+ if(g_cgiMode)
+ fprintf(stdout, "%s%s", g_szOutputSeparator, buf1);
+ else
+ fprintf(stdout, "\n\tNotAfter: %s", buf1);
+ // policy URL
+ err = readCertPolicies(pCert, &pPolicies, &nPols);
+ if(nPols) {
+ for(p = 0; p < nPols; p++) {
+ if(g_cgiMode)
+ fprintf(stdout, "\nSignaturePolicy%s%s%s%s%s%s",
+ g_szOutputSeparator, pPolicies[p].szOID,
+ g_szOutputSeparator, pPolicies[p].szCPS,
+ g_szOutputSeparator, pPolicies[p].szUserNotice);
+ else
+ fprintf(stdout, "\n\tnSignaturePolicy oid: %s cps: %s desc: %s", pPolicies[p].szOID,
+ pPolicies[p].szCPS, pPolicies[p].szUserNotice);
+ } // for p < nPols
+ }
+ PolicyIdentifiers_free(pPolicies, nPols);
+
+}
+
+char* TEST_OIDS_PREFS[] = {
+ "1.3.6.1.4.1.10015.3.7", "1.3.6.1.4.1.10015.7", // tempel test
+ "1.3.6.1.4.1.10015.3.3", "1.3.6.1.4.1.10015.3.11", // mid test
+ "1.3.6.1.4.1.10015.3.2", // digi-id test
+ "1.3.6.1.4.1.10015.3.1" // est-eid test
+};
+
+int checkTestCert(X509* pCert)
+{
+ int err = ERR_OK, i, p;
+ PolicyIdentifier* pPolicies = NULL;
+ DigiDocMemBuf mbuf;
+ int nPols = 0;
+
+ mbuf.pMem = 0;
+ mbuf.nLen = 0;
+ ddocCertGetSubjectCN(pCert, &mbuf);
+ /*if(mbuf.pMem && strstr(mbuf.pMem, "TEST")) {
+ printf("\n Test CN: %s", (char*)(mbuf.pMem));
+ err = ERR_TEST_SIGNATURE;
+ }*/
+ err = readCertPolicies(pCert, &pPolicies, &nPols);
+ if(!err && nPols && !err) {
+ for(p = 0; p < nPols; p++) {
+ //printf("\nOID: %s", pPolicies[p].szOID);
+ for(i = 0; i < 6 && !err; i++) {
+ if(i == 1 && // tempel - test
+ strstr(pPolicies[p].szOID, TEST_OIDS_PREFS[1]) &&
+ strstr(mbuf.pMem, "TEST")) {
+ //printf("\nTempel-Test OID: %s", TEST_OIDS_PREFS[i]);
+ err = ERR_TEST_SIGNATURE;
+ } else if(i != 1) {
+ if(strstr(pPolicies[p].szOID, TEST_OIDS_PREFS[i])) {
+ //printf("\nTest OID: %s", TEST_OIDS_PREFS[i]);
+ err = ERR_TEST_SIGNATURE;
+ }
+ }
+ }
+ }
+ }
+ ddocMemBuf_free(&mbuf);
+ PolicyIdentifiers_free(pPolicies, nPols);
+ if(err == ERR_TEST_SIGNATURE)
+ SET_LAST_ERROR(ERR_TEST_SIGNATURE);
+ return err;
+}
+
+
+int isError(SignedDoc* pSigDoc, int nErrCd)
+{
+ return (nErrCd != ERR_OK && !isWarning(pSigDoc, nErrCd));
+}
+
+int isWarning(SignedDoc* pSigDoc, int nErrCd)
+{
+ if(pSigDoc && pSigDoc->szFormat && !strcmp(pSigDoc->szFormat, SK_XML_1_NAME)) {
+ // currently no warnings for ddoc 1.0
+ return (nErrCd == ERR_OLD_VERSION) || (nErrCd == ERR_TEST_SIGNATURE);
+ } else {
+ return ((nErrCd == ERR_ISSUER_XMLNS) ||
+ (nErrCd == ERR_OLD_VERSION) ||
+ (nErrCd == ERR_TEST_SIGNATURE) ||
+ (nErrCd == ERR_DF_WRONG_DIG)
+ );
+ }
+}
+
+int isLibraryError(int nErrCd)
+{
+ return (nErrCd != ERR_OK &&
+ nErrCd != ERR_OLD_VERSION &&
+ nErrCd != ERR_TEST_SIGNATURE &&
+ nErrCd != ERR_UNSUPPORTED_FORMAT);
+}
+
+int hasWarnings(SignedDoc* pSigDoc)
+{
+ int n;
+ ErrorInfo* pErr;
+
+ for(n = getLastErrorsIdx(); n >= 0; n--) {
+ pErr = getErrorsInfo(n);
+ if(isWarning(pSigDoc, pErr->code))
+ return pErr->code;
+ }
+ return ERR_OK;
+}
+
+int hasErrors(SignedDoc* pSigDoc)
+{
+ int n;
+ ErrorInfo* pErr;
+
+ for(n = getLastErrorsIdx(); n >= 0; n--) {
+ pErr = getErrorsInfo(n);
+ if(isError(pSigDoc, pErr->code))
+ return pErr->code;
+ }
+ return ERR_OK;
+}
+
+void printErrorsAndWarnings(SignedDoc* pSigDoc)
+{
+ int n, m = getLastErrorsIdx();
+ ErrorInfo* pErr;
+ char* pErrStr;
+
+ // list all errors
+ if(g_cgiMode) {
+ /*for(n = 0; n < m; n++) {
+ pErr = getErrorsInfo(n);
+ pErrStr = getErrorString(pErr->code);
+ printf("\nErr: %d cd: %d msg: %s", n, pErr->code, pErrStr);
+ }*/
+ for(n = m; n >= 0; n--) {
+ pErr = getErrorsInfo(n);
+ pErrStr = getErrorString(pErr->code);
+ if(isError(pSigDoc, pErr->code))
+ fprintf(stdout, "\nERROR%s%d%s%s%s%s%s%d%s%s%s%s",
+ g_szOutputSeparator, pErr->code,
+ g_szOutputSeparator, pErrStr,
+ g_szOutputSeparator, pErr->fileName,
+ g_szOutputSeparator, pErr->line,
+ g_szOutputSeparator, pErr->assertion,
+ g_szOutputSeparator, errorClass[getErrorClass(pErr->code)]);
+ }
+ for(n = m; n >= 0; n--) {
+ pErr = getErrorsInfo(n);
+ pErrStr = getErrorString(pErr->code);
+ if(isWarning(pSigDoc, pErr->code))
+ fprintf(stdout, "\nWARNING%s%d%s%s%s%s%s%d%s%s%s%s",
+ g_szOutputSeparator, pErr->code,
+ g_szOutputSeparator, pErrStr,
+ g_szOutputSeparator, pErr->fileName,
+ g_szOutputSeparator, pErr->line,
+ g_szOutputSeparator, pErr->assertion,
+ g_szOutputSeparator, errorClass[getErrorClass(pErr->code)]);
+ }
+ if(g_nLibErrors) {
+ for(n = m; n >= 0; n--) {
+ pErr = getErrorsInfo(n);
+ if(isLibraryError(pErr->code)) {
+ pErrStr = getErrorString(pErr->code);
+ fprintf(stdout, "\nLIBRARY-ERROR%s%d%s%s%s%s%s%d%s%s%s%s",
+ g_szOutputSeparator, pErr->code,
+ g_szOutputSeparator, pErrStr,
+ g_szOutputSeparator, pErr->fileName,
+ g_szOutputSeparator, pErr->line,
+ g_szOutputSeparator, pErr->assertion,
+ g_szOutputSeparator, errorClass[getErrorClass(pErr->code)]);
+ }
+ }
+ }
+ } else {
+ for(n = m; n >= 0; n--) {
+ pErr = getErrorsInfo(n);
+ pErrStr = getErrorString(pErr->code);
+ if(isError(pSigDoc, pErr->code))
+ fprintf(stdout, "\nERROR: %d - %s - %s",
+ pErr->code, pErrStr, pErr->assertion);
+ if(isWarning(pSigDoc, pErr->code))
+ fprintf(stdout, "\nWARNING: %d - %s - %s",
+ pErr->code, pErrStr, pErr->assertion);
+ }
+ }
+}
+
+
+//--------------------------------------------------
+// Verifys sigantures and notaries
+//--------------------------------------------------
+int cmdVerify(SignedDoc* pSigDoc)
+{
+ int err = ERR_OK, s, d, l, m, l1, e, e2, n1, e3;
+ SignatureInfo* pSigInfo = 0;
+ NotaryInfo* pNot;
+ DataFile *pDf = 0;
+ DigiDocMemBuf mbuf;
+ X509* pRcert = 0;
+ const DigiDocMemBuf* pMBuf = 0;
+ char buf1[100], *p1 = 0;
+
+ mbuf.pMem = 0;
+ mbuf.nLen = 0;
+ if(!pSigDoc) {
+ SET_LAST_ERROR(ERR_UNSUPPORTED_FORMAT);
+ return ERR_UNSUPPORTED_FORMAT;
+ }
+ // print signed doc format and version
+ if(g_cgiMode) {
+ fprintf(stdout, "\nSignedDoc%s%s%s%s",
+ g_szOutputSeparator,
+ pSigDoc->szFormat, g_szOutputSeparator,
+ pSigDoc->szFormatVer);
+ } else {
+ fprintf(stdout, "\nSignedDoc format: %s version: %s\n",
+ pSigDoc->szFormat, pSigDoc->szFormatVer);
+ }
+ // display DataFile-s
+ d = getCountOfDataFiles(pSigDoc);
+ for(l = 0; l < d; l++) {
+ pDf = getDataFile(pSigDoc, l);
+ ddocGetDataFileFilename(pSigDoc, pDf->szId, (void**)&p1, &n1);
+ if(g_cgiMode)
+ fprintf(stdout, "\n\nDataFile%s%s%s%s%s%ld%s%s%s%s",
+ g_szOutputSeparator, pDf->szId, g_szOutputSeparator,
+ p1, g_szOutputSeparator,
+ pDf->nSize, g_szOutputSeparator,
+ pDf->szMimeType, g_szOutputSeparator,
+ pDf->szContentType);
+ else
+ fprintf(stdout, "\n\nDataFile: %s, file: %s, size: %ld, mime-type: %s content-type: %s",
+ pDf->szId, p1, pDf->nSize, pDf->szMimeType, pDf->szContentType);
+ if(p1)
+ freeLibMem(p1);
+ }
+
+
+ // verify signatures
+ d = getCountOfSignatures(pSigDoc);
+ for(s = 0; s < d; s++) {
+ pSigInfo = getSignature(pSigDoc, s);
+ e = ddocCertGetSubjectCN(ddocSigInfo_GetSignersCert(pSigInfo), &mbuf);
+ clearErrors();
+ e = verifySignatureAndNotary(pSigDoc, pSigInfo, p_szInFile);
+ if(!e)
+ e = hasErrors(pSigDoc);
+ if(!err && e) err = e;
+ e2 = checkTestCert(ddocSigInfo_GetSignersCert(pSigInfo));
+ if(!err && e2) err = e2;
+ if(!e && e2) e = e2;
+ if(g_cgiMode) {
+ fprintf(stdout, "\n\nSignature%s%s%s%s%s%d%s%s",
+ g_szOutputSeparator,
+ pSigInfo->szId,
+ g_szOutputSeparator,
+ (const char*)mbuf.pMem,
+ g_szOutputSeparator,
+ e,
+ g_szOutputSeparator,
+ (e ? getErrorString(e) : ""));
+ } else {
+ fprintf(stdout, "\n\nSignature: %s - %s - %s", pSigInfo->szId,
+ (const char*)mbuf.pMem, ((!e) ? "OK" : "ERROR"));
+ }
+ ddocMemBuf_free(&mbuf);
+ // print signers roles / manifests
+ m = getCountOfSignerRoles(pSigInfo, 0);
+ for(l = 0; l < m; l++) {
+ if(g_cgiMode)
+ fprintf(stdout, "\nClaimedRole%s%s", g_szOutputSeparator, getSignerRole(pSigInfo, 0, l));
+ else
+ fprintf(stdout, "\n\tClaimedRole: %s", getSignerRole(pSigInfo, 0, l));
+ }
+ if(pSigInfo->sigProdPlace.szCity || pSigInfo->sigProdPlace.szStateOrProvince ||
+ pSigInfo->sigProdPlace.szPostalCode || pSigInfo->sigProdPlace.szCountryName) {
+ if(g_cgiMode) {
+ fprintf(stdout, "\nSignatureProductionPlace%s%s%s%s%s%s%s%s", g_szOutputSeparator,
+ (pSigInfo->sigProdPlace.szCountryName ? pSigInfo->sigProdPlace.szCountryName : ""),
+ g_szOutputSeparator,
+ (pSigInfo->sigProdPlace.szStateOrProvince ? pSigInfo->sigProdPlace.szStateOrProvince : ""),
+ g_szOutputSeparator,
+ (pSigInfo->sigProdPlace.szCity ? pSigInfo->sigProdPlace.szCity : ""),
+ g_szOutputSeparator,
+ (pSigInfo->sigProdPlace.szPostalCode ? pSigInfo->sigProdPlace.szPostalCode : ""));
+ } else {
+ fprintf(stdout, "\n\tnSignatureProductionPlace - Country: %s, State: %s, City: %s, Postal code: %s",
+ (pSigInfo->sigProdPlace.szCountryName ? pSigInfo->sigProdPlace.szCountryName : ""),
+ (pSigInfo->sigProdPlace.szStateOrProvince ? pSigInfo->sigProdPlace.szStateOrProvince : ""),
+ (pSigInfo->sigProdPlace.szCity ? pSigInfo->sigProdPlace.szCity : ""),
+ (pSigInfo->sigProdPlace.szPostalCode ? pSigInfo->sigProdPlace.szPostalCode : ""));
+ }
+ }
+ // signers certificate
+ if(ddocSigInfo_GetSignersCert(pSigInfo))
+ printCertificateInfo(pSigDoc, ddocSigInfo_GetSignersCert(pSigInfo));
+ // confirmation
+ if(pSigDoc && pSigInfo) {
+ pNot = getNotaryWithSigId(pSigDoc, pSigInfo->szId);
+ if(pNot) {
+ pMBuf = ddocNotInfo_GetResponderId(pNot);
+ buf1[0] = 0;
+ l1 = sizeof(buf1);
+ if(pNot->nRespIdType == RESPID_NAME_TYPE) {
+ strncpy(buf1, (const char*)pMBuf->pMem, l1);
+ }
+ if(pNot->nRespIdType == RESPID_KEY_TYPE) {
+ encode((const byte*)pMBuf->pMem, pMBuf->nLen, (byte*)buf1, &l1);
+ }
+ }
+ if(pNot && pMBuf) {
+ if(g_cgiMode)
+ fprintf(stdout, "\nRevocationValues%s%s%s%s",
+ g_szOutputSeparator,
+ buf1,
+ g_szOutputSeparator,
+ pNot->timeProduced);
+ else
+ fprintf(stdout, "\n\tRevocationValues responder: %s produced-at: %s",
+ buf1, pNot->timeProduced);
+ // certificate
+ pRcert = ddocSigInfo_GetOCSPRespondersCert(pSigInfo);
+ e3 = checkTestCert(pRcert);
+ if(!e2 && e3) { // live allkirjastaja sert aga test ocsp
+ fprintf(stdout, "\n\tSigner from LIVE CA-chain but OCSP from TEST CA-chain!");
+ err = e3;
+ SET_LAST_ERROR(e3);
+ }
+ printCertificateInfo(pSigDoc, pRcert);
+ }
+ }
+ printErrorsAndWarnings(pSigDoc);
+ }
+ return err;
+}
+
+
+//--------------------------------------------------
+// Signs the document and gets configrmation
+//--------------------------------------------------
+int cmdSign(SignedDoc* pSigDoc, const char* pin, const char* manifest,
+ const char* city, const char* state, const char* zip, const char* country,
+ int nSlot, int nOcsp, int nSigner, const char* szPkcs12File)
+{
+ int err = ERR_OK;
+ SignatureInfo* pSigInfo = NULL;
+
+ ddocDebug(3, "cmdSign", "Creating new digital signature");
+ err = signDocumentWithSlotAndSigner(pSigDoc, &pSigInfo, pin, manifest,
+ city, state, zip, country, nSlot, nOcsp, nSigner, szPkcs12File);
+ ddocDebug(3, "cmdSign", "End creating new digital signature");
+ RETURN_IF_NOT(err == ERR_OK, err);
+ return ERR_OK;
+}
+
+
+
+
+
+
+//#ifdef WITH_DEPRECATED_FUNCTIONS
+//--------------------------------------------------
+// Runs some test. This is used simply to test
+// new features of the library and the functionality
+// may change.
+//--------------------------------------------------
+void cmdTest2(const char* infile)
+{
+ X509* pCert = 0;
+ //char buf1[X509_NAME_LEN + 10];
+ int err = ERR_OK, nPols = 0;
+ PolicyIdentifier *pPolicies = 0;
+
+ ddocDebug(3, "cmdTest2", "Reading cert: %s", infile);
+ err = ReadCertificate(&pCert, infile);
+ if(!err && pCert) {
+ err = readCertPolicies(pCert, &pPolicies, &nPols);
+ printf("Read pols rc: %d pols: %d\n", err, nPols);
+
+ /*
+ l1 = sizeof(buf1);
+ memset(buf1, 0, sizeof(buf1));
+ err = getCertSubjectName(pCert, buf1, &l1);
+ if(g_cgiMode)
+ fprintf(stdout, "\nDN%s%s%s%d",
+ g_szOutputSeparator, buf1,
+ g_szOutputSeparator, l1);
+ else
+ fprintf(stdout, "\nDN: %s len: %d", buf1, l1);
+ */
+ }
+ if(pCert)
+ X509_free(pCert);
+ if(pPolicies)
+ PolicyIdentifiers_free(pPolicies, nPols);
+}
+//#endif
+
+//--------------------------------------------------
+// Encrypts a file
+//--------------------------------------------------
+int cmdEncrypt(DEncEncryptedData** ppEncData, const char* szFileName)
+{
+ FILE* hFile;
+ SignedDoc *pSigDoc = 0;
+ DEncEncryptionProperty* pEncProperty = 0;
+ int len, err = ERR_OK, i = 0;
+ long lFileLen;
+ char buf[2048], *p = 0;
+#ifdef WIN32
+ wchar_t *convFileName = 0;
+ err = utf82unicode((const char*)szFileName, (char**)&convFileName, &i);
+#endif
+
+ ddocDebug(3, "cmdEncrypt", "Encrypting %s rc: %d", szFileName, err);
+ err = dencEncryptedData_new(ppEncData, DENC_XMLNS_XMLENC, DENC_ENC_METHOD_AES128, 0, 0, 0);
+ if(!err) {
+ err = dencMetaInfo_SetLibVersion(*ppEncData);
+ if(!err) {
+ err = dencMetaInfo_SetFormatVersion(*ppEncData);
+ if(!err) {
+ err = ddocConvertInput(szFileName, &p);
+ if(!err) {
+ err = dencEncryptionProperty_new(*ppEncData, &pEncProperty,
+ 0, 0, ENCPROP_FILENAME, getSimpleFileName(p));
+ if(strstr(p, ".bdoc") || strstr(p, ".asice"))
+ err = dencEncryptedData_SetMimeType(*ppEncData, "application/vnd.etsi.asic-e+zip");
+ err = calculateFileSize(szFileName, &lFileLen);
+ sprintf(buf, "%ld", lFileLen);
+ err = dencEncryptionProperty_new(*ppEncData, &pEncProperty,
+ 0, 0, ENCPROP_ORIG_SIZE, buf);
+ freeLibMem(p);
+ if(!err) {
+ ddocDebug(3, "cmdEncrypt", "Opening %s rc: %d", szFileName, err);
+#ifdef WIN32
+ if((hFile = _wfopen(convFileName, L"rb")) != NULL) {
+#else
+ if((hFile = fopen(szFileName, "rb")) != NULL) {
+#endif
+ do {
+ memset(buf,0,sizeof(buf));
+ len = fread(buf, 1, sizeof(buf), hFile);
+ if(len)
+ err = dencEncryptedData_AppendData(*ppEncData, buf, len);
+ } while(len && !err);
+ fclose(hFile);
+ } // if fopen/wfopen
+ ddocDebug(3, "cmdEncrypt", "Enc data-len: %d rc: %d", (*ppEncData)->mbufEncryptedData.nLen, err);
+ if(!err)
+ err = dencEncryptedData_encryptData(*ppEncData, DENC_COMPRESS_NEVER);
+ } // err - endProp_new
+ } // err - conver filename
+ } // err - serFormatVer
+ } // err - setLibVer
+ } // err - dencEncData_new
+ return err;
+}
+
+
+//--------------------------------------------------
+// Encrypts a file and uses SK specific method of
+// putting the file first in a ddoc container and then into
+// cdoc
+//--------------------------------------------------
+int cmdEncryptSk(DEncEncryptedData** ppEncData, const char* szFileName)
+{
+ SignedDoc *pSigDoc = 0;
+ DEncEncryptionProperty* pEncProperty = 0;
+ DataFile *pDf = 0;
+ int err = ERR_OK;
+ long lSize;
+ char buf[256], *p = 0;
+ DigiDocMemBuf mbuf1;
+
+ mbuf1.pMem = 0;
+ mbuf1.nLen = 0;
+ err = dencEncryptedData_new(ppEncData, DENC_XMLNS_XMLENC, DENC_ENC_METHOD_AES128, 0, 0, 0);
+ if(!err) {
+ err = dencMetaInfo_SetLibVersion(*ppEncData);
+ if(!err) {
+ err = dencMetaInfo_SetFormatVersion(*ppEncData);
+ if(!err) {
+ err = ddocConvertInput(szFileName, &p);
+ if(!err) {
+ err = dencEncryptionProperty_new(*ppEncData, &pEncProperty,
+ 0, 0, ENCPROP_FILENAME, getSimpleFileName(p));
+ if(!err) {
+ err = SignedDoc_new(&pSigDoc, "DIGIDOC-XML", "1.3");
+ if(!err) {
+ calculateFileSize(szFileName, &lSize);
+ err = DataFile_new(&pDf, pSigDoc, NULL, szFileName,
+ "EMBEDDED_BASE64", "application/file", lSize, NULL, 0, NULL, NULL);
+ sprintf(buf, "%ld", lSize);
+ err = dencEncryptionProperty_new(*ppEncData, &pEncProperty,
+ 0, 0, ENCPROP_ORIG_SIZE, buf);
+ if(!err) {
+ err = dencOrigContent_registerDigiDoc(*ppEncData, pSigDoc);
+ if(!err) {
+ sprintf(buf, "%s.ddoc", szFileName);
+ err = createSignedDoc(pSigDoc, NULL, buf);
+ if(!err) {
+ err = ddocReadFile(buf, &mbuf1);
+ if(!err) {
+ err = dencEncryptedData_AppendData(*ppEncData, mbuf1.pMem, mbuf1.nLen);
+ //ddocDebug(3, "EncTest", "Enc data: \"%s\"", mbuf1.pMem);
+ remove(buf);
+ ddocMemBuf_free(&mbuf1);
+ if(!err)
+ err = dencEncryptedData_encryptData(*ppEncData, DENC_COMPRESS_NEVER);
+ } // err - ddocReadFile
+ } // err - createSignedDoc
+ } // err - origContent_register
+ } // err - sigDoc_new
+ } // err - sigDoc_new
+ SignedDoc_free(pSigDoc);
+ } // err - encProp_new
+ freeLibMem(p);
+ } // err - convert filename
+ } // err - setFormatVer
+ } // err - setLibVer
+ } // err - endData_new
+ return err;
+}
+
+
+//--------------------------------------------------
+// Runs various tests. Just for trying out new features
+//--------------------------------------------------
+int runTestCmds(int argc, char** argv)
+{
+ int err = ERR_OK, i;
+ char* infile = NULL;
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ if(!strcmp(argv[i], "-test")) {
+ // add a recipients key
+
+ }
+//#ifdef WITH_DEPRECATED_FUNCTIONS
+ if(!strcmp(argv[i], "-test2")) {
+ ddocConvertInput((const char*)argv[i+1], &infile);
+ cmdTest2(argv[i+1]);
+ }
+//#endif
+ }
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// Encrypts whole files
+//--------------------------------------------------
+int runEncryptFileCmds(int argc, char** argv, DEncEncryptedData* pEncData)
+{
+ int err = ERR_OK, i;
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // add a recipients key
+ if(!strcmp(argv[i], "-encrypt-file")) {
+ if(argc > i+2 && argv[i+1][0] != '-' && argv[i+2][0] != '-') {
+ char* infile = NULL;
+ char* outfile = NULL;
+ char* mime = NULL;
+ ddocConvertInput((const char*)argv[i+1], &infile);
+ ddocConvertInput((const char*)argv[i+2], &outfile);
+ ddocConvertInput((const char*)argv[i+3], &mime);
+ i += 3;
+ // optional arguments
+ checkArguments(argc, argv, &i, &mime);
+ // encrypt the file
+ err = dencEncryptFile(pEncData, infile, outfile, mime);
+ if(infile) freeLibMem(infile);
+ if(outfile) freeLibMem(outfile);
+ if(mime) freeLibMem(mime);
+ if(err) return err;
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <in-file> or <out-file> argument of -encrypt-file command");
+ }
+ }
+ }
+ }
+ return err;
+}
+
+
+//--------------------------------------------------
+// Decrypts whole files
+//--------------------------------------------------
+int runDecryptFileCmds(int argc, char** argv)
+{
+ int err = ERR_OK, i;
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // decrypt a file
+ if(!strcmp(argv[i], "-decrypt-file")) {
+ if(argc > i+2 && argv[i+1][0] != '-' &&
+ argv[i+2][0] != '-' && argv[i+3][0] != '-') {
+ char* infile = NULL;
+ char* outfile = NULL;
+ char* pin = NULL;
+ char* pkcs12file = NULL;
+ ddocConvertInput((const char*)argv[i+1], &infile);
+ ddocConvertInput((const char*)argv[i+2], &outfile);
+ ddocConvertInput((const char*)argv[i+3], &pin);
+ i += 3;
+ // optional arguments
+ checkArguments(argc, argv, &i, &pkcs12file);
+ // decrypt the file
+ err = dencSaxReadDecryptFile(infile, outfile, pin, pkcs12file);
+ if(infile) freeLibMem(infile);
+ if(outfile) freeLibMem(outfile);
+ if(pin) freeLibMem(pin);
+ if(pkcs12file) freeLibMem(pkcs12file);
+ if(err) return err;
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <in-file>, <out-file> or <pin> argument of -decrypt-file command");
+ }
+ }
+ }
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// Generates and encrypts a block of data with specific
+// length
+//--------------------------------------------------
+int cmdEncryptTestSet(DEncEncryptedData** ppEncData, int nSize, char* dir, int nDdoc, int nDel)
+{
+ DEncEncryptionProperty* pEncProperty = 0;
+ int err = ERR_OK, i, nCompress, l2;
+ char *p = 0, fname1[256], fname2[256], c, *p2;
+ SignedDoc* pSigDoc = 0;
+ DataFile *pDf = 0;
+ FILE* hFile;
+ DigiDocMemBuf mbuf1;
+
+ mbuf1.pMem = 0;
+ mbuf1.nLen = 0;
+ nCompress = ConfigItem_lookup_int("DENC_COMPRESS_MODE", DENC_COMPRESS_ALLWAYS);
+ ddocDebug(3, "EncTest", "Test: %d", nSize);
+ err = dencEncryptedData_new(ppEncData, DENC_XMLNS_XMLENC, DENC_ENC_METHOD_AES128, 0, 0, 0);
+ if(err) return err;
+ err = dencMetaInfo_SetLibVersion(*ppEncData);
+ if(err) return err;
+ err = dencMetaInfo_SetFormatVersion(*ppEncData);
+ if(err) return err;
+ sprintf(fname1, "%stest-%d.dat", dir, nSize);
+ err = dencEncryptionProperty_new(*ppEncData, &pEncProperty, 0, 0, ENCPROP_FILENAME, fname1);
+ if(err) return err;
+ p = (char*)malloc(nSize+1);
+ if(!p) return ERR_BAD_ALLOC;
+ memset(p, 0, nSize+1);
+ for(i = 0, c = 'A'; i < nSize; i++, c++) {
+ p[i] = c;
+ if(c >= 'z') c = 'A';
+ }
+ // append x.923 padding if last block is full
+ if(nSize % 16 == 0) {
+ ddocDebug(3, "EncTest", "Full size: %d. Change last 8 bytes to X.923 padding", nSize);
+ p[nSize-1] = 8;
+ for(i = nSize -2; i > nSize - 9; i--)
+ p[i] = 0;
+ }
+ l2 = nSize * 2 + 1;
+ p2 = (char*)malloc(l2);
+ if(!p2) return ERR_BAD_ALLOC;
+ memset(p2, 0, l2);
+ bin2hex((const byte*)p, nSize, (byte*)p2, &l2);
+ ddocDebug(3, "EncTest", "Fil data hex: \"%s\" len: %d", p2, l2);
+ if((hFile = fopen(fname1, "w")) != NULL) {
+ fwrite(p, nSize, 1, hFile);
+ fclose(hFile);
+ }
+ free(p); p = 0;
+ fname2[0] = 0;
+ if(nDdoc) {
+ err = dencEncryptionProperty_new(*ppEncData, &pEncProperty, 0, 0, ENCPROP_ORIG_MIME, DENC_ENCDATA_TYPE_DDOC);
+ err = SignedDoc_new(&pSigDoc, "DIGIDOC-XML", "1.3");
+ if(!err) {
+ err = DataFile_new(&pDf, pSigDoc, NULL, fname1, "EMBEDDED_BASE64", "text/txt", nSize, NULL, 0, NULL, NULL);
+ if(!err) {
+ err = dencOrigContent_registerDigiDoc(*ppEncData, pSigDoc);
+ if(!err) {
+ sprintf(fname2, "%stest-%d.ddoc", dir, nSize);
+ err = createSignedDoc(pSigDoc, NULL, fname2);
+ if(!err) {
+ err = ddocReadFile(fname2, &mbuf1);
+ if(!err)
+ err = dencEncryptedData_AppendData(*ppEncData, mbuf1.pMem, mbuf1.nLen);
+ }
+ }
+ }
+ }
+ //ddocDebug(3, "EncTest", "Enc data: \"%s\"", mbuf1.pMem);
+ if(nDel && fname2[0])
+ remove(fname2);
+ ddocMemBuf_free(&mbuf1);
+ } else {
+ err = dencEncryptedData_AppendData(*ppEncData, p, nSize);
+ }
+ if(nDel && fname1[0])
+ remove(fname1);
+
+ if(!err)
+ err = dencEncryptedData_encryptData(*ppEncData, nCompress);
+ if(pSigDoc)
+ SignedDoc_free(pSigDoc);
+ return err;
+}
+
+//--------------------------------------------------
+// Encrypts generated test files
+//--------------------------------------------------
+int runEncryptTestSetCmds(int argc, char** argv)
+{
+ int err = ERR_OK, i, j;
+ DEncEncryptedData* pEncData = 0;
+ DEncEncryptedKey* pEncKey = 0;
+ X509* pCert = 0;
+ char fname[128];
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // add a recipients key
+ if(!strcmp(argv[i], "-encrypt-test-set")) {
+ if(argc > i+2 && argv[i+1][0] != '-' && argv[i+2][0] != '-') {
+ char* certfile = argv[i+1];
+ char* recipient = argv[i+2];
+ char* outdir = argv[i+3];
+ int nStart = atoi(argv[i+4]);
+ int nEnd = atoi(argv[i+5]);
+ int nDdoc = atoi(argv[i+6]);
+ int nDel = atoi(argv[i+7]);
+
+ for(j = nStart; j < nEnd; j++) {
+ err = ReadCertificate(&pCert, certfile);
+ if(err) return err;
+ pEncData = 0;
+ err = cmdEncryptTestSet(&pEncData, j, outdir, nDdoc, nDel);
+ if(err) return err;
+ err = dencEncryptedKey_new(pEncData, &pEncKey, pCert,
+ DENC_ENC_METHOD_RSA1_5,
+ NULL, recipient, NULL, NULL);
+ sprintf(fname, "%stest-%d.cdoc", outdir, j);
+ err = dencGenEncryptedData_writeToFile(pEncData, fname);
+ dencEncryptedData_free(pEncData);
+ pEncKey = 0;
+ pEncData = 0;
+ }
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Invalid parameters for -encrypt-test-set command");
+ }
+ }
+ }
+ }
+ return err;
+}
+
+
+//--------------------------------------------------
+// Lists EncryptedData objects
+//--------------------------------------------------
+int cmdListEncryptedData(DEncEncryptedData* pEncData)
+{
+ int err = ERR_OK, k;
+ char buf1[50], buf2[50];
+
+ if(g_cgiMode) {
+ fprintf(stdout, "\nEncryptedData%s%s%s%s%s%s%s%s",
+ g_szOutputSeparator, (pEncData->szId ? pEncData->szId : ""),
+ g_szOutputSeparator, (pEncData->szType ? pEncData->szType : ""),
+ g_szOutputSeparator, (pEncData->szMimeType ? pEncData->szMimeType : ""),
+ g_szOutputSeparator, (pEncData->szEncryptionMethod ? pEncData->szEncryptionMethod : ""));
+ err = dencMetaInfo_GetLibVersion(pEncData, buf1, sizeof(buf1), buf2, sizeof(buf2));
+ fprintf(stdout, "\nLIBRARY%s%s%s%s", g_szOutputSeparator, buf1, g_szOutputSeparator, buf2);
+ err = dencMetaInfo_GetFormatVersion(pEncData, buf1, sizeof(buf1), buf2, sizeof(buf2));
+ fprintf(stdout, "\nFORMAT%s%s%s%s", g_szOutputSeparator, buf1, g_szOutputSeparator, buf2);
+ } else {
+ fprintf(stdout, "\nEncryptedData - Id=%s Type=%s MimeType=%s EncryptionMethod=%s",
+ (pEncData->szId ? pEncData->szId : ""),
+ (pEncData->szType ? pEncData->szType : ""),
+ (pEncData->szMimeType ? pEncData->szMimeType : ""),
+ (pEncData->szEncryptionMethod ? pEncData->szEncryptionMethod : ""));
+ err = dencMetaInfo_GetLibVersion(pEncData, buf1, sizeof(buf1), buf2, sizeof(buf2));
+ fprintf(stdout, "\n\tLIBRARY: %s VERSION: %s", buf1, buf2);
+ err = dencMetaInfo_GetFormatVersion(pEncData, buf1, sizeof(buf1), buf2, sizeof(buf2));
+ fprintf(stdout, "\n\tFORMAT: %s VERSION: %s", buf1, buf2);
+ }
+ for(k = 0; k < pEncData->nEncryptedKeys; k++) {
+ DEncEncryptedKey *pEncKey = pEncData->arrEncryptedKeys[k];
+ if(g_cgiMode)
+ fprintf(stdout, "\nEncryptedKey%s%s%s%s%s%s%s%s%s%s%s%s",
+ g_szOutputSeparator, (pEncKey->szId ? pEncKey->szId : ""),
+ g_szOutputSeparator, (pEncKey->szRecipient ? pEncKey->szRecipient : ""),
+ g_szOutputSeparator, (pEncKey->szKeyName ? pEncKey->szKeyName : ""),
+ g_szOutputSeparator, (pEncKey->szCarriedKeyName ? pEncKey->szCarriedKeyName : ""),
+ g_szOutputSeparator, (pEncKey->szEncryptionMethod ? pEncKey->szEncryptionMethod : ""),
+ g_szOutputSeparator, (pEncKey->pCert ? "OK" : "NULL"));
+ else
+ fprintf(stdout, "\nEncryptedKey: Id=%s Recipient=%s KeyName=%s CarriedKeyName=%s EncryptionMethod=%s Cert: %s",
+ (pEncKey->szId ? pEncKey->szId : ""),
+ (pEncKey->szRecipient ? pEncKey->szRecipient : ""),
+ (pEncKey->szKeyName ? pEncKey->szKeyName : ""),
+ (pEncKey->szCarriedKeyName ? pEncKey->szCarriedKeyName : ""),
+ (pEncKey->szEncryptionMethod ? pEncKey->szEncryptionMethod : ""),
+ (pEncKey->pCert ? "OK" : "NULL"));
+ }
+ if(pEncData->encProperties.nEncryptionProperties > 0) {
+ if(g_cgiMode)
+ fprintf(stdout, "\nEncryptionProperties%s%s",
+ g_szOutputSeparator, (pEncData->encProperties.szId ? pEncData->encProperties.szId : ""));
+ else
+ fprintf(stdout, "\nEncryptionProperties: %s",
+ (pEncData->encProperties.szId ? pEncData->encProperties.szId : ""));
+ for(k = 0; k < pEncData->encProperties.nEncryptionProperties; k++) {
+ DEncEncryptionProperty *pEncProp = pEncData->encProperties.arrEncryptionProperties[k];
+ if(g_cgiMode)
+ fprintf(stdout, "\nEncryptionProperty%s%s%s%s%s%s%s%s\n",
+ g_szOutputSeparator, (pEncProp->szId ? pEncProp->szId : ""),
+ g_szOutputSeparator, (pEncProp->szTarget ? pEncProp->szTarget : ""),
+ g_szOutputSeparator, (pEncProp->szName ? pEncProp->szName : ""),
+ g_szOutputSeparator, (pEncProp->szContent ? pEncProp->szContent : ""));
+ else
+ fprintf(stdout, "\nEncryptionProperty Id=%s Target=%s Name=%s Content=%s\n",
+ (pEncProp->szId ? pEncProp->szId : ""),
+ (pEncProp->szTarget ? pEncProp->szTarget : ""),
+ (pEncProp->szName ? pEncProp->szName : ""),
+ (pEncProp->szContent ? pEncProp->szContent : ""));
+ }
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// Add ecryption recipients
+//--------------------------------------------------
+int runDEncListCmds(int argc, char** argv)
+{
+ int err = ERR_OK, i;
+ DEncEncryptedData* pEncData = 0;
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // add a recipients key
+ if(!strcmp(argv[i], "-denc-list")) {
+ if(argc > i+1 && argv[i+1][0] != '-') {
+ char* file = argv[i+1];
+ err = dencSaxReadEncryptedData(&pEncData, file);
+ if(!err)
+ err = cmdListEncryptedData(pEncData);
+ if(pEncData && !err)
+ dencEncryptedData_free(pEncData);
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <file> argument of -denc-list command");
+ }
+ }
+ }
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// decryption file
+//--------------------------------------------------
+int runDecryptCmds(int argc, char** argv, DEncEncryptedData** ppEncData)
+{
+ int err = ERR_OK, i, bDecSk = 0, nSlot = 0, nKey = 0;
+ DEncEncryptedKey* pEncKey = 0;
+ FILE *hFile = 0;
+ SignedDoc *pSigDoc = 0;
+ DataFile *pDf = 0;
+ char fname1[256], *pkcs12file = 0, *infile = 0, *pin = 0, key[300];
+ EVP_PKEY *pkey;
+#ifdef WIN32
+ wchar_t *convFileName = 0;
+ int l1 = 0;
+#endif
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // decrypt file
+ if(!strcmp(argv[i], "-decrypt") ||
+ !strcmp(argv[i], "-decrypt-hex") ||
+ !strcmp(argv[i], "-decrypt-sk")) {
+ if(!strcmp(argv[i], "-decrypt-sk")) bDecSk = 1;
+ if(argc > i+3 &&
+ argv[i+1][0] != '-' &&
+ argv[i+2][0] != '-') {
+ ddocConvertInput(argv[i+1], &infile);
+ ddocConvertInput(argv[i+2], &pin);
+ nKey = 0;
+ memset(key, 0, sizeof(key));
+ if(!strcmp(argv[i], "-decrypt-hex")) {
+ nKey = sizeof(key);
+ hex2bin(pin, (byte*)key, &nKey);
+ }
+ i += 2;
+ if(argc > i+1 && argv[i+1][0] != '-') {
+ ddocConvertInput(argv[i+1], &pkcs12file);
+ i++;
+ }
+ if(argc > i+2 && argv[i+2][0] != '-') {
+ nSlot = atoi(argv[i+2]);
+ i++;
+ }
+ ddocDebug(3, "runDecryptCmds", "Decrypt file: %s pin: %s pkcs12: %s slot: %d", infile, pin, pkcs12file, nSlot);
+ err = dencSaxReadEncryptedData(ppEncData, infile);
+ if(err) return err;
+ // if using hex key
+ if(nKey > 0) {
+ ddocDebug(3, "runDecryptCmds", "Decrypt with key: %s len: %d", pin, nKey);
+ err = dencEncryptedData_decrypt_withKey(*ppEncData, key, nKey);
+ }
+ // if using pkcs12
+ else if(pkcs12file != NULL && strlen(pkcs12file) > 0) {
+ ddocDebug(3, "runDecryptCmds", "Opening pkcs12 file: %s", pkcs12file);
+ err = dencEncryptedData_findEncryptedKeyByPKCS12(*ppEncData, &pEncKey, &pkey, pkcs12file, pin);
+ } else {
+ ddocDebug(3, "runDecryptCmds", "Connecting to pkcs11, slot: %d", nSlot);
+ err = dencEncryptedData_findEncryptedKeyByPKCS11UsingSlot(*ppEncData, &pEncKey, nSlot);
+ }
+ if(!nKey) {
+ if(pEncKey) {
+ if(pkcs12file != NULL && strlen(pkcs12file) > 0)
+ err = dencEncryptedData_decryptWithKey(*ppEncData, pEncKey, pkey);
+ else
+ err = dencEncryptedData_decryptUsingSlot(*ppEncData, pEncKey, pin, nSlot);
+ if(err) return err;
+ } else {
+ err = ERR_DENC_DECRYPT;
+ addError(err, __FILE__, __LINE__, "No transport key found for your smartcard");
+ }
+ }
+ // read in ddoc if necessary
+ if(bDecSk && p_szOutFile) {
+ sprintf(fname1, "%s.ddoc", p_szOutFile);
+ ddocDebug(3, "runDecryptCmds", "writing ddoc to: %s", fname1);
+#ifdef WIN32
+ err = utf82unicode((const char*)fname1, (char**)&convFileName, &l1);
+ ddocDebug(3, "ddocReadFile", "file: %s, conv-file: %s len: %d", fname1, convFileName, i);
+ if((hFile = _wfopen(convFileName, L"wb")) != NULL) {
+#else
+ if((hFile = fopen(fname1, "wb")) != NULL) {
+#endif
+ fwrite((*ppEncData)->mbufEncryptedData.pMem, (*ppEncData)->mbufEncryptedData.nLen, 1, hFile);
+ fclose(hFile);
+ ddocDebug(3, "runDecryptCmds", "Reading ddoc: %s", fname1);
+ err = ddocSaxReadSignedDocFromFile(&pSigDoc, fname1, 0, 0);
+ if(!err && getCountOfDataFiles(pSigDoc) > 0) {
+ pDf = getDataFile(pSigDoc, 0);
+ ddocDebug(3, "runDecryptCmds", "writing DF: %s to: %s", pDf->szId, p_szOutFile);
+ err = ddocExtractDataFile(pSigDoc, fname1, p_szOutFile, pDf->szId, "UTF-8");
+ dencEncryptedData_free(*ppEncData);
+ *ppEncData = NULL;
+ p_szOutFile = NULL;
+ }
+ SignedDoc_free(pSigDoc);
+ if(fname1[0] && !remove(fname1))
+ ddocDebug(3, "runDecryptCmds", "error deleting file: %", fname1);
+ }
+ }
+ // p_szOutFile
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <file> or <pin> argument of -decrypt command");
+ }
+ }
+ }
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// Create digidoc and adds datafiles
+//--------------------------------------------------
+int runExtractCmds(int argc, char** argv, SignedDoc** ppSigDoc)
+{
+ int err = ERR_OK, i;
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // add a DataFile
+ if(!strcmp(argv[i], "-extract")) {
+ if(argc > i+2 && argv[i+1][0] != '-' && argv[i+2][0] != '-') {
+ char* id = NULL;
+ char* file = NULL;
+ char* charset = CHARSET_UTF_8;
+ checkArguments(argc, argv, &i, &id);
+ checkArguments(argc, argv, &i, &file);
+ // optional charset & filenamecharset
+ //checkArguments(argc, argv, &i, &charset);
+ err = ddocExtractDataFile(*ppSigDoc, (const char*)p_szInFile, (const char*)file,
+ (const char*)id, (const char*)charset);
+ // report success
+ if(g_cgiMode)
+ fprintf(stdout, "\nDataFile%s%s%s%s%s%d", g_szOutputSeparator, id,
+ g_szOutputSeparator, file, g_szOutputSeparator, err);
+ else
+ fprintf(stdout, "\nDataFile id: %s path: %s rc: %d", id, file, err);
+
+ if(id) freeLibMem(id);
+ if(file) freeLibMem(file);
+
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <file> argument of -extract command");
+ }
+ }
+ }
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// Create digidoc and adds datafiles
+//--------------------------------------------------
+int runExtractMemCmds(int argc, char** argv, SignedDoc** ppSigDoc)
+{
+ int err = ERR_OK, i;
+ char* pBuf = 0;
+ long nLen = 0;
+ FILE* hFile = 0;
+
+ for(i = 1; (err == ERR_OK) && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // extract DataFile
+ if(!strcmp(argv[i], "-extract-mem")) {
+ if(argc > i+2 && argv[i+1][0] != '-' && argv[i+2][0] != '-') {
+ char* id = NULL;
+ char* file = NULL;
+ checkArguments(argc, argv, &i, &id);
+ checkArguments(argc, argv, &i, &file);
+ err = ddocGetDataFileCachedData(*ppSigDoc, id, (void**)&pBuf, &nLen);
+ printf("\nExtract DF: %s, err: %d data: %ld", id, err, nLen);
+ if(file && (hFile = fopen(file, "wb")) != NULL && pBuf && nLen)
+ fwrite(pBuf, nLen, 1, hFile);
+ if(id) freeLibMem(id);
+ if(file) freeLibMem(file);
+ if(hFile) fclose(hFile);
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <file> argument of -extract command");
+ }
+ }
+ }
+ }
+ if(pBuf)
+ freeLibMem(pBuf);
+ if(hFile)
+ fclose(hFile);
+ return err;
+}
+
+
+//--------------------------------------------------
+// Verfys sigantures and notaries
+//--------------------------------------------------
+int runVerifyCmds(int argc, char** argv, SignedDoc* pSigDoc, DEncEncryptedData* pEncData)
+{
+ int err = ERR_OK, i;
+
+ for(i = 1; !err && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // create new digidoc
+ if(!strcmp(argv[i], "-verify")) {
+ if(pSigDoc) {
+ err = cmdVerify(pSigDoc);
+ }
+ if(pEncData)
+ err = dencValidate(pEncData);
+ }
+ }
+ }
+ return err;
+}
+
+
+//--------------------------------------------------
+// Handles signature commands
+//--------------------------------------------------
+int runSignCmds(int argc, char** argv, SignedDoc** ppSigDoc)
+{
+ int err = ERR_OK, i, nManif, nSlot = 0, nOcsp = 1, nSigner = 1;
+
+ for(i = 1; !err && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // create new digidoc
+ if(!strcmp(argv[i], "-sign")) {
+ char* pin = NULL;
+ char* manifest = NULL;
+ char* city = NULL;
+ char* state = NULL;
+ char* zip = NULL;
+ char* country = NULL;
+ char* sSlot = NULL;
+ char* sOcsp = NULL;
+ char* sSigner = NULL;
+ char* szPkcs12File = NULL;
+ checkArguments(argc, argv, &i, &pin);
+ // if pin is NULL check for autosign pin
+ if(!pin)
+ pin = (char*)ConfigItem_lookup("AUTOSIGN_PIN");
+ if(!pin) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <pin> argument of -sign command");
+ return err;
+ }
+ // check config file
+ nManif = ConfigItem_lookup_int("MANIFEST_MODE", 0);
+ if(nManif == 2) {
+ manifest = (char*)ConfigItem_lookup("DIGIDOC_ROLE_MANIFEST");
+ country = (char*)ConfigItem_lookup("DIGIDOC_ADR_COUNTRY");
+ state = (char*)ConfigItem_lookup("DIGIDOC_ADR_STATE");
+ city = (char*)ConfigItem_lookup("DIGIDOC_ADR_CITY");
+ zip = (char*)ConfigItem_lookup("DIGIDOC_ADR_ZIP");
+ }
+ // optional mainfest argument
+ checkArguments(argc, argv, &i, &manifest);
+ // optional address
+ checkArguments(argc, argv, &i, &city);
+ checkArguments(argc, argv, &i, &state);
+ checkArguments(argc, argv, &i, &zip);
+ checkArguments(argc, argv, &i, &country);
+ checkArguments(argc, argv, &i, &sSlot);
+ checkArguments(argc, argv, &i, &sOcsp);
+ checkArguments(argc, argv, &i, &sSigner);
+ if(sSlot)
+ nSlot = atoi(sSlot);
+ if(sOcsp)
+ nOcsp = atoi(sOcsp);
+ if(sSigner) {
+ if(!strcmp(sSigner, "PKCS11")) nSigner = 1;
+ if(!strcmp(sSigner, "PKCS12")) nSigner = 3;
+#ifdef WIN32
+ if(!strcmp(sSigner, "CNG")) nSigner = 2;
+#endif
+ }
+ checkArguments(argc, argv, &i, &szPkcs12File);
+ err = cmdSign(*ppSigDoc, (const char*)pin, (const char*)manifest,
+ (const char*)city, (const char*)state, (const char*)zip,
+ (const char*)country, nSlot, nOcsp, nSigner, szPkcs12File);
+ if(manifest) freeLibMem(manifest);
+ if(city) freeLibMem(city);
+ if(state) freeLibMem(state);
+ if(zip) freeLibMem(zip);
+ if(country) freeLibMem(country);
+ if(sSlot) freeLibMem(sSlot);
+ if(sOcsp) freeLibMem(sOcsp);
+ if(sSigner) freeLibMem(sSigner);
+ if(szPkcs12File) freeLibMem(szPkcs12File);
+ }
+ }
+ }
+ return err;
+}
+
+
+//--------------------------------------------------
+// Handles commands related to checking certificates
+//--------------------------------------------------
+int runCheckCertCmds(int argc, char** argv)
+{
+ int err = ERR_OK, i;
+ char* szCertFile = 0;
+ X509* pCert = 0;
+ DigiDocMemBuf mbuf;
+
+ mbuf.pMem = 0;
+ mbuf.nLen = 0;
+ for(i = 1; !err && (i < argc); i++) {
+ if(!strcmp(argv[i], "-check-cert") &&
+ argv[i+1][0] != '-') {
+ szCertFile = argv[i+1];
+ i++;
+ if(szCertFile) {
+ err = ReadCertificate(&pCert, szCertFile);
+ if(!err && pCert) {
+ err = ddocVerifyCertByOCSP(pCert, NULL);
+ err = ddocCertGetSubjectCN(pCert, &mbuf);
+ printf("Verifying cert: %s --> RC :%d\n", (const char*)mbuf.pMem, err);
+ ddocMemBuf_free(&mbuf);
+ }
+ if(pCert) {
+ X509_free(pCert);
+ pCert = 0;
+ }
+ }
+ }
+ }
+ return err;
+}
+
+//--------------------------------------------------
+// Handles commands related to adding signature value
+// from a file containging base64 encoded RSA-SHA1 signature value
+//--------------------------------------------------
+int runAddSignValueCmds(int argc, char** argv, SignedDoc* pSigDoc)
+{
+ int err = ERR_OK, i;
+ char *szSignFile = 0, *szSignId = 0;
+ SignatureInfo* pSignInfo = 0;
+
+ for(i = 1; !err && (i < argc); i++) {
+ if(!strcmp(argv[i], "-add-sign-value") && i < argc - 2 &&
+ argv[i+1][0] != '-' && argv[i+2][0] != '-') {
+ checkArguments(argc, argv, &i, &szSignFile);
+ checkArguments(argc, argv, &i, &szSignId);
+ if(!pSigDoc) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "No digidoc document read in yet!");
+ return err;
+ }
+ if(szSignFile && szSignId) {
+ pSignInfo = getSignatureWithId(pSigDoc, szSignId);
+ if(pSignInfo) {
+ // read the file
+ err = setSignatureValueFromFile(pSignInfo, szSignFile);
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Wrong signature id");
+ }
+ // report on success
+ if(g_cgiMode)
+ fprintf(stdout, "\nAddSignValue%s%s%s%s%s%d", g_szOutputSeparator, szSignId,
+ g_szOutputSeparator, szSignFile, g_szOutputSeparator, err);
+ else
+ fprintf(stdout, "\nAddSignValue id: %s path: %s rc: %d", szSignId, szSignFile, err);
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <sign-value-file> or <sign-id> argument of -add-sign-value command");
+ }
+ }
+ }
+ if(szSignFile) freeLibMem(szSignFile);
+ if(szSignId) freeLibMem(szSignId);
+ return err;
+}
+
+
+//--------------------------------------------------
+// Handles commands related to deleting signatures
+//--------------------------------------------------
+int runDelSignCmds(int argc, char** argv, SignedDoc* pSigDoc)
+{
+ int err = ERR_OK, i;
+ char *szSignId = 0;
+ SignatureInfo* pSignInfo = 0;
+
+ for(i = 1; !err && (i < argc); i++) {
+ if(!strcmp(argv[i], "-del-sign") && i < argc - 1 &&
+ argv[i+1][0] != '-') {
+ checkArguments(argc, argv, &i, &szSignId);
+ if(!pSigDoc) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "No digidoc document read in yet!");
+ return err;
+ }
+ if(szSignId) {
+ pSignInfo = getSignatureWithId(pSigDoc, szSignId);
+ if(pSignInfo) {
+ err = SignatureInfo_delete(pSigDoc, szSignId);
+ // report on success
+ if(g_cgiMode)
+ fprintf(stdout, "\nDelSign%s%s%s%d", g_szOutputSeparator, szSignId,
+ g_szOutputSeparator, err);
+ else
+ fprintf(stdout, "\nDelSign id: %s rc: %d", szSignId, err);
+
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "wrong signature id!");
+ }
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <sign-id> argument of -del-sign command");
+ }
+ }
+ }
+ if(szSignId) freeLibMem(szSignId);
+ return err;
+}
+
+
+//--------------------------------------------------
+// Handles commands related to notarizing signatures
+//--------------------------------------------------
+int runGetConfirmationCmds(int argc, char** argv, SignedDoc* pSigDoc)
+{
+ int err = ERR_OK, i;
+ char *szSignId = 0;
+ SignatureInfo* pSignInfo = 0;
+
+ for(i = 1; !err && (i < argc); i++) {
+ if(!strcmp(argv[i], "-get-confirmation") && i < argc - 1 &&
+ argv[i+1][0] != '-') {
+ checkArguments(argc, argv, &i, &szSignId);
+ if(!pSigDoc) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "No digidoc document read in yet!");
+ return err;
+ }
+ if(szSignId) {
+ pSignInfo = getSignatureWithId(pSigDoc, szSignId);
+ if(pSignInfo) {
+ err = notarizeSignature(pSigDoc, pSignInfo);
+ // report on success
+ if(g_cgiMode)
+ fprintf(stdout, "\nNotarizeSignature%s%s%s%d", g_szOutputSeparator, szSignId,
+ g_szOutputSeparator, err);
+ else
+ fprintf(stdout, "\nNotarizeSignature id: %s rc: %d", szSignId, err);
+
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "wrong signature id!");
+ }
+ if(szSignId) freeLibMem(szSignId);
+ } else {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <sign-id> argument of -get-confirmation command");
+ }
+ }
+ }
+ return err;
+}
+
+
+//--------------------------------------------------
+// Signs the document and gets configrmation
+//--------------------------------------------------
+int cmdCalcSign(SignedDoc* pSigDoc, const char* manifest,
+ const char* city, const char* state, const char* zip,
+ const char* country, const char* certFile)
+{
+ int err = ERR_OK, l1;
+ SignatureInfo* pSigInfo = NULL;
+ X509* pCert = NULL;
+ char buf1[50];
+
+ ddocDebug(3, "cmdCalcSign", "Creating new digital signature");
+ RETURN_IF_NULL_PARAM(pSigDoc);
+ RETURN_IF_NULL_PARAM(certFile);
+ // read certificate
+ // this certificate will nto be released since new signature takes ownership!
+ err = ReadCertificate(&pCert, certFile);
+ RETURN_IF_NOT(err == ERR_OK, err);
+ // prepare signature
+ err = ddocPrepareSignature(pSigDoc, &pSigInfo,
+ manifest, city, state, zip, country, pCert, NULL);
+ // base64 encode final hash
+ l1 = sizeof(buf1);
+ err = ddocGetSignedHash(pSigInfo, buf1, &l1, 2, 0);
+ RETURN_IF_NOT(err == ERR_OK, err);
+ // report on success
+ if(g_cgiMode)
+ fprintf(stdout, "\nSignatureHash%s%s%s%s%s%d", g_szOutputSeparator, pSigInfo->szId,
+ g_szOutputSeparator, buf1, g_szOutputSeparator, err);
+ else
+ fprintf(stdout, "\nSignatureHash id: %s hash: %s rc: %d", pSigInfo->szId, buf1, err);
+
+
+ RETURN_IF_NOT(err == ERR_OK, err);
+ return ERR_OK;
+}
+
+//--------------------------------------------------
+// Handles signature commands
+//--------------------------------------------------
+int runCalcSignCmds(int argc, char** argv, SignedDoc* pSigDoc)
+{
+ int err = ERR_OK, i, nManif;
+
+ for(i = 1; !err && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // create new digidoc
+ if(!strcmp(argv[i], "-calc-sign")) {
+ char* certFile = NULL;
+ char* manifest = NULL;
+ char* city = NULL;
+ char* state = NULL;
+ char* zip = NULL;
+ char* country = NULL;
+ checkArguments(argc, argv, &i, &certFile);
+ // check config file
+ nManif = ConfigItem_lookup_int("MANIFEST_MODE", 0);
+ if(nManif == 2) {
+ manifest = (char*)ConfigItem_lookup("DIGIDOC_ROLE_MANIFEST");
+ country = (char*)ConfigItem_lookup("DIGIDOC_ADR_COUNTRY");
+ state = (char*)ConfigItem_lookup("DIGIDOC_ADR_STATE");
+ city = (char*)ConfigItem_lookup("DIGIDOC_ADR_CITY");
+ zip = (char*)ConfigItem_lookup("DIGIDOC_ADR_ZIP");
+ }
+ // optional mainfest argument
+ checkArguments(argc, argv, &i, &manifest);
+ // optional address
+ checkArguments(argc, argv, &i, &city);
+ checkArguments(argc, argv, &i, &state);
+ checkArguments(argc, argv, &i, &zip);
+ checkArguments(argc, argv, &i, &country);
+ if(!certFile) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <cert-file> argument of -calc-sign command");
+ }
+ else
+ err = cmdCalcSign(pSigDoc, (const char*)manifest,
+ (const char*)city, (const char*)state, (const char*)zip,
+ (const char*)country, (const char*)certFile);
+ if(manifest) freeLibMem(manifest);
+ if(city) freeLibMem(city);
+ if(state) freeLibMem(state);
+ if(zip) freeLibMem(zip);
+ if(country) freeLibMem(country);
+ if(certFile) freeLibMem(certFile);
+ }
+ }
+ }
+ return err;
+}
+
+
+//--------------------------------------------------
+// Signs the document and gets configrmation
+//--------------------------------------------------
+int cmdMidSign(SignedDoc* pSigDoc, const char* szPhoneNo,
+ const char* szIdCode, const char* szLang,
+ const char* szService,
+ const char* manifest, const char* city,
+ const char* state, const char* zip,
+ const char* country)
+{
+ int err = ERR_OK, nPollFreq = 0, l1, nStatus = 0;
+ char* szUrl = 0, *szProxyHost = 0, *szProxyPort = 0;
+ long lSesscode = 0;
+ char buf1[10];
+ DigiDocMemBuf mbuf1;
+#ifdef WIN32
+ time_t tNew, tOld;
+#endif
+
+ mbuf1.pMem = 0;
+ mbuf1.nLen = 0;
+ nPollFreq = ConfigItem_lookup_int("DDS_POLLFREQ", 0);
+ szUrl = (char*)ConfigItem_lookup("DDS_URL");
+ szProxyHost = (char*)ConfigItem_lookup("DDS_PROXY_HOST");
+ szProxyPort = (char*)ConfigItem_lookup("DDS_PROXY_PORT");
+ ddocDebug(3, "cmdMidSign", "Creating MID signature using: %s poll freq: %d", szPhoneNo, nPollFreq);
+ // send signature req
+ l1 = sizeof(buf1);
+ ddsSign(pSigDoc, szIdCode, szPhoneNo, szLang, szService,
+ manifest, city, state, zip, country, szUrl, szProxyHost, szProxyPort,
+ &lSesscode, buf1, l1);
+
+ // report on success
+ if(g_cgiMode)
+ fprintf(stdout, "\nMIDSinatureReq%s%ld%s%d",
+ g_szOutputSeparator, lSesscode,
+ g_szOutputSeparator, err);
+ else
+ fprintf(stdout, "\nMIDSignatureReq session: %ld rc: %d", lSesscode, err);
+ // if we should keep on polling
+ if(!err && nPollFreq) {
+ // now check status
+ do {
+#ifdef WIN32
+ time(&tOld);
+ do {
+ time(&tNew);
+ } while(tNew - tOld < nPollFreq);
+#else
+ ddocDebug(3, "cmdMidSign", "Sleep: %d", nPollFreq);
+ sleep(nPollFreq);
+#endif
+ err = ddsGetStatusWithFile(pSigDoc, lSesscode, szUrl, szProxyHost, szProxyPort, &nStatus, p_szInFile);
+ ddocDebug(3, "cmdMidSign", "Txn: %ld status: %d err: %d", lSesscode, nStatus, err);
+ } while(!err && nStatus == 1);
+ }
+ if(g_cgiMode)
+ fprintf(stdout, "\nMID session %s%ld%s%d",
+ g_szOutputSeparator, lSesscode,
+ g_szOutputSeparator, nStatus);
+ else
+ fprintf(stdout, "\nMID session %ld complete status: %d", lSesscode, nStatus);
+
+ RETURN_IF_NOT(err == ERR_OK, err);
+ return ERR_OK;
+}
+
+
+//--------------------------------------------------
+// Handles MID signature commands
+//--------------------------------------------------
+int runMidSignCmds(int argc, char** argv, SignedDoc* pSigDoc)
+{
+ int err = ERR_OK, i, nManif = 0;
+
+ for(i = 1; !err && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // create new digidoc
+ if(!strcmp(argv[i], "-mid-sign")) {
+ char* phoneNo = NULL;
+ char* idcode = NULL;
+ char* service = NULL;
+ char* lang = NULL;
+ char* manifest = NULL;
+ char* city = NULL;
+ char* state = NULL;
+ char* zip = NULL;
+ char* country = NULL;
+ checkArguments(argc, argv, &i, &phoneNo);
+ // check config file
+ nManif = ConfigItem_lookup_int("MANIFEST_MODE", 0);
+ if(nManif == 2) {
+ manifest = (char*)ConfigItem_lookup("DIGIDOC_ROLE_MANIFEST");
+ country = (char*)ConfigItem_lookup("DIGIDOC_ADR_COUNTRY");
+ state = (char*)ConfigItem_lookup("DIGIDOC_ADR_STATE");
+ city = (char*)ConfigItem_lookup("DIGIDOC_ADR_CITY");
+ zip = (char*)ConfigItem_lookup("DIGIDOC_ADR_ZIP");
+ }
+ // optional mainfest argument
+ checkArguments(argc, argv, &i, &idcode);
+ checkArguments(argc, argv, &i, &country);
+ checkArguments(argc, argv, &i, &lang);
+ checkArguments(argc, argv, &i, &service);
+ checkArguments(argc, argv, &i, &manifest);
+ checkArguments(argc, argv, &i, &city);
+ checkArguments(argc, argv, &i, &state);
+ checkArguments(argc, argv, &i, &zip);
+ if(!phoneNo) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <phone-no> argument of -mid-sign command");
+ }
+ else
+ cmdMidSign(pSigDoc, (const char*)phoneNo, (const char*)idcode,
+ (const char*)(lang ? lang : "EST"),
+ (const char*)(service ? service : "Testimine"), (const char*)manifest,
+ (const char*)city, (const char*)state, (const char*)zip,
+ (const char*)(country ? country : "EE"));
+ if(manifest) freeLibMem(manifest);
+ if(city) freeLibMem(city);
+ if(state) freeLibMem(state);
+ if(zip) freeLibMem(zip);
+ if(country) freeLibMem(country);
+ if(phoneNo) freeLibMem(phoneNo);
+ }
+ }
+ }
+ return err;
+}
+
+
+//--------------------------------------------------
+// Handles MID signature commands
+//--------------------------------------------------
+int runMidTestCmds(int argc, char** argv, SignedDoc* pSigDoc)
+{
+ int err = ERR_OK, i, e1;
+ SignedDoc *pSdoc = NULL;
+ DataFile *pDf = NULL;
+ long lSize1, lSize2, lSize3;
+
+ for(i = 1; !err && (i < argc); i++) {
+ if(argv[i][0] == '-') { // all commands and options must start with -
+ // create new digidoc
+ if(!strcmp(argv[i], "-mid-test")) {
+ char* infile = NULL;
+ char* inmime = NULL;
+ char* outddoc = NULL;
+ char* phoneNo = NULL;
+ char* idcode = NULL;
+ char* service = NULL;
+ checkArguments(argc, argv, &i, &infile);
+ checkArguments(argc, argv, &i, &inmime);
+ checkArguments(argc, argv, &i, &outddoc);
+ checkArguments(argc, argv, &i, &phoneNo);
+ checkArguments(argc, argv, &i, &idcode);
+ checkArguments(argc, argv, &i, &service);
+ if(!phoneNo || !idcode || !infile || !inmime || !outddoc) {
+ err = ERR_BAD_PARAM;
+ addError(err, __FILE__, __LINE__, "Missing <phone-no> <idcode> <infile> <inmime> or <outddoc> argument of -mid-test command");
+ } else {
+ p_szInFile = outddoc;
+ printf("Creating ddoc: %s of file: %s mime: %s\n", outddoc, infile, inmime);
+ err = SignedDoc_new(&pSdoc, "DIGIDOC-XML", "1.3");
+ printf("Creating ddoc: %s rc: %d\n", outddoc, err);
+ RETURN_IF_NOT(err == ERR_OK, err);
+ err = calculateFileSize(infile, &lSize1);
+ err = DataFile_new(&pDf, pSdoc, NULL, infile, "EMBEDDED_BASE64", inmime, 0, NULL, 0, NULL, NULL);
+ err = createSignedDoc(pSdoc, NULL, outddoc);
+ if(pDf->nSize == 0 && lSize1 > 0)
+ pDf->nSize = lSize1;
+ err = calculateFileSize(outddoc, &lSize2);
+ printf("Add data-file: %s rc: %d d-size: %ld ddoc-size: %ld\n", infile, err, lSize1, lSize2);
+ err = ddocExtractDataFile(pSdoc, outddoc, "D0.dat", "D0", "UTF-8");
+ err = calculateFileSize("D0.dat", &lSize3);
+ printf("Extract before signing rc: %d size: %ld\n", err, lSize3);
+ printf("MID signing phone: %s id-code: %s\n", phoneNo, idcode);
+ err = cmdMidSign(pSdoc, (const char*)phoneNo, (const char*)idcode,
+ "EST", (service ? service : "Testimine"), NULL, NULL, NULL, NULL, "EE");
+ err = calculateFileSize(outddoc, &lSize2);
+ printf("MID signed phone: %s id-code: %s ddoc-size: %ld rc: %d\n", phoneNo, idcode, lSize2, err);
+ err = cmdVerify(pSdoc);
+ printf("\nVerify after signing rc: %d\n", err);
+ lSize3 = 0;
+ err = ddocExtractDataFile(pSdoc, outddoc, "D0.dat", "D0", "UTF-8");
+ err = calculateFileSize("D0.dat", &lSize3);
+ printf("Extract after signing rc: %d size: %ld\n", err, lSize3);
+ }
+ SignedDoc_free(pSdoc);
+ if(infile) freeLibMem(infile);
+ if(inmime) freeLibMem(inmime);
+ if(outddoc) freeLibMem(outddoc);
+ if(phoneNo) freeLibMem(phoneNo);
+ if(idcode) freeLibMem(idcode);
+ if(service) freeLibMem(service);
+ }
+ }
+ }
+ return err;
+}
+
+
+
+
+//--------------------------------------------------
+// Program main function
+//--------------------------------------------------
+int main(int argc, char** argv)
+{
+ int err = ERR_OK, e = 0;
+ SignedDoc* pSigDoc = 0;
+ DEncEncryptedData* pEncData = 0;
+ time_t t1, t2;
+#ifdef WIN32
+ char buf1[250];
+#endif
+
+ if(argc <= 1) {
+ printUsage();
+ exit(0);
+ }
+ // init DigiDoc library
+ initDigiDocLib();
+#ifdef WIN32
+ // find out program home if invoked with a long command line
+ memset(buf1, 0, sizeof(buf1));
+ getFileNamePath(argv[0], buf1, sizeof(buf1));
+ if(strlen(buf1)) {
+ strncat(buf1, "digidoc.ini", sizeof(buf1));
+ err = initConfigStore(buf1);
+ } else
+ err = initConfigStore(NULL);
+#else
+ // read in config file
+ err = initConfigStore(NULL);
+#endif
+ // clear all errors that were encountered by not finding config files
+ err = checkProgArguments(argc, argv);
+ time(&t1);
+ // register program name and version
+ setGUIVersion(g_szProgNameVer);
+ ddocDebugTruncateLog();
+ // use command line argument if required
+ if(p_szConfigFile)
+ err = readConfigFile(p_szConfigFile, ITEM_TYPE_PRIVATE);
+ // read flags from config file
+ readConfigParams();
+
+ // display programm name and version
+ if(g_cgiMode) {
+ if(ConfigItem_lookup_bool("DIGIDOC_CGI_PRINT_HEADER", 1))
+ fprintf(stdout, "%s%s%s", getLibName(), g_szOutputSeparator, getLibVersion());
+ } else {
+ fprintf(stdout, "%s - %s", getLibName(), getLibVersion());
+ }
+
+ // execute the commands now
+ // check certificate status throught OCSP
+ if(!err)
+ err = runCheckCertCmds(argc, argv);
+ // read input file if necessary
+ if(p_szInFile && !err) {
+ if(p_parseMode != 3)
+ err = cmdReadDigiDoc(&pSigDoc, &pEncData, p_parseMode);
+ else
+ err = cmdReadDigiDocFromMem(&pSigDoc, &pEncData);
+ // if read error was warning then continue
+ if(pSigDoc && isWarning(pSigDoc, err))
+ err = ERR_OK;
+ if(err && pSigDoc)
+ printErrorsAndWarnings(pSigDoc);
+ }
+ // various tests
+ if(!err)
+ err = runTestCmds(argc, argv);
+ if(p_szInEncFile && !err) {
+ if(hasCmdLineArg(argc, argv, "-encrypt-sk"))
+ err = cmdEncryptSk(&pEncData, p_szInEncFile);
+ else
+ err = cmdEncrypt(&pEncData, p_szInEncFile);
+ }
+ // list encrypted files
+ if(!err)
+ err = runDEncListCmds(argc, argv);
+ // add data files
+ if(!err)
+ err = runAddCmds(argc, argv, &pSigDoc);
+ // add data files from mem
+ if(!err)
+ err = runAddMemCmds(argc, argv, &pSigDoc);
+ // add recipients
+ if(!err)
+ err = runRecipientCmds(argc, argv, &pEncData);
+ // encrypt whole files
+ if(!err)
+ err = runEncryptFileCmds(argc, argv, pEncData);
+ // decrypt whole files
+ if(!err)
+ err = runDecryptFileCmds(argc, argv);
+ // run signature commands
+ if(!err)
+ err = runSignCmds(argc, argv, &pSigDoc);
+ // calculate signature hash commands
+ if(!err)
+ err = runCalcSignCmds(argc, argv, pSigDoc);
+ if(!err)
+ err = runMidSignCmds(argc, argv, pSigDoc);
+ if(!err)
+ err = runMidTestCmds(argc, argv, pSigDoc);
+ // verify signatures
+ if(!err) {
+ e = runVerifyCmds(argc, argv, pSigDoc, pEncData);
+ if(!err && e) err = e;
+ }
+ // extract datafiles
+ if(!err)
+ err = runExtractCmds(argc, argv, &pSigDoc);
+ if(!err)
+ err = runExtractMemCmds(argc, argv, &pSigDoc);
+ // decrypt files
+ if(!err)
+ err = runDecryptCmds(argc, argv, &pEncData);
+ // add signature value from a file
+ if(!err)
+ err = runAddSignValueCmds(argc, argv, pSigDoc);
+ // delete signatures
+ if(!err)
+ err = runDelSignCmds(argc, argv, pSigDoc);
+ // notarize signatures
+ if(!err)
+ err = runGetConfirmationCmds(argc, argv, pSigDoc);
+ if(!err)
+ err = runEncryptTestSetCmds(argc, argv);
+ // write output file
+ if(p_szOutFile && !err)
+ if(p_parseMode != 3)
+ err = cmdWrite(pSigDoc, pEncData);
+ else
+ err = cmdWriteMem(pSigDoc, pEncData);
+ time(&t2);
+
+ printErrorsAndWarnings(pSigDoc);
+ if(pSigDoc && !isError(pSigDoc, err)) { // find correct error from list
+ e = hasErrors(pSigDoc);
+ if((!err || !isError(pSigDoc,err)) && e) err = e;
+ }
+ // display programm error code and elapsed time
+ if(g_cgiMode) {
+ if(ConfigItem_lookup_bool("DIGIDOC_CGI_PRINT_TRAILER", 1))
+ fprintf(stdout, "\n%s%s%d%s%ld", getLibName(), g_szOutputSeparator, (isError(pSigDoc,err) ? err : 0), g_szOutputSeparator, (long)(t2-t1));
+ } else {
+ fprintf(stdout, "\n%s - time: %ld sec result: %s", getLibName(), (long)(t2-t1), (isError(pSigDoc,err) ? "failure" : "success"));
+ }
+ fprintf(stdout, "\n");
+ // cleanup
+ if(pSigDoc)
+ SignedDoc_free(pSigDoc);
+ if(pEncData)
+ dencEncryptedData_free(pEncData);
+ if(g_szOutputSeparator)
+ free(g_szOutputSeparator);
+ // cleanup
+#ifndef WIN32 // TODO: somehow this free gives invalid heap error on win32
+ cleanupConfigStore(NULL);
+#endif
+ finalizeDigiDocLib();
+
+ return err;
+}