Exemple #1
0
//============================================================
// Reads in an OCSP Response file in DER format
// szFileName - OCSP response file name
//============================================================
int ReadOCSPResponse(OCSP_RESPONSE **newOCSP_RESPONSE, const char* szFileName)
{
  BIO *bin = NULL;
  OCSP_RESPONSE *resp = NULL;
  int err = ERR_OK;
	
  ddocDebug(4, "ReadOCSPResponse", "File: %s", szFileName);
  RETURN_IF_NULL_PARAM(newOCSP_RESPONSE);
  RETURN_IF_NULL_PARAM(szFileName);

  if((bin = BIO_new_file(szFileName, "rb")) != NULL) {
    ddocDebug(4, "ReadOCSPResponse", "File opened");
    resp = d2i_OCSP_RESPONSE_bio(bin, NULL);
    BIO_free(bin);
    if (resp == NULL) {
      err = ERR_OCSP_WRONG_VERSION;
    }
  } else {
    ddocDebug(4, "ReadOCSPResponse", "Cannot read file:%s", szFileName);
    err =ERR_FILE_READ;
  }
  if (err != ERR_OK) SET_LAST_ERROR(err);
  *newOCSP_RESPONSE = resp;
  return err;
}
STDMETHODIMP CComDigiDocLib::getSupportedFormats(VARIANT *ret)
{
  const char** pArr = ::getSupportedFormats();
  unsigned int nElems = 0;
  SAFEARRAY* pSArr;
  BSTR HUGEP* pData;

  // detect number of elements
  for(; *pArr != NULL; pArr++, nElems++);

  // initialize SAFEARRAY
  pSArr = SafeArrayCreateVector(VT_BSTR, 0, nElems);
  if (pSArr == NULL) {
    return E_OUTOFMEMORY;
  }

  // init variant
  V_ARRAY(ret) = pSArr;
  V_VT(ret) = (VT_ARRAY | VT_BSTR);

  // copy data to variant
  pArr = ::getSupportedFormats();
  SafeArrayAccessData(pSArr, (void HUGEP**)&pData);
  long lArr[1];
  USES_CONVERSION;
  ddocDebug(1, "getSupportedFormats", "num formats: %d", nElems);
  for(lArr[0] = 0; lArr[0] < (long)nElems; lArr[0]++) {
	  ddocDebug(1, "getSupportedFormats", "format: %d - %s", lArr[0], pArr[lArr[0]]);
    pData[lArr[0]] = SysAllocString(A2OLE(pArr[lArr[0]]));
  }
  SafeArrayUnaccessData(pSArr);

	return S_OK;
}
Exemple #3
0
//============================================================
// Locates a private key on the token on basis of its CKA_ID attribute.
// hSession - card session handle
// idData - id value
// idLen - length of id value
// hKey - address of key handle to be returned
// return objects handle or -1 for failure
//============================================================
CK_RV LocatePrivateKeyWithId(CK_SESSION_HANDLE hSession, CK_BYTE_PTR idData, CK_ULONG idLen, CK_OBJECT_HANDLE_PTR hKey)
{
    CK_OBJECT_HANDLE Objects[10];
    CK_RV rv;
    CK_ULONG ulObjectCount = sizeof(Objects)/sizeof(CK_OBJECT_HANDLE), i;
    CK_OBJECT_CLASS ObjClass = CKO_PRIVATE_KEY;
    CK_ATTRIBUTE Template1[] = {
      { CKA_CLASS,   &ObjClass,  sizeof(ObjClass)    },
      { CKA_ID,      (void*)idData,	idLen }
    };	
    CK_ULONG ulCount = sizeof(Template1) / sizeof(CK_ATTRIBUTE);
	char buf2[40];
    int  l2;
    
	l2 = sizeof(buf2);
    bin2hex((const byte*)idData, idLen, (char*)buf2, &l2);
    ddocDebug(3, "LocatePrivateKeyWithId", "LocatePrivateKey with id: %s", buf2);
    //Template1[1].pValue = idData;
    rv = (*ckFunc->C_FindObjectsInit)(hSession, Template1, ulCount);
    if(rv==CKR_OK) {
      // Get list of object handles
      rv = (*ckFunc->C_FindObjects)(hSession,Objects,ulObjectCount, &ulObjectCount);
      ddocDebug(3, "LocatePrivateKeyWithId", "Find: %d count: %ld", rv, ulObjectCount);
      if(rv==CKR_OK) {
	// get labels of all possible private keys
	for(i = 0; i < ulObjectCount; i++) {
	  ddocDebug(3, "LocatePrivateKeyWithId", "Key handle: %d", Objects[i]);
      *hKey = Objects[i];
	} // for i < ulObjectsCount
      }
    }
    // Remember to call C_FindObjectsFinal to terminate the search
    rv = (*ckFunc->C_FindObjectsFinal)(hSession);
    return rv;  
}
Exemple #4
0
//============================================================
// Loads the PKCS#11 driver and
// tests if the driver loaded correctly
// Returns 0 for ok otherwise error code
//============================================================
int loadAndTestDriver(const char* driver, LIBHANDLE* pLibrary, CK_SLOT_ID* slotids, int slots, CK_ULONG slot)
{
  CK_TOKEN_INFO tokinfo;   
  CK_SLOT_INFO slotinfo;
  CK_ULONG idlen, i, ok;
  CK_RV rv;
  int err = ERR_OK;
	
  // initialize
  *pLibrary = NULL;
  memset(slotids, 0, sizeof(CK_SLOT_ID) * slots);
  // try to load the driver
  *pLibrary = initPKCS11Library(driver);
  if(!(*pLibrary))
    SET_LAST_ERROR_RETURN_CODE(ERR_PKCS_LIB_LOAD);    
  idlen = slots;
  rv = GetSlotIds(slotids, &idlen);
  ddocDebug(3, "loadAndTestDriver", "RV: %d slots: %ld", (int)rv, (long)idlen);
  if (rv != CKR_OK) {
    err = ERR_PKCS_SLOT_LIST;
    SET_LAST_ERROR(err);
  }
  if ((slot < 0) || (slot >= idlen)) {
    err = ERR_PKCS_WRONG_SLOT;
    SET_LAST_ERROR(err);
  }
  // it's useful to test DLL load status this way:
  ok = 0;
  for(i = 0; i < idlen; i++) {
    rv = GetSlotInfo(&slotinfo, slotids[i]);
    if(slotinfo.flags & CKF_TOKEN_PRESENT) {
      ddocDebug(3, "loadAndTestDriver", "Read Token: %ld", (long)i);
      rv = GetTokenInfo(&tokinfo, slotids[i]); // if !CKR_OK test
      tokinfo.label[31] = 0;
      ddocDebug(3, "loadAndTestDriver", "RV: %d Token: %s", (int)rv, tokinfo.label);
      if(rv != CKR_OK)
	slotids[i] = INVALID_SLOTIID; // set bad slotids to 0
      else
	ok++; // count the good slots
    } else {
      slotids[i] = INVALID_SLOTIID; // no tokne in this slot
    }
  }
  // fill other slotid's with invalid slotid
  for(i = idlen; i < (CK_ULONG)slots; i++)
    slotids[i] = INVALID_SLOTIID;
  if(ok < slot) {
    err = ERR_PKCS_CARD_READ; // if not enough good slots
    SET_LAST_ERROR(err);
  }
  // in case of error try to unload the module and notify caller
  if (err) {
    if (*pLibrary)
      closePKCS11Library(*pLibrary, 0);
    *pLibrary = NULL;
  }
  return err;
}
Exemple #5
0
//--------------------------------------------------
// Prepares a new signature for signing and calculates
// the final hash value to sign.
// pSigDoc - signed document object
// ppSigInfo - pointer for address of newly allocated signature
// manifest - manifest or role
// city - signers address , city
// state - signers address , state or province
// zip - signers address , postal code
// country - signers address , country name
// id - id for new signature. Optional, use NULL for default
// return returns error code or ERR_OK
//--------------------------------------------------
EXP_OPTION int ddocPrepareSignature(SignedDoc* pSigDoc, SignatureInfo** ppSigInfo,
                                    const char* manifest, const char* city,
                                    const char* state, const char* zip,
                                    const char* country, X509* pCert, const char* id)
{
    int err = ERR_OK, l1;
    DigiDocMemBuf mbuf1, *pMBuf1;
    char buf1[50];

    mbuf1.pMem = 0;
    mbuf1.nLen = 0;
    ddocDebug(3, "ddocPrepareSignature", "Preparing signature manifest: %s country: %s, state: %s, city: %s, zip: %s, cert: %s, id: %s",
              (manifest ? manifest : "NULL"), (country ? country : "NULL"),
              (state ? state : "NULL"), (city ? city : "NULL"), (zip ? zip : "NULL"),
              (pCert ? "OK" : "ERROR"), (id ? id : "NULL"));
    // check mandator fields
    RETURN_IF_NULL_PARAM(pSigDoc);
    RETURN_IF_NULL_PARAM(ppSigInfo);
    RETURN_IF_NULL_PARAM(pCert);
    clearErrors();
    // add new signature
    err = SignatureInfo_new(ppSigInfo, pSigDoc, id);
    RETURN_IF_NOT(err == ERR_OK, err);
    // automatically calculate doc-info elements for this signature
    addAllDocInfos(pSigDoc, *ppSigInfo);
    // add signature production place
    if (city || state || zip || country)
        err = setSignatureProductionPlace(*ppSigInfo, city, state, zip, country);
    // add user roles/manifests
    if (manifest)
        err = addSignerRole(*ppSigInfo, 0, manifest, -1, 0);
    RETURN_IF_NOT(err == ERR_OK, err);
    // add signers certificate
    err = setSignatureCert(*ppSigInfo, pCert);
    RETURN_IF_NOT(err == ERR_OK, err);
    // timestamp
    createTimestamp(pSigDoc, (char*)buf1, sizeof(buf1));
    setString((char**)&((*ppSigInfo)->szTimeStamp), (const char*)buf1, -1);
    // now calculate signed properties digest
    err = calculateSignedPropertiesDigest(pSigDoc, *ppSigInfo);
    // TODO: replace later
    pMBuf1 = ddocDigestValue_GetDigestValue((*ppSigInfo)->pSigPropDigest);
    ddocSigInfo_SetSigPropRealDigest(*ppSigInfo,
                                     (const char*)pMBuf1->pMem, pMBuf1->nLen);
    // signature type & val
    ddocSignatureValue_new(&((*ppSigInfo)->pSigValue), 0, SIGN_RSA_NAME, 0, 0);
    // calc signed-info digest
    l1 = sizeof(buf1);
    err = calculateSignedInfoDigest(pSigDoc, *ppSigInfo, (byte*)buf1, &l1);
    err = ddocSigInfo_SetSigInfoRealDigest(*ppSigInfo, buf1, l1);
    // debug output - final hash to sign
    pMBuf1 = ddocDigestValue_GetDigestValue((*ppSigInfo)->pSigInfoRealDigest);
    ddocEncodeBase64(pMBuf1, &mbuf1);
    ddocDebug(3, "ddocPrepareSignature", "signing hash %s len: %d b64len: %d",
              (char*)mbuf1.pMem, mbuf1.nLen, l1);
    ddocMemBuf_free(&mbuf1);
    return err;
}
Exemple #6
0
//============================================================
// Locates a private key on the token on basis of its CKA_LABEL attribute.
// hSession - card session handle
// idData - address of an array of label buffers
// idlen - array of label lengths
// return objects handle or -1 for failure
//============================================================
CK_RV LocatePrivateKey(CK_SESSION_HANDLE hSession, char idData[20][20], CK_ULONG idLen[20], CK_OBJECT_HANDLE_PTR hKeys)
{
    CK_OBJECT_HANDLE Objects[10];
    CK_RV rv;
    CK_ULONG ulObjectCount = sizeof(Objects)/sizeof(CK_OBJECT_HANDLE), i;
    // CK_BBOOL IsTrue = TRUE;
    CK_OBJECT_HANDLE hPrivateKey = CK_INVALID_HANDLE;
    // Set up a template to search for all Private Key tokens 
    // Given the session context, that is associated with
    // one slot we will find only one object
    CK_OBJECT_CLASS ObjClass = CKO_PRIVATE_KEY;
    char buf1[20];
    CK_ATTRIBUTE Template1[] = {
      { CKA_CLASS,            &ObjClass,  sizeof(ObjClass)    }
    };	
    CK_ATTRIBUTE Template2[] = {
      { CKA_ID,      (void*)0,	idLen[0] }
    };
    CK_ULONG ulCount = sizeof(Template1) / sizeof(CK_ATTRIBUTE);
	
    /*
    ** Initiate the object search
    C_FindObjectsInit initializes a search for token and session objects that match a template.
    hSession is the sessions handle; pTemplate points to a search template that specifies the
    attribute values to match; ulCount is the number of attributes in the search template. The
    matching criterion is an exact byte-for-byte match with all attributes in the template. 
    To find all objects, set ulCount to 0.
    */
    ddocDebug(3, "LocatePrivateKey", "LocatePrivateKey");
    rv = (*ckFunc->C_FindObjectsInit)(hSession,Template1,ulCount);
    if(rv==CKR_OK) {
      // Get list of object handles
      rv = (*ckFunc->C_FindObjects)(hSession,Objects,ulObjectCount, &ulObjectCount);
      ddocDebug(3, "LocatePrivateKey", "Find: %d count: %ld", rv, ulObjectCount);
      if(rv==CKR_OK) {
	// get labels of all possible private keys
	for(i = 0; i < ulObjectCount; i++) {
	  hKeys[i] = Objects[i];
	  ulCount = sizeof(Template2) / sizeof(CK_ATTRIBUTE);
	  // get key id length
	  rv = (*ckFunc->C_GetAttributeValue)(hSession, hKeys[i], Template2, ulCount);
	  if(rv == CKR_OK) {
	    idLen[i] = Template2[0].ulValueLen;
	    // now get key id data
	    Template2[0].pValue = buf1;
	    memset(buf1, 0, sizeof(buf1));
	    rv = (*ckFunc->C_GetAttributeValue)(hSession, hKeys[i], Template2, ulCount);
	    ddocDebug(3, "LocatePrivateKey", "key: %d id %s len: %ld", i, buf1, idLen[i]);
	    memcpy(idData[i], buf1, idLen[i]);
	  }
	} // for i < ulObjectsCount
      }
    }
    // Remember to call C_FindObjectsFinal to terminate the search
    rv = (*ckFunc->C_FindObjectsFinal)(hSession);
    return rv;  
}
Exemple #7
0
//============================================================
// Locates and reads users certificate from smartcard
// slot - number of the slot for decryption key. On ID card allways 0
// ppCert - address for newly allocated certificate pointer
// return error code or ERR_OK
//============================================================
EXP_OPTION int findUsersCertificate(int slot, X509** ppCert)
{
  int err = ERR_OK, l1, l2;
  LIBHANDLE pLibrary = 0;
  CK_RV rv = 0;
  CK_SLOT_ID slotids[20], slId;
  CK_OBJECT_HANDLE hCert;
  CK_SESSION_HANDLE hSession = 0;
  CK_ULONG certLen;
  CK_BYTE certData[2048];
  char driver[100];


  *ppCert = 0;
  snprintf(driver, sizeof(driver), "DIGIDOC_DRIVER_%d_FILE", ConfigItem_lookup_int("DIGIDOC_DEFAULT_DRIVER", 1));
  ddocDebug(3, "findUsersCertificate", "Slot: %d Driver nr: %d - %s", slot,
	    ConfigItem_lookup_int("DIGIDOC_DEFAULT_DRIVER", 1),
	    ConfigItem_lookup(driver));
  err = loadAndTestDriver(ConfigItem_lookup(driver), 
			  &pLibrary, (CK_SLOT_ID*)slotids, 20, (CK_ULONG)slot);
  if(err) return err;

  // find the right slotid
  for(l1 = l2 = 0; l1 < 20; l1++) {
    if(slotids[l1] != INVALID_SLOTIID) {
      if(l2 == slot)
	slId = slotids[l1];
      l2++;
    }
  }
  // open session
  hSession = OpenSession(slId, NULL);
  if (hSession == CK_INVALID_HANDLE) { SET_LAST_ERROR(ERR_PKCS_LOGIN); return ERR_PKCS_LOGIN; }
  ddocDebug(3, "findUsersCertificate", "OpenSession ok, hSession = %d", (int)hSession);
  
  // get cert
  memset(certData, 0, sizeof(certData));  
  certLen = sizeof(certData);
  hCert = LocateCertificate(hSession, certData, &certLen, 0, 0, 0);
  ddocDebug(3, "findUsersCertificate", "hCert = %d, len: %d", (int)hCert, certLen);
  if (hCert == (CK_OBJECT_HANDLE)-1) { err = ERR_PKCS_CERT_LOC; SET_LAST_ERROR(err); }

  // set cert data
  if(certLen)
    err = ddocDecodeX509Data(ppCert, certData, certLen);

  
  ddocDebug(3, "findUsersCertificate", "RV: %d, cert: %s", (int)rv, (*ppCert ? "OK" : "NULL"));
  if(hSession)
    closePKCS11Library(pLibrary, hSession);

  return err;
}
Exemple #8
0
//--------------------------------------------------
// Helper function to read OCSP_RESPONSE from binary input data
// ppResp - address of newly allocated OCSP_RESPONSE object
// pMBufInData - input data
// returns error code or ERR_OK
//--------------------------------------------------
int ddocOcspReadOcspResp(OCSP_RESPONSE** ppResp, DigiDocMemBuf* pMBufInData)
{
  int err = ERR_OK;
  unsigned char* p1;

  RETURN_IF_NULL_PARAM(ppResp);
  RETURN_IF_NULL_PARAM(pMBufInData);
  RETURN_IF_NULL_PARAM(pMBufInData->pMem);
  ddocDebug(4, "ddocOcspReadOcspResp", "converting: %d bytes to OCSP_RESPONSE", pMBufInData->nLen);
  p1 = (unsigned char*)pMBufInData->pMem;
  d2i_OCSP_RESPONSE(ppResp, (const unsigned char**)&p1, pMBufInData->nLen);
  ddocDebug(4, "ddocOcspReadOcspResp", "OCSP_RESPONSE: %s", (*ppResp ? "OK" : "ERR"));
  return err;
}
Exemple #9
0
//============================================================
// Decodes base64 (PEM) OCSP_RESPONSE data and returns a OCSP_RESPONSE object
// ppResp - pointer to a buffer to receive newly allocated OCSP_RESPONSE pointer
// data - (PEM) OCSP_RESPONSE data
// len - length of data in bytes
//============================================================
EXP_OPTION int ddocDecodeOCSPResponsePEMData(OCSP_RESPONSE **ppResp, const byte* data, int len)
{
  byte* p1 = 0;
  int l1 = 0, err = ERR_OK;

  // check input params
  RETURN_IF_NULL_PARAM(data);
  RETURN_IF_NULL_PARAM(ppResp);
  // mark as not read yet
  *ppResp = 0;
  // allocate memory for decoding
  l1 = len; // should be enough as it shrinks
  p1 = (byte*)malloc(l1);
  RETURN_IF_BAD_ALLOC(p1);
  memset(p1, 0, l1);
  // decode base64 data
  decode((const byte*)data, len, p1, &l1);
  // decode OCSP
  err = ddocDecodeOCSPResponseData(ppResp, p1, l1);
  // cleanup
  if(p1)
	  free(p1);
  ddocDebug(3, "ddocDecodeOCSPResponsePEMData", "Decoding %d bytes PEM data - OSCP_RESPONSE %s", len, (*ppResp ? "OK" : "ERROR"));
  return err;
}
Exemple #10
0
//--------------------------------------------------
// Converts xml symbols to corresponding escapes
// src - string with xml special sybols
// returns string with esacpes
//--------------------------------------------------
char* escape2xmlsym(const char* src)
{
    char* dest = 0, c;
    int i, j, l, k;

    l = strlen(src);
    dest = (char*)malloc(l+1);
    SET_LAST_ERROR_RETURN_IF_NOT(dest, ERR_BAD_ALLOC, NULL);
    memset(dest, 0, l+1);
    for(i = j = 0; i < l; i++, j++) {
        if(src[i] == '&') {
            k = findEscape(src + i, &c);
            if(k && c) {
                dest[j] = c;
                i += k - 1;
            }
            else
                dest[j] = src[i];
        }
        else
            dest[j] = src[i];
    }
    ddocDebug(4, "escape2xmlsym", "%s --> %s", src, dest);
    return dest;
}
Exemple #11
0
//============================================================
// Attempts to load and initialize on PKCS#11 driver DLL.
//============================================================
EXP_OPTION LIBHANDLE initPKCS11Library(const char* libName) 
{	
  LIBHANDLE pLibrary = 0;
  CK_C_GetFunctionList pC_GetFunctionList;
  CK_RV rv;

  // load PKCS#11 driver
  ddocDebug(3, "initPKCS11Library", "Loading driver: %s\n", libName);
#ifdef WIN32
  pLibrary = LoadLibrary((LPCSTR)libName);
#else
  pLibrary = dlopen(libName, RTLD_NOW);
#endif
  if(pLibrary != NULL) {
    // printf("Resolve PKCS#11 function index!\n");
    // Get function pointer to C_GetFunctionList
#ifdef WIN32
    pC_GetFunctionList = (CK_C_GetFunctionList)GetProcAddress(/*(HINSTANCE__*)*/pLibrary, "C_GetFunctionList");
#else
    pC_GetFunctionList = (CK_C_GetFunctionList)dlsym(pLibrary, "C_GetFunctionList");
#endif
    if(pC_GetFunctionList != NULL) {
      ddocDebug(3, "initPKCS11Library", "Getting PKCS#11 func!\n");
      // Get function pointers to all PKCS #11 functions
      rv = (*pC_GetFunctionList)(&ckFunc);
      if(rv == CKR_OK) {
	ddocDebug(3, "initPKCS11Library", "Initializing PKCS#11 library:");
	// Initalize Cryptoki
	rv = (*ckFunc->C_Initialize)(0);
	ddocDebug(3, "initPKCS11Library", "Initlialized: %d", (int)rv);
	if(rv != CKR_OK) {
	  ddocDebug(2, "initPKCS11Library", "Error initializing library!\n");
	  pLibrary = NULL;  // error initializing the library 
	}
      } else {
	ddocDebug(2, "initPKCS11Library", "Error getting PKCS#11 func!");
	pLibrary = NULL;  // error getting function pointers
      }
    } else {
      ddocDebug(2, "initPKCS11Library", "Error resolving PKCS#11 function index!");
      pLibrary = NULL;  // error getting function list function
    }
  } else {
#ifdef WIN32
    ddocDebug(2, "initPKCS11Library", "Error loading driver : %s", libName);
#else
    ddocDebug(2, "initPKCS11Library", "Error loading driver : %s", dlerror());
#endif
  }
  return pLibrary;
}
Exemple #12
0
//============================================================
// Cleanup PKCS#11 library session
//============================================================
EXP_OPTION void closePKCS11Library(LIBHANDLE pLibrary, CK_SESSION_HANDLE hSession)
{
  CK_RV rv;

  // close session
  if(hSession > 0) {
    ddocDebug(3, "closePKCS11Library", "Closing PKCS#11 session!");
    rv = (*ckFunc->C_CloseSession)(hSession);
  }
  // finalize library
  rv = (*ckFunc->C_Finalize)(0);
  // remove .so from memory
  ddocDebug(3, "closePKCS11Library", "Closing PKCS#11 library!\n");
  if(pLibrary)
#ifdef WIN32
    FreeLibrary(/*(HINSTANCE__*)*/pLibrary);
#else
  dlclose(pLibrary);
#endif
}
Exemple #13
0
//--------------------------------------------------
// Helper function to write OCSP_RESPONSE to binary output data
// pResp - address of OCSP_RESPONSE object
// pMBufOutData - output data
// returns error code or ERR_OK
//--------------------------------------------------
int ddocOcspWriteOcspResp(OCSP_RESPONSE* pResp, DigiDocMemBuf* pMBufOutData)
{
  int err = ERR_OK, l1;
  unsigned char* p1;

  RETURN_IF_NULL_PARAM(pResp);
  RETURN_IF_NULL_PARAM(pMBufOutData);
  pMBufOutData->pMem = NULL;
  pMBufOutData->nLen = 0;
  // find out how big a buffer we need
  l1 = i2d_OCSP_RESPONSE(pResp, NULL);
  ddocDebug(4, "ddocOcspReadOcspResp", "converting: %d bytes from OCSP_RESPONSE", l1);
  // alloc mem
  err = ddocMemSetLength(pMBufOutData, l1 + 50);  
  p1 = (unsigned char*)pMBufOutData->pMem;
  l1 = i2d_OCSP_RESPONSE(pResp, &p1);
  pMBufOutData->nLen = l1;
  ddocDebug(4, "ddocOcspReadOcspResp", "Converted data: %d", l1);
  return err;
}
Exemple #14
0
//============================================================
// Sign a string using a private key referred by the supplied handle.
// hSession - card session handle
// hPrivateKey - private key handle
// Signature - buffer for signature
// ulSignatureLen - signature buffer length
// sigData - data to be  signed
//============================================================
CK_RV SignData(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hPrivateKey, 
			  CK_BYTE* Signature, CK_ULONG* ulSignatureLen, 
			  CK_BYTE* sigData, CK_ULONG dataLen)
{
  // Set up mechanism for PKCS #1 signing
  CK_MECHANISM Mechanism = { CKM_RSA_PKCS, 0, 0 };
  // Initiate the signature operation
  CK_RV rv = (*ckFunc->C_SignInit)(hSession,&Mechanism,hPrivateKey);
  if(rv == CKR_OK) {
    // Kommentaar: Realiseeritud meetodi CKM_RSA_PKCS jaoks.
    rv = (*ckFunc->C_Sign)(hSession, sigData, dataLen, 
			   Signature, ulSignatureLen);
    if(rv != CKR_OK)
      ddocDebug(1, "SignData", "Error signing - sess: %uld pkey: %uld slen: %uld dlen: %uld. RV = %uld\n", 
		hSession, hPrivateKey, ulSignatureLen, dataLen, rv);
  } // if C_SignInit
  else
    ddocDebug(1, "SignData", "Error initing sign session. RV = %ld", rv);
  ddocDebug(3, "SignData", "RV = %ld", rv);
  return rv;
}
Exemple #15
0
//--------------------------------------------------
// Decodes a single hex digit
// h - hex digit
// return binary value
//--------------------------------------------------
byte h2b(char h)
{
    int i;
    for(i = 0; i < 16; i++) {
        if(g_hexChars[i] == h || g_hexChars[i] == toupper(h))
            return (byte)i;
    }
    // if not found then return an error
    ddocDebug(1, "h2b", "Invalid hex byte: %c", h);
    SET_LAST_ERROR(ERR_BAD_PARAM);
    return 0; // MSTERN: incorrect, VS - yes return -1 if not found. This is an error code
}
Exemple #16
0
//============================================================
// Opens smart card session.
// slotId - id of the sert slot
// pin - card pin
// return session id or -1 for failure
//============================================================
CK_SESSION_HANDLE OpenSession(CK_SLOT_ID slotId, const char *pin)
{ 
  CK_SESSION_HANDLE hSession = 0;
  /*
    Ainult SERIAL_SESSION toetatud, Digiallkirja andvat privaatvo~tit kasutav sessioon
    on initsialiseeritud CKS_RO_USER_FUNCTIONS staatusesse, seda on tehtud Netscape lolli-
    tamiseks, et see igal vo~imalikul ja vo~imatul juhul ei ku"siks pin'i vo~tme jaoks
    mida ta niiehknii kasutada ei oska. Selle jaoks tuleb vajaduse korral ikka C_Login 
    va"lja kutsuda.
  */
  CK_RV rv = (*ckFunc->C_OpenSession)(slotId, CKF_SERIAL_SESSION,0,0,&hSession);
  ddocDebug(3, "OpenSession", "Open sess for slot id: %u - sess: %uld RV = %u", slotId, hSession, rv);
  if(rv == CKR_OK && pin) { // don't login if pin is null. Session can be used also to read certs.
    /* Kommentaar:  	Ainult CKU_USER toetatud. */
    rv = (*ckFunc->C_Login)(hSession, CKU_USER, (unsigned char*)pin, strlen(pin));
    ddocDebug(3, "OpenSession", "Login for slot id: %u - sess: %uld RV = %u", slotId, hSession, rv);
    if(rv != CKR_OK)
      hSession = CK_INVALID_HANDLE; // mark session bad!
  }
  // Return the session handle and exit
  return hSession;
}
Exemple #17
0
//////////////////////////////////////////////////////////
//      DigiDoc file handling methods
//AA 2004/05/20 - ei saanud salvestada faili, kui kataloogis olid täppidega tähed
STDMETHODIMP CComSignedDoc::createSignedDoc(BSTR szOutputFile, BSTR szOldFileName, long *pRetError)
{
	USES_CONVERSION;
	char *p1 = 0;

	if(m_pSignedDoc) {
		p1 = GetBSTR(szOutputFile);
		ddocDebug(3, "CComSignedDoc::createSignedDoc", "Writing to: %s", p1);
		*pRetError = ::createSignedDoc(m_pSignedDoc, 
			(::SysStringLen(szOldFileName) > 0) ? GetBSTR(szOldFileName) : NULL, p1);
		ddocDebug(3, "CComSignedDoc::createSignedDoc", "Wrote");
		if(m_szDigiDocFile) {
			ddocDebug(3, "CComSignedDoc::createSignedDoc", "Free: %s", m_szDigiDocFile);
		
			free(m_szDigiDocFile);
			m_szDigiDocFile = 0;
		}
		ddocDebug(3, "CComSignedDoc::createSignedDoc", "Assign: %s", p1);
		
		m_szDigiDocFile = strdup(p1);
	}
	return S_OK;
}
Exemple #18
0
//============================================================
// Decodes binary (DER) OCSP_RESPONSE data and returns a OCSP_RESPONSE object
// ppResp - pointer to a buffer to receive newly allocated OCSP_RESPONSE pointer
// data - (DER) OCSP_RESPONSE data
// len - length of data in bytes
//============================================================
EXP_OPTION int ddocDecodeOCSPResponseData(OCSP_RESPONSE **ppResp, const byte* data, int len)
{
  BIO* b1 = 0;

  // check input params
  RETURN_IF_NULL_PARAM(data);
  RETURN_IF_NULL_PARAM(ppResp);
  // mark as not read yet
  *ppResp = 0;
  // create BIO
  b1 = BIO_new_mem_buf((void*)data, len);
  RETURN_IF_NOT(b1, ERR_NULL_POINTER);
  // decode OCSP
  *ppResp = d2i_OCSP_RESPONSE_bio(b1, NULL);
  BIO_free(b1);
  ddocDebug(3, "ddocDecodeOCSPResponseData", "Decoding %d bytes DER data - OCSP_RESPONSE %s", len, (*ppResp ? "OK" : "ERROR"));
  RETURN_IF_NOT(*ppResp, ERR_OCSP_UNKNOWN_TYPE);
  return ERR_OK;
}
Exemple #19
0
EXP_OPTION void addError(int code, char *fileName, int line, char *assertion)
{
  //no errors found yet. Set a trace-back mark to the end of array.
  //printf("Error : %d at %s line %d, assertion %s\n", code, fileName, line, assertion);

  ThreadErrors	*threadErrors;
  THREAD_ID Tid = getTid();		//Find our identity

  threadErrors = findThreadErrorsByTid(Tid);
  //	printf("addError init: tid=%ld, threadErrors=%p\n", Tid, threadErrors);
  if (threadErrors == NULL) {	//This Tid has no entry in ThreadErrors table
    threadErrors = addThreadErrorsByTid(Tid);  // MEMLEAK:  ???
    if (threadErrors == NULL)
      return;				// What else can we do?
  }
	
  // printf("addError step 1 : tid=%ld, threadErrors=%p\n", Tid, threadErrors);
  if(threadErrors->currentErrorIdx < 0)
    resetError(&(threadErrors->ddocLastErrors[ERROR_BUF_LENGTH - 1]));

  threadErrors->currentErrorIdx++;

  //index at the end -> roll it over to the beginning
  if(threadErrors->currentErrorIdx == ERROR_BUF_LENGTH)
    threadErrors->currentErrorIdx = 0;

  //set the information
  ddocDebug(4, "addError", "Index: %d Error : %d at %s line %d, assertion %s", threadErrors->currentErrorIdx, code, fileName, line, assertion);
  threadErrors->ddocLastErrors[threadErrors->currentErrorIdx].code = code;
  threadErrors->ddocLastErrors[threadErrors->currentErrorIdx].fileName = fileName;
  threadErrors->ddocLastErrors[threadErrors->currentErrorIdx].line = line;
  threadErrors->ddocLastErrors[threadErrors->currentErrorIdx].assertion = assertion;

  //index at the end? Set the traceback mark to the beginning
  if(threadErrors->currentErrorIdx == ERROR_BUF_LENGTH - 1)
    resetError(&(threadErrors->ddocLastErrors[0]));
  else //set the traceback mark to the next position
    resetError(&(threadErrors->ddocLastErrors[threadErrors->currentErrorIdx + 1]));

  threadErrors->readErrorIdx = threadErrors->currentErrorIdx;
}
//--------------------------------------------------
// Reads in signed XML document and extracts the desired data file
// pSigDoc - signed document object if exists. Can be NULL
// szFileName - digidoc filename
// szDataFileName - name of the file where to store embedded data.
// szDocId - DataFile Id atribute value
// szCharset - convert DataFile content to charset
//--------------------------------------------------
EXP_OPTION int ddocExtractDataFile(SignedDoc* pSigDoc, const char* szFileName,
                                   const char* szDataFileName, const char* szDocId,
                                   const char* szCharset)
{
    FILE *fIn = 0, *fOut = 0;
    int err = ERR_OK, i, nRead, lt, la, lc, j, ld, lb, l, eState = 0, fs = 0;
    long len, lExtr = 0, lSize = 0;
    char chars[1050], tag[100], attr[100], con[1030], dec[70], b64line[70];
    unsigned char b64 = 0, nNc = 0, bFound = 0;
    void *pBuf;
    EVP_ENCODE_CTX ectx;
#ifdef WIN32
    wchar_t *convFileName = 0, *convDataFileName = 0;
    i= 0;
    err = utf82unicode((const char*)szFileName, (char**)&convFileName, &i);
    ddocDebug(3, "ddocExtractDataFile", "file: %s, conv-file: %s len: %d", szFileName, convFileName, i);
    i= 0;
    err = utf82unicode((const char*)szDataFileName, (char**)&convDataFileName, &i);
    ddocDebug(3, "ddocExtractDataFile", "dfile: %s, conv-dfile: %s len: %d", szDataFileName, convDataFileName, i);
#endif

    RETURN_IF_NULL_PARAM(szFileName);
    RETURN_IF_NULL_PARAM(szDataFileName);
    RETURN_IF_NULL_PARAM(szDocId);
    RETURN_IF_NULL_PARAM(szCharset);
    clearErrors();
    ddocDebug(3, "ddocExtractDataFile", "SigDoc: %s, docid: %s, digidoc: %s, file: %s, charset: %s", (pSigDoc ? "OK" : "NULL"), szDocId, szFileName, szDataFileName, szCharset);
    if(szCharset && !strcmp(szCharset, "NO-CHANGE"))
        nNc = 1;
    // try reading from memory if already cached?
    nRead = ddocGetDataFileCachedData(pSigDoc, szDocId, &pBuf, &len);
    if(pBuf) { // gotcha
        ddocDebug(3, "ddocSaxExtractDataFile", "Using cached data: %d bytes", len);
#ifdef WIN32
        if((fOut = _wfopen(convDataFileName, L"wb")) != NULL) {
#else
        if((fOut = fopen(szDataFileName, "wb")) != NULL) {
#endif
            fwrite(pBuf, 1, len, fOut);
            fclose(fOut);
        } else {
            free(pBuf);
            ddocDebug(1, "ddocSaxExtractDataFile", "Error writing file: %s", szDataFileName);
            SET_LAST_ERROR_RETURN_CODE(ERR_FILE_WRITE);
        }
        free(pBuf);
        return nRead;
    }
    // open ddoc file
#ifdef WIN32
    if((fIn = _wfopen(convFileName, L"rb")) != NULL) {
#else
    if((fIn = fopen(szFileName, "rb")) != NULL) {
#endif
        ddocDebug(3, "ddocExtractDataFile", "Opened ddoc-file: %s", szFileName);
        do {
            nRead = fread(chars, 1, 1024, fIn);
            chars[nRead] = 0;
            ddocDebug(6, "ddocExtractDataFile", "Parsing %d bytes: \n%s\n", nRead, chars);
            // handle read data
            for(i = 0; i < nRead; i++) {
                switch(eState) {
                case ST_START: // search '<?xml'
                    if(chars[i] == '<' &&
                            !strncmp(chars+i, "<?xml", 5)) {
                        eState = ST_XML;
                        i += 4;
                    }
                    break;
                case ST_XML: // search '<'
                    if(chars[i] == '<') {
                        eState = ST_TAG_NM;
                        lt = 0;
                        tag[lt] = 0;
                    }
                    break;
                case ST_TAG_NM: // read tag name
                    if(isalnum(chars[i]) || chars[i] == ':' || chars[i] == '/') {
                        if(lt < sizeof(tag)-1) {
                            tag[lt] = chars[i];
                            tag[++lt] = 0;
                        } else {
                            ddocDebug(1, "ddocSaxExtractDataFile", "Invalid xml tag-len > %d", sizeof(tag));
                            SET_LAST_ERROR_RETURN_CODE(ERR_FILE_READ);
                        }
                    } else if(chars[i] == '>') { // tag ended - content
                        eState = ST_CON;
                    } else { // expecting atributes
                        eState = ST_TAG_WS;
                    }
                    break;
                case ST_TAG_WS:
                    if(chars[i] == '>') {
                        if(bFound) {
                            eState = ST_DF_CON;
                            if(b64)
                                EVP_DecodeInit(&ectx);
                        } else
                            eState = ST_CON; // tag endded - content
                        lc = 0;
                        con[lc] = 0;
                    } else if(isalnum(chars[i])) {
                        eState = ST_ATTR_NM; // attr name started
                        la = 0;
                        attr[la] = chars[i];
                        attr[++la] = 0;
                    }
                    break;
                case ST_ATTR_NM:
                    if(isalnum(chars[i])) {
                        if(la < (int)sizeof(attr)-1) {
                            attr[la] = chars[i];
                            attr[++la] = 0;
                        }
                        else
                            ddocDebug(1, "ddocExtractDataFile", "Truncating attr name: %s", attr);
                        break;
                        //19.11.08 added support for '
                    } else if(chars[i] == '\"'/*|| chars[i] == '\''*/) {
                        eState = ST_ATTR_CON;
                        lc = 0;
                        con[lc] = 0;
                        fs = 2;
                    } else if(chars[i] == '\'' && fs==0) {
                        eState = ST_ATTR_CON;
                        lc = 0;
                        con[lc] = 0;
                        fs = 1;
                    } else {
                        eState = ST_ATTR_WS;
                    }
                    break;
                case ST_ATTR_WS:
                    //19.11.08 added support for '
                    if(chars[i] == '\"'/*|| chars[i] == '\''*/) {
                        eState = ST_ATTR_CON;
                        lc = 0;
                        con[lc] = 0;
                    } else if(chars[i] == '\'' && fs==1)  {
                        eState = ST_ATTR_CON;
                        lc = 0;
                        con[lc] = 0;
                    } else {
                        eState = ST_TAG_WS;
                    }
                    break;
                case ST_ATTR_CON:
                    //19.11.08 added support for '
                    if(chars[i] != '\"' /*&& chars[i] != '\''*/) {
                        if(lc < (int)sizeof(con)-1) {
                            con[lc] = chars[i];
                            con[++lc] = 0;
                        } else
                            ddocDebug(1, "ddocExtractDataFile", "Truncating attr content: %s", attr);
                    } else if(chars[i] == '\'' && fs==1)  {
                        if(lc < (int)sizeof(con)-1) {
                            con[lc] = chars[i];
                            con[++lc] = 0;
                        } else
                            ddocDebug(1, "ddocExtractDataFile", "Truncating attr content: %s", attr);
                    } else {
                        eState = ST_TAG_WS;
                        // attribute value complete
                        if(!strcmp(tag, "DataFile")) {
                            //	ddocDebug(3, "ddocSaxExtractDataFile", "DataFile start, attr: %s", attr);
                            if(!strcmp(attr, "ContentType")) {
                                b64 = (!strcmp(con, "EMBEDDED_BASE64")) ? 1 : 0;
                                lb = 0;
                                b64line[0] = 0;
                            }
                            if(!strcmp(attr, "Size") && bFound) {
                                lSize = atol(con);
                            }
                            if(!strcmp(attr, "Id")) {
                                ddocDebug(3, "ddocSaxExtractDataFile", "Found Id: %s searching id: %s", con, szDocId);
                                if(!strcmp(con, szDocId)) {
                                    bFound = 1;
#ifdef WIN32
                                    fOut = _wfopen(convDataFileName, L"wb");
                                    ddocDebug(3, "ddocSaxExtractDataFile", "Opening file: %s handle: %s", convDataFileName, (fOut ? "OK" : "NULL"));
#else
                                    fOut = fopen(szDataFileName, "wb");
                                    ddocDebug(3, "ddocSaxExtractDataFile", "Opening file: %s handle: %s", szDataFileName, (fOut ? "OK" : "NULL"));
#endif
                                    if(!fOut) {
                                        SET_LAST_ERROR(ERR_FILE_WRITE);
                                        err = ERR_FILE_WRITE;
                                        return err;
                                    }
                                }
                            }
                        }
                    }
                    break;
                case ST_CON:
                    if(chars[i] == '<') {
                        eState = ST_TAG_NM;
                        lt = 0;
                        tag[lt] = 0;
                    } else {
                        //con[lc] = chars[i];
                        //con[++lc] = 0;
                    }
                    break;
                case ST_DF_START: // find tag end
                    if(chars[i] == '>') {
                        eState = ST_DF_CON;
                        lc = 0;
                        con[lc] = 0;
                        if(b64)
                            EVP_DecodeInit(&ectx);
                    }
                    break;
                case ST_DF_CON:
                    if(chars[i] == '<') {
                        eState = ST_DF_TAG;
                        lt = 0;
                        tag[lt] = 0;
                    } else {
                        if(lc < (int)sizeof(con) - 1) {
                            if(b64 && !nNc) {
                                for(l = 0; l < lc; ) {
                                    while(lb < 64 && l < lc && l < sizeof(con)) {
                                        if(con[l] != '\n' && con[l] != '\r')
                                            b64line[lb++] = con[l];
                                        l++;
                                    }
                                    if(lb == 64) {
                                        b64line[lb++] = '\n';
                                        b64line[lb] = 0;
                                        ld = sizeof(dec);
                                        dec[0] = 0;
                                        EVP_DecodeUpdate(&ectx, (unsigned char*)dec, &ld, (unsigned char*)b64line, lb);
                                        lExtr += ld;
                                        if(ld > 0)
                                            fwrite(dec, 1, ld, fOut);
                                        lb = 0;
                                    }
                                }
                            } else if(nNc || !b64) {
                                lExtr += lc;
                                fwrite(con, 1, lc, fOut);
                            }
                            lc = 0;
                        }
                        if(lc < sizeof(con)-1) {
                            con[lc] = chars[i];
                            con[++lc] = 0;
                        }
                    }
                    break;
                case ST_DF_TAG:
                    if(/*isalnum(chars[i]) || chars[i] == ':' || chars[i] == '/' ||*/ chars[i] != '>') {
                        if(lt < sizeof(tag)-1) {
                            tag[lt] = chars[i];
                            tag[++lt] = 0;
                        } else {
                            ddocDebug(1, "ddocSaxExtractDataFile", "Invalid xml tag-len > %d", sizeof(tag));
                            SET_LAST_ERROR_RETURN_CODE(ERR_FILE_READ);
                        }
                    } else { // DF intenal tag name ready
                        if(!strcmp(tag, "/DataFile")) { // end of DF
                            eState = ST_DF_END;
                        } else { // wrong tag - this is content
                            if(lc < sizeof(con)-1) {
                                con[lc] = '<';
                                for(j = 0; j < lt; j++)
                                    con[++lc] = tag[j];
                                con[++lc] = '>';
                                con[++lc] = 0;
                            }
                            eState = ST_DF_CON;
                        }
                    }
                    if(eState != ST_DF_END)
                        break;
                case ST_DF_END:
                    if(b64 && !nNc) {
                        if(lc > 0) {
                            for(l = 0; l < lc; ) {
                                while(lb < 64 && l < lc) {
                                    if(con[l] != '\n' && con[l] != '\r')
                                        b64line[lb++] = con[l];
                                    l++;
                                }
                                b64line[lb++] = '\n';
                                b64line[lb] = 0;
                                ld = sizeof(dec);
                                dec[0] = 0;
                                EVP_DecodeUpdate(&ectx, (unsigned char*)dec, &ld, (unsigned char*)b64line, lb);
                                lExtr += ld;
                                if(ld > 0)
                                    fwrite(dec, 1, ld, fOut);
                                lb = 0;
                            }
                        }
                        ld = 0;
                        dec[ld] = 0;
                        EVP_DecodeFinal(&ectx, (unsigned char*)dec, &ld);
                        lExtr += ld;
                        if(ld)
                            fwrite(dec, 1, ld, fOut);
                    } else if(nNc || !b64) {
                        if(lc) {
                            lExtr += lc;
                            fwrite(con, 1, lc, fOut);
                            lc = 0;

                        }
                    }
                    i = sizeof(chars);
                    //AM 24.09.08 RIK
                    eState = ST_DF_END_END;
                    break;
                }
            }
            //AM 24.09.08 RIK ST_DF_END to ST_DF_END_END_END
        } while(nRead > 0 && !err && eState < ST_DF_END_END);
    } else {
        ddocDebug(1, "ddocExtractDataFile", "Error reading file: %s", szFileName);
        SET_LAST_ERROR(ERR_FILE_READ);
    }
    if(fIn)
        fclose(fIn);
    if(fOut)
        fclose(fOut);
    if(!nNc && lSize != lExtr) {
        ddocDebug(1, "ddocExtractDataFile", "Warning! Extracted: %ld bytes but expected: %ld bytes", lExtr, lSize);
        //SET_LAST_ERROR(ERR_FILE_READ);
        //err = ERR_FILE_READ;
    }
    if(!bFound) {
        ddocDebug(1, "ddocExtractDataFile", "DF: %s not found", szDocId);
        SET_LAST_ERROR(ERR_FILE_WRITE);
        err = ERR_FILE_WRITE;
    }
    ddocDebug(3, "ddocExtractDataFile", "Extracted DF: %s to %s size: %ld expected: %ld", szDocId, szDataFileName, lExtr, lSize);
#ifdef WIN32
    free(convFileName);
    free(convDataFileName);
#endif
    return err;
}
Exemple #21
0
//============================================================
// Decrypts RSA encrypted data with the private key
// slot - number of the slot for decryption key. On ID card allways 0
// pin - corresponding pin for the key. On ID card - PIN1
// encData - encrypted data
// encLen - length of encrypted data
// decData - buffer for decrypted data
// encLen - length of buffer. Will be modified by amount of decrypted data
// return error code or ERR_OK
//============================================================
EXP_OPTION int decryptWithEstID(int slot, const char* pin, 
				const char* encData, int encLen, 
				char* decData, int *decLen)
{
  int err = ERR_OK, l1, l2;
  LIBHANDLE pLibrary = 0;
  CK_ULONG keyIdLen[20];
  CK_RV rv;
  CK_SLOT_ID slotids[20], slId;
  CK_SESSION_HANDLE hSession = 0;
  CK_OBJECT_HANDLE hPrivateKey, hKeys[20];
  char keyId[20][20];
  char driver[100];
  CK_MECHANISM Mechanism = { CKM_RSA_PKCS, 0, 0 };
  CK_ULONG outlen;

  ddocDebug(3, "decryptWithEstID", "slot: %d enc-data: %d bytes buffer size: %d", slot, encLen, *decLen);
  snprintf(driver, sizeof(driver), "DIGIDOC_DRIVER_%d_FILE", ConfigItem_lookup_int("DIGIDOC_DEFAULT_DRIVER", 1));
  ddocDebug(3, "decryptWithEstID", "Driver nr: %d - %s", 
	    ConfigItem_lookup_int("DIGIDOC_DEFAULT_DRIVER", 1),
	    ConfigItem_lookup(driver));
  err = loadAndTestDriver(ConfigItem_lookup(driver), 
			  &pLibrary, (CK_SLOT_ID*)slotids, 20, (CK_ULONG)slot);
  if(err) return err;

  // find the right slotid
  for(l1 = l2 = 0; l1 < 20; l1++) {
    if(slotids[l1] != INVALID_SLOTIID) {
      if(l2 == slot)
	slId = slotids[l1];
      l2++;
    }
  }
  // open session
  hSession = OpenSession(slId, pin);
  if (hSession == CK_INVALID_HANDLE) { SET_LAST_ERROR(ERR_PKCS_LOGIN); return ERR_PKCS_LOGIN; }
  ddocDebug(3, "decryptWithEstID", "OpenSession ok, hSession = %d", (int)hSession);
  
  // get private key
  for(l1 = 0; l1 < 20; l1++) {
    memset(keyId[l1], 0, 20);
    keyIdLen[l1] = 0;
  }
  err = LocatePrivateKey(hSession, keyId, keyIdLen, hKeys);
  hPrivateKey = hKeys[0]; //???
  //ddocDebug(3, "decryptWithEstID", "Priv key: %s", keyId);
  //if (hPrivateKey == CK_INVALID_HANDLE) { SET_LAST_ERROR(ERR_PKCS_PK); return ERR_PKCS_PK; }
  // init decrypt
  rv = (*ckFunc->C_DecryptInit)(hSession, &Mechanism, hPrivateKey);
  ddocDebug(3, "decryptWithEstID", "DecryptInit: %d", (int)rv);
  if(rv != CKR_OK) SET_LAST_ERROR_RETURN(ERR_DENC_DECRYPT, ERR_DENC_DECRYPT)
  // decrypt data
  outlen = *decLen;
  rv = (*ckFunc->C_Decrypt)(hSession, (CK_BYTE_PTR)encData, (CK_ULONG)encLen, (CK_BYTE_PTR)decData, (CK_ULONG_PTR)&outlen);
  *decLen = outlen;
  ddocDebug(3, "decryptWithEstID", "RV: %d, dec-len: %d", (int)rv, *decLen);
  if(hSession)
    closePKCS11Library(pLibrary, hSession);
  if(rv != CKR_OK)
    SET_LAST_ERROR_RETURN(ERR_DENC_DECRYPT, ERR_DENC_DECRYPT)
  return err;
}
Exemple #22
0
//============================================================
// Calculates and stores a signature for this SignatureInfo object
// Uses EstEID card to sign the info
// pSigInfo - signature info object
// nSigType - signature type code
// keyfile - RSA key file
// passwd - key password
// certfile - certificate file
//============================================================
EXP_OPTION int calculateSignatureWithEstID(SignedDoc* pSigDoc, SignatureInfo* pSigInfo, 
                    int slot, const char* passwd)
{
  int err = ERR_OK, nKey;
  LIBHANDLE pLibrary = 0;
  CK_ULONG certLen, sigLen, padDigLen;
  CK_RV rv;
  CK_SLOT_ID slotids[20], slId = 0;
  CK_SESSION_HANDLE hSession = 0;
  CK_OBJECT_HANDLE hPrivateKey, hKeys[20], hCert;
  char keyId[20][20];
  CK_ULONG keyIdLen[20];
  CK_BYTE certData[2048];
  CK_BYTE sigDig[100], padDig[130];
  CK_BYTE signature[256];
  CK_BYTE padding[] = { 48, 33, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 4, 20 };
	CK_BYTE padding256[] = { 48, 49, 48, 13, 6, 9, 96, 134, 72, 1 ,101, 3, 4, 2, 1, 5, 0, 4, 32};
	//CK_BYTE padding256[] = { 48, 33, 48, 13, 6, 9, 96, 134, 72, 1 ,101, 3, 4, 2, 1, 5, 0, 4, 32};
  char* buf1;
  int l1, l2;
  X509* x509;
  DigiDocMemBuf mbuf1;

  RETURN_IF_NULL_PARAM(pSigInfo);
  RETURN_IF_NULL_PARAM(pSigDoc);
  // try active driver driver first
  snprintf((char*)signature, sizeof(signature), "DIGIDOC_DRIVER_%d_FILE", 
	  ConfigItem_lookup_int("DIGIDOC_DEFAULT_DRIVER", 1));
  for(l1 = 0; l1 < 20; l1++) 
    slotids[l1] = INVALID_SLOTIID; // initialize
  err = loadAndTestDriver(ConfigItem_lookup((const char*)signature),
			  &pLibrary, (CK_SLOT_ID*)slotids, 20, (CK_ULONG)slot);
  ddocDebug(3, "calculateSignatureWithEstID", "Driver handle: %d err = %d slot: %d", 
	    pLibrary, err, slot);
  RETURN_IF_NOT(err == ERR_OK, err);
  // inittialize
  slId = INVALID_SLOTIID; // not found yet
  //err = ddocLocateSlotWithSignatureCert(pLibrary, slotids, 
  //					&slId, (char*)signature, sizeof(signature));
  
  // find suitable slotid
  
  for(l1 = 0; l1 < 20; l1++) {
    if(slotids[l1] != INVALID_SLOTIID)
      ddocDebug(3, "calculateSignatureWithEstID", 
		"Slot idx: %d = %d", l1, slotids[l1]);
    if(slotids[l1] != INVALID_SLOTIID && l1 == slot) {
      slId = slotids[l1];
      ddocDebug(3, "calculateSignatureWithEstID", 
		"Select idx: %d slot: %d", l1, slId);
    }
  }
  
  // open session
  if(slId != INVALID_SLOTIID) {
    hSession = OpenSession(slId, passwd);
    ddocDebug(3, "calculateSignatureWithEstID", 
	      "Open sess for slot: %d sess = %uld\n", slId, hSession);
    if (hSession == CK_INVALID_HANDLE) { err = ERR_PKCS_LOGIN; SET_LAST_ERROR(err); return err; }
    ddocDebug(3, "calculateSignatureWithEstID", "OpenSession ok, hSession = %d\n", (int)hSession);

    // get private key
    for(l1 = 0; l1 < 20; l1++) {
      memset(keyId[l1], 0, 20);
      keyIdLen[l1] = 0;
    }
    err = LocatePrivateKey(hSession, keyId, keyIdLen, hKeys);
    //ddocDebug(3, "calculateSignatureWithEstID", "Priv key: %s", keyId);
    //if (hPrivateKey == CK_INVALID_HANDLE) { err = ERR_PKCS_PK; SET_LAST_ERROR(err); return err; }

    // get cert     
    memset(certData, 0, sizeof(certData));  
    certLen = sizeof(certData);
    hCert = LocateCertificate(hSession, certData, &certLen, keyId, keyIdLen, &nKey);
    hPrivateKey = hKeys[nKey];
    ddocDebug(3, "calculateSignatureWithEstID", "selected priv-key: %ld pos %d id: %s", hPrivateKey, nKey, keyId[nKey]);
    ddocDebug(3, "calculateSignatureWithEstID", "Cert-len: %ld", certLen);
    //printf("Cert: %s", certData);
    if (hCert == (CK_OBJECT_HANDLE)-1) { err = ERR_PKCS_CERT_LOC; SET_LAST_ERROR(err); return err; }

    // set cert data
    err = ddocDecodeX509Data(&x509, certData, certLen);
    if (!x509) { err = ERR_PKCS_CERT_DECODE;  }
	  // save cert in file
	  if(ConfigItem_lookup_int("DEBUG_LEVEL", 1) > 3)
	  saveCert(x509, "signer.pem", FILE_FORMAT_PEM);
		//AM 07.03.08 setSignatureCert for BDOC
		if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME)) { 
				setSignatureCertBDOC(pSigInfo, x509);
		}else{
				setSignatureCert(pSigInfo, x509);
		}

		//AM 12.03.08
		//VS 23.02.2010 - not necessary?
		/*if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME)) { 
		findCAForCertificate(&ppCA, x509);
		err = bdocSigInfo_addCert(pSigInfo, ppCA, CERTID_TYPE_CA_CERTID);
		}*/ 

    // FIXME
    createTimestamp(pSigDoc, (char*)sigDig, sizeof(sigDig));
    setString((char**)&(pSigInfo->szTimeStamp), (const char*)sigDig, -1);

    // Signed properties digest
    buf1 = createXMLSignedProperties(pSigDoc, pSigInfo, 0);
    //dumpInFile("sigprop-sign1.txt", buf1);
    if (!buf1) { 
      err = ERR_NULL_POINTER; 
      SET_LAST_ERROR(err);
      return err;
    }
    mbuf1.pMem = canonicalizeXML((char*)buf1, strlen(buf1));
    mbuf1.nLen = strlen((const char*)mbuf1.pMem);
    ddocDebugWriteFile(4, "sigprop-signed.txt", &mbuf1);
    l2 = sizeof(sigDig);
	//AM 24.04.08
	if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME))
		err = calculateDigest((const byte*)mbuf1.pMem, mbuf1.nLen, BDOC_DIGEST, sigDig, &l2);
	else
		err = calculateDigest((const byte*)mbuf1.pMem, mbuf1.nLen, DIGEST_SHA1, sigDig, &l2);
    free(buf1);
    ddocMemBuf_free(&mbuf1);
    if (err != ERR_OK) {
      SET_LAST_ERROR(err);			
      return err;
    }
    ddocSigInfo_SetSigPropDigest(pSigInfo, (const char*)sigDig, l2);
    ddocSigInfo_SetSigPropRealDigest(pSigInfo, (const char*)sigDig, l2);
    // create signed info
	//AM 11.03.08 createXMLSignedInfo for BDOC
	if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME))
		buf1 = createXMLSignedInfoBDoc(pSigDoc, pSigInfo);
	else
		buf1 = createXMLSignedInfo(pSigDoc, pSigInfo);      
    if (!buf1) {
      err = ERR_NULL_POINTER;
      SET_LAST_ERROR(err);
      return err ;
    }
    // get digest
    l2 = sizeof(sigDig);
	/*if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME))
		err = calculateDigest((const byte*)buf1, strlen(buf1),  BDOC_DIGEST, sigDig, &l2);
	else*/
		err = calculateDigest((const byte*)buf1, strlen(buf1),  DIGEST_SHA1, sigDig, &l2);
    free(buf1);
    if (err != ERR_OK) {
      err = ERR_NULL_POINTER;
      SET_LAST_ERROR(err);
      return err;
    } 
    ddocSigInfo_SetSigInfoRealDigest(pSigInfo, (const char*)sigDig, l2);
    // sign data
    sigLen = sizeof(signature);
    memset(signature, 0, sizeof(signature));
    // pad PKCS#1 ver 1
    /*if(!strcmp(pSigDoc->szFormat, BDOC_XML_1_NAME) && BDOC_DIGEST==DIGEST_SHA256) {
		padDigLen = 51;
		memset(padDig, 0, sizeof(padDig));
		memcpy(padDig, padding256, 19);
		memcpy(padDig + 19, sigDig, l2);
	} else {*/
		padDigLen = 35;
		memset(padDig, 0, sizeof(padDig));
		memcpy(padDig, padding, 15);
		memcpy(padDig + 15, sigDig, l2);
	//}
    //rv = RSA_padding_add_PKCS1_type_1(padDig, padDigLen, sigDig, l2);
    //rv = RSA_padding_check_PKCS1_type_1(sigDig, l2, padDig, padDigLen, padDigLen+1);
    // checkErrors();
    // sign data
    rv = SignData(hSession, hPrivateKey, 
		  signature, &sigLen, padDig, padDigLen);    
    if (rv != CKR_OK) { 
      err = ERR_PKCS_SIGN_DATA;
      SET_LAST_ERROR(err);
      return err;
    }		

    // set signature value
    ddocSigInfo_SetSignatureValue(pSigInfo, (const char*)signature, (int)sigLen);
  } // if slotid found
    
  if(hSession)
    closePKCS11Library(pLibrary, hSession);
  return err;
}
Exemple #23
0
int ddocLocateSlotWithSignatureCert(LIBHANDLE pLibrary, CK_SLOT_ID* slotids, 
				    CK_SLOT_ID* pSlotId, X509** ppCert, 
				    char idData[20], int* pIdLen, int nSlot, int* pIdx)
{
  int err = ERR_PRIVKEY_READ, i, j, nMatch, l3;
  CK_RV rv;
  CK_SESSION_HANDLE hSession = 0;
  CK_OBJECT_HANDLE objects[10];
  CK_BYTE buf2[20], buf3[40];
  CK_ULONG ulObjectCount = sizeof(objects)/sizeof(CK_OBJECT_HANDLE), ulCount = 0, l1 = 0, l2 = 0;
  CK_OBJECT_CLASS ObjClass = CKO_CERTIFICATE;	
  
  CK_ATTRIBUTE Template1[] = {
    { CKA_CLASS,     &ObjClass,  sizeof(ObjClass) }
  };
  CK_ATTRIBUTE Template2[] = {
    { CKA_VALUE,     (void*)0,	l1  },
    { CKA_ID,	     (void*)0,  sizeof(buf2)}
  };
  char buf1[3000];
  X509* pCert;

  RETURN_IF_NULL_PARAM(pLibrary);
  RETURN_IF_NULL_PARAM(pSlotId);
  RETURN_IF_NULL_PARAM(slotids);
  RETURN_IF_NULL_PARAM(idData);
  RETURN_IF_NULL_PARAM(ppCert);
  // mark as not found
  memset(idData, 0, *pIdLen);
  ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Driver handle: %d err = %d", pLibrary, err);
  // now check every slot
  for(i = 0, nMatch = 0; (i < 20)  && !(*ppCert); i++) {
    if(slotids[i] != INVALID_SLOTIID) {
      ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Checking slot nr: %d id: %d", i, slotids[i]);
      // open session to slot but no login since we just need the cert
      rv = (*ckFunc->C_OpenSession)(slotids[i], CKF_SERIAL_SESSION,0,0,&hSession);
      ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Login rv: %ld session: %ld", rv, hSession);
      if(rv == CKR_OK) {
	ulCount = sizeof(Template1)/sizeof(CK_ATTRIBUTE);
	rv = (*ckFunc->C_FindObjectsInit)(hSession, Template1, ulCount);
	if(rv == CKR_OK) {
	  rv = (*ckFunc->C_FindObjects)(hSession, objects, ulObjectCount, &ulObjectCount);
	  ddocDebug(3, "ddocLocateSlotWithSignatureCert", "slot id: %ld, objects: %ld", 
		    slotids[i], ulObjectCount);
	  if(rv == CKR_OK && ulObjectCount > 0) {
	    ulCount = sizeof(Template2) / sizeof(CK_ATTRIBUTE);
	    for(j = 0; j < (int)ulObjectCount; j++) {
	      l1 = sizeof(buf1);
	      memset(buf1, 0, l1);
	      l2 = sizeof(buf2);
	      memset(buf2, 0, l2);
	      //Template2[0].pValue = 0; // check length first
	      rv = (*ckFunc->C_GetAttributeValue)(hSession, objects[j], Template2, ulCount);
	      if(rv == CKR_OK && Template2[0].ulValueLen < sizeof(buf1)) {
		l1 = Template2[0].ulValueLen;
		// now get cert data
		Template2[0].pValue = buf1;
		Template2[1].pValue = buf2;
		rv = (*ckFunc->C_GetAttributeValue)(hSession, objects[j], Template2, ulCount);
		ddocDebug(3, "ddocLocateSlotWithSignatureCert", "slot id: %ld, object: %ld cert-len: %ld rv: %ld", 
			  slotids[i], j, l1, rv);
		pCert = 0;
		err = ddocDecodeX509Data(&pCert, (const byte*)buf1, l1);
		if(pCert) {
		  if(ddocCertCheckKeyUsage(pCert, KUIDX_NON_REPUDIATION)) {
              if((!nSlot || nSlot == nMatch) && !(*ppCert)) {
                l3 = sizeof(buf3);
                memset(buf3, 0, l3);
                bin2hex((const byte*)buf2, (int)Template2[1].ulValueLen, (char*)buf3, &l3);
	        ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Selecting slot: %d id: %d key-id %s", i, slotids[i], buf3);
	        *pSlotId = slotids[i];
                *pIdx = i;
			    // keep this cert for signing
                if(*ppCert)
                  X509_free(*ppCert);
			    (*ppCert) = pCert;
                pCert = NULL; // mark as used
			    memcpy(idData, buf2, Template2[1].ulValueLen);
                *pIdLen = Template2[1].ulValueLen;
                  err = ERR_OK; // found it
              } else { // useable slot but not a match by slot id
		  ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Useable slot: %d but search: %d", nMatch, nSlot);
                  nMatch++;
              }
		  } // if non-repu cert
        } // if pCert
		  if(pCert)
		    X509_free(pCert);
		  pCert = 0;
    
          } // if get-attribute ok 
	    } // for j < ulObjectCount
	  } // if found any certs
	} // if find-init ok
	rv = (*ckFunc->C_FindObjectsFinal)(hSession);
      } // if login ok
      rv = (*ckFunc->C_CloseSession)(hSession);      
    } // if slotid
  } // for i 

  return err;
}
Exemple #24
0
int ddocLocateSlotWithSignatureCert(LIBHANDLE pLibrary, CK_SLOT_ID* slotids, 
				    CK_SLOT_ID* pSlotId, char* pLabel, CK_ULONG nLabelLen)
{
  int err = ERR_OK, i, j;
  CK_RV rv;
  CK_SESSION_HANDLE hSession = 0;
  CK_OBJECT_HANDLE objects[10];
  CK_ULONG ulObjectCount = sizeof(objects)/sizeof(CK_OBJECT_HANDLE), ulCount = 0, l1 = 0;
  CK_OBJECT_CLASS ObjClass = CKO_CERTIFICATE;	
  CK_ATTRIBUTE Template1[] = {
    { CKA_CLASS,     &ObjClass,  sizeof(ObjClass) }
  };
  CK_ATTRIBUTE Template2[] = {
    { CKA_VALUE,     (void*)0,	l1  }
    //,   { CKA_ID,	     (void*)pLabel,  nLabelLen }
  };
  char buf1[3000];
  X509* pCert;

  RETURN_IF_NULL_PARAM(pLibrary);
  RETURN_IF_NULL_PARAM(pSlotId);
  RETURN_IF_NULL_PARAM(slotids);
  RETURN_IF_NULL_PARAM(pLabel);
  // mark as not found
  *pSlotId = INVALID_SLOTIID;
  ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Driver handle: %d err = %d", pLibrary, err);
  // now check every slot
  for(i = 0; i < 20; i++) {
    if(slotids[i] != INVALID_SLOTIID) {
      ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Checking slot nr: %d id: %d", i, slotids[i]);
      // open session to slot but no login since we just need the cert
      rv = (*ckFunc->C_OpenSession)(slotids[i], CKF_SERIAL_SESSION,0,0,&hSession);
      ddocDebug(3, "ddocLocateSlotWithSignatureCert", "Login rv: %ld session: %ld", rv, hSession);
      if(rv == CKR_OK) {
	ulCount = sizeof(Template1)/sizeof(CK_ATTRIBUTE);
	rv = (*ckFunc->C_FindObjectsInit)(hSession, Template1, ulCount);
	if(rv == CKR_OK) {
	  rv = (*ckFunc->C_FindObjects)(hSession, objects, ulObjectCount, &ulObjectCount);
	  ddocDebug(3, "ddocLocateSlotWithSignatureCert", "slot id: %ld, objects: %ld", 
		    slotids[i], ulObjectCount);
	  if(rv == CKR_OK && ulObjectCount > 0) {
	    ulCount = sizeof(Template2) / sizeof(CK_ATTRIBUTE);
	    for(j = 0; j < (int)ulObjectCount; j++) {
	      l1 = sizeof(buf1);
	      memset(buf1, 0, l1);
	      //Template2[0].pValue = 0; // check length first
	      rv = (*ckFunc->C_GetAttributeValue)(hSession, objects[j], Template2, ulCount);
	      if(rv == CKR_OK && Template2[0].ulValueLen < sizeof(buf1)) {
		l1 = Template2[0].ulValueLen;
		// now get cert data
		Template2[0].pValue = buf1;
		rv = (*ckFunc->C_GetAttributeValue)(hSession, objects[j], Template2, ulCount);
		ddocDebug(3, "ddocLocateSlotWithSignatureCert", "slot id: %ld, object: %ld cert-len: %ld rv: %ld", 
			  slotids[i], j, l1, rv);
		pCert = 0;
		err = ddocDecodeX509Data(&pCert, (const byte*)buf1, l1);
		if(pCert) 
		ddocDebug(3, "ddocLocateSlotWithSignatureCert", 
			  "flags: %ld kusage: %ld xkusage: %ld ku-dig-sign: %d ku-non-repud: %d ku-ex: %d non-rep-ex: %d",
			  pCert->ex_flags, pCert->ex_kusage, pCert->ex_xkusage,
			  pCert->ex_kusage & X509v3_KU_DIGITAL_SIGNATURE,
			  pCert->ex_kusage & X509v3_KU_NON_REPUDIATION,
			  pCert->ex_xkusage & X509v3_KU_DIGITAL_SIGNATURE,
			  pCert->ex_xkusage & X509v3_KU_NON_REPUDIATION);
		if(pCert)
		  X509_free(pCert);
		
	      }
	    } // for j < ulObjectCount
	  } // if found any certs
	} // if find-init ok
	rv = (*ckFunc->C_FindObjectsFinal)(hSession);
      } // if login ok
      rv = (*ckFunc->C_CloseSession)(hSession);      
    } // if slotid
  } // for i 

  return err;
}
Exemple #25
0
//============================================================
// Calculates and stores a signature for this SignatureInfo object
// Uses EstEID card to sign the info
// pSigInfo - signature info object
// nSigType - signature type code
// keyfile - RSA key file
// passwd - key password
// certfile - certificate file
//============================================================
EXP_OPTION int calculateSignatureWithEstID(SignedDoc* pSigDoc, SignatureInfo* pSigInfo, 
                    int slot, const char* passwd)
{
  int err = ERR_OK, nKey;
  LIBHANDLE pLibrary = 0;
  CK_ULONG certLen, sigLen, padDigLen;
  CK_RV rv;
  CK_SLOT_ID slotids[20], slId = 0;
  CK_SESSION_HANDLE hSession = 0;
  CK_OBJECT_HANDLE hPrivateKey = 0, hKeys[20], hCert;
  char keyId[20][20], kId[20];
  CK_ULONG keyIdLen[20];
  CK_BYTE certData[2048];
  CK_BYTE sigDig[100], padDig[130];
  CK_BYTE signature[256];
  CK_BYTE padding[] = { 48, 33, 48, 9, 6, 5, 43, 14, 3, 2, 26, 5, 0, 4, 20 };
  //CK_BYTE padding256[] = { 48, 49, 48, 13, 6, 9, 96, 134, 72, 1 ,101, 3, 4, 2, 1, 5, 0, 4, 32};
  //CK_BYTE padding256[] = { 48, 33, 48, 13, 6, 9, 96, 134, 72, 1 ,101, 3, 4, 2, 1, 5, 0, 4, 32};
  char* buf1;
  int l1, l2, kILen;
  X509* x509 = 0;
  DigiDocMemBuf mbuf1;

  RETURN_IF_NULL_PARAM(pSigInfo);
  RETURN_IF_NULL_PARAM(pSigDoc);
  // try active driver driver first
  snprintf((char*)signature, sizeof(signature), "DIGIDOC_DRIVER_%d_FILE", 
	  ConfigItem_lookup_int("DIGIDOC_DEFAULT_DRIVER", 1));
  for(l1 = 0; l1 < 20; l1++) 
    slotids[l1] = INVALID_SLOTIID; // initialize
  err = loadAndTestDriver(ConfigItem_lookup((const char*)signature),
			  &pLibrary, (CK_SLOT_ID*)slotids, 20, (CK_ULONG)slot);
  ddocDebug(3, "calculateSignatureWithEstID", "Driver handle: %d err = %d slot: %d", 
	    pLibrary, err, slot);
  RETURN_IF_NOT(err == ERR_OK, err);
  // inittialize
  slId = INVALID_SLOTIID; // not found yet  
  // try key-usage check
  if(ConfigItem_lookup_int("KEY_USAGE_CHECK", 1)) {
    kILen = sizeof(kId);
    ddocDebug(3, "calculateSignatureWithEstID", "Find slot by key-usage, slot: %d", slot);
    err = ddocLocateSlotWithSignatureCert(pLibrary, slotids, &slId, &x509, kId, &kILen, slot, &l1);
    ddocDebug(3, "calculateSignatureWithEstID", 
		"Select by key-usage slot idx: %d = %d err: %d key-id: %s, kid-len: %d", l1, slId, err, kId, kILen);
    if(err != ERR_OK || l1 < 0 || l1 >= 20) {
		SET_LAST_ERROR(ERR_SIGNERS_CERT_NON_REPU);
        return ERR_SIGNERS_CERT_NON_REPU;
	}
  } else {
    ddocDebug(3, "calculateSignatureWithEstID", "Find slot by slot idx: %d", slot);
    for(l1 = 0; (l1 < 20) && (slId == INVALID_SLOTIID); l1++) {
      if(slotids[l1] != INVALID_SLOTIID)
        ddocDebug(3, "calculateSignatureWithEstID", 
                        "Slot idx: %d = %d", l1, slotids[l1]);
      if(slotids[l1] != INVALID_SLOTIID && l1 == slot) {
        slId = slotids[l1];
        ddocDebug(3, "calculateSignatureWithEstID", 
                        "Select idx: %d slot: %d", l1, slId);
    } // if slotid
    } // for
  }
  // use default if not found by key-id or direct 
  if(slId == INVALID_SLOTIID) {
      l1 = ConfigItem_lookup_int("DIGIDOC_SIGNATURE_SLOT", 0);
      if(slotids[l1] != INVALID_SLOTIID) {
          ddocDebug(3, "calculateSignatureWithEstID", 
                    "Select default slot idx: %d = %d", l1, slotids[l1]);
          slId = slotids[l1];
      }
  }

  // open session
  if(slId != INVALID_SLOTIID) {
    hSession = OpenSession(slId, passwd);
    ddocDebug(3, "calculateSignatureWithEstID", 
	      "Open sess for slot: %d sess = %d", slId, hSession);
    if (hSession == CK_INVALID_HANDLE) { err = ERR_PKCS_LOGIN; SET_LAST_ERROR(err); return err; }
    ddocDebug(3, "calculateSignatureWithEstID", "OpenSession ok, hSession1 = %d", (int)hSession);

    if(!x509) {
		ddocDebug(3, "calculateSignatureWithEstID", "Cert ok");
      // get private key
      for(l1 = 0; l1 < 20; l1++) {
        memset(keyId[l1], 0, 20);
        keyIdLen[l1] = 0;
      }
      err = LocatePrivateKey(hSession, keyId, keyIdLen, hKeys);
      //ddocDebug(3, "calculateSignatureWithEstID", "Priv key: %s", keyId);
      //

      // get cert  
      memset(certData, 0, sizeof(certData));  
      certLen = sizeof(certData);
      hCert = LocateCertificate(hSession, certData, &certLen, keyId, keyIdLen, &nKey);
      hPrivateKey = hKeys[nKey];
      ddocDebug(3, "calculateSignatureWithEstID", "selected priv-key: %ld pos %d id: %s", hPrivateKey, nKey, keyId[nKey]);
      ddocDebug(3, "calculateSignatureWithEstID", "Cert-len: %ld", certLen);
      //printf("Cert: %s", certData);
      if (hCert == (CK_OBJECT_HANDLE)-1) { err = ERR_PKCS_CERT_LOC; SET_LAST_ERROR(err); return err; }

      // set cert data
      err = ddocDecodeX509Data(&x509, certData, certLen);
      

    } else { // cert already found
		//kILen = sizeof(kId);
        ddocDebug(3, "calculateSignatureWithEstID", "Locate priv key2 id: %s, len: %d, hkey: %d", kId, kILen, hPrivateKey);
		err = LocatePrivateKeyWithId(hSession, (CK_BYTE_PTR)kId, kILen, &hPrivateKey);
		ddocDebug(3, "calculateSignatureWithEstID", "Priv key-id: %s len: %d hkey: %d err: %d", kId, kILen, hPrivateKey, err);
    }	 
	ddocDebug(3, "calculateSignatureWithEstID", "Priv key: %d err: %d", hPrivateKey, err);
    if (hPrivateKey == CK_INVALID_HANDLE) { err = ERR_PKCS_PK; SET_LAST_ERROR(err); return err; }
    if (!x509) { err = ERR_PKCS_CERT_DECODE;  }
      
   // save cert in file
   if(ConfigItem_lookup_int("DEBUG_LEVEL", 1) > 3) 
     saveCert(x509, "signer.pem", FILE_FORMAT_PEM);
   setSignatureCert(pSigInfo, x509);

    // FIXME
    createTimestamp(pSigDoc, (char*)sigDig, sizeof(sigDig));
    setString((char**)&(pSigInfo->szTimeStamp), (const char*)sigDig, -1);

    // Signed properties digest
    buf1 = createXMLSignedProperties(pSigDoc, pSigInfo, 0);
    //dumpInFile("sigprop-sign1.txt", buf1);
    if (!buf1) { 
      err = ERR_NULL_POINTER; 
      SET_LAST_ERROR(err);
      return err;
    }
    mbuf1.pMem = canonicalizeXML((char*)buf1, strlen(buf1));
    mbuf1.nLen = strlen((const char*)mbuf1.pMem);
    ddocDebugWriteFile(4, "sigprop-signed.txt", &mbuf1);
    l2 = sizeof(sigDig);
    err = calculateDigest((const byte*)mbuf1.pMem, mbuf1.nLen, DIGEST_SHA1, sigDig, &l2);
    free(buf1);
    ddocMemBuf_free(&mbuf1);
    if (err != ERR_OK) {
      SET_LAST_ERROR(err);			
      return err;
    }
    ddocSigInfo_SetSigPropDigest(pSigInfo, (const char*)sigDig, l2);
    ddocSigInfo_SetSigPropRealDigest(pSigInfo, (const char*)sigDig, l2);
    // create signed info
    buf1 = createXMLSignedInfo(pSigDoc, pSigInfo);      
    if (!buf1) {
      err = ERR_NULL_POINTER;
      SET_LAST_ERROR(err);
      return err ;
    }
    // get digest
    l2 = sizeof(sigDig);
	err = calculateDigest((const byte*)buf1, strlen(buf1),  DIGEST_SHA1, sigDig, &l2);
    free(buf1);
    if (err != ERR_OK) {
      err = ERR_NULL_POINTER;
      SET_LAST_ERROR(err);
      return err;
    } 
    ddocSigInfo_SetSigInfoRealDigest(pSigInfo, (const char*)sigDig, l2);
    // sign data
    sigLen = sizeof(signature);
    memset(signature, 0, sizeof(signature));
    // pad PKCS#1 ver 1
	padDigLen = 35;
	memset(padDig, 0, sizeof(padDig));
	memcpy(padDig, padding, 15);
	memcpy(padDig + 15, sigDig, l2);
    //rv = RSA_padding_add_PKCS1_type_1(padDig, padDigLen, sigDig, l2);
    //rv = RSA_padding_check_PKCS1_type_1(sigDig, l2, padDig, padDigLen, padDigLen+1);
    // checkErrors();
    // sign data
    rv = SignData(hSession, hPrivateKey, 
		  signature, &sigLen, padDig, padDigLen);    
    if (rv != CKR_OK) { 
      err = ERR_PKCS_SIGN_DATA;
      SET_LAST_ERROR(err);
      return err;
    }		

    // set signature value
    ddocSigInfo_SetSignatureValue(pSigInfo, (const char*)signature, (int)sigLen);
	ddocDebug(3, "calculateSignatureWithEstID", "Sig-len: %ld", sigLen);
    
  } // if slotid found
    
  if(hSession)
    closePKCS11Library(pLibrary, hSession);
  return err;
}
Exemple #26
0
//============================================================
// Locates a certificate on the token on basis of its CKA_LABEL attribute.
// hSession - card session handle
// label - key label
// return objects handle or -1 for failure
//============================================================
CK_OBJECT_HANDLE LocateCertificate(CK_SESSION_HANDLE hSession, 
				   CK_BYTE_PTR certData, CK_ULONG_PTR certLen, 
				   char idData[20][20], CK_ULONG idLen[20],
				   int* pSelKey)
{
  CK_OBJECT_HANDLE Objects[10];
  CK_ULONG ulObjectCount = sizeof(Objects)/sizeof(CK_OBJECT_HANDLE), i, j;
  CK_BYTE buf1[20];
  CK_OBJECT_HANDLE hCert = CK_INVALID_HANDLE;
  CK_RV rv;

  // Set up a template to search for Certificate token objects
  // in the given session and thus slot
  CK_OBJECT_CLASS ObjClass = CKO_CERTIFICATE;	
  CK_ATTRIBUTE Template1[] = {
    { CKA_CLASS,     &ObjClass,  sizeof(ObjClass) },
    { CKA_ID,	     (void*)0,  0 }
  };
  CK_ATTRIBUTE Template3[] = {
    { CKA_CLASS,     &ObjClass,  sizeof(ObjClass) },
  };
  CK_ATTRIBUTE Template2[] = {
    { CKA_VALUE,      (void*)0,	*certLen  },
    { CKA_ID,	     (void*)0,  0 }
  };
  CK_ULONG ulCount = 0;
  
  if(idLen)
    ulCount = sizeof(Template1)/sizeof(CK_ATTRIBUTE);
  else
    ulCount = sizeof(Template3)/sizeof(CK_ATTRIBUTE);
  *certLen = 0;
  /*
  ** Initiate the object search
  C_FindObjectsInit initializes a search for token and session objects that match a template.
  hSession is the sessions handle; pTemplate points to a search template that specifies the
  attribute values to match; ulCount is the number of attributes in the search template. The
  matching criterion is an exact byte-for-byte match with all attributes in the template. 
  To find all objects, set ulCount to 0.
  */
  
  for(j = 0; j < 20 && !(*certLen); j++) {
    if(idLen && idLen[j]) {
      memset(buf1, 0, sizeof(buf1));
      memcpy(buf1, idData[j], idLen[j]);
      Template1[1].pValue = buf1;
      Template1[1].ulValueLen = idLen[j];
    }
    rv = (*ckFunc->C_FindObjectsInit)(hSession, (idLen ? Template1 : Template3), 1); //ulCount);
    if(rv==CKR_OK) {            
      rv = (*ckFunc->C_FindObjects)(hSession,Objects,ulObjectCount, &ulObjectCount);
      ddocDebug(3, "LocateCertificate", "search key-id: %s, found: %ld rv: %ld", buf1, ulObjectCount, rv);
      if(rv==CKR_OK) {
	// pick the first cert that is valid
	// list and ignore any other
	for(i = 0; i < ulObjectCount; i++) {
	  hCert = Objects[i];
	  memset(certData, 0, *certLen);
	  ulCount = sizeof(Template2) / sizeof(CK_ATTRIBUTE);
	  // get cert length
	  *certLen = 0;
	  Template2[1].pValue = buf1;
	  Template2[1].ulValueLen = sizeof(buf1);
	  rv = (*ckFunc->C_GetAttributeValue)(hSession, hCert, Template2, ulCount);
	  ddocDebug(3, "LocateCertificate", "cert-id: %s", buf1);
	  if(rv == CKR_OK && (!idLen ||
	     (idLen && !memcmp(idData[j], buf1, idLen[1])))) {
	      *certLen = Template2[0].ulValueLen;
	      // now get cert data
	      Template2[0].pValue = certData;
	      rv = (*ckFunc->C_GetAttributeValue)(hSession, hCert, Template2, ulCount);
	      ddocDebug(3, "LocateCertificate", "cert-len: %ld", *certLen);
	      if(*certLen > 0 && pSelKey) {
		*pSelKey = j;
		break; // found it
	      }
	    
	  } // if rv == CKR_OK
	} // for i < ulObjectCount
      } // if rv
    } // if rv
    rv = (*ckFunc->C_FindObjectsFinal)(hSession);
  } // for j
  if(hCert == CK_INVALID_HANDLE)
    *certLen = 0;
  return hCert;
}
Exemple #27
0
//============================================================
// Initializes NotaryInfo object with data from OCSP object
// pSigDoc - digidoc main object pointer
// pNotary - NotaryInfo object to be initialized
// resp - OCSP response object
// notCert - Notary cert object
// return error code
//============================================================
int initializeNotaryInfoWithOCSP(SignedDoc *pSigDoc, NotaryInfo *pNotary, 
				OCSP_RESPONSE *resp, X509 *notCert, int initDigest)
{
  int n, err = ERR_OK;
  char buf[500];
  OCSP_RESPBYTES *rb = NULL;
  OCSP_BASICRESP *br = NULL;
  OCSP_RESPDATA  *rd = NULL;
  OCSP_RESPID *rid = NULL;
  // OCSP_CERTSTATUS *cst = NULL;
  OCSP_SINGLERESP *single = NULL;
  OCSP_CERTID *cid = NULL;
  X509_EXTENSION *nonce;
	//AM 26.09.08
	DigiDocMemBuf mbuf1;
	mbuf1.pMem = 0;
	mbuf1.nLen = 0;
	
  RETURN_IF_NULL_PARAM(pNotary);
  RETURN_IF_NULL_PARAM(resp);
  // check the OCSP Response validity
  switch(OCSP_response_status(resp)) {
  case OCSP_RESPONSE_STATUS_SUCCESSFUL: // OK
    break;
  case OCSP_RESPONSE_STATUS_MALFORMEDREQUEST:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_MALFORMED);
  case OCSP_RESPONSE_STATUS_INTERNALERROR:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_INTERNALERR);
  case OCSP_RESPONSE_STATUS_TRYLATER:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_TRYLATER);
  case OCSP_RESPONSE_STATUS_SIGREQUIRED:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_SIGREQUIRED);
  case OCSP_RESPONSE_STATUS_UNAUTHORIZED:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNAUTHORIZED);
  default:
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNSUCCESSFUL);
  }
  RETURN_IF_NULL_PARAM(resp->responseBytes);;
  rb = resp->responseBytes;
  if(OBJ_obj2nid(rb->responseType) != NID_id_pkix_OCSP_basic) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_UNKNOWN_TYPE);
  if((br = OCSP_response_get1_basic(resp)) == NULL) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_BASIC_RESP);
  rd = br->tbsResponseData;
  if(ASN1_INTEGER_get(rd->version) != 0) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_VERSION);
  n = sk_OCSP_SINGLERESP_num(rd->responses);
  if(n != 1) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_ONE_RESPONSE);
  single = sk_OCSP_SINGLERESP_value(rd->responses, 0);
  RETURN_IF_NULL(single);
  cid = single->certId;
  RETURN_IF_NULL(cid);
  ddocDebug(4, "initializeNotaryInfoWithOCSP", "CertStatus-type: %d", single->certStatus->type);
  //printf("TYPE: %d\n", single->certStatus->type);
  if(single->certStatus->type != 0) {
    ddocDebug(4, "initializeNotaryInfoWithOCSP", "errcode: %d", handleOCSPCertStatus(single->certStatus->type));
    SET_LAST_ERROR_RETURN_CODE(handleOCSPCertStatus(single->certStatus->type));
  }
  //Removed 31.10.2003
  //if(single->singleExtensions) 
  //	SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_SINGLE_EXT);
  if(!rd->responseExtensions ||
     (sk_X509_EXTENSION_num(rd->responseExtensions) != 1) ||
     ((nonce = sk_X509_EXTENSION_value(rd->responseExtensions, 0)) == NULL)) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE);
  i2t_ASN1_OBJECT(buf,sizeof(buf),nonce->object);
  if(strcmp(buf, OCSP_NONCE_NAME)) 
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_NO_NONCE);
  rid =  rd->responderId;
  if(rid->type == V_OCSP_RESPID_NAME) {
    pNotary->nRespIdType = RESPID_NAME_TYPE;
  } else if(rid->type == V_OCSP_RESPID_KEY) {
    pNotary->nRespIdType = RESPID_KEY_TYPE;
  } else {
    SET_LAST_ERROR_RETURN_CODE(ERR_OCSP_WRONG_RESPID);
  }
  // producedAt
  err = asn1time2str(pSigDoc, rd->producedAt, buf, sizeof(buf));
  setString(&(pNotary->timeProduced), buf, -1);
  n = sizeof(buf);
  if(rid->type == V_OCSP_RESPID_NAME) {
    //X509_NAME_oneline(rid->value.byName,buf,n);
		//AM 26.09.08
		err = ddocCertGetDNFromName(rid->value.byName, &mbuf1);
		RETURN_IF_NOT(err == ERR_OK, err);
		err = ddocNotInfo_SetResponderId(pNotary, (char*)mbuf1.pMem, -1);
		ddocMemBuf_free(&mbuf1);
  }
  if(rid->type == V_OCSP_RESPID_KEY) {
    err = ddocNotInfo_SetResponderId(pNotary, (const char*)rid->value.byKey->data, rid->value.byKey->length);
  }
  // digest type
  i2t_ASN1_OBJECT(buf,sizeof(buf),cid->hashAlgorithm->algorithm);
  setString(&(pNotary->szDigestType), buf, -1);
  // signature algorithm
  i2t_ASN1_OBJECT(buf,sizeof(buf),br->signatureAlgorithm->algorithm);
  setString(&(pNotary->szSigType), buf, -1);
  // notary cert
  if(notCert && !err)
    err = addNotaryInfoCert(pSigDoc, pNotary, notCert);
  // save the response in memory
  err = ddocNotInfo_SetOCSPResponse_Value(pNotary, resp);
  // get the digest from original OCSP data
  if(initDigest && notCert) {
    err = calcNotaryDigest(pSigDoc, pNotary);
  }
  if(br != NULL)
    OCSP_BASICRESP_free(br);
  if (err != ERR_OK) SET_LAST_ERROR(err);
  return err;
}
Exemple #28
0
//--------------------------------------------------
// Writes encrypted data to a file
// pEncData - encrypted data object [REQUIRED]
// szFileName - name of the file to write the data [REQUIRED]
// returns error code or ERR_OK
//--------------------------------------------------
EXP_OPTION int dencGenEncryptedData_writeToFile(DEncEncryptedData* pEncData, const char* szFileName)
{
  int err = ERR_OK;
  DigiDocMemBuf mbufEncData;
  FILE* hFile;
#ifdef WIN32
  wchar_t *convFileName = 0; 
  int i= 0;
  err = utf82unicode((const char*)szFileName, (char**)&convFileName, &i);
  ddocDebug(3, "ddocGenEncryptedData_writeToFile", "file: %s, conv-file: %s len: %d", szFileName, convFileName, i);
#else
  char convFileName[1024];
  ddocConvertFileName( convFileName, sizeof(convFileName), szFileName );
#endif

  ddocDebug(3, "dencGenEncryptedData_writeToFile", "filename: %s", szFileName);
  RETURN_IF_NULL_PARAM(pEncData)
  RETURN_IF_NULL_PARAM(szFileName)
  // start of element
  mbufEncData.pMem = 0;
  mbufEncData.nLen = 0;
  err = dencGenEncryptedData_toXML(pEncData, &mbufEncData);
#ifdef WIN32
  if(!err && (hFile = _wfopen(convFileName, L"wb")) != NULL) {
#else
  if(!err && (hFile = fopen(convFileName, "wb")) != NULL) {
#endif
    fwrite(mbufEncData.pMem, mbufEncData.nLen, 1, hFile);
    fclose(hFile);
  } else {
    SET_LAST_ERROR_RETURN_CODE(ERR_FILE_WRITE);
    ddocDebug(1, "dencGenEncryptedData_writeToFile", "Error writing encrypted document");
  }
  // cleanup
  ddocMemBuf_free(&mbufEncData);
  return err;
}


//--------------------------------------------------
// Generates the header of XML for <EncryptedData> element
// This contains everything upto the start of base64 encoded cipher data
// pEncData - encrypted data object [REQUIRED]
// pBuf - memory buffer for storing xml [REQUIRED]
// returns error code or ERR_OK
//--------------------------------------------------
int dencGenEncryptedData_header_toXML(DEncEncryptedData* pEncData, DigiDocMemBuf* pBuf)
{
  int err = ERR_OK;
  char* p;
  int i, n;

  RETURN_IF_NULL_PARAM(pBuf)
  RETURN_IF_NULL_PARAM(pEncData)
  // xml header
  err = ddocMemAppendData(pBuf, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>", -1);
  if(err) return err;
  // start of element
  err = ddocGen_startElemBegin(pBuf, "denc:EncryptedData");
  if(err) return err;
  // xmlns:denc
  //p = dencEncryptedData_GetXmlNs(pEncData);
  //if(p)
  err = ddocGen_addAtribute(pBuf, "xmlns:denc", DENC_XMLNS_XMLENC);
  if(err) return err;
  // Id atribute
  p = (char*)dencEncryptedData_GetId(pEncData);
  if(p)
    err = ddocGen_addAtribute(pBuf, "Id", p);
  if(err) return err;
  // Type atribute
  p = (char*)dencEncryptedData_GetType(pEncData);
  if(p)
    err = ddocGen_addAtribute(pBuf, "Type", p);
  if(err) return err;
  // MimeType atribute
  p = (char*)dencEncryptedData_GetMimeType(pEncData);
  if(p)
    err = ddocGen_addAtribute(pBuf, "MimeType", p);
  if(err) return err;
  // Encoding ???
  // end of element start tag
  err = ddocGen_startElemEnd(pBuf);
  if(err) return err;
  // <EncryptionMethod>
  p = (char*)dencEncryptedData_GetEncryptionMethod(pEncData);
  if(p) {
    err = ddocGen_startElemBegin(pBuf, "denc:EncryptionMethod");
    if(err) return err;
    err = ddocGen_addAtribute(pBuf, "Algorithm", p);
    if(err) return err;
    // end of element start tag
    err = ddocGen_startElemEnd(pBuf);
    if(err) return err;
    err = ddocGen_endElem(pBuf, "denc:EncryptionMethod");
    if(err) return err;
  }
  n = dencEncryptedData_GetEncryptedKeyCount(pEncData);
  if(n > 0) {
    // <KeyInfo>
    err = ddocGen_startElemBegin(pBuf, "ds:KeyInfo");
    if(err) return err;
    // xmlns ???
    err = ddocGen_addAtribute(pBuf, "xmlns:ds", DENC_XMLNS_XMLDSIG);
    if(err) return err;
    err = ddocGen_startElemEnd(pBuf);
    if(err) return err;
    // <EncryptedKey>
    for(i = 0; i < n; i++) {
      DEncEncryptedKey* pEncKey = dencEncryptedData_GetEncryptedKey(pEncData, i);
      if(pEncKey) {
	err = dencGenEncryptedKey_toXML(pEncKey, pBuf);
	if(err) return err;
      }
    }
    // end of element <KeyInfo>
    err = ddocGen_endElem(pBuf, "ds:KeyInfo");
    if(err) return err;
  }
  // encrypted data
  err = ddocGen_startElem(pBuf, "denc:CipherData");
  if(err) return err;
  err = ddocGen_startElem(pBuf, "denc:CipherValue");
  // here would come the base64 encoded cipher data
  return err;
}
Exemple #29
0
//--------------------------------------------------
// Calculates file size
// szFileName - file name
// lFileLen - pointer to a buffer where to store the file length
// returns error code or ERR_OK for success
//--------------------------------------------------
EXP_OPTION int calculateFileSize(const char* szFileName, long* lFileLen)
{
    FILE* hFile = 0;
#ifdef WIN32
    int i = 0, err = ERR_OK;
    wchar_t *convFileName = 0;
#endif

    RETURN_IF_NULL_PARAM(szFileName);
    RETURN_IF_NULL_PARAM(lFileLen);
    if(!szFileName || !strlen(szFileName)) return 0;
#ifdef WIN32
    err = utf82unicode((const char*)szFileName, (char**)&convFileName, &i);
    ddocDebug(3, "calculateFileSize", "Opening FILE: %s, conv-file: %s len: %d", szFileName, convFileName, i);
    if((hFile = _wfopen(convFileName,L"rb")) != NULL) {
#else
    if((hFile = fopen(szFileName,"rb")) != NULL) {
#endif
        fseek(hFile, 0, SEEK_END);
        (*lFileLen) = ftell(hFile);
        ddocDebug(3, "calculateFileSize", "Closing FILE: %s, size: %ld", szFileName, (*lFileLen));
        fclose(hFile);
    } // if - fopen
    else
        SET_LAST_ERROR_RETURN_CODE(ERR_FILE_READ);
#ifdef WIN32
    if(convFileName) free(convFileName);
#endif

    return ERR_OK;
}


//--------------------------------------------------
// Calculates files SHA1-RSA signature
// szFileName - file name
// nDigestType - digest type. Supports only SHA1 (0)
// pSigBuf - buffer to store the signature
// nSigLen - buffer size, must be at least 128
//			will be updated by actual signature length
// keyfile - name of the private key file
// passwd - private key password
// returns error code or ERR_OK for success
//--------------------------------------------------
EXP_OPTION int calculateFileSignature(const char* szFileName, int nDigestType,
                                      byte* pSigBuf, int* nSigLen,
                                      const char *keyfile, const char* passwd)
{
    int err = ERR_OK;
    EVP_MD_CTX  ctx;
    byte buf[FILE_BUFSIZE];
    int i;
    FILE *f = NULL;
    EVP_PKEY* pkey = NULL;

    RETURN_IF_NULL_PARAM(szFileName);
    RETURN_IF_NULL_PARAM(pSigBuf);
    RETURN_IF_NULL_PARAM(nSigLen);
    RETURN_IF_NULL_PARAM(keyfile);
    RETURN_IF_NULL_PARAM(passwd);

    memset(pSigBuf, 0, *nSigLen);
    if(nDigestType == DIGEST_SHA1) {
        if(*nSigLen >= SIGNATURE_LEN) {
            if((err = ReadPrivateKey(&pkey, keyfile, passwd, FILE_FORMAT_PEM)) == ERR_OK) {
                if((f = fopen(szFileName,"rb")) != NULL) {
                    EVP_SignInit(&ctx, EVP_sha1());
                    for (;;) {
                        i = fread(buf, sizeof(char), FILE_BUFSIZE, f);
                        if (i <= 0) break;
                        EVP_SignUpdate (&ctx, buf, (unsigned long)i);
                    }
                    err = EVP_SignFinal(&ctx, pSigBuf, (unsigned int*)nSigLen, pkey);
                    if(err == ERR_LIB_NONE)
                        err = ERR_OK;
                    fclose(f);
                    EVP_PKEY_free(pkey);
                } // if - fopen
                else
                    err = ERR_FILE_READ;
            }
            else
                err = ERR_PRIVKEY_READ;
        }
        else
            err = ERR_SIGNATURE_LEN;
    }
    else
        err = ERR_UNSUPPORTED_DIGEST;
    if (err != ERR_OK) SET_LAST_ERROR(err);
    return err;
}
Exemple #30
0
//--------------------------------------------------
// sends an OCSP_REQUES object to remore server and
// retrieves the OCSP_RESPONSE object
// resp - buffer to store the new responses pointer
// req - request objects pointer
// url - OCSP responder URL
//--------------------------------------------------
int ddocPullUrl(const char* url, DigiDocMemBuf* pSendData, DigiDocMemBuf* pRecvData,
                const char* proxyHost, const char* proxyPort)
{
    BIO* cbio = 0, *sbio = 0;
    SSL_CTX *ctx = NULL;
    char *host = NULL, *port = NULL, *path = "/", buf[200];
    int err = ERR_OK, use_ssl = -1, rc;
    long e;

    //RETURN_IF_NULL_PARAM(pSendData); // may be null if nothing to send?
    RETURN_IF_NULL_PARAM(pRecvData);
    RETURN_IF_NULL_PARAM(url);

    ddocDebug(4, "ddocPullUrl", "URL: %s, in: %d bytes", url, pSendData->nLen);
    //there is an HTTP proxy - connect to that instead of the target host
    if (proxyHost != 0 && *proxyHost != '\0') {
        host = (char*)proxyHost;
        if(proxyPort != 0 && *proxyPort != '\0')
            port = (char*)proxyPort;
        path = (char*)url;
    } else {
        if(OCSP_parse_url((char*)url, &host, &port, &path, &use_ssl) == 0) {
            ddocDebug(1, "ddocPullUrl", "Failed to parse the URL");
            return ERR_WRONG_URL_OR_PROXY;
        }
    }

    if((cbio = BIO_new_connect(host)) != 0) {
        ddocDebug(4, "ddocPullUrl", "Host: %s port: %s", host, port);
        if(port != NULL) {
            BIO_set_conn_port(cbio, port);
        }
        if(use_ssl == 1) {
            ctx = SSL_CTX_new(SSLv23_client_method());
            SSL_CTX_set_mode(ctx, SSL_MODE_AUTO_RETRY);
            sbio = BIO_new_ssl(ctx, 1);
            cbio = BIO_push(sbio, cbio);
        }
        if ((rc = BIO_do_connect(cbio)) > 0) {
            ddocDebug(4, "ddocPullUrl", "Connected: %d", rc);
            if(pSendData && pSendData->nLen && pSendData->pMem) {
                rc = BIO_write(cbio, pSendData->pMem, pSendData->nLen);
                ddocDebug(4, "ddocPullUrl", "Sent: %d bytes, got: %d", pSendData->nLen, rc);
            }
            do {
                memset(buf, 0, sizeof(buf));
                rc = BIO_read(cbio, buf, sizeof(buf)-1);
                ddocDebug(4, "ddocPullUrl", "Received: %d bytes\n", rc);
                if(rc > 0)
                    err = ddocMemAppendData(pRecvData, buf, rc);
            } while(rc > 0);
            ddocDebug(4, "ddocPullUrl", "Total received: %d bytes\n", pRecvData->nLen);
        } else {
            //if no connection
            e = checkErrors();
            if(ERR_GET_REASON(e) == BIO_R_BAD_HOSTNAME_LOOKUP ||
                    ERR_GET_REASON(e) == OCSP_R_SERVER_WRITE_ERROR)
                err = ERR_CONNECTION_FAILURE;
            else
                err = (host != NULL) ? ERR_WRONG_URL_OR_PROXY : ERR_CONNECTION_FAILURE;
        }
        BIO_free_all(cbio);
        if (use_ssl != -1) {
            OPENSSL_free(host);
            OPENSSL_free(port);
            OPENSSL_free(path);
            SSL_CTX_free(ctx);
        }
    }
    else
        err = ERR_CONNECTION_FAILURE;
    return(err);
}