16#include <config_crypto.h>
18#include <rtl/character.hxx>
19#include <rtl/strbuf.hxx>
20#include <rtl/string.hxx>
22#include <tools/datetime.hxx>
30#include <com/sun/star/security/XCertificate.hpp>
31#include <com/sun/star/uno/Sequence.hxx>
48#include <com/sun/star/xml/crypto/DigestID.hpp>
49#include <com/sun/star/xml/crypto/NSSInitializer.hpp>
67void appendHex(
sal_Int8 nInt, OStringBuffer& rBuffer )
69 static const char pHexDigits[] = {
'0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
70 '8',
'9',
'A',
'B',
'C',
'D',
'E',
'F' };
71 rBuffer.append( pHexDigits[ (nInt >> 4) & 15 ] );
72 rBuffer.append( pHexDigits[ nInt & 15 ] );
77char *PDFSigningPKCS7PasswordCallback(PK11SlotInfo * , PRBool ,
void *arg)
79 return PL_strdup(
static_cast<char *
>(arg));
98struct MessageImprint {
99 SECAlgorithmID hashAlgorithm;
100 SECItem hashedMessage;
136 MessageImprint messageImprint;
165 SECItem serialNumber;
174 SECAlgorithmID hashAlgorithm;
176 IssuerSerial issuerSerial;
182struct SigningCertificateV2
186 SigningCertificateV2()
205const SEC_ASN1Template GeneralNameTemplate[] =
207 {SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(GeneralName)},
208 {SEC_ASN1_INLINE, offsetof(GeneralName, name), CERT_NameTemplate, 0},
215const SEC_ASN1Template GeneralNamesTemplate[] =
217 {SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(GeneralNames)},
218 {SEC_ASN1_INLINE | SEC_ASN1_CONTEXT_SPECIFIC | 4, offsetof(GeneralNames, names), GeneralNameTemplate, 0},
228const SEC_ASN1Template IssuerSerialTemplate[] =
230 {SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(IssuerSerial)},
231 {SEC_ASN1_INLINE, offsetof(IssuerSerial, issuer), GeneralNamesTemplate, 0},
232 {SEC_ASN1_INTEGER, offsetof(IssuerSerial, serialNumber),
nullptr, 0},
247SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
249const SEC_ASN1Template ESSCertIDv2Template[] =
251 {SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(ESSCertIDv2)},
252 {SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(ESSCertIDv2, hashAlgorithm), SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate), 0},
253 {SEC_ASN1_OCTET_STRING, offsetof(ESSCertIDv2, certHash),
nullptr, 0},
254 {SEC_ASN1_INLINE | SEC_ASN1_XTRN, offsetof(ESSCertIDv2, issuerSerial), IssuerSerialTemplate, 0},
262const SEC_ASN1Template SigningCertificateV2Template[] =
264 {SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(SigningCertificateV2)},
265 {SEC_ASN1_SEQUENCE_OF, offsetof(SigningCertificateV2, certs), ESSCertIDv2Template, 0},
269struct PKIStatusInfo {
271 SECItem statusString;
275const SEC_ASN1Template PKIStatusInfo_Template[] =
277 { SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(PKIStatusInfo) },
278 { SEC_ASN1_INTEGER, offsetof(PKIStatusInfo, status),
nullptr, 0 },
279 { SEC_ASN1_CONSTRUCTED | SEC_ASN1_SEQUENCE | SEC_ASN1_OPTIONAL, offsetof(PKIStatusInfo, statusString),
nullptr, 0 },
280 { SEC_ASN1_BIT_STRING | SEC_ASN1_OPTIONAL, offsetof(PKIStatusInfo, failInfo),
nullptr, 0 },
284const SEC_ASN1Template Any_Template[] =
286 { SEC_ASN1_ANY, 0,
nullptr,
sizeof(SECItem) }
289struct TimeStampResp {
290 PKIStatusInfo status;
291 SECItem timeStampToken;
294const SEC_ASN1Template TimeStampResp_Template[] =
296 { SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(TimeStampResp) },
297 { SEC_ASN1_INLINE, offsetof(TimeStampResp, status), PKIStatusInfo_Template, 0 },
298 { SEC_ASN1_ANY | SEC_ASN1_OPTIONAL, offsetof(TimeStampResp, timeStampToken), Any_Template, 0 },
302const SEC_ASN1Template MessageImprint_Template[] =
304 { SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(MessageImprint) },
305 { SEC_ASN1_INLINE, offsetof(MessageImprint, hashAlgorithm), SECOID_AlgorithmIDTemplate, 0 },
306 { SEC_ASN1_OCTET_STRING, offsetof(MessageImprint, hashedMessage),
nullptr, 0 },
310const SEC_ASN1Template Extension_Template[] =
312 { SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(
Extension) },
313 { SEC_ASN1_OBJECT_ID, offsetof(Extension, extnID),
nullptr, 0 },
314 { SEC_ASN1_BOOLEAN, offsetof(Extension, critical),
nullptr, 0 },
315 { SEC_ASN1_OCTET_STRING, offsetof(Extension, extnValue),
nullptr, 0 },
319const SEC_ASN1Template Extensions_Template[] =
321 { SEC_ASN1_SEQUENCE_OF, 0, Extension_Template, 0 }
324const SEC_ASN1Template TimeStampReq_Template[] =
326 { SEC_ASN1_SEQUENCE, 0,
nullptr,
sizeof(TimeStampReq) },
327 { SEC_ASN1_INTEGER, offsetof(TimeStampReq, version),
nullptr, 0 },
328 { SEC_ASN1_INLINE, offsetof(TimeStampReq, messageImprint), MessageImprint_Template, 0 },
329 { SEC_ASN1_OBJECT_ID | SEC_ASN1_OPTIONAL, offsetof(TimeStampReq, reqPolicy),
nullptr, 0 },
330 { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(TimeStampReq, nonce),
nullptr, 0 },
331 { SEC_ASN1_BOOLEAN | SEC_ASN1_OPTIONAL, offsetof(TimeStampReq, certReq),
nullptr, 0 },
332 { SEC_ASN1_OPTIONAL | SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(TimeStampReq,
extensions), Extensions_Template, 0 },
336size_t AppendToBuffer(
char const *ptr,
size_t size,
size_t nmemb,
void *userdata)
338 OStringBuffer *pBuffer =
static_cast<OStringBuffer*
>(userdata);
339 pBuffer->append(ptr, size*nmemb);
344OUString PKIStatusToString(
int n)
348 case 0:
return "granted";
349 case 1:
return "grantedWithMods";
350 case 2:
return "rejection";
351 case 3:
return "waiting";
352 case 4:
return "revocationWarning";
353 case 5:
return "revocationNotification";
354 default:
return "unknown (" + OUString::number(n) +
")";
358OUString PKIStatusInfoToString(
const PKIStatusInfo& rStatusInfo)
360 OUString
result =
"{status=";
361 if (rStatusInfo.status.len == 1)
362 result += PKIStatusToString(rStatusInfo.status.data[0]);
364 result +=
"unknown (len=" + OUString::number(rStatusInfo.status.len);
383my_SEC_StringToOID(SECItem *to,
const char *from, PRUint32 len)
385 PRUint32 decimal_numbers = 0;
386 PRUint32 result_bytes = 0;
390 static const PRUint32 max_decimal = 0xffffffff / 10;
391 static const char OIDstring[] = {
"OID."};
394 PORT_SetError(SEC_ERROR_INVALID_ARGS);
398 len = PL_strlen(from);
400 if (len >= 4 && !PL_strncasecmp(from, OIDstring, 4)) {
406 PORT_SetError(SEC_ERROR_BAD_DATA);
410 PRUint32 decimal = 0;
411 while (len > 0 && rtl::isAsciiDigit(
static_cast<unsigned char>(*from))) {
412 PRUint32 addend = *
from++ -
'0';
414 if (decimal > max_decimal)
416 decimal = (decimal * 10) + addend;
417 if (decimal < addend)
420 if (len != 0 && *from !=
'.') {
423 if (decimal_numbers == 0) {
428 }
else if (decimal_numbers == 1) {
435 PRUint32 num_bytes = 0;
436 PRUint32 tmp = decimal;
443 if (num_bytes + result_bytes >
sizeof result)
446 rp =
result + result_bytes - 1;
447 rp[tmp] =
static_cast<PRUint8
>(decimal & 0x7f);
450 rp[tmp] =
static_cast<PRUint8
>(decimal | 0x80);
453 result_bytes += num_bytes;
462 if (
to->data &&
to->len >= result_bytes) {
463 to->len = result_bytes;
464 PORT_Memcpy(
to->data, result,
to->len);
467 SECItem result_item = {siBuffer,
nullptr, 0 };
468 result_item.data =
result;
469 result_item.len = result_bytes;
470 rv = SECITEM_CopyItem(
nullptr, to, &result_item);
476my_NSS_CMSAttributeArray_FindAttrByOidTag(NSSCMSAttribute **attrs, SECOidTag oidtag, PRBool only)
479 NSSCMSAttribute *attr1, *attr2;
481 if (attrs ==
nullptr)
484 oid = SECOID_FindOIDByTag(oidtag);
488 while ((attr1 = *attrs++) !=
nullptr) {
489 if (attr1->type.len == oid->oid.len && PORT_Memcmp (attr1->type.data,
495 if (attr1 ==
nullptr)
501 while ((attr2 = *attrs++) !=
nullptr) {
502 if (attr2->type.len == oid->oid.len && PORT_Memcmp (attr2->type.data,
508 if (attr2 !=
nullptr)
515my_NSS_CMSArray_Add(PLArenaPool *poolp,
void ***array,
void *obj)
520 PORT_Assert(array != NULL);
521 if (array ==
nullptr)
524 if (*array ==
nullptr) {
525 dest =
static_cast<void **
>(PORT_ArenaAlloc(poolp, 2 *
sizeof(
void *)));
530 dest =
static_cast<void **
>(PORT_ArenaGrow (poolp,
532 (n + 1) *
sizeof(
void *),
533 (n + 2) *
sizeof(
void *)));
546my_NSS_CMSAttribute_GetType(
const NSSCMSAttribute *attr)
550 typetag = SECOID_FindOID(&(attr->type));
551 if (typetag ==
nullptr)
552 return SEC_OID_UNKNOWN;
554 return typetag->offset;
558my_NSS_CMSAttributeArray_AddAttr(PLArenaPool *poolp, NSSCMSAttribute ***attrs, NSSCMSAttribute *attr)
560 NSSCMSAttribute *oattr;
564 mark = PORT_ArenaMark(poolp);
567 type = my_NSS_CMSAttribute_GetType(attr);
570 oattr = my_NSS_CMSAttributeArray_FindAttrByOidTag(*attrs, type, PR_FALSE);
571 PORT_Assert (oattr == NULL);
572 if (oattr !=
nullptr)
576 if (my_NSS_CMSArray_Add(poolp,
reinterpret_cast<void ***
>(attrs),
static_cast<void *
>(attr)) != SECSuccess)
579 PORT_ArenaUnmark(poolp, mark);
583 PORT_ArenaRelease(poolp, mark);
588my_NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
590 return my_NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->unAuthAttr), attr);
594my_NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
596 return my_NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->authAttr), attr);
599NSSCMSMessage *CreateCMSMessage(
const PRTime* time,
600 NSSCMSSignedData **cms_sd,
601 NSSCMSSignerInfo **cms_signer,
602 CERTCertificate *cert,
605 NSSCMSMessage *
result = NSS_CMSMessage_Create(
nullptr);
608 SAL_WARN(
"svl.crypto",
"NSS_CMSMessage_Create failed");
612 *cms_sd = NSS_CMSSignedData_Create(result);
615 SAL_WARN(
"svl.crypto",
"NSS_CMSSignedData_Create failed");
616 NSS_CMSMessage_Destroy(result);
620 NSSCMSContentInfo *cms_cinfo = NSS_CMSMessage_GetContentInfo(result);
621 if (NSS_CMSContentInfo_SetContent_SignedData(result, cms_cinfo, *cms_sd) != SECSuccess)
623 SAL_WARN(
"svl.crypto",
"NSS_CMSContentInfo_SetContent_SignedData failed");
624 NSS_CMSSignedData_Destroy(*cms_sd);
625 NSS_CMSMessage_Destroy(result);
629 cms_cinfo = NSS_CMSSignedData_GetContentInfo(*cms_sd);
632 if (NSS_CMSContentInfo_SetContent_Data(result, cms_cinfo,
nullptr, PR_TRUE) != SECSuccess)
634 SAL_WARN(
"svl.crypto",
"NSS_CMSContentInfo_SetContent_Data failed");
635 NSS_CMSSignedData_Destroy(*cms_sd);
636 NSS_CMSMessage_Destroy(result);
642 if (SECKEYPrivateKey * pPrivateKey = PK11_FindKeyByAnyCert(cert,
nullptr))
647 SECKEY_DestroyPrivateKey(pPrivateKey);
649 *cms_signer = NSS_CMSSignerInfo_Create(result, cert, SEC_OID_SHA256);
653 pPrivateKey = PK11_FindKeyByDERCert(cert->slot, cert,
nullptr);
654 SECKEYPublicKey *
const pPublicKey = CERT_ExtractPublicKey(cert);
655 if (pPublicKey && pPrivateKey)
657 *cms_signer = NSS_CMSSignerInfo_CreateWithSubjKeyID(result, &cert->subjectKeyID, pPublicKey, pPrivateKey, SEC_OID_SHA256);
658 SECKEY_DestroyPrivateKey(pPrivateKey);
659 SECKEY_DestroyPublicKey(pPublicKey);
664 (**cms_signer).cert = CERT_DupCertificate(cert);
670 SAL_WARN(
"svl.crypto",
"NSS_CMSSignerInfo_Create failed");
671 NSS_CMSSignedData_Destroy(*cms_sd);
672 NSS_CMSMessage_Destroy(result);
676 if (time && NSS_CMSSignerInfo_AddSigningTime(*cms_signer, *time) != SECSuccess)
678 SAL_WARN(
"svl.crypto",
"NSS_CMSSignerInfo_AddSigningTime failed");
679 NSS_CMSSignedData_Destroy(*cms_sd);
680 NSS_CMSMessage_Destroy(result);
684 if (NSS_CMSSignerInfo_IncludeCerts(*cms_signer, NSSCMSCM_CertChain, certUsageEmailSigner) != SECSuccess)
686 SAL_WARN(
"svl.crypto",
"NSS_CMSSignerInfo_IncludeCerts failed");
687 NSS_CMSSignedData_Destroy(*cms_sd);
688 NSS_CMSMessage_Destroy(result);
692 if (NSS_CMSSignedData_AddCertificate(*cms_sd, cert) != SECSuccess)
694 SAL_WARN(
"svl.crypto",
"NSS_CMSSignedData_AddCertificate failed");
695 NSS_CMSSignedData_Destroy(*cms_sd);
696 NSS_CMSMessage_Destroy(result);
700 if (NSS_CMSSignedData_AddSignerInfo(*cms_sd, *cms_signer) != SECSuccess)
702 SAL_WARN(
"svl.crypto",
"NSS_CMSSignedData_AddSignerInfo failed");
703 NSS_CMSSignedData_Destroy(*cms_sd);
704 NSS_CMSMessage_Destroy(result);
708 if (NSS_CMSSignedData_SetDigestValue(*cms_sd, SEC_OID_SHA256, digest) != SECSuccess)
710 SAL_WARN(
"svl.crypto",
"NSS_CMSSignedData_SetDigestValue failed");
711 NSS_CMSSignedData_Destroy(*cms_sd);
712 NSS_CMSMessage_Destroy(result);
719#elif USE_CRYPTO_MSCAPI
722size_t GetDERLengthOfLength(
size_t nLength)
728 while (nLength >> (nRet * 8))
738void WriteDERLength(
SvStream& rStream,
size_t nLength)
740 size_t nLengthOfLength = GetDERLengthOfLength(nLength);
741 if (nLengthOfLength == 1)
750 rStream.
WriteUInt8(0x80 | (nLengthOfLength - 1));
751 for (
size_t i = 1;
i < nLengthOfLength; ++
i)
752 rStream.
WriteUInt8(nLength >> ((nLengthOfLength - i - 1) * 8));
755const unsigned nASN1_INTEGER = 0x02;
756const unsigned nASN1_OCTET_STRING = 0x04;
757const unsigned nASN1_NULL = 0x05;
758const unsigned nASN1_OBJECT_IDENTIFIER = 0x06;
759const unsigned nASN1_SEQUENCE = 0x10;
761const unsigned nASN1_TAGGED_CONSTRUCTED = 0xa0;
762const unsigned nASN1_CONSTRUCTED = 0x20;
765bool CreateSigningCertificateAttribute(
void const * pDerEncoded,
int nDerEncoded, PCCERT_CONTEXT pCertContext,
SvStream& rEncodedCertificate)
773 std::vector<unsigned char> aSHA256{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01};
775 HCRYPTPROV hProv = 0;
776 if (!CryptAcquireContextW(&hProv,
nullptr,
nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
778 SAL_WARN(
"svl.crypto",
"CryptAcquireContext() failed");
782 HCRYPTHASH hHash = 0;
783 if (!CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash))
785 SAL_WARN(
"svl.crypto",
"CryptCreateHash() failed");
789 if (!CryptHashData(hHash,
static_cast<const BYTE*
>(pDerEncoded), nDerEncoded, 0))
791 SAL_WARN(
"svl.crypto",
"CryptHashData() failed");
796 if (!CryptGetHashParam(hHash, HP_HASHVAL,
nullptr, &nHash, 0))
798 SAL_WARN(
"svl.crypto",
"CryptGetHashParam() failed to provide the hash length");
802 std::vector<unsigned char> aHash(nHash);
803 if (!CryptGetHashParam(hHash, HP_HASHVAL, aHash.data(), &nHash, 0))
805 SAL_WARN(
"svl.crypto",
"CryptGetHashParam() failed to provide the hash");
809 CryptDestroyHash(hHash);
810 CryptReleaseContext(hProv, 0);
813 BYTE* pIssuer = pCertContext->pCertInfo->Issuer.pbData;
814 DWORD nIssuer = pCertContext->pCertInfo->Issuer.cbData;
815 BYTE* pSerial = pCertContext->pCertInfo->SerialNumber.pbData;
816 DWORD nSerial = pCertContext->pCertInfo->SerialNumber.cbData;
818 std::vector<BYTE> aSerial(nSerial);
819 for (
size_t i = 0;
i < nSerial; ++
i)
820 aSerial[i] = *(pSerial + nSerial - i - 1);
837 size_t nAlgorithm = 1 + GetDERLengthOfLength(aSHA256.size()) + aSHA256.size();
838 size_t nParameters = 1 + GetDERLengthOfLength(1);
839 size_t nAlgorithmIdentifier = 1 + GetDERLengthOfLength(nAlgorithm + nParameters) + nAlgorithm + nParameters;
840 size_t nCertHash = 1 + GetDERLengthOfLength(aHash.size()) + aHash.size();
841 size_t nName = 1 + GetDERLengthOfLength(nIssuer) + nIssuer;
842 size_t nGeneralNames = 1 + GetDERLengthOfLength(nName) + nName;
843 size_t nCertificateSerialNumber = 1 + GetDERLengthOfLength(nSerial) + nSerial;
844 size_t nIssuerSerial = 1 + GetDERLengthOfLength(nGeneralNames + nCertificateSerialNumber) + nGeneralNames + nCertificateSerialNumber;
845 size_t nESSCertIDv2 = 1 + GetDERLengthOfLength(nAlgorithmIdentifier + nCertHash + nIssuerSerial) + nAlgorithmIdentifier + nCertHash + nIssuerSerial;
846 size_t nESSCertIDv2s = 1 + GetDERLengthOfLength(nESSCertIDv2) + nESSCertIDv2;
849 rEncodedCertificate.
WriteUInt8(nASN1_SEQUENCE | nASN1_CONSTRUCTED);
850 WriteDERLength(rEncodedCertificate, nESSCertIDv2s);
852 rEncodedCertificate.
WriteUInt8(nASN1_SEQUENCE | nASN1_CONSTRUCTED);
853 WriteDERLength(rEncodedCertificate, nESSCertIDv2);
855 rEncodedCertificate.
WriteUInt8(nASN1_SEQUENCE | nASN1_CONSTRUCTED);
856 WriteDERLength(rEncodedCertificate, nAlgorithmIdentifier + nCertHash + nIssuerSerial);
858 rEncodedCertificate.
WriteUInt8(nASN1_SEQUENCE | nASN1_CONSTRUCTED);
859 WriteDERLength(rEncodedCertificate, nAlgorithm + nParameters);
861 rEncodedCertificate.
WriteUInt8(nASN1_OBJECT_IDENTIFIER);
862 WriteDERLength(rEncodedCertificate, aSHA256.size());
863 rEncodedCertificate.
WriteBytes(aSHA256.data(), aSHA256.size());
868 rEncodedCertificate.
WriteUInt8(nASN1_OCTET_STRING);
869 WriteDERLength(rEncodedCertificate, aHash.size());
870 rEncodedCertificate.
WriteBytes(aHash.data(), aHash.size());
872 rEncodedCertificate.
WriteUInt8(nASN1_SEQUENCE | nASN1_CONSTRUCTED);
873 WriteDERLength(rEncodedCertificate, nGeneralNames + nCertificateSerialNumber);
875 rEncodedCertificate.
WriteUInt8(nASN1_SEQUENCE | nASN1_CONSTRUCTED);
876 WriteDERLength(rEncodedCertificate, nName);
878 rEncodedCertificate.
WriteUInt8(nASN1_TAGGED_CONSTRUCTED | 4);
879 WriteDERLength(rEncodedCertificate, nIssuer);
880 rEncodedCertificate.
WriteBytes(pIssuer, nIssuer);
882 rEncodedCertificate.
WriteUInt8(nASN1_INTEGER);
883 WriteDERLength(rEncodedCertificate, nSerial);
884 rEncodedCertificate.
WriteBytes(aSerial.data(), aSerial.size());
897 if (rtl::isAsciiDigit(
static_cast<unsigned char>(
ch)))
901 if (
ch >=
'a' &&
ch <=
'f')
903 else if (
ch >=
'A' &&
ch <=
'F')
914 std::vector<unsigned char> aRet;
915 size_t nHexLen = rHex.size();
919 for (
size_t i = 0;
i < nHexLen; ++
i)
925 SAL_WARN(
"svl.crypto",
"DecodeHexString: invalid hex value");
932 aRet.push_back(nByte);
949 css::uno::Sequence<sal_Int8> aDerEncoded =
m_xCertificate->getEncoded();
950 if (!aDerEncoded.hasElements())
952 SAL_WARN(
"svl.crypto",
"Crypto::Signing: empty certificate");
957 CERTCertificate *cert = CERT_DecodeCertFromPackage(
reinterpret_cast<char *
>(aDerEncoded.getArray()), aDerEncoded.getLength());
961 SAL_WARN(
"svl.crypto",
"CERT_DecodeCertFromPackage failed");
965 std::vector<unsigned char> aHashResult;
970 aHash.
update(
static_cast<const unsigned char*
>(pair.first), pair.second);
975 digest.data = aHashResult.data();
976 digest.len = aHashResult.size();
978 PRTime
now = PR_Now();
979 NSSCMSSignedData *cms_sd(
nullptr);
980 NSSCMSSignerInfo *cms_signer(
nullptr);
981 NSSCMSMessage *cms_msg = CreateCMSMessage(
nullptr, &cms_sd, &cms_signer, cert, &digest);
988 OStringBuffer response_buffer;
989 TimeStampResp response;
990 SECItem response_item;
991 NSSCMSAttribute timestamp;
995 valuesp[1] =
nullptr;
1004 NSSCMSSignedData *ts_cms_sd;
1005 NSSCMSSignerInfo *ts_cms_signer;
1006 NSSCMSMessage *ts_cms_msg = CreateCMSMessage(&
now, &ts_cms_sd, &ts_cms_signer, cert, &digest);
1012 SECItem ts_cms_output;
1013 ts_cms_output.data =
nullptr;
1014 ts_cms_output.len = 0;
1015 PLArenaPool *ts_arena = PORT_NewArena(10000);
1016 NSSCMSEncoderContext *ts_cms_ecx;
1017 ts_cms_ecx = NSS_CMSEncoder_Start(ts_cms_msg,
nullptr,
nullptr, &ts_cms_output, ts_arena, PDFSigningPKCS7PasswordCallback,
1018 const_cast<char*
>(
pass.getStr()),
nullptr,
nullptr,
nullptr,
nullptr);
1020 if (NSS_CMSEncoder_Finish(ts_cms_ecx) != SECSuccess)
1022 SAL_WARN(
"svl.crypto",
"NSS_CMSEncoder_Finish failed");
1031 ts_digest.type = siBuffer;
1032 ts_digest.data = aTsHashResult.data();
1033 ts_digest.len = aTsHashResult.size();
1035 unsigned char cOne = 1;
1036 src.version.type = siUnsignedInteger;
1037 src.version.data = &cOne;
1038 src.version.len =
sizeof(cOne);
1040 src.messageImprint.hashAlgorithm.algorithm.data =
nullptr;
1041 src.messageImprint.hashAlgorithm.parameters.data =
nullptr;
1042 SECOID_SetAlgorithmID(
nullptr, &src.messageImprint.hashAlgorithm, SEC_OID_SHA256,
nullptr);
1043 src.messageImprint.hashedMessage = ts_digest;
1045 src.reqPolicy.type = siBuffer;
1046 src.reqPolicy.data =
nullptr;
1047 src.reqPolicy.len = 0;
1050 src.nonce.type = siUnsignedInteger;
1051 src.nonce.data =
reinterpret_cast<unsigned char*
>(&nNonce);
1052 src.nonce.len =
sizeof(nNonce);
1054 src.certReq.type = siUnsignedInteger;
1055 src.certReq.data = &cOne;
1056 src.certReq.len =
sizeof(cOne);
1058 src.extensions =
nullptr;
1060 SECItem* timestamp_request = SEC_ASN1EncodeItem(
nullptr,
nullptr, &src, TimeStampReq_Template);
1061 if (timestamp_request ==
nullptr)
1063 SAL_WARN(
"svl.crypto",
"SEC_ASN1EncodeItem failed");
1067 if (timestamp_request->data ==
nullptr)
1069 SAL_WARN(
"svl.crypto",
"SEC_ASN1EncodeItem succeeded but got NULL data");
1070 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1074 SAL_INFO(
"svl.crypto",
"request length=" << timestamp_request->len);
1078 CURL* curl = curl_easy_init();
1080 struct curl_slist* slist =
nullptr;
1084 SAL_WARN(
"svl.crypto",
"curl_easy_init failed");
1085 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1089 SAL_INFO(
"svl.crypto",
"Setting curl to verbose: " << (curl_easy_setopt(curl, CURLOPT_VERBOSE, 1) == CURLE_OK ?
"OK" :
"FAIL"));
1093 SAL_WARN(
"svl.crypto",
"curl_easy_setopt(CURLOPT_URL) failed: " << curl_easy_strerror(rc));
1094 curl_easy_cleanup(curl);
1095 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1099 slist = curl_slist_append(slist,
"Content-Type: application/timestamp-query");
1100 slist = curl_slist_append(slist,
"Accept: application/timestamp-reply");
1102 if ((rc = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist)) != CURLE_OK)
1104 SAL_WARN(
"svl.crypto",
"curl_easy_setopt(CURLOPT_HTTPHEADER) failed: " << curl_easy_strerror(rc));
1105 curl_slist_free_all(slist);
1106 curl_easy_cleanup(curl);
1107 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1111 if ((rc = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE,
static_cast<tools::Long>(timestamp_request->len))) != CURLE_OK ||
1112 (rc = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, timestamp_request->data)) != CURLE_OK)
1114 SAL_WARN(
"svl.crypto",
"curl_easy_setopt(CURLOPT_POSTFIELDSIZE or CURLOPT_POSTFIELDS) failed: " << curl_easy_strerror(rc));
1115 curl_easy_cleanup(curl);
1116 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1120 if ((rc = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_buffer)) != CURLE_OK ||
1121 (rc = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, AppendToBuffer)) != CURLE_OK)
1123 SAL_WARN(
"svl.crypto",
"curl_easy_setopt(CURLOPT_WRITEDATA or CURLOPT_WRITEFUNCTION) failed: " << curl_easy_strerror(rc));
1124 curl_easy_cleanup(curl);
1125 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1129 if ((rc = curl_easy_setopt(curl, CURLOPT_POST, 1)) != CURLE_OK)
1131 SAL_WARN(
"svl.crypto",
"curl_easy_setopt(CURLOPT_POST) failed: " << curl_easy_strerror(rc));
1132 curl_easy_cleanup(curl);
1133 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1137 char error_buffer[CURL_ERROR_SIZE];
1138 if ((rc = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, error_buffer)) != CURLE_OK)
1140 SAL_WARN(
"svl.crypto",
"curl_easy_setopt(CURLOPT_ERRORBUFFER) failed: " << curl_easy_strerror(rc));
1141 curl_easy_cleanup(curl);
1142 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1147 if ((rc = curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10)) != CURLE_OK ||
1148 (rc = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10)) != CURLE_OK)
1150 SAL_WARN(
"svl.crypto",
"curl_easy_setopt(CURLOPT_TIMEOUT or CURLOPT_CONNECTTIMEOUT) failed: " << curl_easy_strerror(rc));
1151 curl_easy_cleanup(curl);
1152 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1156 if (curl_easy_perform(curl) != CURLE_OK)
1158 SAL_WARN(
"svl.crypto",
"curl_easy_perform failed: " << error_buffer);
1159 curl_easy_cleanup(curl);
1160 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1164 SAL_INFO(
"svl.crypto",
"PDF signing: got response, length=" << response_buffer.getLength());
1166 curl_slist_free_all(slist);
1167 curl_easy_cleanup(curl);
1168 SECITEM_FreeItem(timestamp_request, PR_TRUE);
1170 memset(&response, 0,
sizeof(response));
1172 response_item.type = siBuffer;
1173 response_item.data =
reinterpret_cast<unsigned char*
>(
const_cast<char*
>(response_buffer.getStr()));
1174 response_item.len = response_buffer.getLength();
1176 if (SEC_ASN1DecodeItem(
nullptr, &response, TimeStampResp_Template, &response_item) != SECSuccess)
1178 SAL_WARN(
"svl.crypto",
"SEC_ASN1DecodeItem failed");
1182 SAL_INFO(
"svl.crypto",
"TimeStampResp received and decoded, status=" << PKIStatusInfoToString(response.status));
1184 if (response.status.status.len != 1 ||
1185 (response.status.status.data[0] != 0 && response.status.status.data[0] != 1))
1187 SAL_WARN(
"svl.crypto",
"Timestamp request was not granted");
1196 values[0] = response.timeStampToken;
1197 values[1].type = siBuffer;
1198 values[1].data =
nullptr;
1201 timestamp.values = valuesp;
1203 typetag.oid.data =
nullptr;
1207 if (my_SEC_StringToOID(&typetag.oid,
"1.2.840.113549.1.9.16.2.14", 0) != SECSuccess)
1209 SAL_WARN(
"svl.crypto",
"SEC_StringToOID failed");
1212 typetag.offset = SEC_OID_UNKNOWN;
1213 typetag.desc =
"id-aa-timeStampToken";
1214 typetag.mechanism = CKM_SHA_1;
1215 typetag.supportedExtension = UNSUPPORTED_CERT_EXTENSION;
1216 timestamp.typeTag = &typetag;
1218 timestamp.type = typetag.oid;
1220 timestamp.encoded = PR_TRUE;
1222 if (my_NSS_CMSSignerInfo_AddUnauthAttr(cms_signer, ×tamp) != SECSuccess)
1224 SAL_WARN(
"svl.crypto",
"NSS_CMSSignerInfo_AddUnauthAttr failed");
1230 ESSCertIDv2* aCertIDs[2];
1231 ESSCertIDv2 aCertID;
1233 aCertID.hashAlgorithm.algorithm.data =
nullptr;
1234 aCertID.hashAlgorithm.parameters.data =
nullptr;
1235 SECOID_SetAlgorithmID(
nullptr, &aCertID.hashAlgorithm, SEC_OID_SHA256,
nullptr);
1237 [&aCertID] () { SECOID_DestroyAlgorithmID(&aCertID.hashAlgorithm,
false); } );
1239 SECItem aCertHashItem;
1240 auto pDerEncoded =
reinterpret_cast<const unsigned char *
>(aDerEncoded.getArray());
1242 aCertHashItem.type = siBuffer;
1243 aCertHashItem.data = aCertHashResult.data();
1244 aCertHashItem.len = aCertHashResult.size();
1245 aCertID.certHash = aCertHashItem;
1247 IssuerSerial aSerial;
1249 aName.name = cert->issuer;
1250 aSerial.issuer.names =
aName;
1251 aSerial.serialNumber = cert->serialNumber;
1252 aCertID.issuerSerial = aSerial;
1254 aCertIDs[0] = &aCertID;
1255 aCertIDs[1] =
nullptr;
1256 SigningCertificateV2 aCertificate;
1257 aCertificate.certs = &aCertIDs[0];
1258 SECItem* pEncodedCertificate = SEC_ASN1EncodeItem(
nullptr,
nullptr, &aCertificate, SigningCertificateV2Template);
1259 if (!pEncodedCertificate)
1261 SAL_WARN(
"svl.crypto",
"SEC_ASN1EncodeItem() failed");
1265 NSSCMSAttribute aAttribute;
1266 SECItem aAttributeValues[2];
1267 SECItem* pAttributeValues[2];
1268 pAttributeValues[0] = aAttributeValues;
1269 pAttributeValues[1] =
nullptr;
1270 aAttributeValues[0] = *pEncodedCertificate;
1271 aAttributeValues[1].type = siBuffer;
1272 aAttributeValues[1].data =
nullptr;
1273 aAttributeValues[1].len = 0;
1274 aAttribute.values = pAttributeValues;
1276 SECOidData aOidData;
1277 aOidData.oid.data =
nullptr;
1283 if (my_SEC_StringToOID(&aOidData.oid,
"1.2.840.113549.1.9.16.2.47", 0) != SECSuccess)
1285 SAL_WARN(
"svl.crypto",
"my_SEC_StringToOID() failed");
1289 [&aOidData] () { SECITEM_FreeItem(&aOidData.oid,
false); } );
1290 aOidData.offset = SEC_OID_UNKNOWN;
1291 aOidData.desc =
"id-aa-signingCertificateV2";
1292 aOidData.mechanism = CKM_SHA_1;
1293 aOidData.supportedExtension = UNSUPPORTED_CERT_EXTENSION;
1294 aAttribute.typeTag = &aOidData;
1295 aAttribute.type = aOidData.oid;
1296 aAttribute.encoded = PR_TRUE;
1298 if (my_NSS_CMSSignerInfo_AddAuthAttr(cms_signer, &aAttribute) != SECSuccess)
1300 SAL_WARN(
"svl.crypto",
"my_NSS_CMSSignerInfo_AddAuthAttr() failed");
1305 cms_output.data =
nullptr;
1307 PLArenaPool *arena = PORT_NewArena(10000);
1308 const ::comphelper::ScopeGuard aScopeGuard(
1309 [&arena]()
mutable { PORT_FreeArena(arena,
true); } );
1310 NSSCMSEncoderContext *cms_ecx;
1317 cms_ecx = NSS_CMSEncoder_Start(cms_msg,
nullptr,
nullptr, &cms_output, arena, PDFSigningPKCS7PasswordCallback,
1318 const_cast<char*
>(
pass.getStr()),
nullptr,
nullptr,
nullptr,
nullptr);
1322 SAL_WARN(
"svl.crypto",
"NSS_CMSEncoder_Start failed");
1326 if (NSS_CMSEncoder_Finish(cms_ecx) != SECSuccess)
1328 SAL_WARN(
"svl.crypto",
"NSS_CMSEncoder_Finish failed");
1335 NSS_CMSMessage_Destroy(cms_msg);
1339 for (
unsigned int i = 0;
i < cms_output.len ;
i++)
1340 appendHex(cms_output.data[
i], rCMSHexBuffer);
1342 SECITEM_FreeItem(pEncodedCertificate, PR_TRUE);
1343 NSS_CMSMessage_Destroy(cms_msg);
1347#elif USE_CRYPTO_MSCAPI
1349 PCCERT_CONTEXT pCertContext = CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
reinterpret_cast<const BYTE*
>(aDerEncoded.getArray()), aDerEncoded.getLength());
1350 if (pCertContext ==
nullptr)
1352 SAL_WARN(
"svl.crypto",
"CertCreateCertificateContext failed: " << WindowsErrorString(GetLastError()));
1356 CRYPT_SIGN_MESSAGE_PARA aPara = {};
1357 aPara.cbSize =
sizeof(aPara);
1358 aPara.dwMsgEncodingType = PKCS_7_ASN_ENCODING | X509_ASN_ENCODING;
1359 aPara.pSigningCert = pCertContext;
1360 aPara.HashAlgorithm.pszObjId =
const_cast<LPSTR
>(szOID_NIST_sha256);
1361 aPara.HashAlgorithm.Parameters.cbData = 0;
1363 aPara.rgpMsgCert = &pCertContext;
1365 NCRYPT_KEY_HANDLE hCryptKey = 0;
1366 DWORD dwFlags = CRYPT_ACQUIRE_CACHE_FLAG | CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG;
1367 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE* phCryptProvOrNCryptKey = &hCryptKey;
1371 if (!CryptAcquireCertificatePrivateKey(pCertContext,
1374 phCryptProvOrNCryptKey,
1378 SAL_WARN(
"svl.crypto",
"CryptAcquireCertificatePrivateKey failed: " << WindowsErrorString(GetLastError()));
1379 CertFreeCertificateContext(pCertContext);
1382 assert(!bFreeNeeded);
1384 CMSG_SIGNER_ENCODE_INFO aSignerInfo = {};
1385 aSignerInfo.cbSize =
sizeof(aSignerInfo);
1386 aSignerInfo.pCertInfo = pCertContext->pCertInfo;
1387 aSignerInfo.hNCryptKey = hCryptKey;
1388 aSignerInfo.dwKeySpec = nKeySpec;
1389 aSignerInfo.HashAlgorithm.pszObjId =
const_cast<LPSTR
>(szOID_NIST_sha256);
1390 aSignerInfo.HashAlgorithm.Parameters.cbData = 0;
1393 CRYPT_INTEGER_BLOB aCertificateBlob;
1395 if (!CreateSigningCertificateAttribute(aDerEncoded.getArray(), aDerEncoded.getLength(), pCertContext, aEncodedCertificate))
1397 SAL_WARN(
"svl.crypto",
"CreateSigningCertificateAttribute() failed");
1400 aCertificateBlob.pbData =
const_cast<BYTE*
>(
static_cast<const BYTE*
>(aEncodedCertificate.
GetData()));
1401 aCertificateBlob.cbData = aEncodedCertificate.
GetSize();
1402 CRYPT_ATTRIBUTE aCertificateAttribute;
1408 aCertificateAttribute.pszObjId =
const_cast<LPSTR
>(
"1.2.840.113549.1.9.16.2.47");
1409 aCertificateAttribute.cValue = 1;
1410 aCertificateAttribute.rgValue = &aCertificateBlob;
1411 aSignerInfo.cAuthAttr = 1;
1412 aSignerInfo.rgAuthAttr = &aCertificateAttribute;
1414 CMSG_SIGNED_ENCODE_INFO aSignedInfo = {};
1415 aSignedInfo.cbSize =
sizeof(aSignedInfo);
1416 aSignedInfo.cSigners = 1;
1417 aSignedInfo.rgSigners = &aSignerInfo;
1419 CERT_BLOB aCertBlob;
1421 aCertBlob.cbData = pCertContext->cbCertEncoded;
1422 aCertBlob.pbData = pCertContext->pbCertEncoded;
1424 aSignedInfo.cCertEncoded = 1;
1425 aSignedInfo.rgCertEncoded = &aCertBlob;
1427 HCRYPTMSG hMsg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
1435 SAL_WARN(
"svl.crypto",
"CryptMsgOpenToEncode failed: " << WindowsErrorString(GetLastError()));
1436 CertFreeCertificateContext(pCertContext);
1445 SAL_WARN(
"svl.crypto",
"CryptMsgUpdate failed: " << WindowsErrorString(GetLastError()));
1446 CryptMsgClose(hMsg);
1447 CertFreeCertificateContext(pCertContext);
1452 PCRYPT_TIMESTAMP_CONTEXT pTsContext =
nullptr;
1456 HCRYPTMSG hDecodedMsg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
1464 SAL_WARN(
"svl.crypto",
"CryptMsgOpenToDecode failed: " << WindowsErrorString(GetLastError()));
1465 CryptMsgClose(hMsg);
1466 CertFreeCertificateContext(pCertContext);
1470 DWORD nTsSigLen = 0;
1472 if (!CryptMsgGetParam(hMsg, CMSG_BARE_CONTENT_PARAM, 0,
nullptr, &nTsSigLen))
1474 SAL_WARN(
"svl.crypto",
"CryptMsgGetParam(CMSG_BARE_CONTENT_PARAM) failed: " << WindowsErrorString(GetLastError()));
1475 CryptMsgClose(hDecodedMsg);
1476 CryptMsgClose(hMsg);
1477 CertFreeCertificateContext(pCertContext);
1481 SAL_INFO(
"svl.crypto",
"nTsSigLen=" << nTsSigLen);
1483 std::unique_ptr<BYTE[]> pTsSig(
new BYTE[nTsSigLen]);
1485 if (!CryptMsgGetParam(hMsg, CMSG_BARE_CONTENT_PARAM, 0, pTsSig.get(), &nTsSigLen))
1487 SAL_WARN(
"svl.crypto",
"CryptMsgGetParam(CMSG_BARE_CONTENT_PARAM) failed: " << WindowsErrorString(GetLastError()));
1488 CryptMsgClose(hDecodedMsg);
1489 CryptMsgClose(hMsg);
1490 CertFreeCertificateContext(pCertContext);
1494 if (!CryptMsgUpdate(hDecodedMsg, pTsSig.get(), nTsSigLen,
TRUE))
1496 SAL_WARN(
"svl.crypto",
"CryptMsgUpdate failed: " << WindowsErrorString(GetLastError()));
1497 CryptMsgClose(hDecodedMsg);
1498 CryptMsgClose(hMsg);
1499 CertFreeCertificateContext(pCertContext);
1503 DWORD nDecodedSignerInfoLen = 0;
1504 if (!CryptMsgGetParam(hDecodedMsg, CMSG_SIGNER_INFO_PARAM, 0,
nullptr, &nDecodedSignerInfoLen))
1506 SAL_WARN(
"svl.crypto",
"CryptMsgGetParam(CMSG_SIGNER_INFO_PARAM) failed: " << WindowsErrorString(GetLastError()));
1507 CryptMsgClose(hDecodedMsg);
1508 CryptMsgClose(hMsg);
1509 CertFreeCertificateContext(pCertContext);
1513 std::unique_ptr<BYTE[]> pDecodedSignerInfoBuf(
new BYTE[nDecodedSignerInfoLen]);
1515 if (!CryptMsgGetParam(hDecodedMsg, CMSG_SIGNER_INFO_PARAM, 0, pDecodedSignerInfoBuf.get(), &nDecodedSignerInfoLen))
1517 SAL_WARN(
"svl.crypto",
"CryptMsgGetParam(CMSG_SIGNER_INFO_PARAM) failed: " << WindowsErrorString(GetLastError()));
1518 CryptMsgClose(hDecodedMsg);
1519 CryptMsgClose(hMsg);
1520 CertFreeCertificateContext(pCertContext);
1524 CMSG_SIGNER_INFO *pDecodedSignerInfo =
reinterpret_cast<CMSG_SIGNER_INFO *
>(pDecodedSignerInfoBuf.get());
1526 CRYPT_TIMESTAMP_PARA aTsPara;
1529 aTsPara.pszTSAPolicyId =
nullptr;
1530 aTsPara.fRequestCerts =
TRUE;
1531 aTsPara.Nonce.cbData =
sizeof(nNonce);
1532 aTsPara.Nonce.pbData =
reinterpret_cast<BYTE *
>(&nNonce);
1533 aTsPara.cExtension = 0;
1534 aTsPara.rgExtension =
nullptr;
1536 if (!CryptRetrieveTimeStamp(o3tl::toW(
m_aSignTSA.getStr()),
1541 pDecodedSignerInfo->EncryptedHash.pbData,
1542 pDecodedSignerInfo->EncryptedHash.cbData,
1547 SAL_WARN(
"svl.crypto",
"CryptRetrieveTimeStamp failed: " << WindowsErrorString(GetLastError()));
1548 CryptMsgClose(hDecodedMsg);
1549 CryptMsgClose(hMsg);
1550 CertFreeCertificateContext(pCertContext);
1554 SAL_INFO(
"svl.crypto",
"Time stamp size is " << pTsContext->cbEncoded <<
" bytes");
1562 CRYPT_INTEGER_BLOB aTimestampBlob;
1563 aTimestampBlob.cbData = pTsContext->cbEncoded;
1564 aTimestampBlob.pbData = pTsContext->pbEncoded;
1566 CRYPT_ATTRIBUTE aTimestampAttribute;
1567 aTimestampAttribute.pszObjId =
const_cast<LPSTR
>(
1568 "1.2.840.113549.1.9.16.2.14");
1569 aTimestampAttribute.cValue = 1;
1570 aTimestampAttribute.rgValue = &aTimestampBlob;
1572 aSignerInfo.cUnauthAttr = 1;
1573 aSignerInfo.rgUnauthAttr = &aTimestampAttribute;
1575 CryptMsgClose(hMsg);
1577 hMsg = CryptMsgOpenToEncode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
1590 SAL_WARN(
"svl.crypto",
"Re-creating the message failed: " << WindowsErrorString(GetLastError()));
1591 CryptMemFree(pTsContext);
1592 CryptMsgClose(hDecodedMsg);
1593 CryptMsgClose(hMsg);
1594 CertFreeCertificateContext(pCertContext);
1599 CryptMsgClose(hDecodedMsg);
1604 if (!CryptMsgGetParam(hMsg, CMSG_CONTENT_PARAM, 0,
nullptr, &nSigLen))
1606 SAL_WARN(
"svl.crypto",
"CryptMsgGetParam(CMSG_CONTENT_PARAM) failed: " << WindowsErrorString(GetLastError()));
1608 CryptMemFree(pTsContext);
1609 CryptMsgClose(hMsg);
1610 CertFreeCertificateContext(pCertContext);
1618 CryptMemFree(pTsContext);
1619 CryptMsgClose(hMsg);
1620 CertFreeCertificateContext(pCertContext);
1624 SAL_INFO(
"svl.crypto",
"Signature size is " << nSigLen <<
" bytes");
1625 std::unique_ptr<BYTE[]> pSig(
new BYTE[nSigLen]);
1627 if (!CryptMsgGetParam(hMsg, CMSG_CONTENT_PARAM, 0, pSig.get(), &nSigLen))
1629 SAL_WARN(
"svl.crypto",
"CryptMsgGetParam(CMSG_CONTENT_PARAM) failed: " << WindowsErrorString(GetLastError()));
1631 CryptMemFree(pTsContext);
1632 CryptMsgClose(hMsg);
1633 CertFreeCertificateContext(pCertContext);
1639 CryptMemFree(pTsContext);
1640 CryptMsgClose(hMsg);
1641 CertFreeCertificateContext(pCertContext);
1643 for (
unsigned int i = 0;
i < nSigLen ;
i++)
1644 appendHex(pSig[
i], rCMSHexBuffer);
1655NSSCMSAttribute* CMSAttributeArray_FindAttrByOidData(NSSCMSAttribute** attrs, SECOidData
const * oid, PRBool only)
1657 NSSCMSAttribute* attr1, *attr2;
1659 if (attrs ==
nullptr)
1665 while ((attr1 = *attrs++) !=
nullptr)
1667 if (attr1->type.len == oid->oid.len && PORT_Memcmp(attr1->type.data,
1673 if (attr1 ==
nullptr)
1679 while ((attr2 = *attrs++) !=
nullptr)
1681 if (attr2->type.len == oid->oid.len && PORT_Memcmp(attr2->type.data,
1687 if (attr2 !=
nullptr)
1694SECStatus StringToOID(SECItem* to,
const char* from, PRUint32 len)
1696 PRUint32 decimal_numbers = 0;
1697 PRUint32 result_bytes = 0;
1701 static const PRUint32 max_decimal = 0xffffffff / 10;
1702 static const char OIDstring[] = {
"OID."};
1706 PORT_SetError(SEC_ERROR_INVALID_ARGS);
1711 len = PL_strlen(from);
1713 if (len >= 4 && !PL_strncasecmp(from, OIDstring, 4))
1721 PORT_SetError(SEC_ERROR_BAD_DATA);
1726 PRUint32 decimal = 0;
1727 while (len > 0 && rtl::isAsciiDigit(
static_cast<unsigned char>(*from)))
1729 PRUint32 addend = *
from++ -
'0';
1731 if (decimal > max_decimal)
1733 decimal = (decimal * 10) + addend;
1734 if (decimal < addend)
1737 if (len != 0 && *from !=
'.')
1741 if (decimal_numbers == 0)
1745 result[0] = decimal * 40;
1748 else if (decimal_numbers == 1)
1758 PRUint32 num_bytes = 0;
1759 PRUint32 tmp = decimal;
1767 if (
static_cast<size_t>(num_bytes) + result_bytes >
sizeof result)
1770 rp =
result + result_bytes - 1;
1771 rp[tmp] =
static_cast<PRUint8
>(decimal & 0x7f);
1775 rp[tmp] =
static_cast<PRUint8
>(decimal | 0x80);
1778 result_bytes += num_bytes;
1789 if (
to->data &&
to->len >= result_bytes)
1791 to->len = result_bytes;
1792 PORT_Memcpy(
to->data, result,
to->len);
1797 SECItem result_item = {siBuffer,
nullptr, 0 };
1798 result_item.data =
result;
1799 result_item.len = result_bytes;
1800 rv = SECITEM_CopyItem(
nullptr, to, &result_item);
1805#elif USE_CRYPTO_MSCAPI
1808bool VerifyNonDetachedSignature(
const std::vector<unsigned char>& aData,
const std::vector<BYTE>& rExpectedHash)
1810 HCRYPTPROV hProv = 0;
1811 if (!CryptAcquireContextW(&hProv,
nullptr,
nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
1813 SAL_WARN(
"svl.crypto",
"CryptAcquireContext() failed");
1817 HCRYPTHASH hHash = 0;
1818 if (!CryptCreateHash(hProv, CALG_SHA1, 0, 0, &hHash))
1820 SAL_WARN(
"svl.crypto",
"CryptCreateHash() failed");
1824 if (!CryptHashData(hHash,
aData.data(),
aData.size(), 0))
1826 SAL_WARN(
"svl.crypto",
"CryptHashData() failed");
1830 DWORD nActualHash = 0;
1831 if (!CryptGetHashParam(hHash, HP_HASHVAL,
nullptr, &nActualHash, 0))
1833 SAL_WARN(
"svl.crypto",
"CryptGetHashParam() failed to provide the hash length");
1837 std::vector<unsigned char> aActualHash(nActualHash);
1838 if (!CryptGetHashParam(hHash, HP_HASHVAL, aActualHash.data(), &nActualHash, 0))
1840 SAL_WARN(
"svl.crypto",
"CryptGetHashParam() failed to provide the hash");
1844 CryptDestroyHash(hHash);
1845 CryptReleaseContext(hProv, 0);
1847 return aActualHash.size() == rExpectedHash.size() &&
1848 !std::memcmp(aActualHash.data(), rExpectedHash.data(), aActualHash.size());
1851OUString GetSubjectName(PCCERT_CONTEXT pCertContext)
1856 DWORD dwData = CertGetNameStringW(pCertContext,
1857 CERT_NAME_SIMPLE_DISPLAY_TYPE,
1864 SAL_WARN(
"svl.crypto",
"ValidateSignature: CertGetNameString failed");
1869 LPWSTR szName =
static_cast<LPWSTR
>(
1870 LocalAlloc(LPTR, dwData *
sizeof(WCHAR)));
1873 SAL_WARN(
"svl.crypto",
"ValidateSignature: Unable to allocate memory for subject name");
1878 if (!CertGetNameStringW(pCertContext,
1879 CERT_NAME_SIMPLE_DISPLAY_TYPE,
1886 SAL_WARN(
"svl.crypto",
"ValidateSignature: CertGetNameString failed");
1898 void ensureNssInit()
1901 css::uno::Reference<css::xml::crypto::XNSSInitializer>
1905 xNSSInitializer->getDigestContext(css::xml::crypto::DigestID::SHA256,
1906 uno::Sequence<beans::NamedValue>());
1912 const bool bNonDetached,
1913 const std::vector<unsigned char>& aSignature,
1918 static std::once_flag aInitOnce;
1919 std::call_once(aInitOnce, ensureNssInit);
1922 SECItem aSignatureItem;
1923 aSignatureItem.data =
const_cast<unsigned char*
>(aSignature.data());
1924 aSignatureItem.len = aSignature.size();
1925 NSSCMSMessage* pCMSMessage = NSS_CMSMessage_CreateFromDER(&aSignatureItem,
1932 if (!NSS_CMSMessage_IsSigned(pCMSMessage))
1934 SAL_WARN(
"svl.crypto",
"ValidateSignature: message is not signed");
1938 NSSCMSContentInfo* pCMSContentInfo = NSS_CMSMessage_ContentLevel(pCMSMessage, 0);
1939 if (!pCMSContentInfo)
1941 SAL_WARN(
"svl.crypto",
"ValidateSignature: NSS_CMSMessage_ContentLevel() failed");
1945 auto pCMSSignedData =
static_cast<NSSCMSSignedData*
>(NSS_CMSContentInfo_GetContent(pCMSContentInfo));
1946 if (!pCMSSignedData)
1948 SAL_WARN(
"svl.crypto",
"ValidateSignature: NSS_CMSContentInfo_GetContent() failed");
1955 std::vector<CERTCertificate*> aDocumentCertificates;
1956 for (
size_t i = 0; pCMSSignedData->rawCerts[
i]; ++
i)
1957 aDocumentCertificates.push_back(
CERT_NewTempCertificate(CERT_GetDefaultCertDB(), pCMSSignedData->rawCerts[
i],
nullptr, 0, 0));
1959 NSSCMSSignerInfo* pCMSSignerInfo = NSS_CMSSignedData_GetSignerInfo(pCMSSignedData, 0);
1960 if (!pCMSSignerInfo)
1962 SAL_WARN(
"svl.crypto",
"ValidateSignature: NSS_CMSSignedData_GetSignerInfo() failed");
1966 SECItem aAlgorithm = NSS_CMSSignedData_GetDigestAlgs(pCMSSignedData)[0]->algorithm;
1967 SECOidTag eOidTag = SECOID_FindOIDTag(&aAlgorithm);
1973 case SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION:
1974 eOidTag = SEC_OID_SHA1;
1976 case SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION:
1977 eOidTag = SEC_OID_SHA256;
1979 case SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION:
1980 eOidTag = SEC_OID_SHA512;
1986 HASH_HashType eHashType = HASH_GetHashTypeByOidTag(eOidTag);
1987 HASHContext* pHASHContext = HASH_Create(eHashType);
1990 SAL_WARN(
"svl.crypto",
"ValidateSignature: HASH_Create() failed");
1995 HASH_Update(pHASHContext,
aData.data(),
aData.size());
1998 unsigned int nMaxResultLen = 0;
2003 rInformation.
nDigestID = xml::crypto::DigestID::SHA1;
2005 case SEC_OID_SHA256:
2007 rInformation.
nDigestID = xml::crypto::DigestID::SHA256;
2009 case SEC_OID_SHA512:
2011 rInformation.
nDigestID = xml::crypto::DigestID::SHA512;
2014 SAL_WARN(
"svl.crypto",
"ValidateSignature: unrecognized algorithm");
2018 auto pActualResultBuffer =
static_cast<unsigned char*
>(PORT_Alloc(nMaxResultLen));
2019 unsigned int nActualResultLen;
2020 HASH_End(pHASHContext, pActualResultBuffer, &nActualResultLen, nMaxResultLen);
2022 CERTCertificate* pCertificate = NSS_CMSSignerInfo_GetSigningCertificate(pCMSSignerInfo, CERT_GetDefaultCertDB());
2025 SAL_WARN(
"svl.crypto",
"ValidateSignature: NSS_CMSSignerInfo_GetSigningCertificate() failed");
2030 uno::Sequence<sal_Int8> aDerCert(pCertificate->derCert.len);
2031 auto aDerCertRange = asNonConstRange(aDerCert);
2032 for (
size_t i = 0;
i < pCertificate->derCert.len; ++
i)
2033 aDerCertRange[
i] = pCertificate->derCert.data[
i];
2037 temp.emplace_back();
2038 temp.back().X509Certificate =
aBuffer.makeStringAndClear();
2039 temp.back().X509Subject = OUString(pCertificate->subjectName, PL_strlen(pCertificate->subjectName), RTL_TEXTENCODING_UTF8);
2041 rInformation.
X509Datas.emplace_back(temp);
2044 PRTime nSigningTime;
2047 if (NSS_CMSSignerInfo_GetSigningTime(pCMSSignerInfo, &nSigningTime) == SECSuccess)
2058 OUStringBuffer rBuffer;
2059 rBuffer.append(
static_cast<sal_Int32
>(aDateTime.
GetYear()));
2060 rBuffer.append(
'-');
2062 rBuffer.append(
'0');
2063 rBuffer.append(
static_cast<sal_Int32
>(aDateTime.
GetMonth()));
2064 rBuffer.append(
'-');
2065 if (aDateTime.
GetDay() < 10)
2066 rBuffer.append(
'0');
2067 rBuffer.append(
static_cast<sal_Int32
>(aDateTime.
GetDay()));
2068 rInformation.
ouDateTime = rBuffer.makeStringAndClear();
2073 SECOidData aOidData;
2074 aOidData.oid.data =
nullptr;
2080 if (StringToOID(&aOidData.oid,
"1.2.840.113549.1.9.16.2.47", 0) != SECSuccess)
2082 SAL_WARN(
"svl.crypto",
"StringToOID() failed");
2085 aOidData.offset = SEC_OID_UNKNOWN;
2086 aOidData.desc =
"id-aa-signingCertificateV2";
2087 aOidData.mechanism = CKM_SHA_1;
2088 aOidData.supportedExtension = UNSUPPORTED_CERT_EXTENSION;
2089 NSSCMSAttribute* pAttribute = CMSAttributeArray_FindAttrByOidData(pCMSSignerInfo->authAttr, &aOidData, PR_TRUE);
2093 SECItem* pContentInfoContentData = pCMSSignedData->contentInfo.content.data;
2094 if (bNonDetached && pContentInfoContentData && pContentInfoContentData->data)
2097 if (!std::memcmp(pActualResultBuffer, pContentInfoContentData->data, nMaxResultLen) && nActualResultLen == pContentInfoContentData->len)
2098 rInformation.
nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
2103 SECItem aActualResultItem;
2104 aActualResultItem.data = pActualResultBuffer;
2105 aActualResultItem.len = nActualResultLen;
2106 if (NSS_CMSSignerInfo_Verify(pCMSSignerInfo, &aActualResultItem,
nullptr) == SECSuccess)
2107 rInformation.
nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
2111 SECITEM_FreeItem(&aOidData.oid,
false);
2112 PORT_Free(pActualResultBuffer);
2113 HASH_Destroy(pHASHContext);
2114 NSS_CMSSignerInfo_Destroy(pCMSSignerInfo);
2115 for (
auto pDocumentCertificate : aDocumentCertificates)
2116 CERT_DestroyCertificate(pDocumentCertificate);
2120#elif USE_CRYPTO_MSCAPI
2123 HCRYPTMSG hMsg = CryptMsgOpenToDecode(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
2131 SAL_WARN(
"svl.crypto",
"ValidateSignature: CryptMsgOpenToDecode() failed");
2136 if (!CryptMsgUpdate(hMsg, aSignature.data(), aSignature.size(),
TRUE))
2138 SAL_WARN(
"svl.crypto",
"ValidateSignature, CryptMsgUpdate() for the header failed: " << WindowsErrorString(GetLastError()));
2145 SAL_WARN(
"svl.crypto",
"ValidateSignature, CryptMsgUpdate() for the content failed: " << WindowsErrorString(GetLastError()));
2149 if (!CryptMsgUpdate(hMsg,
nullptr, 0,
TRUE))
2151 SAL_WARN(
"svl.crypto",
"ValidateSignature, CryptMsgUpdate() for the last content failed: " << WindowsErrorString(GetLastError()));
2156 DWORD nDigestID = 0;
2157 if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_HASH_ALGORITHM_PARAM, 0,
nullptr, &nDigestID))
2159 SAL_WARN(
"svl.crypto",
"ValidateSignature: CryptMsgGetParam() failed: " << WindowsErrorString(GetLastError()));
2162 std::unique_ptr<BYTE[]> pDigestBytes(
new BYTE[nDigestID]);
2163 if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_HASH_ALGORITHM_PARAM, 0, pDigestBytes.get(), &nDigestID))
2165 SAL_WARN(
"svl.crypto",
"ValidateSignature: CryptMsgGetParam() failed: " << WindowsErrorString(GetLastError()));
2168 auto pDigestID =
reinterpret_cast<CRYPT_ALGORITHM_IDENTIFIER*
>(pDigestBytes.get());
2169 if (std::string_view(szOID_NIST_sha256) == pDigestID->pszObjId)
2170 rInformation.
nDigestID = xml::crypto::DigestID::SHA256;
2171 else if (std::string_view(szOID_RSA_SHA1RSA) == pDigestID->pszObjId || std::string_view(szOID_OIWSEC_sha1) == pDigestID->pszObjId)
2172 rInformation.
nDigestID = xml::crypto::DigestID::SHA1;
2175 SAL_WARN(
"svl.crypto",
"ValidateSignature: unhandled algorithm identifier '"<<pDigestID->pszObjId<<
"'");
2178 DWORD nSignerCertInfo = 0;
2179 if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_INFO_PARAM, 0,
nullptr, &nSignerCertInfo))
2181 SAL_WARN(
"svl.crypto",
"ValidateSignature: CryptMsgGetParam() failed");
2184 std::unique_ptr<BYTE[]> pSignerCertInfoBuf(
new BYTE[nSignerCertInfo]);
2185 if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_CERT_INFO_PARAM, 0, pSignerCertInfoBuf.get(), &nSignerCertInfo))
2187 SAL_WARN(
"svl.crypto",
"ValidateSignature: CryptMsgGetParam() failed");
2190 PCERT_INFO pSignerCertInfo =
reinterpret_cast<PCERT_INFO
>(pSignerCertInfoBuf.get());
2194 HCERTSTORE hStoreHandle = CertOpenStore(CERT_STORE_PROV_MSG,
2195 PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
2201 SAL_WARN(
"svl.crypto",
"ValidateSignature: CertOpenStore() failed");
2206 PCCERT_CONTEXT pSignerCertContext = CertGetSubjectCertificateFromStore(hStoreHandle,
2207 PKCS_7_ASN_ENCODING | X509_ASN_ENCODING,
2209 if (!pSignerCertContext)
2211 SAL_WARN(
"svl.crypto",
"ValidateSignature: CertGetSubjectCertificateFromStore() failed");
2217 uno::Sequence<sal_Int8> aDerCert(pSignerCertContext->cbCertEncoded);
2218 std::copy_n(pSignerCertContext->pbCertEncoded, pSignerCertContext->cbCertEncoded,
2219 aDerCert.getArray());
2223 temp.emplace_back();
2224 temp.back().X509Certificate =
aBuffer.makeStringAndClear();
2225 temp.back().X509Subject = GetSubjectName(pSignerCertContext);
2227 rInformation.
X509Datas.emplace_back(temp);
2233 DWORD nContentParam = 0;
2234 if (!CryptMsgGetParam(hMsg, CMSG_CONTENT_PARAM, 0,
nullptr, &nContentParam))
2236 SAL_WARN(
"svl.crypto",
"ValidateSignature: CryptMsgGetParam() failed");
2240 std::vector<BYTE> aContentParam(nContentParam);
2241 if (!CryptMsgGetParam(hMsg, CMSG_CONTENT_PARAM, 0, aContentParam.data(), &nContentParam))
2243 SAL_WARN(
"svl.crypto",
"ValidateSignature: CryptMsgGetParam() failed");
2247 if (VerifyNonDetachedSignature(
aData, aContentParam))
2248 rInformation.
nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
2254 if (CryptMsgControl(hMsg, 0, CMSG_CTRL_VERIFY_SIGNATURE, pSignerCertContext->pCertInfo))
2255 rInformation.
nStatus = xml::crypto::SecurityOperationStatus_OPERATION_SUCCEEDED;
2259 DWORD nSignedAttributes = 0;
2260 if (CryptMsgGetParam(hMsg, CMSG_SIGNER_AUTH_ATTR_PARAM, 0,
nullptr, &nSignedAttributes))
2262 std::unique_ptr<BYTE[]> pSignedAttributesBuf(
new BYTE[nSignedAttributes]);
2263 if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_AUTH_ATTR_PARAM, 0, pSignedAttributesBuf.get(), &nSignedAttributes))
2265 SAL_WARN(
"svl.crypto",
"ValidateSignature: CryptMsgGetParam() authenticated failed");
2268 auto pSignedAttributes =
reinterpret_cast<PCRYPT_ATTRIBUTES
>(pSignedAttributesBuf.get());
2269 for (
size_t nAttr = 0; nAttr < pSignedAttributes->cAttr; ++nAttr)
2271 CRYPT_ATTRIBUTE& rAttr = pSignedAttributes->rgAttr[nAttr];
2277 if (std::string_view(
"1.2.840.113549.1.9.16.2.47") == rAttr.pszObjId)
2286 nSignedAttributes = 0;
2287 if (CryptMsgGetParam(hMsg, CMSG_SIGNER_UNAUTH_ATTR_PARAM, 0,
nullptr, &nSignedAttributes))
2289 std::unique_ptr<BYTE[]> pSignedAttributesBuf(
new BYTE[nSignedAttributes]);
2290 if (!CryptMsgGetParam(hMsg, CMSG_SIGNER_UNAUTH_ATTR_PARAM, 0, pSignedAttributesBuf.get(), &nSignedAttributes))
2292 SAL_WARN(
"svl.crypto",
"ValidateSignature: CryptMsgGetParam() unauthenticated failed");
2295 auto pSignedAttributes =
reinterpret_cast<PCRYPT_ATTRIBUTES
>(pSignedAttributesBuf.get());
2296 for (
size_t nAttr = 0; nAttr < pSignedAttributes->cAttr; ++nAttr)
2298 CRYPT_ATTRIBUTE& rAttr = pSignedAttributes->rgAttr[nAttr];
2300 if (std::string_view(
"1.2.840.113549.1.9.16.2.14") == rAttr.pszObjId)
2302 PCRYPT_TIMESTAMP_CONTEXT pTsContext;
2303 if (!CryptVerifyTimeStampSignature(rAttr.rgValue->pbData, rAttr.rgValue->cbData,
nullptr, 0,
nullptr, &pTsContext,
nullptr,
nullptr))
2305 SAL_WARN(
"svl.crypto",
"CryptMsgUpdate failed: " << WindowsErrorString(GetLastError()));
2316 OUStringBuffer rBuffer;
2317 rBuffer.append(
static_cast<sal_Int32
>(aDateTime.
GetYear()));
2318 rBuffer.append(
'-');
2320 rBuffer.append(
'0');
2321 rBuffer.append(
static_cast<sal_Int32
>(aDateTime.
GetMonth()));
2322 rBuffer.append(
'-');
2323 if (aDateTime.
GetDay() < 10)
2324 rBuffer.append(
'0');
2325 rBuffer.append(
static_cast<sal_Int32
>(aDateTime.
GetDay()));
2326 rInformation.
ouDateTime = rBuffer.makeStringAndClear();
2333 CertCloseStore(hStoreHandle, CERT_CLOSE_STORE_FORCE_FLAG);
2334 CryptMsgClose(hMsg);
2347 const std::vector<std::pair<size_t, size_t>>& aByteRanges,
2348 const bool bNonDetached,
2349 const std::vector<unsigned char>& aSignature,
2353 std::vector<unsigned char> buffer;
2356 for (
const auto& rByteRange : aByteRanges)
2358 rStream.
Seek(rByteRange.first);
2359 const size_t size = buffer.size();
2360 buffer.resize(
size + rByteRange.second);
2364 return Verify(buffer, bNonDetached, aSignature, rInformation);
static DateTime CreateFromUnixTime(const double fSecondsSinceEpoch)
void ConvertToLocalTime()
css::util::DateTime GetUNODateTime() const
static DateTime CreateFromWin32FileDateTime(sal_uInt32 rLower, sal_uInt32 rUpper)
sal_Int16 GetYear() const
sal_uInt16 GetDay() const
sal_uInt16 GetMonth() const
std::size_t WriteBytes(const void *pData, std::size_t nSize)
SvStream & WriteUInt8(sal_uInt8 nuInt8)
sal_uInt64 Seek(sal_uInt64 nPos)
std::size_t ReadBytes(void *pData, std::size_t nSize)
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
std::vector< unsigned char > finalize()
static std::vector< unsigned char > calculateHash(const unsigned char *pInput, size_t length, HashType eType)
void update(const unsigned char *pInput, size_t length)
const css::uno::Reference< css::security::XCertificate > m_xCertificate
The certificate to use for signing.
bool Sign(OStringBuffer &rCMSHexBuffer)
Signs one or more data blocks (as a single, contiguous, array).
static bool Verify(const std::vector< unsigned char > &aData, const bool bNonDetached, const std::vector< unsigned char > &aSignature, SignatureInformation &rInformation)
Verify and get Signature Information given a byte array.
std::vector< std::pair< const void *, sal_Int32 > > m_dataBlocks
Data blocks (pointer-size pairs).
#define MAX_SIGNATURE_CONTENT_LENGTH
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
if(aStr !=aBuf) UpdateName_Impl(m_xFollowLb.get()
constexpr OUStringLiteral aData
unsigned int uniform_uint_distribution(unsigned int a, unsigned int b)
const sal_uInt32 SHA256_HASH_LENGTH
const sal_uInt32 SHA512_HASH_LENGTH
Reference< XComponentContext > getProcessComponentContext()
const sal_uInt32 SHA1_HASH_LENGTH
constexpr OUStringLiteral first
constexpr OUStringLiteral last
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
std::vector< unsigned char > DecodeHexString(std::string_view rHex)
Converts a hex-encoded string into a byte array.
static int AsHex(char ch)
#define CERT_NewTempCertificate
std::vector< char * > values
const wchar_t *typedef BOOL
std::unique_ptr< char[]> aBuffer