13#include "InternalCryptLib.h"
15#include <openssl/asn1.h>
16#include <openssl/asn1t.h>
17#include <openssl/x509.h>
18#include <openssl/x509v3.h>
19#include <openssl/pkcs7.h>
25 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x03, 0x03, 0x01
39 X509_ALGOR *HashAlgorithm;
40 ASN1_OCTET_STRING *HashedMessage;
47DECLARE_ASN1_FUNCTIONS (
69 ASN1_INTEGER *Seconds;
78DECLARE_ASN1_FUNCTIONS (
84 ASN1_IMP_OPT (
TS_ACCURACY, Millis, ASN1_INTEGER, 0),
114 ASN1_INTEGER *Version;
117 ASN1_INTEGER *SerialNumber;
118 ASN1_GENERALIZEDTIME *GenTime;
120 ASN1_BOOLEAN Ordering;
123 STACK_OF (X509_EXTENSION) *Extensions;
130DECLARE_ASN1_FUNCTIONS (
138 ASN1_SIMPLE (
TS_TST_INFO, SerialNumber, ASN1_INTEGER),
139 ASN1_SIMPLE (
TS_TST_INFO, GenTime, ASN1_GENERALIZEDTIME),
144 ASN1_IMP_SEQUENCE_OF_OPT (
TS_TST_INFO, Extensions, X509_EXTENSION, 1)
163 IN ASN1_TIME *Asn1Time,
170 if ((Asn1Time ==
NULL) || (EfiTime ==
NULL)) {
174 Str = (
CONST CHAR8 *)Asn1Time->data;
178 if (Asn1Time->type == V_ASN1_UTCTIME) {
180 EfiTime->Year = (Str[Index++] -
'0') * 10;
181 EfiTime->Year += (Str[Index++] -
'0');
182 if (EfiTime->Year < 70) {
183 EfiTime->Year += 100;
185 }
else if (Asn1Time->type == V_ASN1_GENERALIZEDTIME) {
187 EfiTime->Year = (Str[Index++] -
'0') * 1000;
188 EfiTime->Year += (Str[Index++] -
'0') * 100;
189 EfiTime->Year += (Str[Index++] -
'0') * 10;
190 EfiTime->Year += (Str[Index++] -
'0');
191 if ((EfiTime->Year < 1900) || (EfiTime->Year > 9999)) {
196 EfiTime->Month = (Str[Index++] -
'0') * 10;
197 EfiTime->Month += (Str[Index++] -
'0');
198 if ((EfiTime->Month < 1) || (EfiTime->Month > 12)) {
202 EfiTime->Day = (Str[Index++] -
'0') * 10;
203 EfiTime->Day += (Str[Index++] -
'0');
204 if ((EfiTime->Day < 1) || (EfiTime->Day > 31)) {
208 EfiTime->Hour = (Str[Index++] -
'0') * 10;
209 EfiTime->Hour += (Str[Index++] -
'0');
210 if (EfiTime->Hour > 23) {
214 EfiTime->Minute = (Str[Index++] -
'0') * 10;
215 EfiTime->Minute += (Str[Index++] -
'0');
216 if (EfiTime->Minute > 59) {
220 EfiTime->Second = (Str[Index++] -
'0') * 10;
221 EfiTime->Second += (Str[Index++] -
'0');
222 if (EfiTime->Second > 59) {
247 IN CONST UINT8 *TimestampedData,
253 X509_ALGOR *HashAlgo;
272 if ((ASN1_INTEGER_get (TstInfo->Version)) != 1) {
280 if (TstInfo->Policy ==
NULL) {
289 Imprint = TstInfo->MessageImprint;
290 HashAlgo = X509_ALGOR_dup (Imprint->HashAlgorithm);
292 Md = EVP_get_digestbyobj (HashAlgo->algorithm);
297 MdSize = EVP_MD_size (Md);
299 if (HashedMsg ==
NULL) {
303 MdCtx = EVP_MD_CTX_new ();
308 if ((EVP_DigestInit_ex (MdCtx, Md,
NULL) != 1) ||
309 (EVP_DigestUpdate (MdCtx, TimestampedData, DataSize) != 1) ||
310 (EVP_DigestFinal (MdCtx, HashedMsg,
NULL) != 1))
315 if ((MdSize == (
UINTN)ASN1_STRING_length (Imprint->HashedMessage)) &&
316 (
CompareMem (HashedMsg, ASN1_STRING_get0_data (Imprint->HashedMessage), MdSize) != 0))
324 if (TstInfo->Nonce !=
NULL) {
333 if (TstInfo->Tsa !=
NULL) {
342 X509_ALGOR_free (HashAlgo);
343 EVP_MD_CTX_free (MdCtx);
344 if (HashedMsg !=
NULL) {
380 IN CONST UINT8 *TimestampedData,
386 CONST UINT8 *TokenTemp;
389 CONST UINT8 *CertTemp;
390 X509_STORE *CertStore;
394 CONST UINT8 *TstTemp;
402 if ((TSToken ==
NULL) || (TsaCert ==
NULL) || (TimestampedData ==
NULL) ||
403 (TokenSize > INT_MAX) || (CertSize > INT_MAX) || (DataSize > INT_MAX))
411 if (SigningTime !=
NULL) {
426 Pkcs7 = d2i_PKCS7 (
NULL, (
const unsigned char **)&TokenTemp, (
int)TokenSize);
434 if (!PKCS7_type_is_signed (Pkcs7)) {
442 Cert = d2i_X509 (
NULL, &CertTemp, (
long)CertSize);
450 CertStore = X509_STORE_new ();
451 if ((CertStore ==
NULL) || !(X509_STORE_add_cert (CertStore, Cert))) {
459 X509_STORE_set_flags (
461 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
464 X509_STORE_set_purpose (CertStore, X509_PURPOSE_ANY);
469 OutBio = BIO_new (BIO_s_mem ());
470 if (OutBio ==
NULL) {
474 if (!PKCS7_verify (Pkcs7,
NULL, CertStore,
NULL, OutBio, PKCS7_BINARY)) {
482 if (TstData ==
NULL) {
486 TstSize = BIO_read (OutBio, (
void *)TstData, 2048);
492 TstInfo = d2i_TS_TST_INFO (
494 (
const unsigned char **)&TstTemp,
497 if (TstInfo ==
NULL) {
504 Status =
CheckTSTInfo (TstInfo, TimestampedData, DataSize);
512 if (SigningTime !=
NULL) {
523 X509_STORE_free (CertStore);
525 TS_TST_INFO_free (TstInfo);
527 if (TstData !=
NULL) {
571 STACK_OF (X509_ATTRIBUTE) *Sk;
575 ASN1_OCTET_STRING *EncDigest;
582 if ((AuthData ==
NULL) || (TsaCert ==
NULL)) {
586 if ((DataSize > INT_MAX) || (CertSize > INT_MAX)) {
593 if ((EVP_add_digest (EVP_md5 ()) == 0) || (EVP_add_digest (EVP_sha1 ()) == 0) ||
594 (EVP_add_digest (EVP_sha256 ()) == 0) || (EVP_add_digest (EVP_sha384 ()) == 0) ||
595 (EVP_add_digest (EVP_sha512 ()) == 0) || ((EVP_add_digest_alias (SN_sha1WithRSAEncryption, SN_sha1WithRSA)) == 0))
611 Pkcs7 = d2i_PKCS7 (
NULL, (
const unsigned char **)&Temp, (
int)DataSize);
619 SignerInfos = PKCS7_get_signer_info (Pkcs7);
620 if (!SignerInfos || (sk_PKCS7_SIGNER_INFO_num (SignerInfos) != 1)) {
627 SignInfo = sk_PKCS7_SIGNER_INFO_value (SignerInfos, 0);
628 if (SignInfo ==
NULL) {
635 EncDigest = SignInfo->enc_digest;
636 if (EncDigest ==
NULL) {
644 Sk = SignInfo->unauth_attr;
651 for (Index = 0; Index < (
UINTN)sk_X509_ATTRIBUTE_num (Sk); Index++) {
655 Xa = sk_X509_ATTRIBUTE_value (Sk, (
int)Index);
660 XaObj = X509_ATTRIBUTE_get0_object (Xa);
665 if ((OBJ_length (XaObj) !=
sizeof (mSpcRFC3161OidValue)) ||
666 (
CompareMem (OBJ_get0_data (XaObj), mSpcRFC3161OidValue,
sizeof (mSpcRFC3161OidValue)) != 0))
671 Asn1Type = X509_ATTRIBUTE_get0_type (Xa, 0);
674 if (Asn1Type ==
NULL) {
679 TSToken = Asn1Type->value.octet_string->data;
680 TokenSize = Asn1Type->value.octet_string->length;
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI SetMem(OUT VOID *Buffer, IN UINTN Length, IN UINT8 Value)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
#define GLOBAL_REMOVE_IF_UNREFERENCED
STATIC BOOLEAN CheckTSTInfo(IN CONST TS_TST_INFO *TstInfo, IN CONST UINT8 *TimestampedData, IN UINTN DataSize)
STATIC BOOLEAN ConvertAsn1TimeToEfiTime(IN ASN1_TIME *Asn1Time, OUT EFI_TIME *EfiTime)
BOOLEAN EFIAPI ImageTimestampVerify(IN CONST UINT8 *AuthData, IN UINTN DataSize, IN CONST UINT8 *TsaCert, IN UINTN CertSize, OUT EFI_TIME *SigningTime)
STATIC BOOLEAN 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)