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