summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Sign.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Sign.c
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Sign.c')
-rw-r--r--src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Sign.c194
1 files changed, 194 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Sign.c b/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Sign.c
new file mode 100644
index 00000000..e32fc91c
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/CryptoPkg/Library/BaseCryptLib/Pk/CryptPkcs7Sign.c
@@ -0,0 +1,194 @@
+/** @file
+ PKCS#7 SignedData Sign Wrapper Implementation over OpenSSL.
+
+Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "InternalCryptLib.h"
+
+#include <openssl/objects.h>
+#include <openssl/x509.h>
+#include <openssl/pkcs7.h>
+
+/**
+ Creates a PKCS#7 signedData as described in "PKCS #7: Cryptographic Message
+ Syntax Standard, version 1.5". This interface is only intended to be used for
+ application to perform PKCS#7 functionality validation.
+
+ @param[in] PrivateKey Pointer to the PEM-formatted private key data for
+ data signing.
+ @param[in] PrivateKeySize Size of the PEM private key data in bytes.
+ @param[in] KeyPassword NULL-terminated passphrase used for encrypted PEM
+ key data.
+ @param[in] InData Pointer to the content to be signed.
+ @param[in] InDataSize Size of InData in bytes.
+ @param[in] SignCert Pointer to signer's DER-encoded certificate to sign with.
+ @param[in] OtherCerts Pointer to an optional additional set of certificates to
+ include in the PKCS#7 signedData (e.g. any intermediate
+ CAs in the chain).
+ @param[out] SignedData Pointer to output PKCS#7 signedData. It's caller's
+ responsibility to free the buffer with FreePool().
+ @param[out] SignedDataSize Size of SignedData in bytes.
+
+ @retval TRUE PKCS#7 data signing succeeded.
+ @retval FALSE PKCS#7 data signing failed.
+
+**/
+BOOLEAN
+EFIAPI
+Pkcs7Sign (
+ IN CONST UINT8 *PrivateKey,
+ IN UINTN PrivateKeySize,
+ IN CONST UINT8 *KeyPassword,
+ IN UINT8 *InData,
+ IN UINTN InDataSize,
+ IN UINT8 *SignCert,
+ IN UINT8 *OtherCerts OPTIONAL,
+ OUT UINT8 **SignedData,
+ OUT UINTN *SignedDataSize
+ )
+{
+ BOOLEAN Status;
+ EVP_PKEY *Key;
+ BIO *DataBio;
+ PKCS7 *Pkcs7;
+ UINT8 *RsaContext;
+ UINT8 *P7Data;
+ UINTN P7DataSize;
+ UINT8 *Tmp;
+
+ //
+ // Check input parameters.
+ //
+ if (PrivateKey == NULL || KeyPassword == NULL || InData == NULL ||
+ SignCert == NULL || SignedData == NULL || SignedDataSize == NULL || InDataSize > INT_MAX) {
+ return FALSE;
+ }
+
+ RsaContext = NULL;
+ Key = NULL;
+ Pkcs7 = NULL;
+ DataBio = NULL;
+ Status = FALSE;
+
+ //
+ // Retrieve RSA private key from PEM data.
+ //
+ Status = RsaGetPrivateKeyFromPem (
+ PrivateKey,
+ PrivateKeySize,
+ (CONST CHAR8 *) KeyPassword,
+ (VOID **) &RsaContext
+ );
+ if (!Status) {
+ return Status;
+ }
+
+ Status = FALSE;
+
+ //
+ // Register & Initialize necessary digest algorithms and PRNG for PKCS#7 Handling
+ //
+ if (EVP_add_digest (EVP_md5 ()) == 0) {
+ goto _Exit;
+ }
+ if (EVP_add_digest (EVP_sha1 ()) == 0) {
+ goto _Exit;
+ }
+ if (EVP_add_digest (EVP_sha256 ()) == 0) {
+ goto _Exit;
+ }
+
+ RandomSeed (NULL, 0);
+
+ //
+ // Construct OpenSSL EVP_PKEY for private key.
+ //
+ Key = EVP_PKEY_new ();
+ if (Key == NULL) {
+ goto _Exit;
+ }
+ if (EVP_PKEY_assign_RSA (Key, (RSA *) RsaContext) == 0) {
+ goto _Exit;
+ }
+
+ //
+ // Convert the data to be signed to BIO format.
+ //
+ DataBio = BIO_new (BIO_s_mem ());
+ if (DataBio == NULL) {
+ goto _Exit;
+ }
+
+ if (BIO_write (DataBio, InData, (int) InDataSize) <= 0) {
+ goto _Exit;
+ }
+
+ //
+ // Create the PKCS#7 signedData structure.
+ //
+ Pkcs7 = PKCS7_sign (
+ (X509 *) SignCert,
+ Key,
+ (STACK_OF(X509) *) OtherCerts,
+ DataBio,
+ PKCS7_BINARY | PKCS7_NOATTR | PKCS7_DETACHED
+ );
+ if (Pkcs7 == NULL) {
+ goto _Exit;
+ }
+
+ //
+ // Convert PKCS#7 signedData structure into DER-encoded buffer.
+ //
+ P7DataSize = i2d_PKCS7 (Pkcs7, NULL);
+ if (P7DataSize <= 19) {
+ goto _Exit;
+ }
+
+ P7Data = malloc (P7DataSize);
+ if (P7Data == NULL) {
+ goto _Exit;
+ }
+
+ Tmp = P7Data;
+ P7DataSize = i2d_PKCS7 (Pkcs7, (unsigned char **) &Tmp);
+ ASSERT (P7DataSize > 19);
+
+ //
+ // Strip ContentInfo to content only for signeddata. The data be trimmed off
+ // is totally 19 bytes.
+ //
+ *SignedDataSize = P7DataSize - 19;
+ *SignedData = AllocatePool (*SignedDataSize);
+ if (*SignedData == NULL) {
+ OPENSSL_free (P7Data);
+ goto _Exit;
+ }
+
+ CopyMem (*SignedData, P7Data + 19, *SignedDataSize);
+
+ OPENSSL_free (P7Data);
+
+ Status = TRUE;
+
+_Exit:
+ //
+ // Release Resources
+ //
+ if (Key != NULL) {
+ EVP_PKEY_free (Key);
+ }
+
+ if (DataBio != NULL) {
+ BIO_free (DataBio);
+ }
+
+ if (Pkcs7 != NULL) {
+ PKCS7_free (Pkcs7);
+ }
+
+ return Status;
+}