void CryptoDocThread::decrypt() { err = dencEncryptedData_decryptData( d->enc ); DEncEncryptionProperty *prop = dencEncryptedData_FindEncryptionPropertyByName( d->enc, ENCPROP_ORIG_SIZE ); if( prop && prop->szContent ) { long size = QByteArray( prop->szContent ).toLong(); if( size > 0 && size < d->enc->mbufEncryptedData.nLen ) d->enc->mbufEncryptedData.nLen = size; } d->ddoc = new QTemporaryFile( QDir().tempPath() + "/XXXXXX" ); if( !d->ddoc->open() ) { lastError = CryptoDoc::tr("Failed to create temporary files<br />%1").arg( d->ddoc->errorString() ); return; } d->ddoc->write( (const char*)d->enc->mbufEncryptedData.pMem, d->enc->mbufEncryptedData.nLen ); d->ddoc->flush(); ddocMemBuf_free( &d->enc->mbufEncryptedData ); err = ddocSaxReadSignedDocFromFile( &d->doc, d->ddoc->fileName().toUtf8(), 0, 0 ); if( err != ERR_OK ) lastError = CryptoDoc::tr("Failed to read decrypted data"); else d->cleanProperties(); }
//-------------------------------------------------- // 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; }
//============================================================ // Sets the signatures certificate and calculates // certificate digest & serial number // pSigInfo - signature info object // cert - certficate //============================================================ EXP_OPTION int setSignatureCert(SignatureInfo* pSigInfo, X509* cert) { int err = ERR_OK; RETURN_IF_NULL_PARAM(pSigInfo); RETURN_IF_NULL_PARAM(cert); err = ddocSigInfo_addCert(pSigInfo, cert, CERTID_TYPE_SIGNERS_CERTID); // release old content if it exists ddocMemBuf_free(&(pSigInfo->mbufOrigContent)); return ERR_OK; }
STDMETHODIMP CComCertificate::get_szPropIssuerName(BSTR *pVal) { DigiDocMemBuf mbuf1, mbuf2; mbuf1.pMem = 0; mbuf1.nLen = 0; mbuf2.pMem = 0; mbuf2.nLen = 0; USES_CONVERSION; if (::ddocCertGetIssuerDN((X509*)m_pX509, &mbuf1) != 0) { SetBSTR(pVal,""); //*pVal = SysAllocString(A2OLE("")); } else { ddocMemSetLength(&mbuf2, mbuf1.nLen + 10); utf82oem((const char*)mbuf1.pMem, (char*)mbuf2.pMem, mbuf2.nLen); SetBSTR(pVal, (char*)mbuf2.pMem); //*pVal = SysAllocStringLen(A2OLE(buf), bLen); } ddocMemBuf_free(&mbuf1); ddocMemBuf_free(&mbuf2); return S_OK; }
STDMETHODIMP CComDigiDocLib::getCertIssuerName(long hCert, BSTR *pszStoreTo, long *nRetResult) { DigiDocMemBuf mbuf1, mbuf2; mbuf1.pMem = 0; mbuf1.nLen = 0; mbuf2.pMem = 0; mbuf2.nLen = 0; *nRetResult = ::ddocCertGetIssuerDN((X509*)hCert, &mbuf1); if (*nRetResult == 0) { // allocate as much mem in mbuf2 plus some extra. // Converting to 8 bit makes string shorter so this will be enought ddocMemSetLength(&mbuf2, mbuf1.nLen + 10); utf82oem((const char*)mbuf1.pMem, (char*)mbuf2.pMem, mbuf2.nLen); USES_CONVERSION; SetBSTR(pszStoreTo, (char*)mbuf2.pMem); //*pszStoreTo = SysAllocString(A2OLE(buf)); } ddocMemBuf_free(&mbuf1); ddocMemBuf_free(&mbuf2); return S_OK; }
STDMETHODIMP CComNotaryInfo::get_nextUpdate(BSTR *pVal) { DigiDocMemBuf mbuf1; mbuf1.pMem = 0; mbuf1.nLen = 0; if(m_pNotaryInfo) { ddocNotInfo_GetNextUpdate(getNotaryInfo(), &mbuf1); if(mbuf1.pMem) { Convert::out_retval_sz2BSTR((char*)mbuf1.pMem, pVal); ddocMemBuf_free(&mbuf1); } } return S_OK; }
int FLDigiDoc::verifyCertByOCSP(const QString &certfile) { X509 *pCert = 0; DigiDocMemBuf mbuf; mbuf.pMem = 0; mbuf.nLen = 0; int err = ReadCertificate(&pCert, certfile.latin1()); if (!err && pCert) { err = ddocVerifyCertByOCSP(pCert, NULL); err = ddocCertGetSubjectCN(pCert, &mbuf); ddocMemBuf_free(&mbuf); } if (pCert) { X509_free(pCert); pCert = 0; } return err; }
int FLDigiDoc::certIssuerDN(const QString &certfile, QString &issuerResult) { int err = ERR_OK; X509 *pCert = 0; DigiDocMemBuf mbuf; mbuf.pMem = 0; mbuf.nLen = 0; err = ReadCertificate(&pCert, certfile.latin1()); if (!err && pCert) { err = ddocCertGetIssuerDN(pCert, &mbuf); issuerResult = QString((const char *) mbuf.pMem); ddocMemBuf_free(&mbuf); } if (pCert) { X509_free(pCert); pCert = 0; } return err; }
int FLDigiDoc::certDigest(const QString &certfile, QByteArray &digestResult) { int err = ERR_OK, len1; char buf1[1024 * sizeof(char)]; X509 *pCert = 0; DigiDocMemBuf mbuf; mbuf.pMem = 0; mbuf.nLen = 0; err = ReadCertificate(&pCert, certfile.latin1()); if (!err && pCert) { len1 = sizeof(buf1); buf1[0] = 0; err = ddocCertGetDigest(pCert, &mbuf); encode((const byte *) mbuf.pMem, mbuf.nLen, (byte *) buf1, &len1); digestResult.duplicate((const char *) buf1, len1); ddocMemBuf_free(&mbuf); } if (pCert) { X509_free(pCert); pCert = 0; } return err; }
//-------------------------------------------------- // Helper function to return OCSP_RESPONSE in base64 form // Memory buffer will be resized as necessary. // Caller must release output buffer. // pNotary - Notary object // bHeaders - 1= with headers, 0=no headers // pMBufOutData - output data // returns error code or ERR_OK //-------------------------------------------------- EXP_OPTION int ddocGetOcspBase64(NotaryInfo *pNotary, int bHeaders, DigiDocMemBuf* pMBufOutData) { const DigiDocMemBuf *pMBuf = 0; DigiDocMemBuf mbuf1; RETURN_IF_NULL_PARAM(pNotary); RETURN_IF_NULL_PARAM(pMBufOutData); pMBufOutData->pMem = 0; pMBufOutData->nLen = 0; mbuf1.pMem = 0; mbuf1.nLen = 0; pMBuf = ddocNotInfo_GetOCSPResponse(pNotary); RETURN_IF_NULL(pMBuf); if(bHeaders) { ddocMemAppendData(pMBufOutData, "-----BEGIN OCSP RESPONSE-----\n", -1); ddocEncodeBase64(pMBuf, &mbuf1); ddocMemAppendData(pMBufOutData, (const char*)mbuf1.pMem, mbuf1.nLen); ddocMemAppendData(pMBufOutData, "\n-----END OCSP RESPONSE-----", -1); ddocMemBuf_free(&mbuf1); } else ddocEncodeBase64(pMBuf, pMBufOutData); return ERR_OK; }
//-------------------------------------------------- // Replaces a substring with another substring // pBuf1 - memory buffer to search in // pBuf2 - memory buffer to write converted value to // search - search value // replacement - replacement value //-------------------------------------------------- EXP_OPTION int ddocMemReplaceSubstr(DigiDocMemBuf* pBuf1, DigiDocMemBuf* pBuf2, const char* search, const char* replacement) { int err = ERR_OK, i, n; RETURN_IF_NULL_PARAM(pBuf1); RETURN_IF_NULL_PARAM(pBuf1->pMem); RETURN_IF_NULL_PARAM(pBuf2); RETURN_IF_NULL_PARAM(search); RETURN_IF_NULL_PARAM(replacement); //ddocDebug(7, "ddocMemReplaceSubstr", "Replace: \'%s\' with: \'%s\' in: \'%s\'", // search, replacement, (const char*)pBuf1->pMem); ddocMemBuf_free(pBuf2); n = strlen(search); for(i = 0; !err && (i < pBuf1->nLen); i++) { if(!strncmp((char*)pBuf1->pMem + i, search, n)) { // match err = ddocMemAppendData(pBuf2, replacement, -1); i += strlen(search) - 1; } else { // no match err = ddocMemAppendData(pBuf2, (char*)pBuf1->pMem + i, 1); } } return err; }
//============================================================ // 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; }
//============================================================ // 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; }
//============================================================ // 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; }
//-------------------------------------------------- // 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; }
bool CryptoDoc::decrypt() { if( isNull() ) { setLastError( tr("Container is not open") ); return false; } if( !isEncrypted() ) return true; DEncEncryptedKey *key = 0; for( int i = 0; i < m_enc->nEncryptedKeys; ++i ) { DEncEncryptedKey *tmp = m_enc->arrEncryptedKeys[i]; if( qApp->poller()->token().cert() == SslCertificate::fromX509( Qt::HANDLE(tmp->pCert) ) ) { key = tmp; break; } } if( !key ) { setLastError( tr("You do not have the key to decrypt this document") ); return false; } QByteArray in( (const char*)key->mbufTransportKey.pMem, key->mbufTransportKey.nLen ), out; bool decrypted = false; while( !decrypted ) { switch( qApp->poller()->decrypt( in, out ) ) { case Poller::DecryptOK: decrypted = true; break; case Poller::PinIncorrect: break; default: return false; } } ddocMemAssignData( &m_enc->mbufTransportKey, out.constData(), out.size() ); m_enc->nKeyStatus = DENC_KEY_STATUS_INITIALIZED; int err = dencEncryptedData_decryptData( m_enc ); if( err != ERR_OK ) { setLastError( tr("Failed decrypt data"), err ); return false; } DEncEncryptionProperty *prop = dencEncryptedData_FindEncryptionPropertyByName( m_enc, ENCPROP_ORIG_SIZE ); if( prop && prop->szContent ) { long size = QByteArray( prop->szContent ).toLong(); if( size > 0 && size < m_enc->mbufEncryptedData.nLen ) m_enc->mbufEncryptedData.nLen = size; } QString docName = QFileInfo( m_fileName ).fileName(); m_ddocTemp = Common::tempFilename(); removeFolder( m_ddocTemp ); QDir().mkdir( m_ddocTemp ); m_ddoc = QString( "%1/%2.ddoc" ).arg( m_ddocTemp ).arg( docName ); QFile f( m_ddoc ); if( !f.open( QIODevice::WriteOnly|QIODevice::Truncate ) ) { setLastError( tr("Failed to create temporary files<br />%1").arg( f.errorString() ) ); return false; } f.write( (const char*)m_enc->mbufEncryptedData.pMem, m_enc->mbufEncryptedData.nLen ); f.close(); ddocMemBuf_free( &m_enc->mbufEncryptedData ); err = ddocSaxReadSignedDocFromFile( &m_doc, f.fileName().toUtf8(), 0, 0 ); if( err != ERR_OK ) { setLastError( tr("Failed to read decrypted data"), err ); return false; } for( int i = 0; i < m_doc->nDataFiles; ++i ) { QString file = QString( "%1/%2" ).arg( m_ddocTemp ) .arg( QString::fromUtf8( m_doc->pDataFiles[i]->szFileName ) ); if( QFile::exists( file ) ) QFile::remove( file ); err = ddocSaxExtractDataFile( m_doc, m_ddoc.toUtf8(), file.toUtf8(), m_doc->pDataFiles[i]->szId, CHARSET_UTF_8 ); if( err == ERR_OK ) { ddocMemAssignString( &m_doc->pDataFiles[i]->szFileName, file.toUtf8() ); QFile::setPermissions( file, QFile::ReadOwner ); } else setLastError( tr("Failed to save file '%1'").arg( file ), err ); } cleanProperties(); return !isEncrypted(); }