From 72bb39c0237f8bcc3afa8b623e8b097eec6d69cd Mon Sep 17 00:00:00 2001 From: Steve Langasek Date: Mon, 6 Oct 2014 15:39:48 -0700 Subject: Import upstream version 0.7 --- Cryptlib/Pk/CryptAuthenticode.c | 20 ++ Cryptlib/Pk/CryptDh.c | 86 ++++- Cryptlib/Pk/CryptRsa.c | 722 ---------------------------------------- Cryptlib/Pk/CryptRsaBasic.c | 335 +++++++++++++++++++ Cryptlib/Pk/CryptRsaExt.c | 377 +++++++++++++++++++++ Cryptlib/Pk/CryptX509.c | 164 +++------ 6 files changed, 850 insertions(+), 854 deletions(-) delete mode 100644 Cryptlib/Pk/CryptRsa.c create mode 100644 Cryptlib/Pk/CryptRsaBasic.c create mode 100644 Cryptlib/Pk/CryptRsaExt.c (limited to 'Cryptlib/Pk') diff --git a/Cryptlib/Pk/CryptAuthenticode.c b/Cryptlib/Pk/CryptAuthenticode.c index a4f62b22..bb5f6d4b 100644 --- a/Cryptlib/Pk/CryptAuthenticode.c +++ b/Cryptlib/Pk/CryptAuthenticode.c @@ -26,6 +26,12 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. #include #include +// +// OID ASN.1 Value for SPC_INDIRECT_DATA_OBJID +// +UINT8 mSpcIndirectOidValue[] = { + 0x2B, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x04 + }; /** Verifies the validility of a PE/COFF Authenticode Signature as described in "Windows @@ -70,6 +76,7 @@ AuthenticodeVerify ( UINT8 *SpcIndirectDataContent; UINT8 Asn1Byte; UINTN ContentSize; + UINT8 *SpcIndirectDataOid; // // Check input parameters. @@ -106,6 +113,19 @@ AuthenticodeVerify ( // some authenticode-specific structure. Use opaque ASN.1 string to retrieve // PKCS#7 ContentInfo here. // + SpcIndirectDataOid = (UINT8 *)(Pkcs7->d.sign->contents->type->data); + if (CompareMem ( + SpcIndirectDataOid, + mSpcIndirectOidValue, + sizeof (mSpcIndirectOidValue) + ) != 0) { + // + // Un-matched SPC_INDIRECT_DATA_OBJID. + // + goto _Exit; + } + + SpcIndirectDataContent = (UINT8 *)(Pkcs7->d.sign->contents->d.other->value.asn1_string->data); // diff --git a/Cryptlib/Pk/CryptDh.c b/Cryptlib/Pk/CryptDh.c index 20f13469..942b3d10 100644 --- a/Cryptlib/Pk/CryptDh.c +++ b/Cryptlib/Pk/CryptDh.c @@ -32,7 +32,7 @@ DhNew ( // // Allocates & Initializes DH Context by OpenSSL DH_new() // - return (VOID *)DH_new (); + return (VOID *) DH_new (); } /** @@ -52,7 +52,7 @@ DhFree ( // // Free OpenSSL DH Context // - DH_free ((DH *)DhContext); + DH_free ((DH *) DhContext); } /** @@ -91,7 +91,7 @@ DhGenerateParameter ( // // Check input parameters. // - if (DhContext == NULL || Prime == NULL) { + if (DhContext == NULL || Prime == NULL || PrimeLength > INT_MAX) { return FALSE; } @@ -139,12 +139,13 @@ DhSetParameter ( IN CONST UINT8 *Prime ) { - DH *Dh; + DH *Dh; + BIGNUM *Bn; // // Check input parameters. // - if (DhContext == NULL || Prime == NULL) { + if (DhContext == NULL || Prime == NULL || PrimeLength > INT_MAX) { return FALSE; } @@ -152,14 +153,46 @@ DhSetParameter ( return FALSE; } + Bn = NULL; + Dh = (DH *) DhContext; - Dh->p = BN_new(); - Dh->g = BN_new(); + Dh->g = NULL; + Dh->p = BN_new (); + if (Dh->p == NULL) { + goto Error; + } + + Dh->g = BN_new (); + if (Dh->g == NULL) { + goto Error; + } - BN_bin2bn (Prime, (UINT32) (PrimeLength / 8), Dh->p); - BN_set_word (Dh->g, (UINT32) Generator); + Bn = BN_bin2bn (Prime, (UINT32) (PrimeLength / 8), Dh->p); + if (Bn == NULL) { + goto Error; + } + + if (BN_set_word (Dh->g, (UINT32) Generator) == 0) { + goto Error; + } return TRUE; + +Error: + + if (Dh->p != NULL) { + BN_free (Dh->p); + } + + if (Dh->g != NULL) { + BN_free (Dh->g); + } + + if (Bn != NULL) { + BN_free (Bn); + } + + return FALSE; } /** @@ -194,6 +227,7 @@ DhGenerateKey ( { BOOLEAN RetVal; DH *Dh; + INTN Size; // // Check input parameters. @@ -207,12 +241,17 @@ DhGenerateKey ( } Dh = (DH *) DhContext; - *PublicKeySize = 0; RetVal = (BOOLEAN) DH_generate_key (DhContext); if (RetVal) { + Size = BN_num_bytes (Dh->pub_key); + if ((Size > 0) && (*PublicKeySize < (UINTN) Size)) { + *PublicKeySize = Size; + return FALSE; + } + BN_bn2bin (Dh->pub_key, PublicKey); - *PublicKeySize = BN_num_bytes (Dh->pub_key); + *PublicKeySize = Size; } return RetVal; @@ -227,7 +266,8 @@ DhGenerateKey ( If DhContext is NULL, then return FALSE. If PeerPublicKey is NULL, then return FALSE. If KeySize is NULL, then return FALSE. - If KeySize is large enough but Key is NULL, then return FALSE. + If Key is NULL, then return FALSE. + If KeySize is not large enough, then return FALSE. @param[in, out] DhContext Pointer to the DH context. @param[in] PeerPublicKey Pointer to the peer's public key. @@ -252,23 +292,37 @@ DhComputeKey ( ) { BIGNUM *Bn; + INTN Size; // // Check input parameters. // - if (DhContext == NULL || PeerPublicKey == NULL || KeySize == NULL) { + if (DhContext == NULL || PeerPublicKey == NULL || KeySize == NULL || Key == NULL) { return FALSE; } - if (Key == NULL && *KeySize != 0) { + if (PeerPublicKeySize > INT_MAX) { return FALSE; } Bn = BN_bin2bn (PeerPublicKey, (UINT32) PeerPublicKeySize, NULL); + if (Bn == NULL) { + return FALSE; + } - *KeySize = (BOOLEAN) DH_compute_key (Key, Bn, DhContext); + Size = DH_compute_key (Key, Bn, DhContext); + if (Size < 0) { + BN_free (Bn); + return FALSE; + } - BN_free (Bn); + if (*KeySize < (UINTN) Size) { + *KeySize = Size; + BN_free (Bn); + return FALSE; + } + *KeySize = Size; + BN_free (Bn); return TRUE; } diff --git a/Cryptlib/Pk/CryptRsa.c b/Cryptlib/Pk/CryptRsa.c deleted file mode 100644 index 04833531..00000000 --- a/Cryptlib/Pk/CryptRsa.c +++ /dev/null @@ -1,722 +0,0 @@ -/** @file - RSA Asymmetric Cipher Wrapper Implementation over OpenSSL. - -Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.
-This program and the accompanying materials -are licensed and made available under the terms and conditions of the BSD License -which accompanies this distribution. The full text of the license may be found at -http://opensource.org/licenses/bsd-license.php - -THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - -**/ - -#include "InternalCryptLib.h" - -#include -#include - -// -// ASN.1 value for Hash Algorithm ID with the Distringuished Encoding Rules (DER) -// Refer to Section 9.2 of PKCS#1 v2.1 -// -CONST UINT8 Asn1IdMd5[] = { - 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, - 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 - }; - -CONST UINT8 Asn1IdSha1[] = { - 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, - 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14 - }; - -CONST UINT8 Asn1IdSha256[] = { - 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, - 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, - 0x00, 0x04, 0x20 - }; - - -/** - Allocates and initializes one RSA context for subsequent use. - - @return Pointer to the RSA context that has been initialized. - If the allocations fails, RsaNew() returns NULL. - -**/ -VOID * -EFIAPI -RsaNew ( - VOID - ) -{ - // - // Allocates & Initializes RSA Context by OpenSSL RSA_new() - // - return (VOID *)RSA_new (); -} - -/** - Release the specified RSA context. - - If RsaContext is NULL, then return FALSE. - - @param[in] RsaContext Pointer to the RSA context to be released. - -**/ -VOID -EFIAPI -RsaFree ( - IN VOID *RsaContext - ) -{ - // - // Free OpenSSL RSA Context - // - RSA_free ((RSA *)RsaContext); -} - -/** - Sets the tag-designated key component into the established RSA context. - - This function sets the tag-designated RSA key component into the established - RSA context from the user-specified non-negative integer (octet string format - represented in RSA PKCS#1). - If BigNumber is NULL, then the specified key componenet in RSA context is cleared. - - If RsaContext is NULL, then return FALSE. - - @param[in, out] RsaContext Pointer to RSA context being set. - @param[in] KeyTag Tag of RSA key component being set. - @param[in] BigNumber Pointer to octet integer buffer. - If NULL, then the specified key componenet in RSA - context is cleared. - @param[in] BnSize Size of big number buffer in bytes. - If BigNumber is NULL, then it is ignored. - - @retval TRUE RSA key component was set successfully. - @retval FALSE Invalid RSA key component tag. - -**/ -BOOLEAN -EFIAPI -RsaSetKey ( - IN OUT VOID *RsaContext, - IN RSA_KEY_TAG KeyTag, - IN CONST UINT8 *BigNumber, - IN UINTN BnSize - ) -{ - RSA *RsaKey; - - // - // Check input parameters. - // - if (RsaContext == NULL) { - return FALSE; - } - - RsaKey = (RSA *)RsaContext; - // - // Set RSA Key Components by converting octet string to OpenSSL BN representation. - // NOTE: For RSA public key (used in signature verification), only public components - // (N, e) are needed. - // - switch (KeyTag) { - - // - // RSA Public Modulus (N) - // - case RsaKeyN: - if (RsaKey->n != NULL) { - BN_free (RsaKey->n); - } - RsaKey->n = NULL; - if (BigNumber == NULL) { - break; - } - RsaKey->n = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->n); - break; - - // - // RSA Public Exponent (e) - // - case RsaKeyE: - if (RsaKey->e != NULL) { - BN_free (RsaKey->e); - } - RsaKey->e = NULL; - if (BigNumber == NULL) { - break; - } - RsaKey->e = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->e); - break; - - // - // RSA Private Exponent (d) - // - case RsaKeyD: - if (RsaKey->d != NULL) { - BN_free (RsaKey->d); - } - RsaKey->d = NULL; - if (BigNumber == NULL) { - break; - } - RsaKey->d = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->d); - break; - - // - // RSA Secret Prime Factor of Modulus (p) - // - case RsaKeyP: - if (RsaKey->p != NULL) { - BN_free (RsaKey->p); - } - RsaKey->p = NULL; - if (BigNumber == NULL) { - break; - } - RsaKey->p = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->p); - break; - - // - // RSA Secret Prime Factor of Modules (q) - // - case RsaKeyQ: - if (RsaKey->q != NULL) { - BN_free (RsaKey->q); - } - RsaKey->q = NULL; - if (BigNumber == NULL) { - break; - } - RsaKey->q = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->q); - break; - - // - // p's CRT Exponent (== d mod (p - 1)) - // - case RsaKeyDp: - if (RsaKey->dmp1 != NULL) { - BN_free (RsaKey->dmp1); - } - RsaKey->dmp1 = NULL; - if (BigNumber == NULL) { - break; - } - RsaKey->dmp1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmp1); - break; - - // - // q's CRT Exponent (== d mod (q - 1)) - // - case RsaKeyDq: - if (RsaKey->dmq1 != NULL) { - BN_free (RsaKey->dmq1); - } - RsaKey->dmq1 = NULL; - if (BigNumber == NULL) { - break; - } - RsaKey->dmq1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmq1); - break; - - // - // The CRT Coefficient (== 1/q mod p) - // - case RsaKeyQInv: - if (RsaKey->iqmp != NULL) { - BN_free (RsaKey->iqmp); - } - RsaKey->iqmp = NULL; - if (BigNumber == NULL) { - break; - } - RsaKey->iqmp = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->iqmp); - break; - - default: - return FALSE; - } - - return TRUE; -} - -/** - Gets the tag-designated RSA key component from the established RSA context. - - This function retrieves the tag-designated RSA key component from the - established RSA context as a non-negative integer (octet string format - represented in RSA PKCS#1). - If specified key component has not been set or has been cleared, then returned - BnSize is set to 0. - If the BigNumber buffer is too small to hold the contents of the key, FALSE - is returned and BnSize is set to the required buffer size to obtain the key. - - If RsaContext is NULL, then return FALSE. - If BnSize is NULL, then return FALSE. - If BnSize is large enough but BigNumber is NULL, then return FALSE. - - @param[in, out] RsaContext Pointer to RSA context being set. - @param[in] KeyTag Tag of RSA key component being set. - @param[out] BigNumber Pointer to octet integer buffer. - @param[in, out] BnSize On input, the size of big number buffer in bytes. - On output, the size of data returned in big number buffer in bytes. - - @retval TRUE RSA key component was retrieved successfully. - @retval FALSE Invalid RSA key component tag. - @retval FALSE BnSize is too small. - -**/ -BOOLEAN -EFIAPI -RsaGetKey ( - IN OUT VOID *RsaContext, - IN RSA_KEY_TAG KeyTag, - OUT UINT8 *BigNumber, - IN OUT UINTN *BnSize - ) -{ - RSA *RsaKey; - BIGNUM *BnKey; - UINTN Size; - - // - // Check input parameters. - // - if (RsaContext == NULL || BnSize == NULL) { - return FALSE; - } - - RsaKey = (RSA *) RsaContext; - Size = *BnSize; - *BnSize = 0; - - switch (KeyTag) { - - // - // RSA Public Modulus (N) - // - case RsaKeyN: - if (RsaKey->n == NULL) { - return TRUE; - } - BnKey = RsaKey->n; - break; - - // - // RSA Public Exponent (e) - // - case RsaKeyE: - if (RsaKey->e == NULL) { - return TRUE; - } - BnKey = RsaKey->e; - break; - - // - // RSA Private Exponent (d) - // - case RsaKeyD: - if (RsaKey->d == NULL) { - return TRUE; - } - BnKey = RsaKey->d; - break; - - // - // RSA Secret Prime Factor of Modulus (p) - // - case RsaKeyP: - if (RsaKey->p == NULL) { - return TRUE; - } - BnKey = RsaKey->p; - break; - - // - // RSA Secret Prime Factor of Modules (q) - // - case RsaKeyQ: - if (RsaKey->q == NULL) { - return TRUE; - } - BnKey = RsaKey->q; - break; - - // - // p's CRT Exponent (== d mod (p - 1)) - // - case RsaKeyDp: - if (RsaKey->dmp1 == NULL) { - return TRUE; - } - BnKey = RsaKey->dmp1; - break; - - // - // q's CRT Exponent (== d mod (q - 1)) - // - case RsaKeyDq: - if (RsaKey->dmq1 == NULL) { - return TRUE; - } - BnKey = RsaKey->dmq1; - break; - - // - // The CRT Coefficient (== 1/q mod p) - // - case RsaKeyQInv: - if (RsaKey->iqmp == NULL) { - return TRUE; - } - BnKey = RsaKey->iqmp; - break; - - default: - return FALSE; - } - - *BnSize = Size; - Size = BN_num_bytes (BnKey); - - if (*BnSize < Size) { - *BnSize = Size; - return FALSE; - } - - if (BigNumber == NULL) { - return FALSE; - } - *BnSize = BN_bn2bin (BnKey, BigNumber) ; - - return TRUE; -} - -/** - Generates RSA key components. - - This function generates RSA key components. It takes RSA public exponent E and - length in bits of RSA modulus N as input, and generates all key components. - If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used. - - Before this function can be invoked, pseudorandom number generator must be correctly - initialized by RandomSeed(). - - If RsaContext is NULL, then return FALSE. - - @param[in, out] RsaContext Pointer to RSA context being set. - @param[in] ModulusLength Length of RSA modulus N in bits. - @param[in] PublicExponent Pointer to RSA public exponent. - @param[in] PublicExponentSize Size of RSA public exponent buffer in bytes. - - @retval TRUE RSA key component was generated successfully. - @retval FALSE Invalid RSA key component tag. - -**/ -BOOLEAN -EFIAPI -RsaGenerateKey ( - IN OUT VOID *RsaContext, - IN UINTN ModulusLength, - IN CONST UINT8 *PublicExponent, - IN UINTN PublicExponentSize - ) -{ - BIGNUM *KeyE; - BOOLEAN RetVal; - - // - // Check input parameters. - // - if (RsaContext == NULL) { - return FALSE; - } - - KeyE = BN_new (); - if (PublicExponent == NULL) { - BN_set_word (KeyE, 0x10001); - } else { - BN_bin2bn (PublicExponent, (UINT32) PublicExponentSize, KeyE); - } - - RetVal = FALSE; - if (RSA_generate_key_ex ((RSA *) RsaContext, (UINT32) ModulusLength, KeyE, NULL) == 1) { - RetVal = TRUE; - } - - BN_free (KeyE); - return RetVal; -} - -/** - Validates key components of RSA context. - - This function validates key compoents of RSA context in following aspects: - - Whether p is a prime - - Whether q is a prime - - Whether n = p * q - - Whether d*e = 1 mod lcm(p-1,q-1) - - If RsaContext is NULL, then return FALSE. - - @param[in] RsaContext Pointer to RSA context to check. - - @retval TRUE RSA key components are valid. - @retval FALSE RSA key components are not valid. - -**/ -BOOLEAN -EFIAPI -RsaCheckKey ( - IN VOID *RsaContext - ) -{ - UINTN Reason; - - // - // Check input parameters. - // - if (RsaContext == NULL) { - return FALSE; - } - - if (RSA_check_key ((RSA *) RsaContext) != 1) { - Reason = ERR_GET_REASON (ERR_peek_last_error ()); - if (Reason == RSA_R_P_NOT_PRIME || - Reason == RSA_R_Q_NOT_PRIME || - Reason == RSA_R_N_DOES_NOT_EQUAL_P_Q || - Reason == RSA_R_D_E_NOT_CONGRUENT_TO_1) { - return FALSE; - } - } - - return TRUE; -} - -/** - Performs the PKCS1-v1_5 encoding methods defined in RSA PKCS #1. - - @param Message Message buffer to be encoded. - @param MessageSize Size of message buffer in bytes. - @param DigestInfo Pointer to buffer of digest info for output. - - @return Size of DigestInfo in bytes. - -**/ -UINTN -DigestInfoEncoding ( - IN CONST UINT8 *Message, - IN UINTN MessageSize, - OUT UINT8 *DigestInfo - ) -{ - CONST UINT8 *HashDer; - UINTN DerSize; - - // - // Check input parameters. - // - if (Message == NULL || DigestInfo == NULL) { - return FALSE; - } - - // - // The original message length is used to determine the hash algorithm since - // message is digest value hashed by the specified algorithm. - // - switch (MessageSize) { - case MD5_DIGEST_SIZE: - HashDer = Asn1IdMd5; - DerSize = sizeof (Asn1IdMd5); - break; - - case SHA1_DIGEST_SIZE: - HashDer = Asn1IdSha1; - DerSize = sizeof (Asn1IdSha1); - break; - - case SHA256_DIGEST_SIZE: - HashDer = Asn1IdSha256; - DerSize = sizeof (Asn1IdSha256); - break; - - default: - return FALSE; - } - - CopyMem (DigestInfo, HashDer, DerSize); - CopyMem (DigestInfo + DerSize, Message, MessageSize); - - return (DerSize + MessageSize); -} - -/** - Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme. - - This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in - RSA PKCS#1. - If the Signature buffer is too small to hold the contents of signature, FALSE - is returned and SigSize is set to the required buffer size to obtain the signature. - - If RsaContext is NULL, then return FALSE. - If MessageHash is NULL, then return FALSE. - If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE. - If SigSize is large enough but Signature is NULL, then return FALSE. - - @param[in] RsaContext Pointer to RSA context for signature generation. - @param[in] MessageHash Pointer to octet message hash to be signed. - @param[in] HashSize Size of the message hash in bytes. - @param[out] Signature Pointer to buffer to receive RSA PKCS1-v1_5 signature. - @param[in, out] SigSize On input, the size of Signature buffer in bytes. - On output, the size of data returned in Signature buffer in bytes. - - @retval TRUE Signature successfully generated in PKCS1-v1_5. - @retval FALSE Signature generation failed. - @retval FALSE SigSize is too small. - -**/ -BOOLEAN -EFIAPI -RsaPkcs1Sign ( - IN VOID *RsaContext, - IN CONST UINT8 *MessageHash, - IN UINTN HashSize, - OUT UINT8 *Signature, - IN OUT UINTN *SigSize - ) -{ - RSA *Rsa; - UINTN Size; - INTN ReturnVal; - - // - // Check input parameters. - // - if (RsaContext == NULL || MessageHash == NULL || - (HashSize != MD5_DIGEST_SIZE && HashSize != SHA1_DIGEST_SIZE && HashSize != SHA256_DIGEST_SIZE)) { - return FALSE; - } - - Rsa = (RSA *) RsaContext; - Size = BN_num_bytes (Rsa->n); - - if (*SigSize < Size) { - *SigSize = Size; - return FALSE; - } - - if (Signature == NULL) { - return FALSE; - } - - Size = DigestInfoEncoding (MessageHash, HashSize, Signature); - - ReturnVal = RSA_private_encrypt ( - (UINT32) Size, - Signature, - Signature, - Rsa, - RSA_PKCS1_PADDING - ); - - if (ReturnVal < (INTN) Size) { - return FALSE; - } - - *SigSize = (UINTN)ReturnVal; - return TRUE; -} - -/** - Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in - RSA PKCS#1. - - If RsaContext is NULL, then return FALSE. - If MessageHash is NULL, then return FALSE. - If Signature is NULL, then return FALSE. - If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE. - - @param[in] RsaContext Pointer to RSA context for signature verification. - @param[in] MessageHash Pointer to octet message hash to be checked. - @param[in] HashSize Size of the message hash in bytes. - @param[in] Signature Pointer to RSA PKCS1-v1_5 signature to be verified. - @param[in] SigSize Size of signature in bytes. - - @retval TRUE Valid signature encoded in PKCS1-v1_5. - @retval FALSE Invalid signature or invalid RSA context. - -**/ -BOOLEAN -EFIAPI -RsaPkcs1Verify ( - IN VOID *RsaContext, - IN CONST UINT8 *MessageHash, - IN UINTN HashSize, - IN UINT8 *Signature, - IN UINTN SigSize - ) -{ - INTN Length; - - // - // Check input parameters. - // - if (RsaContext == NULL || MessageHash == NULL || Signature == NULL) { - return FALSE; - } - - - // - // Check for unsupported hash size: - // Only MD5, SHA-1 or SHA-256 digest size is supported - // - if (HashSize != MD5_DIGEST_SIZE && HashSize != SHA1_DIGEST_SIZE && HashSize != SHA256_DIGEST_SIZE) { - return FALSE; - } - - // - // RSA PKCS#1 Signature Decoding using OpenSSL RSA Decryption with Public Key - // - Length = RSA_public_decrypt ( - (UINT32) SigSize, - Signature, - Signature, - RsaContext, - RSA_PKCS1_PADDING - ); - - // - // Invalid RSA Key or PKCS#1 Padding Checking Failed (if Length < 0) - // NOTE: Length should be the addition of HashSize and some DER value. - // Ignore more strict length checking here. - // - if (Length < (INTN) HashSize) { - return FALSE; - } - - // - // Validate the MessageHash and Decoded Signature - // NOTE: The decoded Signature should be the DER encoding of the DigestInfo value - // DigestInfo ::= SEQUENCE { - // digestAlgorithm AlgorithmIdentifier - // digest OCTET STRING - // } - // Then Memory Comparing should skip the DER value of the underlying SEQUENCE - // type and AlgorithmIdentifier. - // - if (CompareMem (MessageHash, Signature + Length - HashSize, HashSize) == 0) { - // - // Valid RSA PKCS#1 Signature - // - return TRUE; - } else { - // - // Failed to verification - // - return FALSE; - } -} diff --git a/Cryptlib/Pk/CryptRsaBasic.c b/Cryptlib/Pk/CryptRsaBasic.c new file mode 100644 index 00000000..3e430989 --- /dev/null +++ b/Cryptlib/Pk/CryptRsaBasic.c @@ -0,0 +1,335 @@ +/** @file + RSA Asymmetric Cipher Wrapper Implementation over OpenSSL. + + This file implements following APIs which provide basic capabilities for RSA: + 1) RsaNew + 2) RsaFree + 3) RsaSetKey + 4) RsaPkcs1Verify + +Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "InternalCryptLib.h" + +#include +#include + +/** + Allocates and initializes one RSA context for subsequent use. + + @return Pointer to the RSA context that has been initialized. + If the allocations fails, RsaNew() returns NULL. + +**/ +VOID * +EFIAPI +RsaNew ( + VOID + ) +{ + // + // Allocates & Initializes RSA Context by OpenSSL RSA_new() + // + return (VOID *) RSA_new (); +} + +/** + Release the specified RSA context. + + @param[in] RsaContext Pointer to the RSA context to be released. + +**/ +VOID +EFIAPI +RsaFree ( + IN VOID *RsaContext + ) +{ + // + // Free OpenSSL RSA Context + // + RSA_free ((RSA *) RsaContext); +} + +/** + Sets the tag-designated key component into the established RSA context. + + This function sets the tag-designated RSA key component into the established + RSA context from the user-specified non-negative integer (octet string format + represented in RSA PKCS#1). + If BigNumber is NULL, then the specified key componenet in RSA context is cleared. + + If RsaContext is NULL, then return FALSE. + + @param[in, out] RsaContext Pointer to RSA context being set. + @param[in] KeyTag Tag of RSA key component being set. + @param[in] BigNumber Pointer to octet integer buffer. + If NULL, then the specified key componenet in RSA + context is cleared. + @param[in] BnSize Size of big number buffer in bytes. + If BigNumber is NULL, then it is ignored. + + @retval TRUE RSA key component was set successfully. + @retval FALSE Invalid RSA key component tag. + +**/ +BOOLEAN +EFIAPI +RsaSetKey ( + IN OUT VOID *RsaContext, + IN RSA_KEY_TAG KeyTag, + IN CONST UINT8 *BigNumber, + IN UINTN BnSize + ) +{ + RSA *RsaKey; + + // + // Check input parameters. + // + if (RsaContext == NULL || BnSize > INT_MAX) { + return FALSE; + } + + RsaKey = (RSA *) RsaContext; + // + // Set RSA Key Components by converting octet string to OpenSSL BN representation. + // NOTE: For RSA public key (used in signature verification), only public components + // (N, e) are needed. + // + switch (KeyTag) { + + // + // RSA Public Modulus (N) + // + case RsaKeyN: + if (RsaKey->n != NULL) { + BN_free (RsaKey->n); + } + RsaKey->n = NULL; + if (BigNumber == NULL) { + break; + } + RsaKey->n = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->n); + if (RsaKey->n == NULL) { + return FALSE; + } + + break; + + // + // RSA Public Exponent (e) + // + case RsaKeyE: + if (RsaKey->e != NULL) { + BN_free (RsaKey->e); + } + RsaKey->e = NULL; + if (BigNumber == NULL) { + break; + } + RsaKey->e = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->e); + if (RsaKey->e == NULL) { + return FALSE; + } + + break; + + // + // RSA Private Exponent (d) + // + case RsaKeyD: + if (RsaKey->d != NULL) { + BN_free (RsaKey->d); + } + RsaKey->d = NULL; + if (BigNumber == NULL) { + break; + } + RsaKey->d = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->d); + if (RsaKey->d == NULL) { + return FALSE; + } + + break; + + // + // RSA Secret Prime Factor of Modulus (p) + // + case RsaKeyP: + if (RsaKey->p != NULL) { + BN_free (RsaKey->p); + } + RsaKey->p = NULL; + if (BigNumber == NULL) { + break; + } + RsaKey->p = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->p); + if (RsaKey->p == NULL) { + return FALSE; + } + + break; + + // + // RSA Secret Prime Factor of Modules (q) + // + case RsaKeyQ: + if (RsaKey->q != NULL) { + BN_free (RsaKey->q); + } + RsaKey->q = NULL; + if (BigNumber == NULL) { + break; + } + RsaKey->q = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->q); + if (RsaKey->q == NULL) { + return FALSE; + } + + break; + + // + // p's CRT Exponent (== d mod (p - 1)) + // + case RsaKeyDp: + if (RsaKey->dmp1 != NULL) { + BN_free (RsaKey->dmp1); + } + RsaKey->dmp1 = NULL; + if (BigNumber == NULL) { + break; + } + RsaKey->dmp1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmp1); + if (RsaKey->dmp1 == NULL) { + return FALSE; + } + + break; + + // + // q's CRT Exponent (== d mod (q - 1)) + // + case RsaKeyDq: + if (RsaKey->dmq1 != NULL) { + BN_free (RsaKey->dmq1); + } + RsaKey->dmq1 = NULL; + if (BigNumber == NULL) { + break; + } + RsaKey->dmq1 = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->dmq1); + if (RsaKey->dmq1 == NULL) { + return FALSE; + } + + break; + + // + // The CRT Coefficient (== 1/q mod p) + // + case RsaKeyQInv: + if (RsaKey->iqmp != NULL) { + BN_free (RsaKey->iqmp); + } + RsaKey->iqmp = NULL; + if (BigNumber == NULL) { + break; + } + RsaKey->iqmp = BN_bin2bn (BigNumber, (UINT32) BnSize, RsaKey->iqmp); + if (RsaKey->iqmp == NULL) { + return FALSE; + } + + break; + + default: + return FALSE; + } + + return TRUE; +} + +/** + Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in + RSA PKCS#1. + + If RsaContext is NULL, then return FALSE. + If MessageHash is NULL, then return FALSE. + If Signature is NULL, then return FALSE. + If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE. + + @param[in] RsaContext Pointer to RSA context for signature verification. + @param[in] MessageHash Pointer to octet message hash to be checked. + @param[in] HashSize Size of the message hash in bytes. + @param[in] Signature Pointer to RSA PKCS1-v1_5 signature to be verified. + @param[in] SigSize Size of signature in bytes. + + @retval TRUE Valid signature encoded in PKCS1-v1_5. + @retval FALSE Invalid signature or invalid RSA context. + +**/ +BOOLEAN +EFIAPI +RsaPkcs1Verify ( + IN VOID *RsaContext, + IN CONST UINT8 *MessageHash, + IN UINTN HashSize, + IN CONST UINT8 *Signature, + IN UINTN SigSize + ) +{ + INT32 DigestType; + UINT8 *SigBuf; + + // + // Check input parameters. + // + if (RsaContext == NULL || MessageHash == NULL || Signature == NULL) { + return FALSE; + } + + if (SigSize > INT_MAX || SigSize == 0) { + return FALSE; + } + + // + // Determine the message digest algorithm according to digest size. + // Only MD5, SHA-1 or SHA-256 algorithm is supported. + // + switch (HashSize) { + case MD5_DIGEST_SIZE: + DigestType = NID_md5; + break; + + case SHA1_DIGEST_SIZE: + DigestType = NID_sha1; + break; + + case SHA256_DIGEST_SIZE: + DigestType = NID_sha256; + break; + + default: + return FALSE; + } + + SigBuf = (UINT8 *) Signature; + return (BOOLEAN) RSA_verify ( + DigestType, + MessageHash, + (UINT32) HashSize, + SigBuf, + (UINT32) SigSize, + (RSA *) RsaContext + ); +} diff --git a/Cryptlib/Pk/CryptRsaExt.c b/Cryptlib/Pk/CryptRsaExt.c new file mode 100644 index 00000000..5c21d121 --- /dev/null +++ b/Cryptlib/Pk/CryptRsaExt.c @@ -0,0 +1,377 @@ +/** @file + RSA Asymmetric Cipher Wrapper Implementation over OpenSSL. + + This file implements following APIs which provide more capabilities for RSA: + 1) RsaGetKey + 2) RsaGenerateKey + 3) RsaCheckKey + 4) RsaPkcs1Sign + +Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.
+This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "InternalCryptLib.h" + +#include +#include +#include + +/** + Gets the tag-designated RSA key component from the established RSA context. + + This function retrieves the tag-designated RSA key component from the + established RSA context as a non-negative integer (octet string format + represented in RSA PKCS#1). + If specified key component has not been set or has been cleared, then returned + BnSize is set to 0. + If the BigNumber buffer is too small to hold the contents of the key, FALSE + is returned and BnSize is set to the required buffer size to obtain the key. + + If RsaContext is NULL, then return FALSE. + If BnSize is NULL, then return FALSE. + If BnSize is large enough but BigNumber is NULL, then return FALSE. + + @param[in, out] RsaContext Pointer to RSA context being set. + @param[in] KeyTag Tag of RSA key component being set. + @param[out] BigNumber Pointer to octet integer buffer. + @param[in, out] BnSize On input, the size of big number buffer in bytes. + On output, the size of data returned in big number buffer in bytes. + + @retval TRUE RSA key component was retrieved successfully. + @retval FALSE Invalid RSA key component tag. + @retval FALSE BnSize is too small. + +**/ +BOOLEAN +EFIAPI +RsaGetKey ( + IN OUT VOID *RsaContext, + IN RSA_KEY_TAG KeyTag, + OUT UINT8 *BigNumber, + IN OUT UINTN *BnSize + ) +{ + RSA *RsaKey; + BIGNUM *BnKey; + UINTN Size; + + // + // Check input parameters. + // + if (RsaContext == NULL || BnSize == NULL) { + return FALSE; + } + + RsaKey = (RSA *) RsaContext; + Size = *BnSize; + *BnSize = 0; + + switch (KeyTag) { + + // + // RSA Public Modulus (N) + // + case RsaKeyN: + if (RsaKey->n == NULL) { + return TRUE; + } + BnKey = RsaKey->n; + break; + + // + // RSA Public Exponent (e) + // + case RsaKeyE: + if (RsaKey->e == NULL) { + return TRUE; + } + BnKey = RsaKey->e; + break; + + // + // RSA Private Exponent (d) + // + case RsaKeyD: + if (RsaKey->d == NULL) { + return TRUE; + } + BnKey = RsaKey->d; + break; + + // + // RSA Secret Prime Factor of Modulus (p) + // + case RsaKeyP: + if (RsaKey->p == NULL) { + return TRUE; + } + BnKey = RsaKey->p; + break; + + // + // RSA Secret Prime Factor of Modules (q) + // + case RsaKeyQ: + if (RsaKey->q == NULL) { + return TRUE; + } + BnKey = RsaKey->q; + break; + + // + // p's CRT Exponent (== d mod (p - 1)) + // + case RsaKeyDp: + if (RsaKey->dmp1 == NULL) { + return TRUE; + } + BnKey = RsaKey->dmp1; + break; + + // + // q's CRT Exponent (== d mod (q - 1)) + // + case RsaKeyDq: + if (RsaKey->dmq1 == NULL) { + return TRUE; + } + BnKey = RsaKey->dmq1; + break; + + // + // The CRT Coefficient (== 1/q mod p) + // + case RsaKeyQInv: + if (RsaKey->iqmp == NULL) { + return TRUE; + } + BnKey = RsaKey->iqmp; + break; + + default: + return FALSE; + } + + *BnSize = Size; + Size = BN_num_bytes (BnKey); + + if (*BnSize < Size) { + *BnSize = Size; + return FALSE; + } + + if (BigNumber == NULL) { + return FALSE; + } + *BnSize = BN_bn2bin (BnKey, BigNumber) ; + + return TRUE; +} + +/** + Generates RSA key components. + + This function generates RSA key components. It takes RSA public exponent E and + length in bits of RSA modulus N as input, and generates all key components. + If PublicExponent is NULL, the default RSA public exponent (0x10001) will be used. + + Before this function can be invoked, pseudorandom number generator must be correctly + initialized by RandomSeed(). + + If RsaContext is NULL, then return FALSE. + + @param[in, out] RsaContext Pointer to RSA context being set. + @param[in] ModulusLength Length of RSA modulus N in bits. + @param[in] PublicExponent Pointer to RSA public exponent. + @param[in] PublicExponentSize Size of RSA public exponent buffer in bytes. + + @retval TRUE RSA key component was generated successfully. + @retval FALSE Invalid RSA key component tag. + +**/ +BOOLEAN +EFIAPI +RsaGenerateKey ( + IN OUT VOID *RsaContext, + IN UINTN ModulusLength, + IN CONST UINT8 *PublicExponent, + IN UINTN PublicExponentSize + ) +{ + BIGNUM *KeyE; + BOOLEAN RetVal; + + // + // Check input parameters. + // + if (RsaContext == NULL || ModulusLength > INT_MAX || PublicExponentSize > INT_MAX) { + return FALSE; + } + + KeyE = BN_new (); + if (KeyE == NULL) { + return FALSE; + } + + RetVal = FALSE; + + if (PublicExponent == NULL) { + if (BN_set_word (KeyE, 0x10001) == 0) { + goto _Exit; + } + } else { + if (BN_bin2bn (PublicExponent, (UINT32) PublicExponentSize, KeyE) == NULL) { + goto _Exit; + } + } + + if (RSA_generate_key_ex ((RSA *) RsaContext, (UINT32) ModulusLength, KeyE, NULL) == 1) { + RetVal = TRUE; + } + +_Exit: + BN_free (KeyE); + return RetVal; +} + +/** + Validates key components of RSA context. + + This function validates key compoents of RSA context in following aspects: + - Whether p is a prime + - Whether q is a prime + - Whether n = p * q + - Whether d*e = 1 mod lcm(p-1,q-1) + + If RsaContext is NULL, then return FALSE. + + @param[in] RsaContext Pointer to RSA context to check. + + @retval TRUE RSA key components are valid. + @retval FALSE RSA key components are not valid. + +**/ +BOOLEAN +EFIAPI +RsaCheckKey ( + IN VOID *RsaContext + ) +{ + UINTN Reason; + + // + // Check input parameters. + // + if (RsaContext == NULL) { + return FALSE; + } + + if (RSA_check_key ((RSA *) RsaContext) != 1) { + Reason = ERR_GET_REASON (ERR_peek_last_error ()); + if (Reason == RSA_R_P_NOT_PRIME || + Reason == RSA_R_Q_NOT_PRIME || + Reason == RSA_R_N_DOES_NOT_EQUAL_P_Q || + Reason == RSA_R_D_E_NOT_CONGRUENT_TO_1) { + return FALSE; + } + } + + return TRUE; +} + +/** + Carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme. + + This function carries out the RSA-SSA signature generation with EMSA-PKCS1-v1_5 encoding scheme defined in + RSA PKCS#1. + If the Signature buffer is too small to hold the contents of signature, FALSE + is returned and SigSize is set to the required buffer size to obtain the signature. + + If RsaContext is NULL, then return FALSE. + If MessageHash is NULL, then return FALSE. + If HashSize is not equal to the size of MD5, SHA-1 or SHA-256 digest, then return FALSE. + If SigSize is large enough but Signature is NULL, then return FALSE. + + @param[in] RsaContext Pointer to RSA context for signature generation. + @param[in] MessageHash Pointer to octet message hash to be signed. + @param[in] HashSize Size of the message hash in bytes. + @param[out] Signature Pointer to buffer to receive RSA PKCS1-v1_5 signature. + @param[in, out] SigSize On input, the size of Signature buffer in bytes. + On output, the size of data returned in Signature buffer in bytes. + + @retval TRUE Signature successfully generated in PKCS1-v1_5. + @retval FALSE Signature generation failed. + @retval FALSE SigSize is too small. + +**/ +BOOLEAN +EFIAPI +RsaPkcs1Sign ( + IN VOID *RsaContext, + IN CONST UINT8 *MessageHash, + IN UINTN HashSize, + OUT UINT8 *Signature, + IN OUT UINTN *SigSize + ) +{ + RSA *Rsa; + UINTN Size; + INT32 DigestType; + + // + // Check input parameters. + // + if (RsaContext == NULL || MessageHash == NULL) { + return FALSE; + } + + Rsa = (RSA *) RsaContext; + Size = BN_num_bytes (Rsa->n); + + if (*SigSize < Size) { + *SigSize = Size; + return FALSE; + } + + if (Signature == NULL) { + return FALSE; + } + + // + // Determine the message digest algorithm according to digest size. + // Only MD5, SHA-1 or SHA-256 algorithm is supported. + // + switch (HashSize) { + case MD5_DIGEST_SIZE: + DigestType = NID_md5; + break; + + case SHA1_DIGEST_SIZE: + DigestType = NID_sha1; + break; + + case SHA256_DIGEST_SIZE: + DigestType = NID_sha256; + break; + + default: + return FALSE; + } + + return (BOOLEAN) RSA_sign ( + DigestType, + MessageHash, + (UINT32) HashSize, + Signature, + (UINT32 *) SigSize, + (RSA *) RsaContext + ); +} diff --git a/Cryptlib/Pk/CryptX509.c b/Cryptlib/Pk/CryptX509.c index a0c5a2a7..5abe970c 100644 --- a/Cryptlib/Pk/CryptX509.c +++ b/Cryptlib/Pk/CryptX509.c @@ -38,9 +38,7 @@ X509ConstructCertificate ( OUT UINT8 **SingleX509Cert ) { - BIO *CertBio; X509 *X509Cert; - BOOLEAN Status; // // Check input parameters. @@ -49,31 +47,17 @@ X509ConstructCertificate ( return FALSE; } - Status = FALSE; - // // Read DER-encoded X509 Certificate and Construct X509 object. // - CertBio = BIO_new (BIO_s_mem ()); - BIO_write (CertBio, Cert, (int) CertSize); - if (CertBio == NULL) { - goto _Exit; - } - X509Cert = d2i_X509_bio (CertBio, NULL); + X509Cert = d2i_X509 (NULL, &Cert, (long) CertSize); if (X509Cert == NULL) { - goto _Exit; + return FALSE; } *SingleX509Cert = (UINT8 *) X509Cert; - Status = TRUE; - -_Exit: - // - // Release Resources. - // - BIO_free (CertBio); - return Status; + return TRUE; } /** @@ -224,91 +208,6 @@ X509StackFree ( sk_X509_pop_free ((STACK_OF(X509) *) X509Stack, X509_free); } -/** - Pop single certificate from STACK_OF(X509). - - If X509Stack, Cert, or CertSize is NULL, then return FALSE. - - @param[in] X509Stack Pointer to a X509 stack object. - @param[out] Cert Pointer to a X509 certificate. - @param[out] CertSize Length of output X509 certificate in bytes. - - @retval TRUE The X509 stack pop succeeded. - @retval FALSE The pop operation failed. - -**/ -BOOLEAN -X509PopCertificate ( - IN VOID *X509Stack, - OUT UINT8 **Cert, - OUT UINTN *CertSize - ) -{ - BIO *CertBio; - X509 *X509Cert; - STACK_OF(X509) *CertStack; - BOOLEAN Status; - int Result; - int Length; - VOID *Buffer; - - Status = FALSE; - - if ((X509Stack == NULL) || (Cert == NULL) || (CertSize == NULL)) { - return Status; - } - - CertStack = (STACK_OF(X509) *) X509Stack; - - X509Cert = sk_X509_pop (CertStack); - - if (X509Cert == NULL) { - return Status; - } - - Buffer = NULL; - - CertBio = BIO_new (BIO_s_mem ()); - if (CertBio == NULL) { - return Status; - } - - Result = i2d_X509_bio (CertBio, X509Cert); - if (Result == 0) { - goto _Exit; - } - - Length = ((BUF_MEM *) CertBio->ptr)->length; - if (Length <= 0) { - goto _Exit; - } - - Buffer = malloc (Length); - if (Buffer == NULL) { - goto _Exit; - } - - Result = BIO_read (CertBio, Buffer, Length); - if (Result != Length) { - goto _Exit; - } - - *Cert = Buffer; - *CertSize = Length; - - Status = TRUE; - -_Exit: - - BIO_free (CertBio); - - if (!Status && (Buffer != NULL)) { - free (Buffer); - } - - return Status; -} - /** Retrieve the subject bytes from one X.509 certificate. @@ -346,7 +245,6 @@ X509GetSubjectName ( return FALSE; } - Status = FALSE; X509Cert = NULL; // @@ -354,20 +252,27 @@ X509GetSubjectName ( // Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert); if ((X509Cert == NULL) || (!Status)) { + Status = FALSE; goto _Exit; } + Status = FALSE; + // // Retrieve subject name from certificate object. // X509Name = X509_get_subject_name (X509Cert); + if (X509Name == NULL) { + goto _Exit; + } + if (*SubjectSize < (UINTN) X509Name->bytes->length) { *SubjectSize = (UINTN) X509Name->bytes->length; goto _Exit; } *SubjectSize = (UINTN) X509Name->bytes->length; if (CertSubject != NULL) { - CopyMem (CertSubject, (UINT8 *)X509Name->bytes->data, *SubjectSize); + CopyMem (CertSubject, (UINT8 *) X509Name->bytes->data, *SubjectSize); Status = TRUE; } @@ -375,7 +280,9 @@ _Exit: // // Release Resources. // - X509_free (X509Cert); + if (X509Cert != NULL) { + X509_free (X509Cert); + } return Status; } @@ -415,7 +322,6 @@ RsaGetPublicKeyFromX509 ( return FALSE; } - Status = FALSE; Pkey = NULL; X509Cert = NULL; @@ -424,9 +330,12 @@ RsaGetPublicKeyFromX509 ( // Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert); if ((X509Cert == NULL) || (!Status)) { + Status = FALSE; goto _Exit; } + Status = FALSE; + // // Retrieve and check EVP_PKEY data from X509 Certificate. // @@ -446,8 +355,13 @@ _Exit: // // Release Resources. // - X509_free (X509Cert); - EVP_PKEY_free (Pkey); + if (X509Cert != NULL) { + X509_free (X509Cert); + } + + if (Pkey != NULL) { + EVP_PKEY_free (Pkey); + } return Status; } @@ -498,15 +412,22 @@ X509VerifyCert ( // // Register & Initialize necessary digest algorithms for certificate verification. // - EVP_add_digest (EVP_md5()); - EVP_add_digest (EVP_sha1()); - EVP_add_digest (EVP_sha256()); + 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; + } // // Read DER-encoded certificate to be verified and Construct X509 object. // Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **) &X509Cert); if ((X509Cert == NULL) || (!Status)) { + Status = FALSE; goto _Exit; } @@ -515,9 +436,12 @@ X509VerifyCert ( // Status = X509ConstructCertificate (CACert, CACertSize, (UINT8 **) &X509CACert); if ((X509CACert == NULL) || (!Status)) { + Status = FALSE; goto _Exit; } + Status = FALSE; + // // Set up X509 Store for trusted certificate. // @@ -546,9 +470,17 @@ _Exit: // // Release Resources. // - X509_free (X509Cert); - X509_free (X509CACert); - X509_STORE_free (CertStore); + if (X509Cert != NULL) { + X509_free (X509Cert); + } + + if (X509CACert != NULL) { + X509_free (X509CACert); + } + if (CertStore != NULL) { + X509_STORE_free (CertStore); + } + return Status; } -- cgit v1.2.3