summaryrefslogtreecommitdiff
path: root/Core/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c')
-rw-r--r--Core/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c665
1 files changed, 0 insertions, 665 deletions
diff --git a/Core/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c b/Core/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
deleted file mode 100644
index d63c23df09..0000000000
--- a/Core/CryptoPkg/Library/BaseCryptLib/Pk/CryptTs.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/** @file
- RFC3161 Timestamp Countersignature Verification over OpenSSL.
- The timestamp is generated by a TimeStamping Authority (TSA) and asserts that a
- publisher's signature existed before the specified time. The timestamp extends
- the lifetime of the signature when a signing certificate expires or is later
- revoked.
-
-Copyright (c) 2014 - 2017, Intel Corporation. All rights reserved.<BR>
-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 <openssl/asn1.h>
-#include <openssl/asn1t.h>
-#include <openssl/x509.h>
-#include <openssl/x509v3.h>
-#include <openssl/pkcs7.h>
-
-//
-// OID ASN.1 Value for SPC_RFC3161_OBJID ("1.3.6.1.4.1.311.3.3.1")
-//
-UINT8 mSpcRFC3161OidValue[] = {
- 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x03, 0x03, 0x01
- };
-
-///
-/// The messageImprint field SHOULD contain the hash of the datum to be
-/// time-stamped. The hash is represented as an OCTET STRING. Its
-/// length MUST match the length of the hash value for that algorithm
-/// (e.g., 20 bytes for SHA-1 or 16 bytes for MD5).
-///
-/// MessageImprint ::= SEQUENCE {
-/// hashAlgorithm AlgorithmIdentifier,
-/// hashedMessage OCTET STRING }
-///
-typedef struct {
- X509_ALGOR *HashAlgorithm;
- ASN1_OCTET_STRING *HashedMessage;
-} TS_MESSAGE_IMPRINT;
-
-//
-// ASN.1 Functions for TS_MESSAGE_IMPRINT
-//
-DECLARE_ASN1_FUNCTIONS (TS_MESSAGE_IMPRINT)
-ASN1_SEQUENCE (TS_MESSAGE_IMPRINT) = {
- ASN1_SIMPLE (TS_MESSAGE_IMPRINT, HashAlgorithm, X509_ALGOR),
- ASN1_SIMPLE (TS_MESSAGE_IMPRINT, HashedMessage, ASN1_OCTET_STRING)
-} ASN1_SEQUENCE_END (TS_MESSAGE_IMPRINT)
-IMPLEMENT_ASN1_FUNCTIONS (TS_MESSAGE_IMPRINT)
-
-///
-/// Accuracy represents the time deviation around the UTC time contained
-/// in GeneralizedTime of time-stamp token.
-///
-/// Accuracy ::= SEQUENCE {
-/// seconds INTEGER OPTIONAL,
-/// millis [0] INTEGER (1..999) OPTIONAL,
-/// micros [1] INTEGER (1..999) OPTIONAL }
-///
-typedef struct {
- ASN1_INTEGER *Seconds;
- ASN1_INTEGER *Millis;
- ASN1_INTEGER *Micros;
-} TS_ACCURACY;
-
-//
-// ASN.1 Functions for TS_ACCURACY
-//
-DECLARE_ASN1_FUNCTIONS (TS_ACCURACY)
-ASN1_SEQUENCE (TS_ACCURACY) = {
- ASN1_OPT (TS_ACCURACY, Seconds, ASN1_INTEGER),
- ASN1_IMP_OPT (TS_ACCURACY, Millis, ASN1_INTEGER, 0),
- ASN1_IMP_OPT (TS_ACCURACY, Micros, ASN1_INTEGER, 1)
-} ASN1_SEQUENCE_END (TS_ACCURACY)
-IMPLEMENT_ASN1_FUNCTIONS (TS_ACCURACY)
-
-///
-/// The timestamp token info resulting from a successful timestamp request,
-/// as defined in RFC 3161.
-///
-/// TSTInfo ::= SEQUENCE {
-/// version INTEGER { v1(1) },
-/// policy TSAPolicyId,
-/// messageImprint MessageImprint,
-/// -- MUST have the same value as the similar field in
-/// -- TimeStampReq
-/// serialNumber INTEGER,
-/// -- Time-Stamping users MUST be ready to accommodate integers
-/// -- up to 160 bits.
-/// genTime GeneralizedTime,
-/// accuracy Accuracy OPTIONAL,
-/// ordering BOOLEAN DEFAULT FALSE,
-/// nonce INTEGER OPTIONAL,
-/// -- MUST be present if the similar field was present
-/// -- in TimeStampReq. In that case it MUST have the same value.
-/// tsa [0] GeneralName OPTIONAL,
-/// extensions [1] IMPLICIT Extensions OPTIONAL }
-///
-typedef struct {
- ASN1_INTEGER *Version;
- ASN1_OBJECT *Policy;
- TS_MESSAGE_IMPRINT *MessageImprint;
- ASN1_INTEGER *SerialNumber;
- ASN1_GENERALIZEDTIME *GenTime;
- TS_ACCURACY *Accuracy;
- ASN1_BOOLEAN Ordering;
- ASN1_INTEGER *Nonce;
- GENERAL_NAME *Tsa;
- STACK_OF(X509_EXTENSION) *Extensions;
-} TS_TST_INFO;
-
-//
-// ASN.1 Functions for TS_TST_INFO
-//
-DECLARE_ASN1_FUNCTIONS (TS_TST_INFO)
-ASN1_SEQUENCE (TS_TST_INFO) = {
- ASN1_SIMPLE (TS_TST_INFO, Version, ASN1_INTEGER),
- ASN1_SIMPLE (TS_TST_INFO, Policy, ASN1_OBJECT),
- ASN1_SIMPLE (TS_TST_INFO, MessageImprint, TS_MESSAGE_IMPRINT),
- ASN1_SIMPLE (TS_TST_INFO, SerialNumber, ASN1_INTEGER),
- ASN1_SIMPLE (TS_TST_INFO, GenTime, ASN1_GENERALIZEDTIME),
- ASN1_OPT (TS_TST_INFO, Accuracy, TS_ACCURACY),
- ASN1_OPT (TS_TST_INFO, Ordering, ASN1_FBOOLEAN),
- ASN1_OPT (TS_TST_INFO, Nonce, ASN1_INTEGER),
- ASN1_EXP_OPT(TS_TST_INFO, Tsa, GENERAL_NAME, 0),
- ASN1_IMP_SEQUENCE_OF_OPT (TS_TST_INFO, Extensions, X509_EXTENSION, 1)
-} ASN1_SEQUENCE_END (TS_TST_INFO)
-IMPLEMENT_ASN1_FUNCTIONS (TS_TST_INFO)
-
-
-/**
- Convert ASN.1 GeneralizedTime to EFI Time.
-
- @param[in] Asn1Time Pointer to the ASN.1 GeneralizedTime to be converted.
- @param[out] SigningTime Return the corresponding EFI Time.
-
- @retval TRUE The time convertion succeeds.
- @retval FALSE Invalid parameters.
-
-**/
-BOOLEAN
-EFIAPI
-ConvertAsn1TimeToEfiTime (
- IN ASN1_TIME *Asn1Time,
- OUT EFI_TIME *EfiTime
- )
-{
- CONST CHAR8 *Str;
- UINTN Index;
-
- if ((Asn1Time == NULL) || (EfiTime == NULL)) {
- return FALSE;
- }
-
- Str = (CONST CHAR8*)Asn1Time->data;
- SetMem (EfiTime, 0, sizeof (EFI_TIME));
-
- Index = 0;
- if (Asn1Time->type == V_ASN1_UTCTIME) { /* two digit year */
- EfiTime->Year = (Str[Index++] - '0') * 10;
- EfiTime->Year += (Str[Index++] - '0');
- if (EfiTime->Year < 70) {
- EfiTime->Year += 100;
- }
- } else if (Asn1Time->type == V_ASN1_GENERALIZEDTIME) { /* four digit year */
- EfiTime->Year = (Str[Index++] - '0') * 1000;
- EfiTime->Year += (Str[Index++] - '0') * 100;
- EfiTime->Year += (Str[Index++] - '0') * 10;
- EfiTime->Year += (Str[Index++] - '0');
- if ((EfiTime->Year < 1900) || (EfiTime->Year > 9999)) {
- return FALSE;
- }
- }
-
- EfiTime->Month = (Str[Index++] - '0') * 10;
- EfiTime->Month += (Str[Index++] - '0');
- if ((EfiTime->Month < 1) || (EfiTime->Month > 12)) {
- return FALSE;
- }
-
- EfiTime->Day = (Str[Index++] - '0') * 10;
- EfiTime->Day += (Str[Index++] - '0');
- if ((EfiTime->Day < 1) || (EfiTime->Day > 31)) {
- return FALSE;
- }
-
- EfiTime->Hour = (Str[Index++] - '0') * 10;
- EfiTime->Hour += (Str[Index++] - '0');
- if (EfiTime->Hour > 23) {
- return FALSE;
- }
-
- EfiTime->Minute = (Str[Index++] - '0') * 10;
- EfiTime->Minute += (Str[Index++] - '0');
- if (EfiTime->Minute > 59) {
- return FALSE;
- }
-
- EfiTime->Second = (Str[Index++] - '0') * 10;
- EfiTime->Second += (Str[Index++] - '0');
- if (EfiTime->Second > 59) {
- return FALSE;
- }
-
- /* Note: we did not adjust the time based on time zone information */
-
- return TRUE;
-}
-
-/**
-
- Check the validity of TimeStamp Token Information.
-
- @param[in] TstInfo Pointer to the TS_TST_INFO structure.
- @param[in] TimestampedData Pointer to the data to be time-stamped.
- @param[in] DataSize Size of timestamped data in bytes.
-
- @retval TRUE The TimeStamp Token Information is valid.
- @retval FALSE Invalid TimeStamp Token Information.
-
-**/
-BOOLEAN
-EFIAPI
-CheckTSTInfo (
- IN CONST TS_TST_INFO *TstInfo,
- IN CONST UINT8 *TimestampedData,
- IN UINTN DataSize
- )
-{
- BOOLEAN Status;
- TS_MESSAGE_IMPRINT *Imprint;
- X509_ALGOR *HashAlgo;
- CONST EVP_MD *Md;
- EVP_MD_CTX *MdCtx;
- UINTN MdSize;
- UINT8 *HashedMsg;
-
- //
- // Initialization
- //
- Status = FALSE;
- HashAlgo = NULL;
- HashedMsg = NULL;
- MdCtx = NULL;
-
- //
- // -- Check version number of Timestamp:
- // The version field (currently v1) describes the version of the time-stamp token.
- // Conforming time-stamping servers MUST be able to provide version 1 time-stamp tokens.
- //
- if ((ASN1_INTEGER_get (TstInfo->Version)) != 1) {
- return FALSE;
- }
-
- //
- // -- Check Policies
- // The policy field MUST indicate the TSA's policy under which the response was produced.
- //
- if (TstInfo->Policy == NULL) {
- /// NOTE: Need to check if the requested and returned policies.
- /// We have no information about the Requested TSA Policy.
- return FALSE;
- }
-
- //
- // -- Compute & Check Message Imprint
- //
- Imprint = TstInfo->MessageImprint;
- HashAlgo = X509_ALGOR_dup (Imprint->HashAlgorithm);
-
- Md = EVP_get_digestbyobj (HashAlgo->algorithm);
- if (Md == NULL) {
- goto _Exit;
- }
-
- MdSize = EVP_MD_size (Md);
- HashedMsg = AllocateZeroPool (MdSize);
- if (HashedMsg == NULL) {
- goto _Exit;
- }
- MdCtx = EVP_MD_CTX_new ();
- if (MdCtx == NULL) {
- goto _Exit;
- }
- if ((EVP_DigestInit_ex (MdCtx, Md, NULL) != 1) ||
- (EVP_DigestUpdate (MdCtx, TimestampedData, DataSize) != 1) ||
- (EVP_DigestFinal (MdCtx, HashedMsg, NULL) != 1)) {
- goto _Exit;
- }
- if ((MdSize == (UINTN)ASN1_STRING_length (Imprint->HashedMessage)) &&
- (CompareMem (HashedMsg, ASN1_STRING_get0_data (Imprint->HashedMessage), MdSize) != 0)) {
- goto _Exit;
- }
-
- //
- // -- Check Nonces
- //
- if (TstInfo->Nonce != NULL) {
- //
- // Nonces is optional, No error if no nonce is returned;
- //
- }
-
- //
- // -- Check if the TSA name and signer certificate is matched.
- //
- if (TstInfo->Tsa != NULL) {
- //
- // Ignored the optional Tsa field checking.
- //
- }
-
- Status = TRUE;
-
-_Exit:
- X509_ALGOR_free (HashAlgo);
- EVP_MD_CTX_free (MdCtx);
- if (HashedMsg != NULL) {
- FreePool (HashedMsg);
- }
-
- return Status;
-}
-
-/**
- Verifies the validity of a TimeStamp Token as described in RFC 3161 ("Internet
- X.509 Public Key Infrastructure Time-Stamp Protocol (TSP)").
-
- If TSToken is NULL, then return FALSE.
- If TimestampedData is NULL, then return FALSE.
-
- @param[in] TSToken Pointer to the RFC3161 TimeStamp Token, which is generated
- by a TSA and located in the software publisher's SignerInfo
- structure.
- @param[in] TokenSize Size of the TimeStamp Token in bytes.
- @param[in] TsaCert Pointer to a trusted/root TSA certificate encoded in DER.
- @param[in] CertSize Size of the trusted TSA certificate in bytes.
- @param[in] TimestampedData Pointer to the data to be time-stamped.
- @param[in] DataSize Size of timestamped data in bytes.
- @param[out] SigningTime Return the time of timestamp generation time if the timestamp
- signature is valid.
-
- @retval TRUE The specified timestamp token is valid.
- @retval FALSE Invalid timestamp token.
-
-**/
-BOOLEAN
-EFIAPI
-TimestampTokenVerify (
- IN CONST UINT8 *TSToken,
- IN UINTN TokenSize,
- IN CONST UINT8 *TsaCert,
- IN UINTN CertSize,
- IN CONST UINT8 *TimestampedData,
- IN UINTN DataSize,
- OUT EFI_TIME *SigningTime
- )
-{
- BOOLEAN Status;
- CONST UINT8 *TokenTemp;
- PKCS7 *Pkcs7;
- X509 *Cert;
- CONST UINT8 *CertTemp;
- X509_STORE *CertStore;
- BIO *OutBio;
- UINT8 *TstData;
- UINTN TstSize;
- CONST UINT8 *TstTemp;
- TS_TST_INFO *TstInfo;
-
- Status = FALSE;
-
- //
- // Check input parameters
- //
- if ((TSToken == NULL) || (TsaCert == NULL) || (TimestampedData == NULL) ||
- (TokenSize > INT_MAX) || (CertSize > INT_MAX) || (DataSize > INT_MAX)) {
- return FALSE;
- }
-
- //
- // Initializations
- //
- if (SigningTime != NULL) {
- SetMem (SigningTime, sizeof (EFI_TIME), 0);
- }
- Pkcs7 = NULL;
- Cert = NULL;
- CertStore = NULL;
- OutBio = NULL;
- TstData = NULL;
- TstInfo = NULL;
-
- //
- // TimeStamp Token should contain one valid DER-encoded ASN.1 PKCS#7 structure.
- //
- TokenTemp = TSToken;
- Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &TokenTemp, (int) TokenSize);
- if (Pkcs7 == NULL) {
- goto _Exit;
- }
-
- //
- // The timestamp signature (TSA's response) will be one PKCS#7 signed data.
- //
- if (!PKCS7_type_is_signed (Pkcs7)) {
- goto _Exit;
- }
-
- //
- // Read the trusted TSA certificate (DER-encoded), and Construct X509 Certificate.
- //
- CertTemp = TsaCert;
- Cert = d2i_X509 (NULL, &CertTemp, (long) CertSize);
- if (Cert == NULL) {
- goto _Exit;
- }
-
- //
- // Setup X509 Store for trusted certificate.
- //
- CertStore = X509_STORE_new ();
- if ((CertStore == NULL) || !(X509_STORE_add_cert (CertStore, Cert))) {
- goto _Exit;
- }
-
- //
- // Allow partial certificate chains, terminated by a non-self-signed but
- // still trusted intermediate certificate. Also disable time checks.
- //
- X509_STORE_set_flags (CertStore,
- X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME);
-
- X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);
-
- //
- // Verifies the PKCS#7 signedData structure, and output the signed contents.
- //
- OutBio = BIO_new (BIO_s_mem ());
- if (OutBio == NULL) {
- goto _Exit;
- }
- if (!PKCS7_verify (Pkcs7, NULL, CertStore, NULL, OutBio, PKCS7_BINARY)) {
- goto _Exit;
- }
-
- //
- // Read the signed contents detached in timestamp signature.
- //
- TstData = AllocateZeroPool (2048);
- if (TstData == NULL) {
- goto _Exit;
- }
- TstSize = BIO_read (OutBio, (void *) TstData, 2048);
-
- //
- // Construct TS_TST_INFO structure from the signed contents.
- //
- TstTemp = TstData;
- TstInfo = d2i_TS_TST_INFO (NULL, (const unsigned char **) &TstTemp,
- (int)TstSize);
- if (TstInfo == NULL) {
- goto _Exit;
- }
-
- //
- // Check TS_TST_INFO structure.
- //
- Status = CheckTSTInfo (TstInfo, TimestampedData, DataSize);
- if (!Status) {
- goto _Exit;
- }
-
- //
- // Retrieve the signing time from TS_TST_INFO structure.
- //
- if (SigningTime != NULL) {
- SetMem (SigningTime, sizeof (EFI_TIME), 0);
- Status = ConvertAsn1TimeToEfiTime (TstInfo->GenTime, SigningTime);
- }
-
-_Exit:
- //
- // Release Resources
- //
- PKCS7_free (Pkcs7);
- X509_free (Cert);
- X509_STORE_free (CertStore);
- BIO_free (OutBio);
- TS_TST_INFO_free (TstInfo);
-
- if (TstData != NULL) {
- FreePool (TstData);
- }
-
- return Status;
-}
-
-/**
- Verifies the validity of a RFC3161 Timestamp CounterSignature embedded in PE/COFF Authenticode
- signature.
-
- If AuthData is NULL, then return FALSE.
-
- @param[in] AuthData Pointer to the Authenticode Signature retrieved from signed
- PE/COFF image to be verified.
- @param[in] DataSize Size of the Authenticode Signature in bytes.
- @param[in] TsaCert Pointer to a trusted/root TSA certificate encoded in DER, which
- is used for TSA certificate chain verification.
- @param[in] CertSize Size of the trusted certificate in bytes.
- @param[out] SigningTime Return the time of timestamp generation time if the timestamp
- signature is valid.
-
- @retval TRUE The specified Authenticode includes a valid RFC3161 Timestamp CounterSignature.
- @retval FALSE No valid RFC3161 Timestamp CounterSignature in the specified Authenticode data.
-
-**/
-BOOLEAN
-EFIAPI
-ImageTimestampVerify (
- IN CONST UINT8 *AuthData,
- IN UINTN DataSize,
- IN CONST UINT8 *TsaCert,
- IN UINTN CertSize,
- OUT EFI_TIME *SigningTime
- )
-{
- BOOLEAN Status;
- PKCS7 *Pkcs7;
- CONST UINT8 *Temp;
- STACK_OF(PKCS7_SIGNER_INFO) *SignerInfos;
- PKCS7_SIGNER_INFO *SignInfo;
- UINTN Index;
- STACK_OF(X509_ATTRIBUTE) *Sk;
- X509_ATTRIBUTE *Xa;
- ASN1_OBJECT *XaObj;
- ASN1_TYPE *Asn1Type;
- ASN1_OCTET_STRING *EncDigest;
- UINT8 *TSToken;
- UINTN TokenSize;
-
- //
- // Input Parameters Checking.
- //
- if ((AuthData == NULL) || (TsaCert == NULL)) {
- return FALSE;
- }
-
- if ((DataSize > INT_MAX) || (CertSize > INT_MAX)) {
- return FALSE;
- }
-
- //
- // Register & Initialize necessary digest algorithms for PKCS#7 Handling.
- //
- if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1 ()) == 0) ||
- (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0) {
- return FALSE;
- }
-
- //
- // Initialization.
- //
- Status = FALSE;
- Pkcs7 = NULL;
- SignInfo = NULL;
-
- //
- // Decode ASN.1-encoded Authenticode data into PKCS7 structure.
- //
- Temp = AuthData;
- Pkcs7 = d2i_PKCS7 (NULL, (const unsigned char **) &Temp, (int) DataSize);
- if (Pkcs7 == NULL) {
- goto _Exit;
- }
-
- //
- // Check if there is one and only one signer.
- //
- SignerInfos = PKCS7_get_signer_info (Pkcs7);
- if (!SignerInfos || (sk_PKCS7_SIGNER_INFO_num (SignerInfos) != 1)) {
- goto _Exit;
- }
-
- //
- // Locate the TimeStamp CounterSignature.
- //
- SignInfo = sk_PKCS7_SIGNER_INFO_value (SignerInfos, 0);
- if (SignInfo == NULL) {
- goto _Exit;
- }
-
- //
- // Locate Message Digest which will be the data to be time-stamped.
- //
- EncDigest = SignInfo->enc_digest;
- if (EncDigest == NULL) {
- goto _Exit;
- }
-
- //
- // The RFC3161 timestamp counterSignature is contained in unauthenticatedAttributes field
- // of SignerInfo.
- //
- Sk = SignInfo->unauth_attr;
- if (Sk == NULL) { // No timestamp counterSignature.
- goto _Exit;
- }
-
- Asn1Type = NULL;
- for (Index = 0; Index < (UINTN) sk_X509_ATTRIBUTE_num (Sk); Index++) {
- //
- // Search valid RFC3161 timestamp counterSignature based on OBJID.
- //
- Xa = sk_X509_ATTRIBUTE_value (Sk, (int)Index);
- if (Xa == NULL) {
- continue;
- }
- XaObj = X509_ATTRIBUTE_get0_object(Xa);
- if (XaObj == NULL) {
- continue;
- }
- if ((OBJ_length(XaObj) != sizeof (mSpcRFC3161OidValue)) ||
- (CompareMem (OBJ_get0_data(XaObj), mSpcRFC3161OidValue, sizeof (mSpcRFC3161OidValue)) != 0)) {
- continue;
- }
- Asn1Type = X509_ATTRIBUTE_get0_type(Xa, 0);
- }
-
- if (Asn1Type == NULL) {
- Status = FALSE;
- goto _Exit;
- }
- TSToken = Asn1Type->value.octet_string->data;
- TokenSize = Asn1Type->value.octet_string->length;
-
- //
- // TimeStamp counterSignature (Token) verification.
- //
- Status = TimestampTokenVerify (
- TSToken,
- TokenSize,
- TsaCert,
- CertSize,
- EncDigest->data,
- EncDigest->length,
- SigningTime
- );
-
-_Exit:
- //
- // Release Resources
- //
- PKCS7_free (Pkcs7);
-
- return Status;
-}