From f215e02bf85f68d3a6106c2a1f4f7f063f819064 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Thu, 11 Apr 2024 10:17:27 +0200 Subject: Adding upstream version 7.0.14-dfsg. Signed-off-by: Daniel Baumann --- src/VBox/Runtime/common/crypto/pkcs7-sign.cpp | 592 ++++++++++++++++++++++++++ 1 file changed, 592 insertions(+) create mode 100644 src/VBox/Runtime/common/crypto/pkcs7-sign.cpp (limited to 'src/VBox/Runtime/common/crypto/pkcs7-sign.cpp') diff --git a/src/VBox/Runtime/common/crypto/pkcs7-sign.cpp b/src/VBox/Runtime/common/crypto/pkcs7-sign.cpp new file mode 100644 index 00000000..c1600d60 --- /dev/null +++ b/src/VBox/Runtime/common/crypto/pkcs7-sign.cpp @@ -0,0 +1,592 @@ +/* $Id: pkcs7-sign.cpp $ */ +/** @file + * IPRT - Crypto - PKCS \#7, Signing + */ + +/* + * Copyright (C) 2006-2023 Oracle and/or its affiliates. + * + * This file is part of VirtualBox base platform packages, as + * available from https://www.virtualbox.org. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation, in version 3 of the + * License. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, see . + * + * The contents of this file may alternatively be used under the terms + * of the Common Development and Distribution License Version 1.0 + * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included + * in the VirtualBox distribution, in which case the provisions of the + * CDDL are applicable instead of those of the GPL. + * + * You may elect to license modified versions of this file under the + * terms and conditions of either the GPL or the CDDL or both. + * + * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0 + */ + + +/********************************************************************************************************************************* +* Header Files * +*********************************************************************************************************************************/ +#include "internal/iprt.h" +#include + +#include +#include +#include +#include +#include +#include +#include + +#ifdef IPRT_WITH_OPENSSL +# include "internal/iprt-openssl.h" +# include "internal/openssl-pre.h" +# include +# include +# include +# include +# include +# include "internal/openssl-post.h" +#endif + + +/********************************************************************************************************************************* +* Structures and Typedefs * +*********************************************************************************************************************************/ +/** + * PKCS\#7 / CMS signing operation instance. + */ +typedef struct RTCRPKCS7SIGNINGJOBINT +{ + /** Magic value (RTCRPKCS7SIGNINGJOBINT). */ + uint32_t u32Magic; + /** Reference counter. */ + uint32_t volatile cRefs; + /** RTCRPKCS7SIGN_F_XXX. */ + uint64_t fFlags; + /** Set if finalized. */ + bool fFinallized; + + //.... +} RTCRPKCS7SIGNINGJOBINT; + +/** Magic value for RTCRPKCS7SIGNINGJOBINT (Jonathan Lethem). */ +#define RTCRPKCS7SIGNINGJOBINT_MAGIC UINT32_C(0x19640219) + +/** Handle to PKCS\#7/CMS signing operation. */ +typedef struct RTCRPKCS7SIGNINGJOBINT *RTCRPKCS7SIGNINGJOB; +/** Pointer to a PKCS\#7/CMS signing operation handle. */ +typedef RTCRPKCS7SIGNINGJOB *PRTCRPKCS7SIGNINGJOB; + +//// CMS_sign +//RTDECL(int) RTCrPkcs7Sign(PRTCRPKCS7SIGNINGJOB *phJob, uint64_t fFlags, PCRTCRX509CERTIFICATE pSigner, RTCRKEY hPrivateKey, +// RTCRSTORE hAdditionalCerts, +// + +#ifdef IPRT_WITH_OPENSSL + +static int rtCrPkcs7SimpleSignSignedDataDoV1TweakContent(PKCS7 *pOsslPkcs7, const char *pszContentId, + const void *pvData, size_t cbData, + PRTERRINFO pErrInfo) +{ + AssertReturn(pszContentId, RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_MISSING_CONTENT_TYPE_ATTRIB, + "RTCRPKCS7SIGN_SD_F_NO_DATA_ENCAP requires content type in additional attribs")); + + /* + * Create a new inner PKCS#7 content container, forcing it to the 'other' type. + */ + PKCS7 *pOsslInnerContent = PKCS7_new(); + if (!pOsslInnerContent) + return RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "PKCS7_new failed"); + + /* Set the type. */ + int rc; + pOsslInnerContent->type = OBJ_txt2obj(pszContentId, 1); + if (pOsslInnerContent->type) + { + /* Create a dynamic ASN1 type which we set to a sequence. */ + ASN1_TYPE *pOsslOther = pOsslInnerContent->d.other = ASN1_TYPE_new(); + if (pOsslOther) + { + pOsslOther->type = V_ASN1_SEQUENCE; + + /* Create a string and put the data in it. */ + ASN1_STRING *pOsslStr = pOsslOther->value.sequence = ASN1_STRING_new(); + if (pOsslStr) + { + rc = ASN1_STRING_set(pOsslStr, pvData, (int)cbData); /* copies the buffer content */ + if (rc > 0) + { + /* + * Set the content in the PKCS#7 signed data we're constructing. + * This consumes pOsslInnerContent on success. + */ + rc = PKCS7_set_content(pOsslPkcs7, pOsslInnerContent); + if (rc > 0) + return VINF_SUCCESS; + + /* failed */ + rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "PKCS7_set_content"); + } + else + rc = RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "ASN1_STRING_set(,,%#x)", cbData); + } + else + rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "ASN1_STRING_new"); + } + else + rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "ASN1_TYPE_new"); + } + else + rc = RTErrInfoSetF(pErrInfo, VERR_NO_MEMORY, "OBJ_txt2obj(%s, 1) failed", pszContentId); + PKCS7_free(pOsslInnerContent); + return rc; +} + + +static int rtCrPkcs7SimpleSignSignedDataDoV1TweakedFinal(PKCS7 *pOsslPkcs7, const char *pszContentId, + const void *pvData, size_t cbData, PRTERRINFO pErrInfo) +{ + AssertReturn(pszContentId, RTErrInfoSet(pErrInfo, VERR_CR_PKCS7_MISSING_CONTENT_TYPE_ATTRIB, + "RTCRPKCS7SIGN_SD_F_NO_DATA_ENCAP requires content type in additional attribs")); + + /* + * Prepare a BIO of what should be hashed with all the hashing filters attached. + */ + BIO *pOsslBio = PKCS7_dataInit(pOsslPkcs7, NULL); + if (!pOsslBio) + return RTErrInfoSet(pErrInfo, VERR_CR_CIPHER_OSSL_ENCRYPT_FINAL_FAILED, "PKCS7_dataInit failed"); + + /* + * Now write the data. + * + * We must skip the outer wrapper here (see RTCrPkcs7VerifySignedData). This + * is probably a bit presumptive about what we're working on, so add an extra + * flag for this later. + */ + uint8_t const *pbToWrite = (uint8_t const *)pvData; + size_t cbToWrite = cbData; + + /** @todo add extra flag for this? */ + RTASN1CURSORPRIMARY SkipCursor; + RTAsn1CursorInitPrimary(&SkipCursor, pvData, (uint32_t)cbData, + pErrInfo,&g_RTAsn1DefaultAllocator, RTASN1CURSOR_FLAGS_DER, "skip"); + RTASN1CORE SkipAsn1Core = { 0 }; + int rc = RTAsn1CursorReadHdr(&SkipCursor.Cursor, &SkipAsn1Core, "skip-core"); + if (RT_SUCCESS(rc)) + { + pbToWrite += SkipAsn1Core.cbHdr; + cbToWrite -= SkipAsn1Core.cbHdr; + + rc = BIO_write(pOsslBio, pbToWrite, (int)cbToWrite); + if (rc == (ssize_t)cbToWrite) + { + BIO_flush(pOsslBio); /** @todo error check this */ + if (true) + { + /* + * Finalize the job - produce the signer info signatures and stuff. + */ + rc = PKCS7_dataFinal(pOsslPkcs7, pOsslBio); + if (rc > 0) + { + /* + * Now tweak the content so we get the desired content type and + * no extra wrappers and stuff. + */ + rc = rtCrPkcs7SimpleSignSignedDataDoV1TweakContent(pOsslPkcs7, pszContentId, pvData, cbData, pErrInfo); + } + else + rc = RTErrInfoSetF(pErrInfo, VERR_CR_CIPHER_OSSL_ENCRYPT_FINAL_FAILED, "PKCS7_dataFinal failed: %d", rc); + } + } + else + rc = RTErrInfoSetF(pErrInfo, VERR_CR_CIPHER_OSSL_ENCRYPT_FINAL_FAILED, + "%zu byte data write failed: %d", cbToWrite, rc); + } + BIO_free_all(pOsslBio); + return rc; +} + + +static int rtCrPkcs7SimpleSignSignedDataDoV1AttribConversion(PKCS7_SIGNER_INFO *pSignerInfo, + PCRTCRPKCS7ATTRIBUTES pAdditionalAuthenticatedAttribs, + const char **ppszContentId, PRTERRINFO pErrInfo) +{ + int rc = VINF_SUCCESS; + *ppszContentId = NULL; + + if (pAdditionalAuthenticatedAttribs) + { + + /* + * Convert each attribute. + */ + STACK_OF(X509_ATTRIBUTE) *pOsslAttributes = sk_X509_ATTRIBUTE_new_null(); + for (uint32_t i = 0; i < pAdditionalAuthenticatedAttribs->cItems && RT_SUCCESS(rc); i++) + { + PCRTCRPKCS7ATTRIBUTE pAttrib = pAdditionalAuthenticatedAttribs->papItems[i]; + + /* Look out for content type, as we will probably need that for + RTCRPKCS7SIGN_SD_F_NO_DATA_ENCAP later. */ + if ( pAttrib->enmType == RTCRPKCS7ATTRIBUTETYPE_OBJ_IDS + && RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_CONTENT_TYPE_OID) == 0) + { + AssertBreakStmt(!*ppszContentId, rc = VERR_CR_PKCS7_BAD_CONTENT_TYPE_ATTRIB); + AssertBreakStmt(pAttrib->uValues.pObjIds && pAttrib->uValues.pObjIds->cItems == 1, + rc = VERR_CR_PKCS7_BAD_CONTENT_TYPE_ATTRIB); + *ppszContentId = pAttrib->uValues.pObjIds->papItems[0]->szObjId; + } + + /* The conversion (IPRT encode, OpenSSL decode). */ + X509_ATTRIBUTE *pOsslAttrib; + rc = rtCrOpenSslConvertPkcs7Attribute((void **)&pOsslAttrib, pAttrib, pErrInfo); + if (RT_SUCCESS(rc)) + { + if (!sk_X509_ATTRIBUTE_push(pOsslAttributes, pOsslAttrib)) + rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "sk_X509_ATTRIBUTE_push failed"); + } + } + + /* + * If we've successfully converted all the attributes, make a deep copy + * (waste of resource, but whatever) into the signer info we're working on. + */ + if (RT_SUCCESS(rc)) + { + rc = PKCS7_set_signed_attributes(pSignerInfo, pOsslAttributes); /* deep copy */ + if (rc <= 0) + rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "PKCS7_set_signed_attributes failed"); + } + + /* + * Free the attributes (they were copied). Cannot use X509_ATTRIBUTE_pop_free as + * the callback causes Visual C++ to complain about exceptions on the callback. + */ + for (int i = sk_X509_ATTRIBUTE_num(pOsslAttributes) - 1; i >= 0; i--) + X509_ATTRIBUTE_free(sk_X509_ATTRIBUTE_value(pOsslAttributes, i)); + sk_X509_ATTRIBUTE_free(pOsslAttributes); + } + return rc; +} + +static int rtCrPkcs7SimpleSignSignedDataDoV1(uint32_t fFlags, X509 *pOsslSigner, EVP_PKEY *pEvpPrivateKey, + BIO *pOsslData, const EVP_MD *pEvpMd, STACK_OF(X509) *pOsslAdditionalCerts, + PCRTCRPKCS7ATTRIBUTES pAdditionalAuthenticatedAttribs, + const void *pvData, size_t cbData, + BIO **ppOsslResult, PRTERRINFO pErrInfo) +{ + /* + * Use PKCS7_sign with PKCS7_PARTIAL to start a extended the signing process. + */ + /* Create a ContentInfo we can modify using CMS_sign w/ CMS_PARTIAL. */ + unsigned int fOsslSign = PKCS7_BINARY | PKCS7_PARTIAL; + if (fFlags & RTCRPKCS7SIGN_SD_F_DEATCHED) + fOsslSign |= PKCS7_DETACHED; + if (fFlags & RTCRPKCS7SIGN_SD_F_NO_SMIME_CAP) + fOsslSign |= PKCS7_NOSMIMECAP; + int rc = VINF_SUCCESS; + PKCS7 *pCms = PKCS7_sign(NULL, NULL, pOsslAdditionalCerts, NULL, fOsslSign); + if (pCms != NULL) + { + /* + * Add a signer. + */ + PKCS7_SIGNER_INFO *pSignerInfo = PKCS7_sign_add_signer(pCms, pOsslSigner, pEvpPrivateKey, pEvpMd, fOsslSign); + if (pSignerInfo) + { + /* + * Add additional attributes to the signer. + */ + const char *pszContentId = NULL; + rc = rtCrPkcs7SimpleSignSignedDataDoV1AttribConversion(pSignerInfo, pAdditionalAuthenticatedAttribs, + &pszContentId, pErrInfo); + if (RT_SUCCESS(rc)) + { + /* + * Finalized and actually sign the data. + */ + bool const fTweaked = (fFlags & (RTCRPKCS7SIGN_SD_F_DEATCHED | RTCRPKCS7SIGN_SD_F_NO_DATA_ENCAP)) + == RTCRPKCS7SIGN_SD_F_NO_DATA_ENCAP; + if (fTweaked) + rc = rtCrPkcs7SimpleSignSignedDataDoV1TweakedFinal(pCms, pszContentId, pvData, cbData, pErrInfo); + else + { + rc = PKCS7_final(pCms, pOsslData, fOsslSign); + if (rc > 0) + rc = VINF_SUCCESS; + else + rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "PKCS7_final"); + /** @todo maybe we want to use rtCrPkcs7SimpleSignSignedDataDoV1TweakContent + * for when the content type isn't 'data'... */ + } + if (RT_SUCCESS(rc)) + { + /* + * Get the output and copy it into the result buffer. + */ + BIO *pOsslResult = BIO_new(BIO_s_mem()); + if (pOsslResult) + { + rc = i2d_PKCS7_bio(pOsslResult, pCms); + if (rc > 0) + { + *ppOsslResult = pOsslResult; + rc = VINF_SUCCESS; + } + else + { + rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "i2d_PKCS7_bio"); + BIO_free(pOsslResult); + } + } + else + rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "BIO_new/BIO_s_mem"); + } + } + else + rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "PKCS7_sign_add_signer"); + } + PKCS7_free(pCms); + } + else + rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "PKCS7_sign"); + return rc; +} + + +static int rtCrPkcs7SimpleSignSignedDataDoDefault(uint32_t fFlags, X509 *pOsslSigner, EVP_PKEY *pEvpPrivateKey, + BIO *pOsslData, const EVP_MD *pEvpMd, STACK_OF(X509) *pOsslAdditionalCerts, + PCRTCRPKCS7ATTRIBUTES pAdditionalAuthenticatedAttribs, + BIO **ppOsslResult, PRTERRINFO pErrInfo) + +{ + /* + * Use CMS_sign with CMS_PARTIAL to start a extended the signing process. + */ + /* Create a ContentInfo we can modify using CMS_sign w/ CMS_PARTIAL. */ + unsigned int fOsslSign = CMS_BINARY | CMS_PARTIAL; + if (fFlags & RTCRPKCS7SIGN_SD_F_DEATCHED) + fOsslSign |= CMS_DETACHED; + if (fFlags & RTCRPKCS7SIGN_SD_F_NO_SMIME_CAP) + fOsslSign |= CMS_NOSMIMECAP; + int rc = VINF_SUCCESS; + CMS_ContentInfo *pCms = CMS_sign(NULL, NULL, pOsslAdditionalCerts, NULL, fOsslSign); + if (pCms != NULL) + { + /* + * Set encapsulated content type if present in the auth attribs. + */ + uint32_t iAuthAttrSkip = UINT32_MAX; + for (uint32_t i = 0; i < pAdditionalAuthenticatedAttribs->cItems && RT_SUCCESS(rc); i++) + { + PCRTCRPKCS7ATTRIBUTE pAttrib = pAdditionalAuthenticatedAttribs->papItems[i]; + if ( pAttrib->enmType == RTCRPKCS7ATTRIBUTETYPE_OBJ_IDS + && RTAsn1ObjId_CompareWithString(&pAttrib->Type, RTCR_PKCS9_ID_CONTENT_TYPE_OID) == 0) + { + AssertBreakStmt(pAttrib->uValues.pObjIds && pAttrib->uValues.pObjIds->cItems == 1, + rc = VERR_INTERNAL_ERROR_3); + PCRTASN1OBJID pObjId = pAttrib->uValues.pObjIds->papItems[0]; + ASN1_OBJECT *pOsslObjId = OBJ_txt2obj(pObjId->szObjId, 0 /*no_name*/); + if (pOsslObjId) + { + rc = CMS_set1_eContentType(pCms, pOsslObjId); + ASN1_OBJECT_free(pOsslObjId); + if (rc < 0) + rc = RTErrInfoSetF(pErrInfo, VERR_CR_PKIX_GENERIC_ERROR, + "CMS_set1_eContentType(%s)", pObjId->szObjId); + } + else + rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "OBJ_txt2obj"); + + iAuthAttrSkip = i; + break; + } + } + if (RT_SUCCESS(rc)) + { + /* + * Add a signer. + */ + CMS_SignerInfo *pSignerInfo = CMS_add1_signer(pCms, pOsslSigner, pEvpPrivateKey, pEvpMd, fOsslSign); + if (pSignerInfo) + { + /* + * Add additional attributes, skipping the content type if found above. + */ + if (pAdditionalAuthenticatedAttribs) + for (uint32_t i = 0; i < pAdditionalAuthenticatedAttribs->cItems && RT_SUCCESS(rc); i++) + if (i != iAuthAttrSkip) + { + PCRTCRPKCS7ATTRIBUTE pAttrib = pAdditionalAuthenticatedAttribs->papItems[i]; + X509_ATTRIBUTE *pOsslAttrib; + rc = rtCrOpenSslConvertPkcs7Attribute((void **)&pOsslAttrib, pAttrib, pErrInfo); + if (RT_SUCCESS(rc)) + { + rc = CMS_signed_add1_attr(pSignerInfo, pOsslAttrib); + rtCrOpenSslFreeConvertedPkcs7Attribute((void **)pOsslAttrib); + if (rc <= 0) + rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "CMS_signed_add1_attr"); + } + } + if (RT_SUCCESS(rc)) + { + /* + * Finalized and actually sign the data. + */ + rc = CMS_final(pCms, pOsslData, NULL /*dcont*/, fOsslSign); + if (rc > 0) + { + /* + * Get the output and copy it into the result buffer. + */ + BIO *pOsslResult = BIO_new(BIO_s_mem()); + if (pOsslResult) + { + rc = i2d_CMS_bio(pOsslResult, pCms); + if (rc > 0) + { + *ppOsslResult = pOsslResult; + rc = VINF_SUCCESS; + } + else + { + rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "i2d_CMS_bio"); + BIO_free(pOsslResult); + } + } + else + rc = RTErrInfoSet(pErrInfo, VERR_NO_MEMORY, "BIO_new/BIO_s_mem"); + } + else + rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "CMS_final"); + } + } + else + rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "CMS_add1_signer"); + } + CMS_ContentInfo_free(pCms); + } + else + rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "CMS_sign"); + return rc; +} + +#endif /* IPRT_WITH_OPENSSL */ + + + +RTDECL(int) RTCrPkcs7SimpleSignSignedData(uint32_t fFlags, PCRTCRX509CERTIFICATE pSigner, RTCRKEY hPrivateKey, + void const *pvData, size_t cbData, RTDIGESTTYPE enmDigestType, + RTCRSTORE hAdditionalCerts, PCRTCRPKCS7ATTRIBUTES pAdditionalAuthenticatedAttribs, + void *pvResult, size_t *pcbResult, PRTERRINFO pErrInfo) +{ + size_t const cbResultBuf = *pcbResult; + *pcbResult = 0; + AssertReturn(!(fFlags & ~RTCRPKCS7SIGN_SD_F_VALID_MASK), VERR_INVALID_FLAGS); +#ifdef IPRT_WITH_OPENSSL + AssertReturn((int)cbData >= 0 && (unsigned)cbData == cbData, VERR_TOO_MUCH_DATA); + + /* + * Resolve the digest type. + */ + const EVP_MD *pEvpMd = NULL; + if (enmDigestType != RTDIGESTTYPE_UNKNOWN) + { + pEvpMd = (const EVP_MD *)rtCrOpenSslConvertDigestType(enmDigestType, pErrInfo); + AssertReturn(pEvpMd, pErrInfo ? pErrInfo->rc : VERR_INVALID_PARAMETER); + } + + /* + * Convert the private key. + */ + EVP_PKEY *pEvpPrivateKey = NULL; + int rc = rtCrKeyToOpenSslKey(hPrivateKey, false /*fNeedPublic*/, (void **)&pEvpPrivateKey, pErrInfo); + if (RT_SUCCESS(rc)) + { + /* + * Convert the signing certificate. + */ + X509 *pOsslSigner = NULL; + rc = rtCrOpenSslConvertX509Cert((void **)&pOsslSigner, pSigner, pErrInfo); + if (RT_SUCCESS(rc)) + { + /* + * Convert any additional certificates. + */ + STACK_OF(X509) *pOsslAdditionalCerts = NULL; + if (hAdditionalCerts != NIL_RTCRSTORE) + rc = RTCrStoreConvertToOpenSslCertStack(hAdditionalCerts, 0 /*fFlags*/, (void **)&pOsslAdditionalCerts, pErrInfo); + if (RT_SUCCESS(rc)) + { + /* + * Create a BIO for the data buffer. + */ + BIO *pOsslData = BIO_new_mem_buf((void *)pvData, (int)cbData); + if (pOsslData) + { + /* + * Do the work. + */ + BIO *pOsslResult = NULL; + if (!(fFlags & RTCRPKCS7SIGN_SD_F_USE_V1)) + rc = rtCrPkcs7SimpleSignSignedDataDoDefault(fFlags, pOsslSigner, pEvpPrivateKey, pOsslData, pEvpMd, + pOsslAdditionalCerts, pAdditionalAuthenticatedAttribs, + &pOsslResult, pErrInfo); + else + rc = rtCrPkcs7SimpleSignSignedDataDoV1(fFlags, pOsslSigner, pEvpPrivateKey, pOsslData, pEvpMd, + pOsslAdditionalCerts, pAdditionalAuthenticatedAttribs, + pvData, cbData, + &pOsslResult, pErrInfo); + BIO_free(pOsslData); + if (RT_SUCCESS(rc)) + { + /* + * Copy out the result. + */ + BUF_MEM *pBuf = NULL; + rc = (int)BIO_get_mem_ptr(pOsslResult, &pBuf); + if (rc > 0) + { + AssertPtr(pBuf); + size_t const cbResult = pBuf->length; + if ( cbResultBuf >= cbResult + && pvResult != NULL) + { + memcpy(pvResult, pBuf->data, cbResult); + rc = VINF_SUCCESS; + } + else + rc = VERR_BUFFER_OVERFLOW; + *pcbResult = cbResult; + } + else + rc = RTErrInfoSet(pErrInfo, VERR_GENERAL_FAILURE, "BIO_get_mem_ptr"); + BIO_free(pOsslResult); + } + } + } + rtCrOpenSslFreeConvertedX509Cert(pOsslSigner); + } + EVP_PKEY_free(pEvpPrivateKey); + } + return rc; +#else + RT_NOREF(fFlags, pSigner, hPrivateKey, pvData, cbData, enmDigestType, hAdditionalCerts, pAdditionalAuthenticatedAttribs, + pvResult, pErrInfo, cbResultBuf); + *pcbResult = 0; + return VERR_NOT_IMPLEMENTED; +#endif +} + -- cgit v1.2.3