//-------------------------------------------------- // 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; }
//-------------------------------------------------- // 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; }