CryptoPkg: Add ImageTimestampVerify based on Mbedtls
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4177 Timestamp Countersignature Verification implementaion based on Mbedtls. Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Yi Li <yi1.li@intel.com> Signed-off-by: Wenxing Hou <wenxing.hou@intel.com> Reviewed-by: Yi Li <yi1.li@intel.com> Acked-by: Jiewen Yao <Jiewen.yao@intel.com>
This commit is contained in:
parent
27a7345882
commit
3096fcf81d
381
CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c
Normal file
381
CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptTs.c
Normal file
@ -0,0 +1,381 @@
|
||||
/** @file
|
||||
RFC3161 Timestamp Countersignature Verification Wrapper Implementation which does
|
||||
not provide real capabilities.
|
||||
|
||||
Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
**/
|
||||
|
||||
#include "InternalCryptLib.h"
|
||||
#include <mbedtls/asn1.h>
|
||||
|
||||
//
|
||||
// OID ASN.1 Value for SPC_RFC3161_OBJID ("1.3.6.1.4.1.311.3.3.1")
|
||||
//
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED const UINT8 mSpcRFC3161OidValue[] = {
|
||||
0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x03, 0x03, 0x01
|
||||
};
|
||||
|
||||
/**
|
||||
Convert ASN.1 GeneralizedTime to EFI Time.
|
||||
|
||||
@param[in] Ptr Pointer to the ASN.1 GeneralizedTime to be converted.
|
||||
@param[out] EfiTime Return the corresponding EFI Time.
|
||||
|
||||
@retval TRUE The time conversion succeeds.
|
||||
@retval FALSE Invalid parameters.
|
||||
|
||||
**/
|
||||
STATIC
|
||||
BOOLEAN
|
||||
ConvertAsn1TimeToEfiTime (
|
||||
IN UINT8 *Ptr,
|
||||
OUT EFI_TIME *EfiTime
|
||||
)
|
||||
{
|
||||
CONST CHAR8 *Str;
|
||||
UINTN Index;
|
||||
|
||||
if ((Ptr == NULL) || (EfiTime == NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Str = (CONST CHAR8 *)Ptr;
|
||||
SetMem (EfiTime, sizeof (EFI_TIME), 0);
|
||||
|
||||
Index = 0;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
Verifies the validity of a RFC3161 Timestamp CounterSignature embedded in PE/COFF Authenticode
|
||||
signature.
|
||||
|
||||
Return FALSE to indicate this interface is not supported.
|
||||
|
||||
@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 FALSE This interface is not supported.
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
ImageTimestampVerify (
|
||||
IN CONST UINT8 *AuthData,
|
||||
IN UINTN DataSize,
|
||||
IN CONST UINT8 *TsaCert,
|
||||
IN UINTN CertSize,
|
||||
OUT EFI_TIME *SigningTime
|
||||
)
|
||||
{
|
||||
BOOLEAN Status;
|
||||
UINT8 *Ptr;
|
||||
UINT8 *End;
|
||||
INT32 Len;
|
||||
UINTN ObjLen;
|
||||
UINT8 *TempPtr;
|
||||
|
||||
//
|
||||
// Initializations
|
||||
//
|
||||
if (SigningTime != NULL) {
|
||||
SetMem (SigningTime, sizeof (EFI_TIME), 0);
|
||||
}
|
||||
|
||||
//
|
||||
// Input Parameters Checking.
|
||||
//
|
||||
if ((AuthData == NULL) || (TsaCert == NULL)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((DataSize > INT_MAX) || (CertSize > INT_MAX)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr = (UINT8 *)(UINTN)AuthData;
|
||||
Len = (UINT32)DataSize;
|
||||
End = Ptr + Len;
|
||||
|
||||
// ContentInfo
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// ContentType
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
// content
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
End = Ptr + ObjLen;
|
||||
// signedData
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// version
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
// digestAlgo
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// encapContentInfo
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// cert
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
TempPtr = Ptr;
|
||||
// OPTIONAL CRLs
|
||||
if (mbedtls_asn1_get_tag (&TempPtr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) == 0) {
|
||||
Ptr = TempPtr + ObjLen;
|
||||
}
|
||||
|
||||
// signerInfo
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// sub parse
|
||||
// signerInfo
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
End = Ptr + ObjLen;
|
||||
|
||||
// version
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// sid
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// digestalgo
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// OPTIONAL AuthenticatedAttributes
|
||||
TempPtr = Ptr;
|
||||
if (mbedtls_asn1_get_tag (&TempPtr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) == 0) {
|
||||
Ptr = TempPtr + ObjLen;
|
||||
}
|
||||
|
||||
// signaturealgo
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// signature
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OCTET_STRING) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// OPTIONAL UnauthenticatedAttributes
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, 0xA1) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Attribute
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// type
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (CompareMem (Ptr, mSpcRFC3161OidValue, sizeof (mSpcRFC3161OidValue)) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// values
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// values
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// signedData OID
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// [0]
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// integer
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
// SET
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SET) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// tST OID
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_CONTEXT_SPECIFIC) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OCTET_STRING) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Integer
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
// policy OID
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
// sequence
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
// Integer
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_INTEGER) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Ptr += ObjLen;
|
||||
|
||||
// GeneralizedTime
|
||||
if (mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_GENERALIZED_TIME) != 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//
|
||||
// Retrieve the signing time from TS_TST_INFO structure.
|
||||
//
|
||||
if (SigningTime != NULL) {
|
||||
SetMem (SigningTime, sizeof (EFI_TIME), 0);
|
||||
Status = ConvertAsn1TimeToEfiTime (Ptr, SigningTime);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user