public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH V3 0/4] CryptoPkg: add more X509 functions.
@ 2022-10-12  4:35 Qi Zhang
  2022-10-12  4:35 ` [PATCH V3 1/4] CryptoPkg: add new X509 function definition Qi Zhang
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Qi Zhang @ 2022-10-12  4:35 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

This patch serial is to add more CryptoX509 functions.

Tested by:
1. https://github.com/tianocore/edk2-staging/tree/DeviceSecurity.
2. Unit test: CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c

Review PR: https://github.com/tianocore/edk2/pull/3464.

V2 change: rename X509SetDateTime() to X509FormatDateTime().
V3 change: rebase this patch serial with the patch serial
           "CryptoPkg: Add EC key retrieving and signature interface."
           So the merge order is Ec -> X509.

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>

Qi Zhang (4):
  CryptoPkg: add new X509 function definition.
  CryptoPkg: add new X509 function.
  CryptoPkg: add new X509 function to Crypto Service.
  CryptoPkg: add Unit Test for X509 new function.

 CryptoPkg/Driver/Crypto.c                     |  432 ++++++-
 CryptoPkg/Include/Library/BaseCryptLib.h      |  374 ++++++
 .../Pcd/PcdCryptoServiceFamilyEnable.h        |   34 +-
 CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c | 1036 +++++++++++++++++
 .../Library/BaseCryptLib/Pk/CryptX509Null.c   |  429 +++++++
 .../BaseCryptLibNull/Pk/CryptX509Null.c       |  429 +++++++
 .../BaseCryptLibOnProtocolPpi/CryptLib.c      |  415 +++++++
 CryptoPkg/Private/Protocol/Crypto.h           |  392 ++++++-
 .../BaseCryptLib/BaseCryptLibUnitTests.c      |    1 +
 .../Library/BaseCryptLib/TestBaseCryptLib.h   |    4 +
 .../BaseCryptLib/TestBaseCryptLibHost.inf     |    1 +
 .../BaseCryptLib/TestBaseCryptLibShell.inf    |    1 +
 .../UnitTest/Library/BaseCryptLib/X509Tests.c |  631 ++++++++++
 13 files changed, 4167 insertions(+), 12 deletions(-)
 create mode 100644 CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c

-- 
2.26.2.windows.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH V3 1/4] CryptoPkg: add new X509 function definition.
  2022-10-12  4:35 [PATCH V3 0/4] CryptoPkg: add more X509 functions Qi Zhang
@ 2022-10-12  4:35 ` Qi Zhang
  2022-10-12  4:35 ` [PATCH V3 2/4] CryptoPkg: add new X509 function Qi Zhang
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Qi Zhang @ 2022-10-12  4:35 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
---
 CryptoPkg/Include/Library/BaseCryptLib.h | 374 +++++++++++++++++++++++
 1 file changed, 374 insertions(+)

diff --git a/CryptoPkg/Include/Library/BaseCryptLib.h b/CryptoPkg/Include/Library/BaseCryptLib.h
index dfeb8c7d55..a52bd91ad6 100644
--- a/CryptoPkg/Include/Library/BaseCryptLib.h
+++ b/CryptoPkg/Include/Library/BaseCryptLib.h
@@ -2471,6 +2471,380 @@ ImageTimestampVerify (
   OUT EFI_TIME     *SigningTime
   );
 
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  );
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  );
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  );
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  );
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  );
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]      To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  );
+
+/**
+  Format a DateTimeStr to DataTime object in DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509FormatDateTime (
+  IN   CONST CHAR8  *DateTimeStr,
+  OUT  VOID         *DateTime,
+  IN OUT UINTN      *DateTimeSize
+  );
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN  CONST  VOID  *DateTime1,
+  IN  CONST  VOID  *DateTime2
+  );
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  );
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  );
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  );
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate. If index is -1 indecate the
+                                    last certificate in CertChain.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  );
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8    **Ptr,
+  IN CONST UINT8  *End,
+  OUT UINTN       *Length,
+  IN     UINT32   Tag
+  );
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  );
+
 // =====================================================================================
 //    DH Key Exchange Primitive
 // =====================================================================================
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH V3 2/4] CryptoPkg: add new X509 function.
  2022-10-12  4:35 [PATCH V3 0/4] CryptoPkg: add more X509 functions Qi Zhang
  2022-10-12  4:35 ` [PATCH V3 1/4] CryptoPkg: add new X509 function definition Qi Zhang
@ 2022-10-12  4:35 ` Qi Zhang
  2022-10-12  4:36 ` [PATCH V3 3/4] CryptoPkg: add new X509 function to Crypto Service Qi Zhang
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Qi Zhang @ 2022-10-12  4:35 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
---
 CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c | 1036 +++++++++++++++++
 .../Library/BaseCryptLib/Pk/CryptX509Null.c   |  429 +++++++
 .../BaseCryptLibNull/Pk/CryptX509Null.c       |  429 +++++++
 3 files changed, 1894 insertions(+)

diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
index 58d3f27b11..1d91ac3b0f 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c
@@ -8,8 +8,22 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 
 #include "InternalCryptLib.h"
 #include <openssl/x509.h>
+#include <openssl/x509v3.h>
+#include <crypto/asn1.h>
+#include <openssl/asn1.h>
 #include <openssl/rsa.h>
 
+/* OID*/
+#define OID_EXT_KEY_USAGE      { 0x55, 0x1D, 0x25 }
+#define OID_BASIC_CONSTRAINTS  { 0x55, 0x1D, 0x13 }
+
+static CONST UINT8  mOidExtKeyUsage[]      = OID_EXT_KEY_USAGE;
+static CONST UINT8  mOidBasicConstraints[] = OID_BASIC_CONSTRAINTS;
+
+#define CRYPTO_ASN1_TAG_CLASS_MASK  0xC0
+#define CRYPTO_ASN1_TAG_PC_MASK     0x20
+#define CRYPTO_ASN1_TAG_VALUE_MASK  0x1F
+
 /**
   Construct a X509 object from DER-encoded certificate data.
 
@@ -925,3 +939,1025 @@ _Exit:
   return FALSE;
  #endif
 }
+
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  BOOLEAN  Status;
+  X509     *X509Cert;
+
+  X509Cert = NULL;
+  Status   = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    //
+    // Invalid X.509 Certificate
+    //
+    Status = FALSE;
+  }
+
+  if (Status) {
+    *Version = X509_get_version (X509Cert);
+  }
+
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  BOOLEAN       Status;
+  X509          *X509Cert;
+  ASN1_INTEGER  *Asn1Integer;
+
+  Status = FALSE;
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (SerialNumberSize == NULL)) {
+    return Status;
+  }
+
+  X509Cert = NULL;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    *SerialNumberSize = 0;
+    Status            = FALSE;
+    goto _Exit;
+  }
+
+  //
+  // Retrieve subject name from certificate object.
+  //
+  Asn1Integer = X509_get_serialNumber (X509Cert);
+  if (Asn1Integer == NULL) {
+    *SerialNumberSize = 0;
+    Status            = FALSE;
+    goto _Exit;
+  }
+
+  if (*SerialNumberSize < (UINTN)Asn1Integer->length) {
+    *SerialNumberSize = (UINTN)Asn1Integer->length;
+    Status            = FALSE;
+    goto _Exit;
+  }
+
+  if (SerialNumber != NULL) {
+    CopyMem (SerialNumber, Asn1Integer->data, *SerialNumberSize);
+    Status = TRUE;
+  }
+
+  *SerialNumberSize = (UINTN)Asn1Integer->length;
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  BOOLEAN    Status;
+  X509       *X509Cert;
+  X509_NAME  *X509Name;
+  UINTN      X509NameSize;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (CertIssuerSize == NULL)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  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;
+  }
+
+  X509NameSize = i2d_X509_NAME (X509Name, NULL);
+  if (*CertIssuerSize < X509NameSize) {
+    *CertIssuerSize = X509NameSize;
+    goto _Exit;
+  }
+
+  *CertIssuerSize = X509NameSize;
+  if (CertIssuer != NULL) {
+    i2d_X509_NAME (X509Name, &CertIssuer);
+    Status = TRUE;
+  }
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  BOOLEAN      Status;
+  X509         *X509Cert;
+  int          Nid;
+  ASN1_OBJECT  *Asn1Obj;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (OidSize == NULL) || (CertSize == 0)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+  Status   = FALSE;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    Status = FALSE;
+    goto _Exit;
+  }
+
+  //
+  // Retrieve subject name from certificate object.
+  //
+  Nid = X509_get_signature_nid (X509Cert);
+  if (Nid == NID_undef) {
+    *OidSize = 0;
+    Status   = FALSE;
+    goto _Exit;
+  }
+
+  Asn1Obj = OBJ_nid2obj (Nid);
+  if (Asn1Obj == NULL) {
+    *OidSize = 0;
+    Status   = FALSE;
+    goto _Exit;
+  }
+
+  if (*OidSize < (UINTN)Asn1Obj->length) {
+    *OidSize = Asn1Obj->length;
+    Status   = FALSE;
+    goto _Exit;
+  }
+
+  if (Oid != NULL) {
+    CopyMem (Oid, Asn1Obj->data, Asn1Obj->length);
+  }
+
+  *OidSize = Asn1Obj->length;
+  Status   = TRUE;
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  BOOLEAN  Status;
+  INTN     i;
+  X509     *X509Cert;
+
+  CONST STACK_OF (X509_EXTENSION) *Extensions;
+  ASN1_OBJECT        *Asn1Obj;
+  ASN1_OCTET_STRING  *Asn1Oct;
+  X509_EXTENSION     *Ext;
+  UINTN              ObjLength;
+  UINTN              OctLength;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (CertSize == 0) || (Oid == NULL) || (OidSize == 0) || (ExtensionDataSize == NULL)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+  Status   = FALSE;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    *ExtensionDataSize = 0;
+    goto Cleanup;
+  }
+
+  //
+  // Retrieve Extensions from certificate object.
+  //
+  Extensions = X509_get0_extensions (X509Cert);
+  if (sk_X509_EXTENSION_num (Extensions) <= 0) {
+    *ExtensionDataSize = 0;
+    goto Cleanup;
+  }
+
+  //
+  // Traverse Extensions
+  //
+  Status    = FALSE;
+  Asn1Oct   = NULL;
+  OctLength = 0;
+  for (i = 0; i < sk_X509_EXTENSION_num (Extensions); i++) {
+    Ext = sk_X509_EXTENSION_value (Extensions, (int)i);
+    if (Ext == NULL) {
+      continue;
+    }
+
+    Asn1Obj = X509_EXTENSION_get_object (Ext);
+    if (Asn1Obj == NULL) {
+      continue;
+    }
+
+    Asn1Oct = X509_EXTENSION_get_data (Ext);
+    if (Asn1Oct == NULL) {
+      continue;
+    }
+
+    ObjLength = OBJ_length (Asn1Obj);
+    OctLength = ASN1_STRING_length (Asn1Oct);
+    if ((OidSize == ObjLength) && (CompareMem (OBJ_get0_data (Asn1Obj), Oid, OidSize) == 0)) {
+      //
+      // Extension Found
+      //
+      Status = TRUE;
+      break;
+    }
+
+    //
+    // reset to 0 if not found
+    //
+    OctLength = 0;
+  }
+
+  if (Status) {
+    if (*ExtensionDataSize < OctLength) {
+      *ExtensionDataSize = OctLength;
+      Status             = FALSE;
+      goto Cleanup;
+    }
+
+    if (Asn1Oct != NULL) {
+      CopyMem (ExtensionData, ASN1_STRING_get0_data (Asn1Oct), OctLength);
+    }
+
+    *ExtensionDataSize = OctLength;
+  } else {
+    *ExtensionDataSize = 0;
+  }
+
+Cleanup:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  BOOLEAN  Status;
+
+  Status = X509GetExtensionData (Cert, CertSize, mOidExtKeyUsage, sizeof (mOidExtKeyUsage), Usage, UsageSize);
+  return Status;
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[out]     To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  BOOLEAN          Status;
+  X509             *X509Cert;
+  CONST ASN1_TIME  *F;
+  CONST ASN1_TIME  *T;
+  UINTN            TSize;
+  UINTN            FSize;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (FromSize == NULL) || (ToSize == NULL) || (CertSize == 0)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+  Status   = FALSE;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    goto _Exit;
+  }
+
+  //
+  // Retrieve Validity from/to from certificate object.
+  //
+  F = X509_get0_notBefore (X509Cert);
+  T = X509_get0_notAfter (X509Cert);
+
+  if ((F == NULL) || (T == NULL)) {
+    goto _Exit;
+  }
+
+  FSize = sizeof (ASN1_TIME) + F->length;
+  if (*FromSize < FSize) {
+    *FromSize = FSize;
+    goto _Exit;
+  }
+
+  *FromSize = FSize;
+  if (From != NULL) {
+    CopyMem (From, F, sizeof (ASN1_TIME));
+    ((ASN1_TIME *)From)->data = From + sizeof (ASN1_TIME);
+    CopyMem (From + sizeof (ASN1_TIME), F->data, F->length);
+  }
+
+  TSize = sizeof (ASN1_TIME) + T->length;
+  if (*ToSize < TSize) {
+    *ToSize = TSize;
+    goto _Exit;
+  }
+
+  *ToSize = TSize;
+  if (To != NULL) {
+    CopyMem (To, T, sizeof (ASN1_TIME));
+    ((ASN1_TIME *)To)->data = To + sizeof (ASN1_TIME);
+    CopyMem (To + sizeof (ASN1_TIME), T->data, T->length);
+  }
+
+  Status = TRUE;
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Format a DateTimeStr to DataTime object in DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509FormatDateTime (
+  IN  CONST  CHAR8  *DateTimeStr,
+  OUT VOID          *DateTime,
+  IN OUT UINTN      *DateTimeSize
+  )
+{
+  BOOLEAN    Status;
+  INT32      Ret;
+  ASN1_TIME  *Dt;
+  UINTN      DSize;
+
+  Dt     = NULL;
+  Status = FALSE;
+
+  Dt = ASN1_TIME_new ();
+  if (Dt == NULL) {
+    Status = FALSE;
+    goto Cleanup;
+  }
+
+  Ret = ASN1_TIME_set_string_X509 (Dt, DateTimeStr);
+  if (Ret != 1) {
+    Status = FALSE;
+    goto Cleanup;
+  }
+
+  DSize = sizeof (ASN1_TIME) + Dt->length;
+  if (*DateTimeSize < DSize) {
+    *DateTimeSize = DSize;
+    Status        = FALSE;
+    goto Cleanup;
+  }
+
+  *DateTimeSize = DSize;
+  if (DateTime != NULL) {
+    CopyMem (DateTime, Dt, sizeof (ASN1_TIME));
+    ((ASN1_TIME *)DateTime)->data = (UINT8 *)DateTime + sizeof (ASN1_TIME);
+    CopyMem ((UINT8 *)DateTime + sizeof (ASN1_TIME), Dt->data, Dt->length);
+  }
+
+  Status = TRUE;
+
+Cleanup:
+  if (Dt != NULL) {
+    ASN1_TIME_free (Dt);
+  }
+
+  return Status;
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN CONST  VOID  *DateTime1,
+  IN CONST  VOID  *DateTime2
+  )
+{
+  return (INT32)ASN1_TIME_compare (DateTime1, DateTime2);
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  BOOLEAN  Status;
+  X509     *X509Cert;
+
+  //
+  // Check input parameters.
+  //
+  if ((Cert == NULL) || (Usage == NULL)) {
+    return FALSE;
+  }
+
+  X509Cert = NULL;
+  Status   = FALSE;
+
+  //
+  // Read DER-encoded X509 Certificate and Construct X509 object.
+  //
+  Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
+  if ((X509Cert == NULL) || (!Status)) {
+    goto _Exit;
+  }
+
+  //
+  // Retrieve subject name from certificate object.
+  //
+  *Usage = X509_get_key_usage (X509Cert);
+  if (*Usage == NID_undef) {
+    goto _Exit;
+  }
+
+  Status = TRUE;
+
+_Exit:
+  //
+  // Release Resources.
+  //
+  if (X509Cert != NULL) {
+    X509_free (X509Cert);
+  }
+
+  return Status;
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  CONST UINT8  *TmpPtr;
+  UINTN        Length;
+  UINT32       Asn1Tag;
+  UINT32       ObjClass;
+  CONST UINT8  *CurrentCert;
+  UINTN        CurrentCertLen;
+  CONST UINT8  *PrecedingCert;
+  UINTN        PrecedingCertLen;
+  BOOLEAN      VerifyFlag;
+  INT32        Ret;
+
+  PrecedingCert    = RootCert;
+  PrecedingCertLen = RootCertLength;
+
+  CurrentCert    = CertChain;
+  Length         = 0;
+  CurrentCertLen = 0;
+
+  VerifyFlag = FALSE;
+  while (TRUE) {
+    TmpPtr = CurrentCert;
+    Ret    = ASN1_get_object (
+               (CONST UINT8 **)&TmpPtr,
+               (long *)&Length,
+               (int *)&Asn1Tag,
+               (int *)&ObjClass,
+               (long)(CertChainLength + CertChain - TmpPtr)
+               );
+    if ((Asn1Tag != V_ASN1_SEQUENCE) || (Ret == 0x80)) {
+      break;
+    }
+
+    //
+    // Calculate CurrentCert length;
+    //
+    CurrentCertLen = TmpPtr - CurrentCert + Length;
+
+    //
+    // Verify CurrentCert with preceding cert;
+    //
+    VerifyFlag = X509VerifyCert (CurrentCert, CurrentCertLen, PrecedingCert, PrecedingCertLen);
+    if (VerifyFlag == FALSE) {
+      break;
+    }
+
+    //
+    // move Current cert to Preceding cert
+    //
+    PrecedingCertLen = CurrentCertLen;
+    PrecedingCert    = CurrentCert;
+
+    //
+    // Move to next
+    //
+    CurrentCert = CurrentCert + CurrentCertLen;
+  }
+
+  return VerifyFlag;
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  UINTN        Asn1Len;
+  INT32        CurrentIndex;
+  UINTN        CurrentCertLen;
+  CONST UINT8  *CurrentCert;
+  CONST UINT8  *TmpPtr;
+  INT32        Ret;
+  UINT32       Asn1Tag;
+  UINT32       ObjClass;
+
+  //
+  // Check input parameters.
+  //
+  if ((CertChain == NULL) || (Cert == NULL) ||
+      (CertIndex < -1) || (CertLength == NULL))
+  {
+    return FALSE;
+  }
+
+  Asn1Len        = 0;
+  CurrentCertLen = 0;
+  CurrentCert    = CertChain;
+  CurrentIndex   = -1;
+
+  //
+  // Traverse the certificate chain
+  //
+  while (TRUE) {
+    TmpPtr = CurrentCert;
+
+    // Get asn1 object and taglen
+    Ret = ASN1_get_object (
+            (CONST UINT8 **)&TmpPtr,
+            (long *)&Asn1Len,
+            (int *)&Asn1Tag,
+            (int *)&ObjClass,
+            (long)(CertChainLength + CertChain - TmpPtr)
+            );
+    if ((Asn1Tag != V_ASN1_SEQUENCE) || (Ret == 0x80)) {
+      break;
+    }
+
+    //
+    // Calculate CurrentCert length;
+    //
+    CurrentCertLen = TmpPtr - CurrentCert + Asn1Len;
+    CurrentIndex++;
+
+    if (CurrentIndex == CertIndex) {
+      *Cert       = CurrentCert;
+      *CertLength = CurrentCertLen;
+      return TRUE;
+    }
+
+    //
+    // Move to next
+    //
+    CurrentCert = CurrentCert + CurrentCertLen;
+  }
+
+  //
+  // If CertIndex is -1, Return the last certificate
+  //
+  if ((CertIndex == -1) && (CurrentIndex >= 0)) {
+    *Cert       = CurrentCert - CurrentCertLen;
+    *CertLength = CurrentCertLen;
+    return TRUE;
+  }
+
+  return FALSE;
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8    **Ptr,
+  IN CONST UINT8  *End,
+  OUT UINTN       *Length,
+  IN     UINT32   Tag
+  )
+{
+  UINT8  *PtrOld;
+  INT32  ObjTag;
+  INT32  ObjCls;
+  long   ObjLength;
+
+  //
+  // Save Ptr position
+  //
+  PtrOld = *Ptr;
+
+  ASN1_get_object ((CONST UINT8 **)Ptr, &ObjLength, &ObjTag, &ObjCls, (INT32)(End - (*Ptr)));
+  if ((ObjTag == (INT32)(Tag & CRYPTO_ASN1_TAG_VALUE_MASK)) &&
+      (ObjCls == (INT32)(Tag & CRYPTO_ASN1_TAG_CLASS_MASK)))
+  {
+    *Length = (UINTN)ObjLength;
+    return TRUE;
+  } else {
+    //
+    // if doesn't match Tag, restore Ptr to origin Ptr
+    //
+    *Ptr = PtrOld;
+    return FALSE;
+  }
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  BOOLEAN  Status;
+
+  if ((Cert == NULL) || (CertSize == 0) || (BasicConstraintsSize == NULL)) {
+    return FALSE;
+  }
+
+  Status = X509GetExtensionData (
+             (UINT8 *)Cert,
+             CertSize,
+             mOidBasicConstraints,
+             sizeof (mOidBasicConstraints),
+             BasicConstraints,
+             BasicConstraintsSize
+             );
+
+  return Status;
+}
diff --git a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c
index c6718e6aeb..7217501948 100644
--- a/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c
+++ b/CryptoPkg/Library/BaseCryptLib/Pk/CryptX509Null.c
@@ -320,3 +320,432 @@ EcGetPublicKeyFromX509 (
   ASSERT (FALSE);
   return FALSE;
 }
+
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]     To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Format a DateTimeStr to DataTime object in DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509FormatDateTime (
+  IN CONST CHAR8  *DateTimeStr,
+  OUT VOID        *DateTime,
+  IN OUT UINTN    *DateTimeSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN  CONST  VOID  *DateTime1,
+  IN  CONST  VOID  *DateTime2
+  )
+{
+  ASSERT (FALSE);
+  return -3;
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8    **Ptr,
+  IN CONST UINT8  *End,
+  OUT UINTN       *Length,
+  IN     UINT32   Tag
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
diff --git a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptX509Null.c b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptX509Null.c
index c6718e6aeb..5fb564ca67 100644
--- a/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptX509Null.c
+++ b/CryptoPkg/Library/BaseCryptLibNull/Pk/CryptX509Null.c
@@ -320,3 +320,432 @@ EcGetPublicKeyFromX509 (
   ASSERT (FALSE);
   return FALSE;
 }
+
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]     To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Format a DateTimeStr to DataTime object in DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509FormatDateTime (
+  IN CONST CHAR8  *DateTimeStr,
+  OUT VOID        *DateTime,
+  IN OUT UINTN    *DateTimeSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN CONST  VOID  *DateTime1,
+  IN CONST  VOID  *DateTime2
+  )
+{
+  ASSERT (FALSE);
+  return -3;
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8    **Ptr,
+  IN CONST UINT8  *End,
+  OUT UINTN       *Length,
+  IN     UINT32   Tag
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  ASSERT (FALSE);
+  return FALSE;
+}
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH V3 3/4] CryptoPkg: add new X509 function to Crypto Service.
  2022-10-12  4:35 [PATCH V3 0/4] CryptoPkg: add more X509 functions Qi Zhang
  2022-10-12  4:35 ` [PATCH V3 1/4] CryptoPkg: add new X509 function definition Qi Zhang
  2022-10-12  4:35 ` [PATCH V3 2/4] CryptoPkg: add new X509 function Qi Zhang
@ 2022-10-12  4:36 ` Qi Zhang
  2022-10-12  4:36 ` [PATCH V3 4/4] CryptoPkg: add Unit Test for X509 new function Qi Zhang
  2022-10-12  6:43 ` [PATCH V3 0/4] CryptoPkg: add more X509 functions Yao, Jiewen
  4 siblings, 0 replies; 6+ messages in thread
From: Qi Zhang @ 2022-10-12  4:36 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
---
 CryptoPkg/Driver/Crypto.c                     | 432 +++++++++++++++++-
 .../Pcd/PcdCryptoServiceFamilyEnable.h        |  34 +-
 .../BaseCryptLibOnProtocolPpi/CryptLib.c      | 415 +++++++++++++++++
 CryptoPkg/Private/Protocol/Crypto.h           | 392 +++++++++++++++-
 4 files changed, 1261 insertions(+), 12 deletions(-)

diff --git a/CryptoPkg/Driver/Crypto.c b/CryptoPkg/Driver/Crypto.c
index 1928adbff7..bdbb4863a9 100644
--- a/CryptoPkg/Driver/Crypto.c
+++ b/CryptoPkg/Driver/Crypto.c
@@ -3086,6 +3086,421 @@ CryptoServiceX509GetTBSCert (
   return CALL_BASECRYPTLIB (X509.Services.GetTBSCert, X509GetTBSCert, (Cert, CertSize, TBSCert, TBSCertSize), FALSE);
 }
 
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetVersion, X509GetVersion, (Cert, CertSize, Version), FALSE);
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetSerialNumber, X509GetSerialNumber, (Cert, CertSize, SerialNumber, SerialNumberSize), FALSE);
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetIssuerName, X509GetIssuerName, (Cert, CertSize, CertIssuer, CertIssuerSize), FALSE);
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetSignatureAlgorithm, X509GetSignatureAlgorithm, (Cert, CertSize, Oid, OidSize), FALSE);
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetExtensionData, X509GetExtensionData, (Cert, CertSize, Oid, OidSize, ExtensionData, ExtensionDataSize), FALSE);
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetExtendedKeyUsage, X509GetExtendedKeyUsage, (Cert, CertSize, Usage, UsageSize), FALSE);
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]      To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetValidity, X509GetValidity, (Cert, CertSize, From, FromSize, To, ToSize), FALSE);
+}
+
+/**
+  Format a DateTimeStr to DataTime object in DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509FormatDateTime (
+  IN CONST CHAR8  *DateTimeStr,
+  OUT VOID        *DateTime,
+  IN OUT UINTN    *DateTimeSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.FormatDateTime, X509FormatDateTime, (DateTimeStr, DateTime, DateTimeSize), FALSE);
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+CryptoServiceX509CompareDateTime (
+  IN  CONST VOID  *DateTime1,
+  IN  CONST VOID  *DateTime2
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.CompareDateTime, X509CompareDateTime, (DateTime1, DateTime2), FALSE);
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetKeyUsage, X509GetKeyUsage, (Cert, CertSize, Usage), FALSE);
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.VerifyCertChain, X509VerifyCertChain, (RootCert, RootCertLength, CertChain, CertChainLength), FALSE);
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetCertFromCertChain, X509GetCertFromCertChain, (CertChain, CertChainLength, CertIndex, Cert, CertLength), FALSE);
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+CryptoServiceAsn1GetTag (
+  IN OUT UINT8    **Ptr,
+  IN CONST UINT8  *End,
+  OUT UINTN       *Length,
+  IN     UINT32   Tag
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.Asn1GetTag, Asn1GetTag, (Ptr, End, Length, Tag), FALSE);
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+CryptoServiceX509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  return CALL_BASECRYPTLIB (X509.Services.GetExtendedBasicConstraints, X509GetExtendedBasicConstraints, (Cert, CertSize, BasicConstraints, BasicConstraintsSize), FALSE);
+}
+
 /**
   Derives a key from a password using a salt and iteration count, based on PKCS#5 v2.0
   password based encryption key derivation function PBKDF2, as specified in RFC 2898.
@@ -6557,5 +6972,20 @@ const EDKII_CRYPTO_PROTOCOL  mEdkiiCrypto = {
   CryptoServiceEcGetPublicKeyFromX509,
   CryptoServiceEcGetPrivateKeyFromPem,
   CryptoServiceEcDsaSign,
-  CryptoServiceEcDsaVerify
+  CryptoServiceEcDsaVerify,
+  /// X509 (Continued)
+  CryptoServiceX509GetVersion,
+  CryptoServiceX509GetSerialNumber,
+  CryptoServiceX509GetIssuerName,
+  CryptoServiceX509GetSignatureAlgorithm,
+  CryptoServiceX509GetExtensionData,
+  CryptoServiceX509GetExtendedKeyUsage,
+  CryptoServiceX509GetValidity,
+  CryptoServiceX509FormatDateTime,
+  CryptoServiceX509CompareDateTime,
+  CryptoServiceX509GetKeyUsage,
+  CryptoServiceX509VerifyCertChain,
+  CryptoServiceX509GetCertFromCertChain,
+  CryptoServiceAsn1GetTag,
+  CryptoServiceX509GetExtendedBasicConstraints
 };
diff --git a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
index 12b0c0583e..f1f5084e70 100644
--- a/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
+++ b/CryptoPkg/Include/Pcd/PcdCryptoServiceFamilyEnable.h
@@ -187,16 +187,30 @@ typedef struct {
   } Sha512;
   union {
     struct {
-      UINT8    GetSubjectName             : 1;
-      UINT8    GetCommonName              : 1;
-      UINT8    GetOrganizationName        : 1;
-      UINT8    VerifyCert                 : 1;
-      UINT8    ConstructCertificate       : 1;
-      UINT8    ConstructCertificateStack  : 1;
-      UINT8    ConstructCertificateStackV : 1;
-      UINT8    Free                       : 1;
-      UINT8    StackFree                  : 1;
-      UINT8    GetTBSCert                 : 1;
+      UINT8    GetSubjectName              : 1;
+      UINT8    GetCommonName               : 1;
+      UINT8    GetOrganizationName         : 1;
+      UINT8    VerifyCert                  : 1;
+      UINT8    ConstructCertificate        : 1;
+      UINT8    ConstructCertificateStack   : 1;
+      UINT8    ConstructCertificateStackV  : 1;
+      UINT8    Free                        : 1;
+      UINT8    StackFree                   : 1;
+      UINT8    GetTBSCert                  : 1;
+      UINT8    GetVersion                  : 1;
+      UINT8    GetSerialNumber             : 1;
+      UINT8    GetIssuerName               : 1;
+      UINT8    GetSignatureAlgorithm       : 1;
+      UINT8    GetExtensionData            : 1;
+      UINT8    GetExtendedKeyUsage         : 1;
+      UINT8    GetValidity                 : 1;
+      UINT8    FormatDateTime              : 1;
+      UINT8    CompareDateTime             : 1;
+      UINT8    GetKeyUsage                 : 1;
+      UINT8    VerifyCertChain             : 1;
+      UINT8    GetCertFromCertChain        : 1;
+      UINT8    Asn1GetTag                  : 1;
+      UINT8    GetExtendedBasicConstraints : 1;
     } Services;
     UINT32    Family;
   } X509;
diff --git a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
index 48ec6d3528..4e31bc278e 100644
--- a/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
+++ b/CryptoPkg/Library/BaseCryptLibOnProtocolPpi/CryptLib.c
@@ -2322,6 +2322,421 @@ X509GetTBSCert (
   CALL_CRYPTO_SERVICE (X509GetTBSCert, (Cert, CertSize, TBSCert, TBSCertSize), FALSE);
 }
 
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetVersion (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetVersion, (Cert, CertSize, Version), FALSE);
+}
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSerialNumber (
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetSerialNumber, (Cert, CertSize, SerialNumber, SerialNumberSize), FALSE);
+}
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+BOOLEAN
+EFIAPI
+X509GetIssuerName (
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetIssuerName, (Cert, CertSize, CertIssuer, CertIssuerSize), FALSE);
+}
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetSignatureAlgorithm (
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetSignatureAlgorithm, (Cert, CertSize, Oid, OidSize), FALSE);
+}
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtensionData (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetExtensionData, (Cert, CertSize, Oid, OidSize, ExtensionData, ExtensionDataSize), FALSE);
+}
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetExtendedKeyUsage (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetExtendedKeyUsage, (Cert, CertSize, Usage, UsageSize), FALSE);
+}
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[in]      From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[in]      To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetValidity  (
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetValidity, (Cert, CertSize, From, FromSize, To, ToSize), FALSE);
+}
+
+/**
+  Format a DateTimeStr to DataTime object in DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[out]     DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509FormatDateTime (
+  IN  CONST CHAR8  *DateTimeStr,
+  OUT VOID         *DateTime,
+  IN OUT UINTN     *DateTimeSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509FormatDateTime, (DateTimeStr, DateTime, DateTimeSize), FALSE);
+}
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+INT32
+EFIAPI
+X509CompareDateTime (
+  IN CONST  VOID  *DateTime1,
+  IN CONST  VOID  *DateTime2
+  )
+{
+  CALL_CRYPTO_SERVICE (X509CompareDateTime, (DateTime1, DateTime2), FALSE);
+}
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+BOOLEAN
+EFIAPI
+X509GetKeyUsage (
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetKeyUsage, (Cert, CertSize, Usage), FALSE);
+}
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+BOOLEAN
+EFIAPI
+X509VerifyCertChain (
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  )
+{
+  CALL_CRYPTO_SERVICE (X509VerifyCertChain, (RootCert, RootCertLength, CertChain, CertChainLength), FALSE);
+}
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+BOOLEAN
+EFIAPI
+X509GetCertFromCertChain (
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetCertFromCertChain, (CertChain, CertChainLength, CertIndex, Cert, CertLength), FALSE);
+}
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+BOOLEAN
+EFIAPI
+Asn1GetTag (
+  IN OUT UINT8    **Ptr,
+  IN CONST UINT8  *End,
+  OUT UINTN       *Length,
+  IN     UINT32   Tag
+  )
+{
+  CALL_CRYPTO_SERVICE (Asn1GetTag, (Ptr, End, Length, Tag), FALSE);
+}
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+BOOLEAN
+EFIAPI
+X509GetExtendedBasicConstraints             (
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  )
+{
+  CALL_CRYPTO_SERVICE (X509GetExtendedBasicConstraints, (Cert, CertSize, BasicConstraints, BasicConstraintsSize), FALSE);
+}
+
 /**
   Derives a key from a password using a salt and iteration count, based on PKCS#5 v2.0
   password based encryption key derivation function PBKDF2, as specified in RFC 2898.
diff --git a/CryptoPkg/Private/Protocol/Crypto.h b/CryptoPkg/Private/Protocol/Crypto.h
index bfb278d388..0e0b1d9401 100644
--- a/CryptoPkg/Private/Protocol/Crypto.h
+++ b/CryptoPkg/Private/Protocol/Crypto.h
@@ -21,7 +21,7 @@
 /// the EDK II Crypto Protocol is extended, this version define must be
 /// increased.
 ///
-#define EDKII_CRYPTO_VERSION  15
+#define EDKII_CRYPTO_VERSION  16
 
 ///
 /// EDK II Crypto Protocol forward declaration
@@ -2351,6 +2351,381 @@ BOOLEAN
   OUT UINTN        *TBSCertSize
   );
 
+/**
+  Retrieve the version from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     Version      Pointer to the retrieved version integer.
+
+  @retval TRUE           The certificate version retrieved successfully.
+  @retval FALSE          If  Cert is NULL or CertSize is Zero.
+  @retval FALSE          The operation is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_VERSION)(
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINTN        *Version
+  );
+
+/**
+  Retrieve the serialNumber from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertSize is 0, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     SerialNumber  Pointer to the retrieved certificate SerialNumber bytes.
+  @param[in, out] SerialNumberSize  The size in bytes of the SerialNumber buffer on input,
+                               and the size of buffer returned SerialNumber on output.
+
+  @retval TRUE                     The certificate serialNumber retrieved successfully.
+  @retval FALSE                    If Cert is NULL or CertSize is Zero.
+                                   If SerialNumberSize is NULL.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SerialNumber exists.
+  @retval FALSE                    If the SerialNumber is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   SerialNumberSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_SERIAL_NUMBER)(
+  IN      CONST UINT8 *Cert,
+  IN      UINTN CertSize,
+  OUT     UINT8 *SerialNumber, OPTIONAL
+  IN OUT  UINTN         *SerialNumberSize
+  );
+
+/**
+  Retrieve the issuer bytes from one X.509 certificate.
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     CertIssuer  Pointer to the retrieved certificate subject bytes.
+  @param[in, out] CertIssuerSize  The size in bytes of the CertIssuer buffer on input,
+                               and the size of buffer returned CertSubject on output.
+
+  @retval  TRUE   The certificate issuer retrieved successfully.
+  @retval  FALSE  Invalid certificate, or the CertIssuerSize is too small for the result.
+                  The CertIssuerSize will be updated with the required size.
+  @retval  FALSE  This interface is not supported.
+
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_ISSUER_NAME)(
+  IN      CONST UINT8  *Cert,
+  IN      UINTN        CertSize,
+  OUT     UINT8        *CertIssuer,
+  IN OUT  UINTN        *CertIssuerSize
+  );
+
+/**
+  Retrieve the Signature Algorithm from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Oid              Signature Algorithm Object identifier buffer.
+  @param[in,out]  OidSize          Signature Algorithm Object identifier buffer size
+
+  @retval TRUE           The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If OidSize is NULL.
+                                   If Oid is not NULL and *OidSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no SignatureType.
+  @retval FALSE                    If the Oid is NULL. The required buffer size
+                                   is returned in the OidSize.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_SIGNATURE_ALGORITHM)(
+  IN CONST UINT8 *Cert,
+  IN       UINTN CertSize,
+  OUT   UINT8 *Oid, OPTIONAL
+  IN OUT   UINTN       *OidSize
+  );
+
+/**
+  Retrieve Extension data from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[in]      Oid              Object identifier buffer
+  @param[in]      OidSize          Object identifier buffer size
+  @param[out]     ExtensionData    Extension bytes.
+  @param[in, out] ExtensionDataSize Extension bytes size.
+
+  @retval TRUE                     The certificate Extension data retrieved successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If ExtensionDataSize is NULL.
+                                   If ExtensionData is not NULL and *ExtensionDataSize is 0.
+                                   If Certificate is invalid.
+  @retval FALSE                    If no Extension entry match Oid.
+  @retval FALSE                    If the ExtensionData is NULL. The required buffer size
+                                   is returned in the ExtensionDataSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_EXTENSION_DATA)(
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     CONST UINT8  *Oid,
+  IN     UINTN        OidSize,
+  OUT UINT8           *ExtensionData,
+  IN OUT UINTN        *ExtensionDataSize
+  );
+
+/**
+  Retrieve the Extended Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage bytes.
+  @param[in, out] UsageSize        Key Usage buffer sizs in bytes.
+
+  @retval TRUE                     The Usage bytes retrieve successfully.
+  @retval FALSE                    If Cert is NULL.
+                                   If CertSize is NULL.
+                                   If Usage is not NULL and *UsageSize is 0.
+                                   If Cert is invalid.
+  @retval FALSE                    If the Usage is NULL. The required buffer size
+                                   is returned in the UsageSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_EXTENDED_KEY_USAGE)(
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  OUT UINT8           *Usage,
+  IN OUT UINTN        *UsageSize
+  );
+
+/**
+  Retrieve the Validity from one X.509 certificate
+
+  If Cert is NULL, then return FALSE.
+  If CertIssuerSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      Cert         Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize     Size of the X509 certificate in bytes.
+  @param[out]     From         notBefore Pointer to DateTime object.
+  @param[in,out]  FromSize     notBefore DateTime object size.
+  @param[out]     To           notAfter Pointer to DateTime object.
+  @param[in,out]  ToSize       notAfter DateTime object size.
+
+  Note: X509CompareDateTime to compare DateTime oject
+        x509SetDateTime to get a DateTime object from a DateTimeStr
+
+  @retval  TRUE   The certificate Validity retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Validity retrieve failed.
+  @retval  FALSE  This interface is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_VALIDITY)(
+  IN     CONST UINT8  *Cert,
+  IN     UINTN        CertSize,
+  IN     UINT8        *From,
+  IN OUT UINTN        *FromSize,
+  IN     UINT8        *To,
+  IN OUT UINTN        *ToSize
+  );
+
+/**
+  Format a DateTimeStr to DataTime object in DataTime Buffer
+
+  If DateTimeStr is NULL, then return FALSE.
+  If DateTimeSize is NULL, then return FALSE.
+  If this interface is not supported, then return FALSE.
+
+  @param[in]      DateTimeStr      DateTime string like YYYYMMDDhhmmssZ
+                                   Ref: https://www.w3.org/TR/NOTE-datetime
+                                   Z stand for UTC time
+  @param[in,out]  DateTime         Pointer to a DateTime object.
+  @param[in,out]  DateTimeSize     DateTime object buffer size.
+
+  @retval TRUE                     The DateTime object create successfully.
+  @retval FALSE                    If DateTimeStr is NULL.
+                                   If DateTimeSize is NULL.
+                                   If DateTime is not NULL and *DateTimeSize is 0.
+                                   If Year Month Day Hour Minute Second combination is invalid datetime.
+  @retval FALSE                    If the DateTime is NULL. The required buffer size
+                                   (including the final null) is returned in the
+                                   DateTimeSize parameter.
+  @retval FALSE                    The operation is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_FORMAT_DATE_TIME)(
+  IN CONST CHAR8  *DateTimeStr,
+  OUT VOID      *DateTime,
+  IN OUT UINTN  *DateTimeSize
+  );
+
+/**
+  Compare DateTime1 object and DateTime2 object.
+
+  If DateTime1 is NULL, then return -2.
+  If DateTime2 is NULL, then return -2.
+  If DateTime1 == DateTime2, then return 0
+  If DateTime1 > DateTime2, then return 1
+  If DateTime1 < DateTime2, then return -1
+
+  @param[in]      DateTime1         Pointer to a DateTime Ojbect
+  @param[in]      DateTime2         Pointer to a DateTime Object
+
+  @retval  0      If DateTime1 == DateTime2
+  @retval  1      If DateTime1 > DateTime2
+  @retval  -1     If DateTime1 < DateTime2
+**/
+typedef
+INT32
+(EFIAPI *EDKII_CRYPTO_X509_COMPARE_DATE_TIME)(
+  IN CONST  VOID  *DateTime1,
+  IN CONST  VOID  *DateTime2
+  );
+
+/**
+  Retrieve the Key Usage from one X.509 certificate.
+
+  @param[in]      Cert             Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize         Size of the X509 certificate in bytes.
+  @param[out]     Usage            Key Usage (CRYPTO_X509_KU_*)
+
+  @retval  TRUE   The certificate Key Usage retrieved successfully.
+  @retval  FALSE  Invalid certificate, or Usage is NULL
+  @retval  FALSE  This interface is not supported.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_KEY_USAGE)(
+  IN    CONST UINT8  *Cert,
+  IN    UINTN        CertSize,
+  OUT   UINTN        *Usage
+  );
+
+/**
+  Verify one X509 certificate was issued by the trusted CA.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      RootCert          Trusted Root Certificate buffer
+
+  @param[in]      RootCertLength    Trusted Root Certificate buffer length
+
+  @retval  TRUE   All cerificates was issued by the first certificate in X509Certchain.
+  @retval  FALSE  Invalid certificate or the certificate was not issued by the given
+                  trusted CA.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_VERIFY_CERT_CHAIN)(
+  IN CONST UINT8  *RootCert,
+  IN UINTN        RootCertLength,
+  IN CONST UINT8  *CertChain,
+  IN UINTN        CertChainLength
+  );
+
+/**
+  Get one X509 certificate from CertChain.
+
+  @param[in]      CertChain         One or more ASN.1 DER-encoded X.509 certificates
+                                    where the first certificate is signed by the Root
+                                    Certificate or is the Root Cerificate itself. and
+                                    subsequent cerificate is signed by the preceding
+                                    cerificate.
+  @param[in]      CertChainLength   Total length of the certificate chain, in bytes.
+
+  @param[in]      CertIndex         Index of certificate.
+
+  @param[out]     Cert              The certificate at the index of CertChain.
+  @param[out]     CertLength        The length certificate at the index of CertChain.
+
+  @retval  TRUE   Success.
+  @retval  FALSE  Failed to get certificate from certificate chain.
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_CERT_FROM_CERT_CHAIN)(
+  IN CONST UINT8   *CertChain,
+  IN UINTN         CertChainLength,
+  IN CONST INT32   CertIndex,
+  OUT CONST UINT8  **Cert,
+  OUT UINTN        *CertLength
+  );
+
+/**
+  Retrieve the tag and length of the tag.
+
+  @param Ptr      The position in the ASN.1 data
+  @param End      End of data
+  @param Length   The variable that will receive the length
+  @param Tag      The expected tag
+
+  @retval      TRUE   Get tag successful
+  @retval      FALSe  Failed to get tag or tag not match
+**/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_ASN1_GET_TAG)(
+  IN OUT UINT8   **Ptr,
+  IN CONST UINT8   *End,
+  OUT UINTN      *Length,
+  IN     UINT32  Tag
+  );
+
+/**
+  Retrieve the basic constraints from one X.509 certificate.
+
+  @param[in]      Cert                     Pointer to the DER-encoded X509 certificate.
+  @param[in]      CertSize                 size of the X509 certificate in bytes.
+  @param[out]     BasicConstraints         basic constraints bytes.
+  @param[in, out] BasicConstraintsSize     basic constraints buffer sizs in bytes.
+
+  @retval TRUE                     The basic constraints retrieve successfully.
+  @retval FALSE                    If cert is NULL.
+                                   If cert_size is NULL.
+                                   If basic_constraints is not NULL and *basic_constraints_size is 0.
+                                   If cert is invalid.
+  @retval FALSE                    The required buffer size is small.
+                                   The return buffer size is basic_constraints_size parameter.
+  @retval FALSE                    If no Extension entry match oid.
+  @retval FALSE                    The operation is not supported.
+ **/
+typedef
+BOOLEAN
+(EFIAPI *EDKII_CRYPTO_X509_GET_EXTENDED_BASIC_CONSTRAINTS)(
+  CONST UINT8  *Cert,
+  UINTN        CertSize,
+  UINT8        *BasicConstraints,
+  UINTN        *BasicConstraintsSize
+  );
+
 // =====================================================================================
 //    Symmetric Cryptography Primitive
 // =====================================================================================
@@ -5213,6 +5588,21 @@ struct _EDKII_CRYPTO_PROTOCOL {
   EDKII_CRYPTO_EC_GET_PRIVATE_KEY_FROM_PEM            EcGetPrivateKeyFromPem;
   EDKII_CRYPTO_EC_DSA_SIGN                            EcDsaSign;
   EDKII_CRYPTO_EC_DSA_VERIFY                          EcDsaVerify;
+  /// X509 (Continued)
+  EDKII_CRYPTO_X509_GET_VERSION                       X509GetVersion;
+  EDKII_CRYPTO_X509_GET_SERIAL_NUMBER                 X509GetSerialNumber;
+  EDKII_CRYPTO_X509_GET_ISSUER_NAME                   X509GetIssuerName;
+  EDKII_CRYPTO_X509_GET_SIGNATURE_ALGORITHM           X509GetSignatureAlgorithm;
+  EDKII_CRYPTO_X509_GET_EXTENSION_DATA                X509GetExtensionData;
+  EDKII_CRYPTO_X509_GET_EXTENDED_KEY_USAGE            X509GetExtendedKeyUsage;
+  EDKII_CRYPTO_X509_GET_VALIDITY                      X509GetValidity;
+  EDKII_CRYPTO_X509_FORMAT_DATE_TIME                  X509FormatDateTime;
+  EDKII_CRYPTO_X509_COMPARE_DATE_TIME                 X509CompareDateTime;
+  EDKII_CRYPTO_X509_GET_KEY_USAGE                     X509GetKeyUsage;
+  EDKII_CRYPTO_X509_VERIFY_CERT_CHAIN                 X509VerifyCertChain;
+  EDKII_CRYPTO_X509_GET_CERT_FROM_CERT_CHAIN          X509GetCertFromCertChain;
+  EDKII_CRYPTO_ASN1_GET_TAG                           Asn1GetTag;
+  EDKII_CRYPTO_X509_GET_EXTENDED_BASIC_CONSTRAINTS    X509GetExtendedBasicConstraints;
 };
 
 extern GUID  gEdkiiCryptoProtocolGuid;
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH V3 4/4] CryptoPkg: add Unit Test for X509 new function.
  2022-10-12  4:35 [PATCH V3 0/4] CryptoPkg: add more X509 functions Qi Zhang
                   ` (2 preceding siblings ...)
  2022-10-12  4:36 ` [PATCH V3 3/4] CryptoPkg: add new X509 function to Crypto Service Qi Zhang
@ 2022-10-12  4:36 ` Qi Zhang
  2022-10-12  6:43 ` [PATCH V3 0/4] CryptoPkg: add more X509 functions Yao, Jiewen
  4 siblings, 0 replies; 6+ messages in thread
From: Qi Zhang @ 2022-10-12  4:36 UTC (permalink / raw)
  To: devel; +Cc: Qi Zhang, Jiewen Yao, Jian J Wang, Xiaoyu Lu, Guomin Jiang

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082

Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
Cc: Guomin Jiang <guomin.jiang@intel.com>
Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
---
 .../BaseCryptLib/BaseCryptLibUnitTests.c      |   1 +
 .../Library/BaseCryptLib/TestBaseCryptLib.h   |   4 +
 .../BaseCryptLib/TestBaseCryptLibHost.inf     |   1 +
 .../BaseCryptLib/TestBaseCryptLibShell.inf    |   1 +
 .../UnitTest/Library/BaseCryptLib/X509Tests.c | 631 ++++++++++++++++++
 5 files changed, 638 insertions(+)
 create mode 100644 CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c

diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
index 63bae35b80..5546259488 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/BaseCryptLibUnitTests.c
@@ -29,6 +29,7 @@ SUITE_DESC  mSuiteDesc[] = {
   { "Aead AES Gcm tests",            "CryptoPkg.BaseCryptLib", NULL, NULL, &mAeadAesGcmTestNum,     mAeadAesGcmTest     },
   { "Bn verify tests",               "CryptoPkg.BaseCryptLib", NULL, NULL, &mBnTestNum,             mBnTest             },
   { "EC verify tests",               "CryptoPkg.BaseCryptLib", NULL, NULL, &mEcTestNum,             mEcTest             },
+  { "X509 Verify tests",             "CryptoPkg.BaseCryptLib", NULL, NULL, &mX509TestNum,           mX509Test           },
 };
 
 EFI_STATUS
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
index 3a84e63a87..91f3ec41d4 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLib.h
@@ -97,6 +97,10 @@ extern TEST_DESC  mBnTest[];
 
 extern UINTN      mEcTestNum;
 extern TEST_DESC  mEcTest[];
+
+extern UINTN      mX509TestNum;
+extern TEST_DESC  mX509Test[];
+
 /** Creates a framework you can use */
 EFI_STATUS
 EFIAPI
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
index 023b796946..07113d6ed6 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibHost.inf
@@ -41,6 +41,7 @@
   AeadAesGcmTests.c
   BnTests.c
   EcTests.c
+  X509Tests.c
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
index 5bfd190236..0450b8a29c 100644
--- a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/TestBaseCryptLibShell.inf
@@ -40,6 +40,7 @@
   AeadAesGcmTests.c
   BnTests.c
   EcTests.c
+  X509Tests.c
 
 [Packages]
   MdePkg/MdePkg.dec
diff --git a/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c
new file mode 100644
index 0000000000..b3d11ea330
--- /dev/null
+++ b/CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c
@@ -0,0 +1,631 @@
+/** @file
+  Application for X509 Cert Validation.
+
+Copyright (c) 2022, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "TestBaseCryptLib.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mOidSubjectAltName[] = { 0x55, 0x1D, 0x11 };
+
+//
+// use openssl tool to create the test certificates.
+//
+// openssl req -nodes -x509 -days 3650 -newkey rsa:4096 -keyout ca.key -out ca.cert -sha256 -subj "/CN=intel test RSA CA"
+// openssl rsa -in ca.key -outform der -out ca.key.der
+// openssl req -nodes -newkey rsa:3072 -keyout inter.key -out inter.req -sha256 -batch -subj "/CN=intel test RSA intermediate cert"
+// openssl req -nodes -newkey rsa:2048 -keyout end_requester.key -out end_requester.req -sha256 -batch -subj "/CN=intel test RSA requseter cert"
+// openssl req -nodes -newkey rsa:2048 -keyout end_responder.key -out end_responder.req -sha256 -batch -subj "/CN=intel test RSA responder cert"
+// openssl x509 -req -in inter.req -out inter.cert -CA ca.cert -CAkey ca.key -sha256 -days 3650 -set_serial 1 -extensions v3_inter -extfile ../openssl.cnf
+// openssl x509 -req -in end_requester.req -out end_requester.cert -CA inter.cert -CAkey inter.key -sha256 -days 3650 -set_serial 2 -extensions v3_end -extfile ../openssl.cnf
+// openssl x509 -req -in end_responder.req -out end_responder.cert -CA inter.cert -CAkey inter.key -sha256 -days 3650 -set_serial 3 -extensions v3_end -extfile ../openssl.cnf
+// openssl asn1parse -in ca.cert -out ca.cert.der
+// openssl asn1parse -in inter.cert -out inter.cert.der
+// openssl asn1parse -in end_requester.cert -out end_requester.cert.der
+// cat ca.cert.der inter.cert.der end_requester.cert.der > bundle_requester.certchain.der
+// openssl rsa -inform PEM -outform DER -in end_requester.key -out end_requester.key.der
+//
+
+//
+// dump of inter.cert.der
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mTestCert[] = {
+  0x30, 0x82, 0x04, 0xa0, 0x30, 0x82, 0x02, 0x88, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+  0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69, 0x6e, 0x74, 0x65,
+  0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17,
+  0x0d, 0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x17, 0x0d,
+  0x33, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x30, 0x2b, 0x31,
+  0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20,
+  0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65,
+  0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d,
+  0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01,
+  0x8f, 0x00, 0x30, 0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xd1, 0xcf, 0x2d, 0x21, 0x38,
+  0xe4, 0x81, 0xa6, 0xf2, 0xe5, 0xca, 0xac, 0x09, 0x2b, 0x04, 0x2a, 0x52, 0x76, 0x2f, 0xa3, 0x4b,
+  0x43, 0xc2, 0xd6, 0xb5, 0x3e, 0x2b, 0x29, 0x6f, 0x1b, 0x7d, 0x36, 0x60, 0xcd, 0x71, 0xf4, 0xcf,
+  0x8a, 0x24, 0xac, 0x8f, 0x5f, 0x78, 0x70, 0xc9, 0x84, 0x48, 0xfb, 0x1d, 0xcb, 0xee, 0x34, 0x3c,
+  0x4c, 0xe1, 0x1a, 0x92, 0x54, 0x43, 0x45, 0xe0, 0xdd, 0x14, 0xd5, 0xac, 0x13, 0xae, 0xcc, 0x45,
+  0xdc, 0x52, 0xdd, 0x45, 0x22, 0x10, 0xab, 0xb2, 0x1b, 0x3e, 0xad, 0x36, 0x6f, 0x00, 0x59, 0xb6,
+  0xfd, 0x27, 0xb8, 0x57, 0xbb, 0x66, 0x72, 0x1e, 0x7b, 0xe8, 0xc7, 0xaf, 0x5e, 0x65, 0x5c, 0x58,
+  0x3d, 0x9e, 0x78, 0x26, 0xb7, 0x70, 0x9a, 0xe7, 0x3c, 0xfc, 0x90, 0x64, 0xb2, 0xb2, 0xb2, 0x80,
+  0x22, 0xb3, 0x1c, 0x23, 0x73, 0x6a, 0xe3, 0xcb, 0x5b, 0x4e, 0x29, 0x71, 0xdd, 0xfd, 0xd7, 0x15,
+  0x3a, 0xd6, 0xa3, 0xe0, 0x4a, 0x53, 0x65, 0xa6, 0xae, 0x6a, 0x83, 0xb0, 0x00, 0x3f, 0x64, 0x4b,
+  0x01, 0xcd, 0x97, 0xb1, 0xe1, 0x54, 0x1e, 0xa2, 0x33, 0x4e, 0xf0, 0x13, 0x33, 0x80, 0xe5, 0x41,
+  0x9c, 0x5e, 0xb3, 0x5d, 0xae, 0x53, 0x2c, 0x41, 0x51, 0xf2, 0x00, 0x3e, 0x03, 0xe2, 0x0d, 0xa4,
+  0xf5, 0x24, 0x08, 0x46, 0xc2, 0xed, 0x6b, 0xf2, 0xe0, 0x1b, 0x04, 0xb7, 0xe8, 0xda, 0x85, 0xa4,
+  0x2f, 0x4b, 0x53, 0xfa, 0x76, 0x72, 0x0a, 0x28, 0xbf, 0x3c, 0xa8, 0x85, 0x03, 0xee, 0x51, 0xb5,
+  0x5c, 0xa9, 0xa5, 0x70, 0x47, 0x07, 0x11, 0x32, 0xc5, 0x5f, 0x7a, 0x07, 0xfb, 0x5f, 0x4a, 0x52,
+  0x65, 0x33, 0x0c, 0x17, 0x8e, 0x74, 0xe5, 0xec, 0x7d, 0x52, 0xa0, 0xd4, 0xef, 0x64, 0xcc, 0x5e,
+  0xe2, 0x3d, 0x46, 0x1e, 0x73, 0xab, 0x43, 0x2d, 0x05, 0xfa, 0xa3, 0x6d, 0x86, 0x02, 0xe7, 0xc8,
+  0x5f, 0x44, 0xfe, 0xeb, 0x14, 0x73, 0x2d, 0xf4, 0x0b, 0x72, 0x49, 0xe3, 0xef, 0x55, 0x05, 0x1b,
+  0x2f, 0xf9, 0x73, 0xeb, 0xed, 0xcc, 0x5e, 0x52, 0x17, 0x43, 0x94, 0x85, 0xc7, 0x0e, 0x73, 0x89,
+  0x22, 0xdc, 0x02, 0x5f, 0x99, 0x69, 0x58, 0x16, 0x89, 0x1e, 0x6f, 0x75, 0xf8, 0xd3, 0xe7, 0x0a,
+  0xb1, 0x01, 0x42, 0x71, 0xa6, 0xc5, 0xb2, 0xd0, 0xc0, 0x75, 0x96, 0x2e, 0xc2, 0x32, 0x49, 0x0a,
+  0xe8, 0x85, 0xbd, 0x22, 0x4c, 0x95, 0xd4, 0xf8, 0x2d, 0x72, 0x05, 0x4f, 0x0e, 0x56, 0x9c, 0xc3,
+  0x30, 0x3d, 0xfd, 0x30, 0x63, 0x92, 0x72, 0x6b, 0xaf, 0x80, 0x9d, 0xd0, 0xc2, 0x36, 0xe7, 0xc1,
+  0x37, 0xd0, 0x64, 0x88, 0x64, 0x3c, 0x33, 0xdd, 0x87, 0xdd, 0xd9, 0xa2, 0x79, 0x44, 0xd8, 0x25,
+  0x84, 0x0e, 0xfd, 0x9d, 0xd6, 0xc1, 0x7a, 0x2d, 0x23, 0x08, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01,
+  0xa3, 0x5e, 0x30, 0x5c, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01,
+  0x01, 0xff, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0xfe, 0x30,
+  0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x46, 0xcd, 0xb4, 0x52, 0x02, 0x29,
+  0x26, 0xc7, 0x52, 0x23, 0x81, 0x65, 0xcd, 0x87, 0x2f, 0x96, 0x1b, 0x01, 0x2c, 0xc5, 0x30, 0x20,
+  0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06,
+  0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03,
+  0x82, 0x02, 0x01, 0x00, 0x71, 0x14, 0xca, 0xfe, 0x03, 0x92, 0xc6, 0x88, 0x52, 0x76, 0x43, 0xd9,
+  0x8a, 0xf7, 0x22, 0x94, 0xef, 0x40, 0xa7, 0xc3, 0x7b, 0x6f, 0xb4, 0xd0, 0x42, 0xc3, 0x59, 0x1f,
+  0x77, 0xef, 0xac, 0x18, 0xce, 0x7c, 0xab, 0x48, 0x85, 0x22, 0xf1, 0x50, 0x2c, 0xe0, 0x63, 0x4d,
+  0x9d, 0x0e, 0xed, 0x38, 0xff, 0xd9, 0xed, 0x3c, 0x7e, 0x3e, 0x84, 0xb1, 0xa7, 0x78, 0x62, 0x37,
+  0x39, 0x6d, 0xd5, 0x5d, 0x46, 0x9a, 0x6f, 0x63, 0xc2, 0xa7, 0x90, 0xf9, 0x7a, 0xa7, 0x4b, 0xa2,
+  0x8a, 0xa8, 0x50, 0x13, 0x16, 0x9c, 0x4f, 0xcc, 0x28, 0x58, 0x6c, 0x9f, 0x65, 0x6e, 0xf0, 0x9a,
+  0x92, 0x59, 0x94, 0xa4, 0xb5, 0xfd, 0x8f, 0xf0, 0x7c, 0x1e, 0xba, 0xc3, 0x21, 0x13, 0xfb, 0x33,
+  0xba, 0xad, 0x4b, 0x1d, 0x42, 0x23, 0x16, 0x8b, 0x3e, 0xcd, 0xb5, 0x69, 0x9c, 0x7c, 0xa1, 0x9b,
+  0x92, 0xc1, 0x2f, 0x9c, 0x89, 0x3f, 0x28, 0x24, 0x67, 0x48, 0x47, 0xf0, 0xb1, 0xc0, 0xf0, 0x4c,
+  0xbf, 0xf6, 0x64, 0xde, 0x33, 0xc3, 0xd6, 0x5b, 0xe6, 0xc3, 0xdd, 0xa5, 0xba, 0x42, 0x02, 0x0f,
+  0xbc, 0xbe, 0xde, 0x14, 0x12, 0x7c, 0xfb, 0xe6, 0xbb, 0xdd, 0xf2, 0x6b, 0xd7, 0x75, 0xe6, 0xf5,
+  0xda, 0xbe, 0xe9, 0xbf, 0xa6, 0x87, 0x09, 0x41, 0x6c, 0x9d, 0x19, 0x9c, 0xb1, 0x7c, 0x89, 0x9f,
+  0x32, 0xb3, 0x0a, 0x59, 0x10, 0xc6, 0x8c, 0xa0, 0x5b, 0xda, 0xa6, 0xa3, 0xf8, 0x33, 0x77, 0x7a,
+  0xf4, 0xb0, 0x8a, 0xcf, 0xc8, 0x3f, 0x2e, 0xb8, 0xf1, 0x9e, 0x7b, 0x47, 0x2d, 0x85, 0x3b, 0x58,
+  0xcd, 0x4b, 0xbc, 0x87, 0xd2, 0xf3, 0xcd, 0x36, 0x80, 0x9b, 0x4a, 0x0f, 0x24, 0x30, 0x1d, 0x3f,
+  0x6f, 0x56, 0xcf, 0x6e, 0x2d, 0xcf, 0xa8, 0x17, 0xd5, 0x97, 0x0b, 0x22, 0xa6, 0x59, 0xef, 0xef,
+  0xd4, 0x9a, 0x0e, 0x6f, 0xb9, 0xf0, 0x48, 0x2a, 0x54, 0x22, 0x77, 0x27, 0x90, 0x84, 0x42, 0x56,
+  0x85, 0x80, 0x78, 0x4f, 0xd9, 0x14, 0x2a, 0xf0, 0x5d, 0x6b, 0x46, 0x60, 0x3d, 0xad, 0xa5, 0xa2,
+  0xb9, 0x04, 0x23, 0x92, 0x1b, 0x70, 0xa3, 0xdb, 0xaa, 0xf0, 0x5f, 0x1c, 0xd8, 0x26, 0xbb, 0x51,
+  0x17, 0xfc, 0x93, 0x6d, 0x70, 0x19, 0x54, 0xe2, 0x6f, 0x82, 0x8a, 0x49, 0xa6, 0x19, 0xcc, 0x97,
+  0x53, 0x90, 0x27, 0xd9, 0x8d, 0xaa, 0x8c, 0xc3, 0x2b, 0xbc, 0x0a, 0x72, 0x3a, 0x41, 0xb8, 0xfa,
+  0x1e, 0xbb, 0x8b, 0x27, 0x06, 0x75, 0x53, 0x91, 0xac, 0x8d, 0x75, 0xf2, 0xa6, 0xea, 0x85, 0x7e,
+  0x34, 0x06, 0x9e, 0xf9, 0xe9, 0x13, 0xa3, 0xfe, 0x2e, 0x38, 0x4b, 0x3f, 0x61, 0x11, 0x1f, 0x6b,
+  0xd3, 0xfe, 0xc9, 0x13, 0xbc, 0x12, 0xfe, 0xbc, 0xff, 0xaa, 0x38, 0x73, 0x8a, 0x73, 0x8c, 0xcf,
+  0xcc, 0xd3, 0xe7, 0xba, 0x98, 0xfd, 0xf4, 0xf5, 0xf6, 0xa9, 0xc8, 0x07, 0x5b, 0x16, 0xae, 0x76,
+  0x86, 0x24, 0x25, 0xcc, 0x7c, 0xdb, 0x1e, 0x7f, 0xc4, 0xe4, 0xd3, 0x89, 0x5a, 0x91, 0x6a, 0x9c,
+  0x93, 0x03, 0xd2, 0xd2, 0xc0, 0x29, 0x69, 0x58, 0x52, 0x6c, 0xca, 0x91, 0x7d, 0xd2, 0x3d, 0xc7,
+  0x2f, 0x8a, 0x4e, 0x55, 0x03, 0x34, 0x16, 0x01, 0x2f, 0x4f, 0x57, 0xea, 0x10, 0xa7, 0xfb, 0xe3,
+  0x2e, 0x2c, 0x7f, 0x5d, 0x27, 0x93, 0x74, 0x95, 0x25, 0x1a, 0x1e, 0x54, 0x1a, 0xb6, 0xe1, 0xdc,
+  0xc8, 0xe4, 0x84, 0xeb, 0x38, 0x0f, 0x05, 0x74, 0xf3, 0x3a, 0xf9, 0xd8, 0x00, 0x43, 0xe9, 0x24,
+  0x1e, 0x45, 0xb4, 0xe2, 0x38, 0x8b, 0x6a, 0x4f, 0xb6, 0x0b, 0x1d, 0xac, 0xbc, 0xec, 0xda, 0x41,
+  0x9c, 0x7f, 0xa8, 0x15, 0x09, 0x3b, 0x0b, 0x99, 0xc4, 0x48, 0xdd, 0xde, 0x0d, 0x65, 0x86, 0x72,
+  0xaa, 0x0a, 0x4e, 0x71,
+};
+
+//
+// dump of ca.cert.der
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mTestCaCert[] = {
+  0x30, 0x82, 0x05, 0x19, 0x30, 0x82, 0x03, 0x01, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x1d,
+  0xaf, 0x4e, 0xf1, 0x99, 0xbf, 0xee, 0xe2, 0x6d, 0x7e, 0x4a, 0xac, 0xac, 0x20, 0x00, 0xeb, 0x78,
+  0xf6, 0x6a, 0xe9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+  0x05, 0x00, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69,
+  0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41,
+  0x30, 0x1e, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x35,
+  0x5a, 0x17, 0x0d, 0x33, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x35, 0x5a,
+  0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69, 0x6e, 0x74,
+  0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41, 0x30, 0x82,
+  0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd5,
+  0x13, 0x55, 0xb1, 0x0d, 0x44, 0x17, 0x6a, 0x06, 0x39, 0x66, 0xee, 0xbc, 0x43, 0x81, 0xea, 0xe0,
+  0x93, 0x3f, 0x70, 0xb5, 0x5b, 0x07, 0xde, 0xa0, 0x24, 0x47, 0xd0, 0xf8, 0x99, 0xe6, 0x50, 0x17,
+  0xb4, 0x02, 0x60, 0xd9, 0x1a, 0x6c, 0xd3, 0x55, 0x60, 0x61, 0xde, 0x80, 0x6d, 0x38, 0x29, 0x46,
+  0xbb, 0x45, 0xa2, 0xeb, 0x24, 0x1c, 0xbb, 0x87, 0x1f, 0x14, 0xed, 0x3a, 0xd5, 0x32, 0xd5, 0x11,
+  0x4b, 0xf4, 0x99, 0x78, 0x00, 0x11, 0x8d, 0x6d, 0x6e, 0x5a, 0x0b, 0x81, 0xff, 0x08, 0x59, 0x01,
+  0x2b, 0xf0, 0x9b, 0x52, 0x88, 0x41, 0xb6, 0x3e, 0x62, 0x7b, 0xbd, 0x25, 0x96, 0x64, 0x8e, 0xb1,
+  0x2b, 0x6a, 0xf8, 0x39, 0x93, 0x0a, 0x6b, 0x3f, 0x8c, 0x2b, 0x35, 0x6e, 0x80, 0x32, 0x86, 0xf6,
+  0x0f, 0x1e, 0x8c, 0xd4, 0x4e, 0x77, 0xbe, 0xaf, 0xe5, 0x4c, 0x47, 0x66, 0xdd, 0x62, 0xce, 0x64,
+  0x65, 0x80, 0xca, 0xbd, 0x87, 0x94, 0x3e, 0xff, 0x3d, 0x0a, 0xd4, 0x39, 0xcc, 0xd1, 0xef, 0xd1,
+  0x1a, 0x55, 0x2c, 0xeb, 0xdc, 0xcf, 0x9a, 0x59, 0x92, 0xda, 0xca, 0xf6, 0xae, 0x88, 0xbc, 0xc0,
+  0x43, 0xe5, 0xa9, 0x60, 0xb2, 0x0f, 0x69, 0xa2, 0x2a, 0x98, 0x56, 0x0f, 0x4b, 0x0b, 0x63, 0xb3,
+  0x4e, 0x8b, 0x43, 0xb4, 0x7f, 0x52, 0x1e, 0x5a, 0x9e, 0xdf, 0xa7, 0x98, 0x4d, 0xb9, 0x3b, 0x58,
+  0x80, 0x69, 0x38, 0xb7, 0xeb, 0x20, 0x91, 0xbf, 0x59, 0x81, 0x44, 0xfc, 0xc6, 0xaf, 0xc2, 0xc8,
+  0xe1, 0xae, 0x3d, 0xc5, 0xb6, 0x55, 0xa8, 0xa2, 0xcd, 0xec, 0x0b, 0xbe, 0x9c, 0x34, 0x2b, 0xf5,
+  0x4b, 0x2e, 0x3b, 0x26, 0xaa, 0x22, 0x12, 0x29, 0xc2, 0x66, 0xc2, 0x40, 0xdd, 0x12, 0xfa, 0xf0,
+  0xb4, 0xe8, 0x95, 0x20, 0x59, 0x91, 0x9e, 0x7d, 0x36, 0x6e, 0x2d, 0x99, 0x53, 0x44, 0x2b, 0x43,
+  0x12, 0x08, 0x74, 0x76, 0xd5, 0x21, 0xd3, 0x08, 0x37, 0xe1, 0xe6, 0xe3, 0xc4, 0x67, 0x88, 0x29,
+  0xea, 0x06, 0x97, 0x9f, 0x61, 0x0d, 0x5d, 0x39, 0x17, 0x03, 0x87, 0x89, 0x35, 0xe0, 0xd5, 0x87,
+  0xa1, 0x5b, 0x0c, 0x3c, 0x35, 0x3d, 0xd6, 0x6f, 0xdd, 0x6f, 0xa5, 0x11, 0x9f, 0x80, 0x20, 0xca,
+  0x8b, 0x67, 0xd2, 0x2c, 0x7c, 0x51, 0x68, 0x15, 0x2c, 0x9c, 0x08, 0x86, 0xc8, 0x6c, 0xf0, 0x9d,
+  0xc2, 0x98, 0xb9, 0x6e, 0x31, 0xaf, 0x2b, 0x34, 0x9c, 0xe3, 0xd0, 0xe9, 0x85, 0x37, 0x2b, 0x1f,
+  0x21, 0xd2, 0xb9, 0xa4, 0x8d, 0x3f, 0xa3, 0x1a, 0x9f, 0x7d, 0x1b, 0xb6, 0xe0, 0xf6, 0x19, 0xf4,
+  0x19, 0xf8, 0x50, 0xa7, 0x1b, 0xec, 0xb9, 0xbb, 0xa4, 0xd2, 0x20, 0xf3, 0xed, 0xc7, 0xa7, 0x94,
+  0x2b, 0x0b, 0x9a, 0x74, 0xb8, 0xba, 0xd7, 0x42, 0x97, 0xab, 0xb4, 0xe9, 0xbe, 0x1e, 0x07, 0x0c,
+  0x05, 0x55, 0x54, 0xba, 0x05, 0x73, 0x99, 0xf2, 0x29, 0x88, 0x69, 0x4f, 0x1b, 0x2e, 0x87, 0x7b,
+  0x74, 0x94, 0xae, 0xc2, 0x2f, 0x3c, 0x90, 0xb5, 0x5c, 0x01, 0x46, 0xc6, 0x42, 0xfb, 0xa9, 0xad,
+  0x82, 0x1b, 0xd9, 0x38, 0xbe, 0x0d, 0x72, 0x4c, 0x06, 0x03, 0x92, 0xc2, 0xc8, 0x7f, 0x7b, 0xd4,
+  0x86, 0x83, 0xb8, 0x62, 0xd9, 0xf7, 0x2f, 0xc1, 0x57, 0x88, 0x85, 0xa5, 0x61, 0xc5, 0x93, 0xfc,
+  0x17, 0xe0, 0x98, 0x11, 0x88, 0x0d, 0x03, 0x0b, 0x6e, 0x01, 0x16, 0xcc, 0xf2, 0x3c, 0x5f, 0x61,
+  0x8c, 0x27, 0x31, 0xca, 0x4d, 0x35, 0x7a, 0xc1, 0xf3, 0xfe, 0x06, 0xff, 0xca, 0x7b, 0x96, 0xad,
+  0x0d, 0xff, 0x9e, 0x12, 0x44, 0x51, 0x6e, 0xf4, 0xaa, 0x2e, 0xce, 0xe8, 0xc7, 0xa6, 0xe9, 0xae,
+  0xc0, 0xbe, 0xde, 0x7b, 0x93, 0x3d, 0x1d, 0xf9, 0xfb, 0x4d, 0xa7, 0x0b, 0x73, 0xfb, 0x7b, 0x02,
+  0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x03, 0xfe, 0xb0, 0x3f, 0x09, 0xe5, 0xe1, 0xf4, 0x2e, 0x87, 0xfb, 0x41, 0x86,
+  0xf6, 0x76, 0xd3, 0x93, 0xbe, 0x96, 0x85, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+  0x30, 0x16, 0x80, 0x14, 0x03, 0xfe, 0xb0, 0x3f, 0x09, 0xe5, 0xe1, 0xf4, 0x2e, 0x87, 0xfb, 0x41,
+  0x86, 0xf6, 0x76, 0xd3, 0x93, 0xbe, 0x96, 0x85, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+  0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x02, 0x15, 0x73,
+  0x60, 0x10, 0xbc, 0x95, 0xac, 0x63, 0x15, 0x09, 0x6b, 0x0c, 0x09, 0x4a, 0x74, 0xcd, 0xe3, 0x58,
+  0xcc, 0x6c, 0xf3, 0x55, 0x80, 0xe9, 0x75, 0x47, 0x2c, 0x80, 0x4e, 0x5f, 0xfe, 0xbd, 0x2e, 0xd7,
+  0x42, 0x89, 0x44, 0x57, 0xbe, 0x51, 0x84, 0x53, 0xb6, 0x40, 0x80, 0xd6, 0xcc, 0xe2, 0x80, 0x22,
+  0x53, 0xd9, 0x31, 0x65, 0xf9, 0x3c, 0x8b, 0x7b, 0xe6, 0xa6, 0x6e, 0xfd, 0x9d, 0x27, 0xe5, 0xcd,
+  0xfd, 0x82, 0xcf, 0xd6, 0x18, 0xbe, 0xa6, 0xed, 0x72, 0xce, 0x5f, 0x45, 0x12, 0x6a, 0xaa, 0x95,
+  0x42, 0x25, 0x28, 0x8b, 0xfc, 0x4b, 0xc9, 0xad, 0xdd, 0xdb, 0x4c, 0x74, 0x10, 0x2e, 0x90, 0x2a,
+  0x06, 0x4f, 0x2e, 0xb4, 0x54, 0xb9, 0xc0, 0x60, 0xb9, 0x4d, 0xee, 0x59, 0x1c, 0x18, 0x8d, 0xd1,
+  0x49, 0xc3, 0xe9, 0x1b, 0xf1, 0xfc, 0xc3, 0x83, 0x1f, 0x6a, 0xb0, 0xfc, 0x8d, 0xfc, 0x30, 0xed,
+  0x9c, 0xcb, 0x78, 0x52, 0xe8, 0x09, 0x3d, 0x4f, 0xdc, 0xbc, 0xad, 0x84, 0xc1, 0xd5, 0x5a, 0x0a,
+  0x07, 0xa3, 0xf6, 0x42, 0xd7, 0x54, 0x55, 0x01, 0x8e, 0x53, 0xce, 0xcb, 0x2a, 0x11, 0xf7, 0x89,
+  0x7e, 0xaf, 0x6f, 0x4c, 0xb9, 0x56, 0x4a, 0x67, 0x4a, 0xf9, 0x4f, 0x64, 0x15, 0xfa, 0xb0, 0xf9,
+  0x97, 0xe2, 0xf6, 0xa8, 0xf4, 0xe7, 0x0a, 0x7a, 0x83, 0x4e, 0xf6, 0xe9, 0xac, 0x5e, 0xd9, 0xa8,
+  0xea, 0x6b, 0x06, 0xcb, 0x2c, 0x41, 0xc1, 0x7e, 0xf5, 0x79, 0xfc, 0x7c, 0x05, 0x06, 0x8f, 0x27,
+  0xaa, 0x3b, 0x61, 0x82, 0x72, 0x55, 0xa9, 0xa0, 0xa0, 0xa5, 0x69, 0x2f, 0x95, 0x40, 0xfc, 0xfe,
+  0x4a, 0x0f, 0x7d, 0x8c, 0x89, 0xaa, 0xc0, 0x1d, 0x87, 0x03, 0xa1, 0xce, 0xee, 0x23, 0x4f, 0xc5,
+  0x7c, 0xb4, 0xb6, 0x2b, 0x6f, 0x05, 0x30, 0xc9, 0x16, 0x51, 0xdf, 0xc7, 0x16, 0x3c, 0x08, 0x38,
+  0x20, 0xf9, 0xc5, 0xe0, 0x4a, 0xfa, 0xcb, 0x8c, 0xc3, 0xc5, 0xbb, 0x5c, 0xad, 0xca, 0xc2, 0x52,
+  0x45, 0x2f, 0x54, 0x70, 0x78, 0x33, 0x70, 0xc2, 0xed, 0x68, 0xf1, 0x89, 0x67, 0xa3, 0x19, 0x24,
+  0xcb, 0x8f, 0x99, 0x1b, 0x28, 0x81, 0x6c, 0x4e, 0x25, 0xb1, 0x27, 0x3d, 0x9f, 0xe7, 0x3d, 0xa7,
+  0x73, 0x9e, 0x4c, 0x1a, 0x63, 0x8e, 0xf9, 0xa7, 0xb6, 0x21, 0xe7, 0x4c, 0xdf, 0xfb, 0x36, 0x47,
+  0xda, 0x2d, 0xbb, 0x52, 0x55, 0xf8, 0x44, 0x0d, 0x0c, 0xde, 0xe2, 0x13, 0x42, 0x1b, 0xa2, 0xad,
+  0xa0, 0x0f, 0x39, 0x6c, 0x78, 0x32, 0x7a, 0x03, 0x9e, 0x55, 0x4e, 0x43, 0xf7, 0x0c, 0x35, 0xd9,
+  0x1d, 0x2c, 0x0f, 0x30, 0x30, 0x3e, 0x09, 0xe2, 0x31, 0xa6, 0xb0, 0x1e, 0xa9, 0xf5, 0x4b, 0xa1,
+  0x74, 0x09, 0x50, 0xd4, 0xd3, 0xd3, 0x3e, 0x76, 0xb1, 0x67, 0xfc, 0x51, 0xb0, 0x93, 0x22, 0xc4,
+  0x6b, 0x8a, 0x27, 0x45, 0x19, 0x3b, 0x35, 0x91, 0x61, 0x36, 0xe7, 0x9c, 0xf6, 0xda, 0x96, 0x30,
+  0x7d, 0xf4, 0x11, 0xc4, 0x3f, 0x35, 0x4e, 0x7a, 0xd6, 0x6e, 0xb6, 0xea, 0xe7, 0x66, 0x6f, 0x23,
+  0x5c, 0x53, 0x76, 0x53, 0xfc, 0x35, 0x93, 0xe5, 0xfc, 0xb9, 0x6b, 0xb9, 0xd3, 0x6c, 0x48, 0x66,
+  0x6f, 0xd7, 0x10, 0x6e, 0x25, 0x72, 0x71, 0x31, 0xfa, 0xc0, 0xdf, 0x31, 0xca, 0xd1, 0xaf, 0xc2,
+  0x8e, 0xa5, 0xca, 0xd7, 0x3f, 0x4e, 0xde, 0x47, 0xd5, 0x8e, 0xfc, 0x75, 0xb6, 0x71, 0x83, 0xd9,
+  0xfd, 0x11, 0x35, 0x81, 0xbf, 0x10, 0x0d, 0x3e, 0x50, 0x45, 0x07, 0x39, 0x08, 0x73, 0x7a, 0x0b,
+  0x21, 0x32, 0xaf, 0xf4, 0x99, 0xeb, 0x4d, 0xd4, 0xe8, 0x2a, 0x06, 0x98, 0x43, 0xbb, 0xbb, 0x11,
+  0x63, 0x99, 0xa8, 0x41, 0x22, 0xe8, 0x86, 0x79, 0x4b, 0x53, 0xb7, 0x73, 0x1b,
+};
+
+//
+// dump of bundle_requester.certchain.der
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mTestBundleCert[] = {
+  0x30, 0x82, 0x05, 0x19, 0x30, 0x82, 0x03, 0x01, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x14, 0x1d,
+  0xaf, 0x4e, 0xf1, 0x99, 0xbf, 0xee, 0xe2, 0x6d, 0x7e, 0x4a, 0xac, 0xac, 0x20, 0x00, 0xeb, 0x78,
+  0xf6, 0x6a, 0xe9, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
+  0x05, 0x00, 0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69,
+  0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41,
+  0x30, 0x1e, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x35,
+  0x5a, 0x17, 0x0d, 0x33, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x35, 0x5a,
+  0x30, 0x1c, 0x31, 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69, 0x6e, 0x74,
+  0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41, 0x30, 0x82,
+  0x02, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05,
+  0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, 0x02, 0x82, 0x02, 0x01, 0x00, 0xd5,
+  0x13, 0x55, 0xb1, 0x0d, 0x44, 0x17, 0x6a, 0x06, 0x39, 0x66, 0xee, 0xbc, 0x43, 0x81, 0xea, 0xe0,
+  0x93, 0x3f, 0x70, 0xb5, 0x5b, 0x07, 0xde, 0xa0, 0x24, 0x47, 0xd0, 0xf8, 0x99, 0xe6, 0x50, 0x17,
+  0xb4, 0x02, 0x60, 0xd9, 0x1a, 0x6c, 0xd3, 0x55, 0x60, 0x61, 0xde, 0x80, 0x6d, 0x38, 0x29, 0x46,
+  0xbb, 0x45, 0xa2, 0xeb, 0x24, 0x1c, 0xbb, 0x87, 0x1f, 0x14, 0xed, 0x3a, 0xd5, 0x32, 0xd5, 0x11,
+  0x4b, 0xf4, 0x99, 0x78, 0x00, 0x11, 0x8d, 0x6d, 0x6e, 0x5a, 0x0b, 0x81, 0xff, 0x08, 0x59, 0x01,
+  0x2b, 0xf0, 0x9b, 0x52, 0x88, 0x41, 0xb6, 0x3e, 0x62, 0x7b, 0xbd, 0x25, 0x96, 0x64, 0x8e, 0xb1,
+  0x2b, 0x6a, 0xf8, 0x39, 0x93, 0x0a, 0x6b, 0x3f, 0x8c, 0x2b, 0x35, 0x6e, 0x80, 0x32, 0x86, 0xf6,
+  0x0f, 0x1e, 0x8c, 0xd4, 0x4e, 0x77, 0xbe, 0xaf, 0xe5, 0x4c, 0x47, 0x66, 0xdd, 0x62, 0xce, 0x64,
+  0x65, 0x80, 0xca, 0xbd, 0x87, 0x94, 0x3e, 0xff, 0x3d, 0x0a, 0xd4, 0x39, 0xcc, 0xd1, 0xef, 0xd1,
+  0x1a, 0x55, 0x2c, 0xeb, 0xdc, 0xcf, 0x9a, 0x59, 0x92, 0xda, 0xca, 0xf6, 0xae, 0x88, 0xbc, 0xc0,
+  0x43, 0xe5, 0xa9, 0x60, 0xb2, 0x0f, 0x69, 0xa2, 0x2a, 0x98, 0x56, 0x0f, 0x4b, 0x0b, 0x63, 0xb3,
+  0x4e, 0x8b, 0x43, 0xb4, 0x7f, 0x52, 0x1e, 0x5a, 0x9e, 0xdf, 0xa7, 0x98, 0x4d, 0xb9, 0x3b, 0x58,
+  0x80, 0x69, 0x38, 0xb7, 0xeb, 0x20, 0x91, 0xbf, 0x59, 0x81, 0x44, 0xfc, 0xc6, 0xaf, 0xc2, 0xc8,
+  0xe1, 0xae, 0x3d, 0xc5, 0xb6, 0x55, 0xa8, 0xa2, 0xcd, 0xec, 0x0b, 0xbe, 0x9c, 0x34, 0x2b, 0xf5,
+  0x4b, 0x2e, 0x3b, 0x26, 0xaa, 0x22, 0x12, 0x29, 0xc2, 0x66, 0xc2, 0x40, 0xdd, 0x12, 0xfa, 0xf0,
+  0xb4, 0xe8, 0x95, 0x20, 0x59, 0x91, 0x9e, 0x7d, 0x36, 0x6e, 0x2d, 0x99, 0x53, 0x44, 0x2b, 0x43,
+  0x12, 0x08, 0x74, 0x76, 0xd5, 0x21, 0xd3, 0x08, 0x37, 0xe1, 0xe6, 0xe3, 0xc4, 0x67, 0x88, 0x29,
+  0xea, 0x06, 0x97, 0x9f, 0x61, 0x0d, 0x5d, 0x39, 0x17, 0x03, 0x87, 0x89, 0x35, 0xe0, 0xd5, 0x87,
+  0xa1, 0x5b, 0x0c, 0x3c, 0x35, 0x3d, 0xd6, 0x6f, 0xdd, 0x6f, 0xa5, 0x11, 0x9f, 0x80, 0x20, 0xca,
+  0x8b, 0x67, 0xd2, 0x2c, 0x7c, 0x51, 0x68, 0x15, 0x2c, 0x9c, 0x08, 0x86, 0xc8, 0x6c, 0xf0, 0x9d,
+  0xc2, 0x98, 0xb9, 0x6e, 0x31, 0xaf, 0x2b, 0x34, 0x9c, 0xe3, 0xd0, 0xe9, 0x85, 0x37, 0x2b, 0x1f,
+  0x21, 0xd2, 0xb9, 0xa4, 0x8d, 0x3f, 0xa3, 0x1a, 0x9f, 0x7d, 0x1b, 0xb6, 0xe0, 0xf6, 0x19, 0xf4,
+  0x19, 0xf8, 0x50, 0xa7, 0x1b, 0xec, 0xb9, 0xbb, 0xa4, 0xd2, 0x20, 0xf3, 0xed, 0xc7, 0xa7, 0x94,
+  0x2b, 0x0b, 0x9a, 0x74, 0xb8, 0xba, 0xd7, 0x42, 0x97, 0xab, 0xb4, 0xe9, 0xbe, 0x1e, 0x07, 0x0c,
+  0x05, 0x55, 0x54, 0xba, 0x05, 0x73, 0x99, 0xf2, 0x29, 0x88, 0x69, 0x4f, 0x1b, 0x2e, 0x87, 0x7b,
+  0x74, 0x94, 0xae, 0xc2, 0x2f, 0x3c, 0x90, 0xb5, 0x5c, 0x01, 0x46, 0xc6, 0x42, 0xfb, 0xa9, 0xad,
+  0x82, 0x1b, 0xd9, 0x38, 0xbe, 0x0d, 0x72, 0x4c, 0x06, 0x03, 0x92, 0xc2, 0xc8, 0x7f, 0x7b, 0xd4,
+  0x86, 0x83, 0xb8, 0x62, 0xd9, 0xf7, 0x2f, 0xc1, 0x57, 0x88, 0x85, 0xa5, 0x61, 0xc5, 0x93, 0xfc,
+  0x17, 0xe0, 0x98, 0x11, 0x88, 0x0d, 0x03, 0x0b, 0x6e, 0x01, 0x16, 0xcc, 0xf2, 0x3c, 0x5f, 0x61,
+  0x8c, 0x27, 0x31, 0xca, 0x4d, 0x35, 0x7a, 0xc1, 0xf3, 0xfe, 0x06, 0xff, 0xca, 0x7b, 0x96, 0xad,
+  0x0d, 0xff, 0x9e, 0x12, 0x44, 0x51, 0x6e, 0xf4, 0xaa, 0x2e, 0xce, 0xe8, 0xc7, 0xa6, 0xe9, 0xae,
+  0xc0, 0xbe, 0xde, 0x7b, 0x93, 0x3d, 0x1d, 0xf9, 0xfb, 0x4d, 0xa7, 0x0b, 0x73, 0xfb, 0x7b, 0x02,
+  0x03, 0x01, 0x00, 0x01, 0xa3, 0x53, 0x30, 0x51, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04,
+  0x16, 0x04, 0x14, 0x03, 0xfe, 0xb0, 0x3f, 0x09, 0xe5, 0xe1, 0xf4, 0x2e, 0x87, 0xfb, 0x41, 0x86,
+  0xf6, 0x76, 0xd3, 0x93, 0xbe, 0x96, 0x85, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+  0x30, 0x16, 0x80, 0x14, 0x03, 0xfe, 0xb0, 0x3f, 0x09, 0xe5, 0xe1, 0xf4, 0x2e, 0x87, 0xfb, 0x41,
+  0x86, 0xf6, 0x76, 0xd3, 0x93, 0xbe, 0x96, 0x85, 0x30, 0x0f, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01,
+  0x01, 0xff, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, 0x00, 0x02, 0x15, 0x73,
+  0x60, 0x10, 0xbc, 0x95, 0xac, 0x63, 0x15, 0x09, 0x6b, 0x0c, 0x09, 0x4a, 0x74, 0xcd, 0xe3, 0x58,
+  0xcc, 0x6c, 0xf3, 0x55, 0x80, 0xe9, 0x75, 0x47, 0x2c, 0x80, 0x4e, 0x5f, 0xfe, 0xbd, 0x2e, 0xd7,
+  0x42, 0x89, 0x44, 0x57, 0xbe, 0x51, 0x84, 0x53, 0xb6, 0x40, 0x80, 0xd6, 0xcc, 0xe2, 0x80, 0x22,
+  0x53, 0xd9, 0x31, 0x65, 0xf9, 0x3c, 0x8b, 0x7b, 0xe6, 0xa6, 0x6e, 0xfd, 0x9d, 0x27, 0xe5, 0xcd,
+  0xfd, 0x82, 0xcf, 0xd6, 0x18, 0xbe, 0xa6, 0xed, 0x72, 0xce, 0x5f, 0x45, 0x12, 0x6a, 0xaa, 0x95,
+  0x42, 0x25, 0x28, 0x8b, 0xfc, 0x4b, 0xc9, 0xad, 0xdd, 0xdb, 0x4c, 0x74, 0x10, 0x2e, 0x90, 0x2a,
+  0x06, 0x4f, 0x2e, 0xb4, 0x54, 0xb9, 0xc0, 0x60, 0xb9, 0x4d, 0xee, 0x59, 0x1c, 0x18, 0x8d, 0xd1,
+  0x49, 0xc3, 0xe9, 0x1b, 0xf1, 0xfc, 0xc3, 0x83, 0x1f, 0x6a, 0xb0, 0xfc, 0x8d, 0xfc, 0x30, 0xed,
+  0x9c, 0xcb, 0x78, 0x52, 0xe8, 0x09, 0x3d, 0x4f, 0xdc, 0xbc, 0xad, 0x84, 0xc1, 0xd5, 0x5a, 0x0a,
+  0x07, 0xa3, 0xf6, 0x42, 0xd7, 0x54, 0x55, 0x01, 0x8e, 0x53, 0xce, 0xcb, 0x2a, 0x11, 0xf7, 0x89,
+  0x7e, 0xaf, 0x6f, 0x4c, 0xb9, 0x56, 0x4a, 0x67, 0x4a, 0xf9, 0x4f, 0x64, 0x15, 0xfa, 0xb0, 0xf9,
+  0x97, 0xe2, 0xf6, 0xa8, 0xf4, 0xe7, 0x0a, 0x7a, 0x83, 0x4e, 0xf6, 0xe9, 0xac, 0x5e, 0xd9, 0xa8,
+  0xea, 0x6b, 0x06, 0xcb, 0x2c, 0x41, 0xc1, 0x7e, 0xf5, 0x79, 0xfc, 0x7c, 0x05, 0x06, 0x8f, 0x27,
+  0xaa, 0x3b, 0x61, 0x82, 0x72, 0x55, 0xa9, 0xa0, 0xa0, 0xa5, 0x69, 0x2f, 0x95, 0x40, 0xfc, 0xfe,
+  0x4a, 0x0f, 0x7d, 0x8c, 0x89, 0xaa, 0xc0, 0x1d, 0x87, 0x03, 0xa1, 0xce, 0xee, 0x23, 0x4f, 0xc5,
+  0x7c, 0xb4, 0xb6, 0x2b, 0x6f, 0x05, 0x30, 0xc9, 0x16, 0x51, 0xdf, 0xc7, 0x16, 0x3c, 0x08, 0x38,
+  0x20, 0xf9, 0xc5, 0xe0, 0x4a, 0xfa, 0xcb, 0x8c, 0xc3, 0xc5, 0xbb, 0x5c, 0xad, 0xca, 0xc2, 0x52,
+  0x45, 0x2f, 0x54, 0x70, 0x78, 0x33, 0x70, 0xc2, 0xed, 0x68, 0xf1, 0x89, 0x67, 0xa3, 0x19, 0x24,
+  0xcb, 0x8f, 0x99, 0x1b, 0x28, 0x81, 0x6c, 0x4e, 0x25, 0xb1, 0x27, 0x3d, 0x9f, 0xe7, 0x3d, 0xa7,
+  0x73, 0x9e, 0x4c, 0x1a, 0x63, 0x8e, 0xf9, 0xa7, 0xb6, 0x21, 0xe7, 0x4c, 0xdf, 0xfb, 0x36, 0x47,
+  0xda, 0x2d, 0xbb, 0x52, 0x55, 0xf8, 0x44, 0x0d, 0x0c, 0xde, 0xe2, 0x13, 0x42, 0x1b, 0xa2, 0xad,
+  0xa0, 0x0f, 0x39, 0x6c, 0x78, 0x32, 0x7a, 0x03, 0x9e, 0x55, 0x4e, 0x43, 0xf7, 0x0c, 0x35, 0xd9,
+  0x1d, 0x2c, 0x0f, 0x30, 0x30, 0x3e, 0x09, 0xe2, 0x31, 0xa6, 0xb0, 0x1e, 0xa9, 0xf5, 0x4b, 0xa1,
+  0x74, 0x09, 0x50, 0xd4, 0xd3, 0xd3, 0x3e, 0x76, 0xb1, 0x67, 0xfc, 0x51, 0xb0, 0x93, 0x22, 0xc4,
+  0x6b, 0x8a, 0x27, 0x45, 0x19, 0x3b, 0x35, 0x91, 0x61, 0x36, 0xe7, 0x9c, 0xf6, 0xda, 0x96, 0x30,
+  0x7d, 0xf4, 0x11, 0xc4, 0x3f, 0x35, 0x4e, 0x7a, 0xd6, 0x6e, 0xb6, 0xea, 0xe7, 0x66, 0x6f, 0x23,
+  0x5c, 0x53, 0x76, 0x53, 0xfc, 0x35, 0x93, 0xe5, 0xfc, 0xb9, 0x6b, 0xb9, 0xd3, 0x6c, 0x48, 0x66,
+  0x6f, 0xd7, 0x10, 0x6e, 0x25, 0x72, 0x71, 0x31, 0xfa, 0xc0, 0xdf, 0x31, 0xca, 0xd1, 0xaf, 0xc2,
+  0x8e, 0xa5, 0xca, 0xd7, 0x3f, 0x4e, 0xde, 0x47, 0xd5, 0x8e, 0xfc, 0x75, 0xb6, 0x71, 0x83, 0xd9,
+  0xfd, 0x11, 0x35, 0x81, 0xbf, 0x10, 0x0d, 0x3e, 0x50, 0x45, 0x07, 0x39, 0x08, 0x73, 0x7a, 0x0b,
+  0x21, 0x32, 0xaf, 0xf4, 0x99, 0xeb, 0x4d, 0xd4, 0xe8, 0x2a, 0x06, 0x98, 0x43, 0xbb, 0xbb, 0x11,
+  0x63, 0x99, 0xa8, 0x41, 0x22, 0xe8, 0x86, 0x79, 0x4b, 0x53, 0xb7, 0x73, 0x1b, 0x30, 0x82, 0x04,
+  0xa0, 0x30, 0x82, 0x02, 0x88, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x01, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x1c, 0x31, 0x1a,
+  0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x11, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74,
+  0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x32,
+  0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x17, 0x0d, 0x33, 0x32, 0x30,
+  0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x30, 0x2b, 0x31, 0x29, 0x30, 0x27,
+  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74, 0x65, 0x73,
+  0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61,
+  0x74, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0xa2, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x8f, 0x00, 0x30,
+  0x82, 0x01, 0x8a, 0x02, 0x82, 0x01, 0x81, 0x00, 0xd1, 0xcf, 0x2d, 0x21, 0x38, 0xe4, 0x81, 0xa6,
+  0xf2, 0xe5, 0xca, 0xac, 0x09, 0x2b, 0x04, 0x2a, 0x52, 0x76, 0x2f, 0xa3, 0x4b, 0x43, 0xc2, 0xd6,
+  0xb5, 0x3e, 0x2b, 0x29, 0x6f, 0x1b, 0x7d, 0x36, 0x60, 0xcd, 0x71, 0xf4, 0xcf, 0x8a, 0x24, 0xac,
+  0x8f, 0x5f, 0x78, 0x70, 0xc9, 0x84, 0x48, 0xfb, 0x1d, 0xcb, 0xee, 0x34, 0x3c, 0x4c, 0xe1, 0x1a,
+  0x92, 0x54, 0x43, 0x45, 0xe0, 0xdd, 0x14, 0xd5, 0xac, 0x13, 0xae, 0xcc, 0x45, 0xdc, 0x52, 0xdd,
+  0x45, 0x22, 0x10, 0xab, 0xb2, 0x1b, 0x3e, 0xad, 0x36, 0x6f, 0x00, 0x59, 0xb6, 0xfd, 0x27, 0xb8,
+  0x57, 0xbb, 0x66, 0x72, 0x1e, 0x7b, 0xe8, 0xc7, 0xaf, 0x5e, 0x65, 0x5c, 0x58, 0x3d, 0x9e, 0x78,
+  0x26, 0xb7, 0x70, 0x9a, 0xe7, 0x3c, 0xfc, 0x90, 0x64, 0xb2, 0xb2, 0xb2, 0x80, 0x22, 0xb3, 0x1c,
+  0x23, 0x73, 0x6a, 0xe3, 0xcb, 0x5b, 0x4e, 0x29, 0x71, 0xdd, 0xfd, 0xd7, 0x15, 0x3a, 0xd6, 0xa3,
+  0xe0, 0x4a, 0x53, 0x65, 0xa6, 0xae, 0x6a, 0x83, 0xb0, 0x00, 0x3f, 0x64, 0x4b, 0x01, 0xcd, 0x97,
+  0xb1, 0xe1, 0x54, 0x1e, 0xa2, 0x33, 0x4e, 0xf0, 0x13, 0x33, 0x80, 0xe5, 0x41, 0x9c, 0x5e, 0xb3,
+  0x5d, 0xae, 0x53, 0x2c, 0x41, 0x51, 0xf2, 0x00, 0x3e, 0x03, 0xe2, 0x0d, 0xa4, 0xf5, 0x24, 0x08,
+  0x46, 0xc2, 0xed, 0x6b, 0xf2, 0xe0, 0x1b, 0x04, 0xb7, 0xe8, 0xda, 0x85, 0xa4, 0x2f, 0x4b, 0x53,
+  0xfa, 0x76, 0x72, 0x0a, 0x28, 0xbf, 0x3c, 0xa8, 0x85, 0x03, 0xee, 0x51, 0xb5, 0x5c, 0xa9, 0xa5,
+  0x70, 0x47, 0x07, 0x11, 0x32, 0xc5, 0x5f, 0x7a, 0x07, 0xfb, 0x5f, 0x4a, 0x52, 0x65, 0x33, 0x0c,
+  0x17, 0x8e, 0x74, 0xe5, 0xec, 0x7d, 0x52, 0xa0, 0xd4, 0xef, 0x64, 0xcc, 0x5e, 0xe2, 0x3d, 0x46,
+  0x1e, 0x73, 0xab, 0x43, 0x2d, 0x05, 0xfa, 0xa3, 0x6d, 0x86, 0x02, 0xe7, 0xc8, 0x5f, 0x44, 0xfe,
+  0xeb, 0x14, 0x73, 0x2d, 0xf4, 0x0b, 0x72, 0x49, 0xe3, 0xef, 0x55, 0x05, 0x1b, 0x2f, 0xf9, 0x73,
+  0xeb, 0xed, 0xcc, 0x5e, 0x52, 0x17, 0x43, 0x94, 0x85, 0xc7, 0x0e, 0x73, 0x89, 0x22, 0xdc, 0x02,
+  0x5f, 0x99, 0x69, 0x58, 0x16, 0x89, 0x1e, 0x6f, 0x75, 0xf8, 0xd3, 0xe7, 0x0a, 0xb1, 0x01, 0x42,
+  0x71, 0xa6, 0xc5, 0xb2, 0xd0, 0xc0, 0x75, 0x96, 0x2e, 0xc2, 0x32, 0x49, 0x0a, 0xe8, 0x85, 0xbd,
+  0x22, 0x4c, 0x95, 0xd4, 0xf8, 0x2d, 0x72, 0x05, 0x4f, 0x0e, 0x56, 0x9c, 0xc3, 0x30, 0x3d, 0xfd,
+  0x30, 0x63, 0x92, 0x72, 0x6b, 0xaf, 0x80, 0x9d, 0xd0, 0xc2, 0x36, 0xe7, 0xc1, 0x37, 0xd0, 0x64,
+  0x88, 0x64, 0x3c, 0x33, 0xdd, 0x87, 0xdd, 0xd9, 0xa2, 0x79, 0x44, 0xd8, 0x25, 0x84, 0x0e, 0xfd,
+  0x9d, 0xd6, 0xc1, 0x7a, 0x2d, 0x23, 0x08, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x5e, 0x30,
+  0x5c, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x05, 0x30, 0x03, 0x01, 0x01, 0xff, 0x30,
+  0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x01, 0xfe, 0x30, 0x1d, 0x06, 0x03,
+  0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x46, 0xcd, 0xb4, 0x52, 0x02, 0x29, 0x26, 0xc7, 0x52,
+  0x23, 0x81, 0x65, 0xcd, 0x87, 0x2f, 0x96, 0x1b, 0x01, 0x2c, 0xc5, 0x30, 0x20, 0x06, 0x03, 0x55,
+  0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x16, 0x30, 0x14, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05,
+  0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, 0x30, 0x0d, 0x06,
+  0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01,
+  0x00, 0x71, 0x14, 0xca, 0xfe, 0x03, 0x92, 0xc6, 0x88, 0x52, 0x76, 0x43, 0xd9, 0x8a, 0xf7, 0x22,
+  0x94, 0xef, 0x40, 0xa7, 0xc3, 0x7b, 0x6f, 0xb4, 0xd0, 0x42, 0xc3, 0x59, 0x1f, 0x77, 0xef, 0xac,
+  0x18, 0xce, 0x7c, 0xab, 0x48, 0x85, 0x22, 0xf1, 0x50, 0x2c, 0xe0, 0x63, 0x4d, 0x9d, 0x0e, 0xed,
+  0x38, 0xff, 0xd9, 0xed, 0x3c, 0x7e, 0x3e, 0x84, 0xb1, 0xa7, 0x78, 0x62, 0x37, 0x39, 0x6d, 0xd5,
+  0x5d, 0x46, 0x9a, 0x6f, 0x63, 0xc2, 0xa7, 0x90, 0xf9, 0x7a, 0xa7, 0x4b, 0xa2, 0x8a, 0xa8, 0x50,
+  0x13, 0x16, 0x9c, 0x4f, 0xcc, 0x28, 0x58, 0x6c, 0x9f, 0x65, 0x6e, 0xf0, 0x9a, 0x92, 0x59, 0x94,
+  0xa4, 0xb5, 0xfd, 0x8f, 0xf0, 0x7c, 0x1e, 0xba, 0xc3, 0x21, 0x13, 0xfb, 0x33, 0xba, 0xad, 0x4b,
+  0x1d, 0x42, 0x23, 0x16, 0x8b, 0x3e, 0xcd, 0xb5, 0x69, 0x9c, 0x7c, 0xa1, 0x9b, 0x92, 0xc1, 0x2f,
+  0x9c, 0x89, 0x3f, 0x28, 0x24, 0x67, 0x48, 0x47, 0xf0, 0xb1, 0xc0, 0xf0, 0x4c, 0xbf, 0xf6, 0x64,
+  0xde, 0x33, 0xc3, 0xd6, 0x5b, 0xe6, 0xc3, 0xdd, 0xa5, 0xba, 0x42, 0x02, 0x0f, 0xbc, 0xbe, 0xde,
+  0x14, 0x12, 0x7c, 0xfb, 0xe6, 0xbb, 0xdd, 0xf2, 0x6b, 0xd7, 0x75, 0xe6, 0xf5, 0xda, 0xbe, 0xe9,
+  0xbf, 0xa6, 0x87, 0x09, 0x41, 0x6c, 0x9d, 0x19, 0x9c, 0xb1, 0x7c, 0x89, 0x9f, 0x32, 0xb3, 0x0a,
+  0x59, 0x10, 0xc6, 0x8c, 0xa0, 0x5b, 0xda, 0xa6, 0xa3, 0xf8, 0x33, 0x77, 0x7a, 0xf4, 0xb0, 0x8a,
+  0xcf, 0xc8, 0x3f, 0x2e, 0xb8, 0xf1, 0x9e, 0x7b, 0x47, 0x2d, 0x85, 0x3b, 0x58, 0xcd, 0x4b, 0xbc,
+  0x87, 0xd2, 0xf3, 0xcd, 0x36, 0x80, 0x9b, 0x4a, 0x0f, 0x24, 0x30, 0x1d, 0x3f, 0x6f, 0x56, 0xcf,
+  0x6e, 0x2d, 0xcf, 0xa8, 0x17, 0xd5, 0x97, 0x0b, 0x22, 0xa6, 0x59, 0xef, 0xef, 0xd4, 0x9a, 0x0e,
+  0x6f, 0xb9, 0xf0, 0x48, 0x2a, 0x54, 0x22, 0x77, 0x27, 0x90, 0x84, 0x42, 0x56, 0x85, 0x80, 0x78,
+  0x4f, 0xd9, 0x14, 0x2a, 0xf0, 0x5d, 0x6b, 0x46, 0x60, 0x3d, 0xad, 0xa5, 0xa2, 0xb9, 0x04, 0x23,
+  0x92, 0x1b, 0x70, 0xa3, 0xdb, 0xaa, 0xf0, 0x5f, 0x1c, 0xd8, 0x26, 0xbb, 0x51, 0x17, 0xfc, 0x93,
+  0x6d, 0x70, 0x19, 0x54, 0xe2, 0x6f, 0x82, 0x8a, 0x49, 0xa6, 0x19, 0xcc, 0x97, 0x53, 0x90, 0x27,
+  0xd9, 0x8d, 0xaa, 0x8c, 0xc3, 0x2b, 0xbc, 0x0a, 0x72, 0x3a, 0x41, 0xb8, 0xfa, 0x1e, 0xbb, 0x8b,
+  0x27, 0x06, 0x75, 0x53, 0x91, 0xac, 0x8d, 0x75, 0xf2, 0xa6, 0xea, 0x85, 0x7e, 0x34, 0x06, 0x9e,
+  0xf9, 0xe9, 0x13, 0xa3, 0xfe, 0x2e, 0x38, 0x4b, 0x3f, 0x61, 0x11, 0x1f, 0x6b, 0xd3, 0xfe, 0xc9,
+  0x13, 0xbc, 0x12, 0xfe, 0xbc, 0xff, 0xaa, 0x38, 0x73, 0x8a, 0x73, 0x8c, 0xcf, 0xcc, 0xd3, 0xe7,
+  0xba, 0x98, 0xfd, 0xf4, 0xf5, 0xf6, 0xa9, 0xc8, 0x07, 0x5b, 0x16, 0xae, 0x76, 0x86, 0x24, 0x25,
+  0xcc, 0x7c, 0xdb, 0x1e, 0x7f, 0xc4, 0xe4, 0xd3, 0x89, 0x5a, 0x91, 0x6a, 0x9c, 0x93, 0x03, 0xd2,
+  0xd2, 0xc0, 0x29, 0x69, 0x58, 0x52, 0x6c, 0xca, 0x91, 0x7d, 0xd2, 0x3d, 0xc7, 0x2f, 0x8a, 0x4e,
+  0x55, 0x03, 0x34, 0x16, 0x01, 0x2f, 0x4f, 0x57, 0xea, 0x10, 0xa7, 0xfb, 0xe3, 0x2e, 0x2c, 0x7f,
+  0x5d, 0x27, 0x93, 0x74, 0x95, 0x25, 0x1a, 0x1e, 0x54, 0x1a, 0xb6, 0xe1, 0xdc, 0xc8, 0xe4, 0x84,
+  0xeb, 0x38, 0x0f, 0x05, 0x74, 0xf3, 0x3a, 0xf9, 0xd8, 0x00, 0x43, 0xe9, 0x24, 0x1e, 0x45, 0xb4,
+  0xe2, 0x38, 0x8b, 0x6a, 0x4f, 0xb6, 0x0b, 0x1d, 0xac, 0xbc, 0xec, 0xda, 0x41, 0x9c, 0x7f, 0xa8,
+  0x15, 0x09, 0x3b, 0x0b, 0x99, 0xc4, 0x48, 0xdd, 0xde, 0x0d, 0x65, 0x86, 0x72, 0xaa, 0x0a, 0x4e,
+  0x71, 0x30, 0x82, 0x03, 0xeb, 0x30, 0x82, 0x02, 0x53, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01,
+  0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00,
+  0x30, 0x2b, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x69, 0x6e, 0x74,
+  0x65, 0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x69, 0x6e, 0x74, 0x65,
+  0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x1e, 0x17,
+  0x0d, 0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x17, 0x0d,
+  0x33, 0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x30, 0x28, 0x31,
+  0x26, 0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1d, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20,
+  0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x72, 0x65, 0x71, 0x75, 0x73, 0x65, 0x74,
+  0x65, 0x72, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30,
+  0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x93, 0x47, 0xf3, 0x71, 0x6b, 0x24, 0x1e, 0xc0,
+  0xeb, 0x6b, 0x22, 0x23, 0xe7, 0xc8, 0x10, 0x9d, 0xb2, 0xef, 0x1e, 0x65, 0xe9, 0xff, 0xd6, 0x37,
+  0xee, 0xc5, 0x3f, 0x29, 0x25, 0x94, 0xb4, 0x30, 0x97, 0x51, 0xe3, 0x51, 0xa4, 0x39, 0xd1, 0x27,
+  0x32, 0x9e, 0x6b, 0x80, 0xc2, 0x29, 0xf2, 0x28, 0xd1, 0x49, 0xdc, 0x62, 0x27, 0x5b, 0x3f, 0xce,
+  0x83, 0xd7, 0x7b, 0x09, 0x37, 0x48, 0x16, 0x7f, 0x2e, 0x6e, 0xfa, 0x67, 0xaa, 0x92, 0x17, 0xcb,
+  0xff, 0x4b, 0xe3, 0x1b, 0xd1, 0xa6, 0xe3, 0x6c, 0x4d, 0x9f, 0x9e, 0xc7, 0x01, 0xed, 0x9f, 0x14,
+  0xb0, 0x34, 0x44, 0xa2, 0x88, 0x28, 0xf2, 0x3f, 0xad, 0xf2, 0xf7, 0x51, 0x8c, 0xfe, 0x43, 0x73,
+  0xfa, 0x8d, 0x2f, 0x63, 0x8c, 0x0e, 0xe5, 0x27, 0xdc, 0x12, 0x81, 0x26, 0xea, 0x92, 0x67, 0x7d,
+  0xc9, 0xfc, 0xec, 0x4c, 0xcc, 0x79, 0x4d, 0x2d, 0xfe, 0xf6, 0x63, 0xb7, 0x63, 0xca, 0x70, 0x24,
+  0xe0, 0x23, 0x53, 0x92, 0xe8, 0x56, 0xb7, 0x85, 0x6d, 0x25, 0x9e, 0xe0, 0x24, 0xa8, 0x5c, 0xe0,
+  0x0f, 0xc1, 0xb6, 0x20, 0x2f, 0x85, 0x2a, 0x67, 0xf6, 0x1b, 0x58, 0x60, 0x5a, 0x14, 0xda, 0xc2,
+  0x03, 0x10, 0x79, 0x33, 0x3c, 0x41, 0xc6, 0xbe, 0xd2, 0xee, 0x2f, 0x65, 0xd5, 0xad, 0x9c, 0xc6,
+  0x09, 0xae, 0x26, 0xf2, 0xac, 0xc2, 0x65, 0x12, 0x74, 0x09, 0xe8, 0x89, 0x66, 0xf6, 0x95, 0xb8,
+  0x6a, 0x5f, 0x96, 0xc2, 0x3c, 0x9f, 0x01, 0x52, 0xa8, 0xc8, 0x4e, 0xd8, 0xba, 0x95, 0x38, 0x5b,
+  0xf8, 0xc6, 0x43, 0x54, 0xac, 0x63, 0x90, 0xd4, 0xde, 0x11, 0x40, 0x27, 0xe5, 0x12, 0x1d, 0x72,
+  0xa2, 0xec, 0xad, 0x0a, 0x8b, 0x68, 0x21, 0x9d, 0xea, 0x16, 0x70, 0x5f, 0x32, 0x3a, 0xed, 0x4f,
+  0x0b, 0xb2, 0x44, 0x1f, 0x44, 0x9b, 0x4c, 0x03, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x9c,
+  0x30, 0x81, 0x99, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30,
+  0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xe0, 0x30, 0x1d,
+  0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7c, 0x69, 0x5e, 0x84, 0xbb, 0xc7, 0x6b,
+  0xfc, 0x45, 0x70, 0xa4, 0x4b, 0x1e, 0x67, 0x70, 0x04, 0xa4, 0x37, 0xdd, 0x72, 0x30, 0x31, 0x06,
+  0x03, 0x55, 0x1d, 0x11, 0x04, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
+  0x01, 0x83, 0x1c, 0x82, 0x12, 0x01, 0xa0, 0x18, 0x0c, 0x16, 0x41, 0x43, 0x4d, 0x45, 0x3a, 0x57,
+  0x49, 0x44, 0x47, 0x45, 0x54, 0x3a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30,
+  0x30, 0x2a, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x20, 0x30, 0x1e, 0x06, 0x08,
+  0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
+  0x03, 0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09,
+  0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x81, 0x00,
+  0x8e, 0x19, 0x08, 0xec, 0x7a, 0xcc, 0x6d, 0x04, 0x5f, 0xb7, 0xf9, 0xd2, 0xcd, 0x76, 0xee, 0x44,
+  0x1b, 0x7c, 0x19, 0xcb, 0x18, 0xdd, 0x60, 0x50, 0x3a, 0x54, 0xb1, 0x75, 0x17, 0xf6, 0xce, 0x19,
+  0x15, 0x09, 0x9e, 0x5b, 0xfc, 0x5c, 0xb3, 0x20, 0x8d, 0xcb, 0x9d, 0xfc, 0x23, 0x12, 0x68, 0x87,
+  0x55, 0x0d, 0x3b, 0x5f, 0x9f, 0x4e, 0xb2, 0x17, 0x13, 0x0b, 0xc4, 0x6f, 0xbe, 0x43, 0x75, 0xa6,
+  0xb7, 0x3c, 0x0e, 0xe0, 0xdf, 0x84, 0xe5, 0x88, 0x46, 0x08, 0xc3, 0x36, 0x1b, 0x31, 0x02, 0x92,
+  0x7c, 0x53, 0xc4, 0x08, 0x63, 0x3e, 0x46, 0x75, 0xd7, 0x35, 0x9a, 0xd0, 0x76, 0x71, 0xf9, 0x57,
+  0x97, 0xc7, 0x3c, 0x3b, 0xce, 0x7a, 0x82, 0x95, 0x15, 0x8e, 0x20, 0xcc, 0x7b, 0xa0, 0xc4, 0x68,
+  0x21, 0x26, 0x9c, 0xfd, 0x29, 0x83, 0x41, 0x19, 0x98, 0xb6, 0x8a, 0x3a, 0x06, 0x5f, 0x01, 0x1b,
+  0x80, 0xac, 0x33, 0xd9, 0x0c, 0x9c, 0xea, 0x70, 0xd7, 0xf5, 0x1e, 0xb0, 0x78, 0x24, 0xbc, 0x59,
+  0xaf, 0x07, 0xc6, 0x16, 0x46, 0xdd, 0x9d, 0x00, 0x9a, 0xc8, 0x9a, 0x04, 0x19, 0x4d, 0x62, 0xa9,
+  0x4f, 0x7c, 0x05, 0x24, 0x93, 0xc6, 0x01, 0xc5, 0xb2, 0x89, 0xe8, 0x62, 0x47, 0xbe, 0xa3, 0xd1,
+  0x9c, 0x47, 0x31, 0x06, 0x16, 0x6b, 0x3b, 0xf8, 0xad, 0xb0, 0x4c, 0xfb, 0x2b, 0x6b, 0x8e, 0x88,
+  0x53, 0x70, 0x75, 0x40, 0x30, 0xaf, 0xfe, 0xc5, 0xf3, 0x0f, 0x86, 0x8f, 0x58, 0x56, 0x67, 0xbd,
+  0x15, 0x1f, 0x8a, 0x5c, 0xa3, 0x8a, 0x9a, 0x88, 0xe5, 0xf2, 0xd3, 0x7f, 0xac, 0x56, 0x34, 0x21,
+  0x24, 0xf7, 0xde, 0x9d, 0x97, 0x9b, 0xe6, 0x20, 0xd6, 0x3d, 0x48, 0x73, 0x29, 0x23, 0xf9, 0x0f,
+  0xab, 0x04, 0xe6, 0x1d, 0x70, 0xee, 0xcb, 0x5a, 0xe5, 0x8a, 0xf4, 0xbc, 0x4b, 0xad, 0x18, 0xec,
+  0x25, 0x8a, 0xb8, 0x91, 0xf9, 0x53, 0xf4, 0xe4, 0xce, 0xa7, 0x54, 0xf6, 0x83, 0x66, 0x07, 0xc5,
+  0x51, 0x48, 0x20, 0x54, 0x5b, 0x5d, 0xc1, 0x80, 0x04, 0x17, 0x89, 0x14, 0x5a, 0x06, 0x34, 0x86,
+  0xdb, 0x8b, 0xaf, 0x04, 0x24, 0xd9, 0xbd, 0xa8, 0x27, 0x09, 0x51, 0xfe, 0x6e, 0x47, 0x3c, 0x29,
+  0x0a, 0x64, 0x3e, 0x0f, 0x00, 0xf1, 0xd9, 0xdc, 0xe9, 0xd1, 0x3c, 0xcf, 0xa4, 0xa9, 0x4f, 0x54,
+  0x02, 0xcf, 0xa1, 0x40, 0x49, 0x61, 0x2a, 0x07, 0xa2, 0x44, 0x35, 0x20, 0x20, 0x56, 0x1c, 0x27,
+  0xa2, 0xff, 0x07, 0x3e, 0x8b, 0xfe, 0x60, 0x42, 0x75, 0x0c, 0xe3, 0x8f, 0xee, 0x33, 0x8d, 0xfc,
+  0x3b, 0x53, 0x36, 0x39, 0x10, 0x1a, 0xe3, 0xd2, 0x09, 0x7b, 0x00, 0xd0, 0xbd, 0x39, 0xf4, 0xcc,
+  0xe3, 0x42, 0xd4, 0xa5, 0x2d, 0x0b, 0x58, 0xdf, 0x24, 0x7f, 0x85, 0x0a, 0xf2, 0x17, 0x76, 0xdd,
+};
+
+//
+// dump of end_requester.key.der
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8  mTestEndCert[] = {
+  0x30, 0x82, 0x03, 0xeb, 0x30, 0x82, 0x02, 0x53, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x02,
+  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+  0x2b, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x20, 0x69, 0x6e, 0x74, 0x65,
+  0x6c, 0x20, 0x74, 0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x69, 0x6e, 0x74, 0x65, 0x72,
+  0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x1e, 0x17, 0x0d,
+  0x32, 0x32, 0x30, 0x31, 0x30, 0x35, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x17, 0x0d, 0x33,
+  0x32, 0x30, 0x31, 0x30, 0x33, 0x30, 0x36, 0x31, 0x31, 0x30, 0x36, 0x5a, 0x30, 0x28, 0x31, 0x26,
+  0x30, 0x24, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1d, 0x69, 0x6e, 0x74, 0x65, 0x6c, 0x20, 0x74,
+  0x65, 0x73, 0x74, 0x20, 0x52, 0x53, 0x41, 0x20, 0x72, 0x65, 0x71, 0x75, 0x73, 0x65, 0x74, 0x65,
+  0x72, 0x20, 0x63, 0x65, 0x72, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86,
+  0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82,
+  0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0x93, 0x47, 0xf3, 0x71, 0x6b, 0x24, 0x1e, 0xc0, 0xeb,
+  0x6b, 0x22, 0x23, 0xe7, 0xc8, 0x10, 0x9d, 0xb2, 0xef, 0x1e, 0x65, 0xe9, 0xff, 0xd6, 0x37, 0xee,
+  0xc5, 0x3f, 0x29, 0x25, 0x94, 0xb4, 0x30, 0x97, 0x51, 0xe3, 0x51, 0xa4, 0x39, 0xd1, 0x27, 0x32,
+  0x9e, 0x6b, 0x80, 0xc2, 0x29, 0xf2, 0x28, 0xd1, 0x49, 0xdc, 0x62, 0x27, 0x5b, 0x3f, 0xce, 0x83,
+  0xd7, 0x7b, 0x09, 0x37, 0x48, 0x16, 0x7f, 0x2e, 0x6e, 0xfa, 0x67, 0xaa, 0x92, 0x17, 0xcb, 0xff,
+  0x4b, 0xe3, 0x1b, 0xd1, 0xa6, 0xe3, 0x6c, 0x4d, 0x9f, 0x9e, 0xc7, 0x01, 0xed, 0x9f, 0x14, 0xb0,
+  0x34, 0x44, 0xa2, 0x88, 0x28, 0xf2, 0x3f, 0xad, 0xf2, 0xf7, 0x51, 0x8c, 0xfe, 0x43, 0x73, 0xfa,
+  0x8d, 0x2f, 0x63, 0x8c, 0x0e, 0xe5, 0x27, 0xdc, 0x12, 0x81, 0x26, 0xea, 0x92, 0x67, 0x7d, 0xc9,
+  0xfc, 0xec, 0x4c, 0xcc, 0x79, 0x4d, 0x2d, 0xfe, 0xf6, 0x63, 0xb7, 0x63, 0xca, 0x70, 0x24, 0xe0,
+  0x23, 0x53, 0x92, 0xe8, 0x56, 0xb7, 0x85, 0x6d, 0x25, 0x9e, 0xe0, 0x24, 0xa8, 0x5c, 0xe0, 0x0f,
+  0xc1, 0xb6, 0x20, 0x2f, 0x85, 0x2a, 0x67, 0xf6, 0x1b, 0x58, 0x60, 0x5a, 0x14, 0xda, 0xc2, 0x03,
+  0x10, 0x79, 0x33, 0x3c, 0x41, 0xc6, 0xbe, 0xd2, 0xee, 0x2f, 0x65, 0xd5, 0xad, 0x9c, 0xc6, 0x09,
+  0xae, 0x26, 0xf2, 0xac, 0xc2, 0x65, 0x12, 0x74, 0x09, 0xe8, 0x89, 0x66, 0xf6, 0x95, 0xb8, 0x6a,
+  0x5f, 0x96, 0xc2, 0x3c, 0x9f, 0x01, 0x52, 0xa8, 0xc8, 0x4e, 0xd8, 0xba, 0x95, 0x38, 0x5b, 0xf8,
+  0xc6, 0x43, 0x54, 0xac, 0x63, 0x90, 0xd4, 0xde, 0x11, 0x40, 0x27, 0xe5, 0x12, 0x1d, 0x72, 0xa2,
+  0xec, 0xad, 0x0a, 0x8b, 0x68, 0x21, 0x9d, 0xea, 0x16, 0x70, 0x5f, 0x32, 0x3a, 0xed, 0x4f, 0x0b,
+  0xb2, 0x44, 0x1f, 0x44, 0x9b, 0x4c, 0x03, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0x9c, 0x30,
+  0x81, 0x99, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00,
+  0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xe0, 0x30, 0x1d, 0x06,
+  0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x7c, 0x69, 0x5e, 0x84, 0xbb, 0xc7, 0x6b, 0xfc,
+  0x45, 0x70, 0xa4, 0x4b, 0x1e, 0x67, 0x70, 0x04, 0xa4, 0x37, 0xdd, 0x72, 0x30, 0x31, 0x06, 0x03,
+  0x55, 0x1d, 0x11, 0x04, 0x2a, 0x30, 0x28, 0xa0, 0x26, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01,
+  0x83, 0x1c, 0x82, 0x12, 0x01, 0xa0, 0x18, 0x0c, 0x16, 0x41, 0x43, 0x4d, 0x45, 0x3a, 0x57, 0x49,
+  0x44, 0x47, 0x45, 0x54, 0x3a, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x30,
+  0x2a, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x20, 0x30, 0x1e, 0x06, 0x08, 0x2b,
+  0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03,
+  0x02, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, 0x30, 0x0d, 0x06, 0x09, 0x2a,
+  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x81, 0x00, 0x8e,
+  0x19, 0x08, 0xec, 0x7a, 0xcc, 0x6d, 0x04, 0x5f, 0xb7, 0xf9, 0xd2, 0xcd, 0x76, 0xee, 0x44, 0x1b,
+  0x7c, 0x19, 0xcb, 0x18, 0xdd, 0x60, 0x50, 0x3a, 0x54, 0xb1, 0x75, 0x17, 0xf6, 0xce, 0x19, 0x15,
+  0x09, 0x9e, 0x5b, 0xfc, 0x5c, 0xb3, 0x20, 0x8d, 0xcb, 0x9d, 0xfc, 0x23, 0x12, 0x68, 0x87, 0x55,
+  0x0d, 0x3b, 0x5f, 0x9f, 0x4e, 0xb2, 0x17, 0x13, 0x0b, 0xc4, 0x6f, 0xbe, 0x43, 0x75, 0xa6, 0xb7,
+  0x3c, 0x0e, 0xe0, 0xdf, 0x84, 0xe5, 0x88, 0x46, 0x08, 0xc3, 0x36, 0x1b, 0x31, 0x02, 0x92, 0x7c,
+  0x53, 0xc4, 0x08, 0x63, 0x3e, 0x46, 0x75, 0xd7, 0x35, 0x9a, 0xd0, 0x76, 0x71, 0xf9, 0x57, 0x97,
+  0xc7, 0x3c, 0x3b, 0xce, 0x7a, 0x82, 0x95, 0x15, 0x8e, 0x20, 0xcc, 0x7b, 0xa0, 0xc4, 0x68, 0x21,
+  0x26, 0x9c, 0xfd, 0x29, 0x83, 0x41, 0x19, 0x98, 0xb6, 0x8a, 0x3a, 0x06, 0x5f, 0x01, 0x1b, 0x80,
+  0xac, 0x33, 0xd9, 0x0c, 0x9c, 0xea, 0x70, 0xd7, 0xf5, 0x1e, 0xb0, 0x78, 0x24, 0xbc, 0x59, 0xaf,
+  0x07, 0xc6, 0x16, 0x46, 0xdd, 0x9d, 0x00, 0x9a, 0xc8, 0x9a, 0x04, 0x19, 0x4d, 0x62, 0xa9, 0x4f,
+  0x7c, 0x05, 0x24, 0x93, 0xc6, 0x01, 0xc5, 0xb2, 0x89, 0xe8, 0x62, 0x47, 0xbe, 0xa3, 0xd1, 0x9c,
+  0x47, 0x31, 0x06, 0x16, 0x6b, 0x3b, 0xf8, 0xad, 0xb0, 0x4c, 0xfb, 0x2b, 0x6b, 0x8e, 0x88, 0x53,
+  0x70, 0x75, 0x40, 0x30, 0xaf, 0xfe, 0xc5, 0xf3, 0x0f, 0x86, 0x8f, 0x58, 0x56, 0x67, 0xbd, 0x15,
+  0x1f, 0x8a, 0x5c, 0xa3, 0x8a, 0x9a, 0x88, 0xe5, 0xf2, 0xd3, 0x7f, 0xac, 0x56, 0x34, 0x21, 0x24,
+  0xf7, 0xde, 0x9d, 0x97, 0x9b, 0xe6, 0x20, 0xd6, 0x3d, 0x48, 0x73, 0x29, 0x23, 0xf9, 0x0f, 0xab,
+  0x04, 0xe6, 0x1d, 0x70, 0xee, 0xcb, 0x5a, 0xe5, 0x8a, 0xf4, 0xbc, 0x4b, 0xad, 0x18, 0xec, 0x25,
+  0x8a, 0xb8, 0x91, 0xf9, 0x53, 0xf4, 0xe4, 0xce, 0xa7, 0x54, 0xf6, 0x83, 0x66, 0x07, 0xc5, 0x51,
+  0x48, 0x20, 0x54, 0x5b, 0x5d, 0xc1, 0x80, 0x04, 0x17, 0x89, 0x14, 0x5a, 0x06, 0x34, 0x86, 0xdb,
+  0x8b, 0xaf, 0x04, 0x24, 0xd9, 0xbd, 0xa8, 0x27, 0x09, 0x51, 0xfe, 0x6e, 0x47, 0x3c, 0x29, 0x0a,
+  0x64, 0x3e, 0x0f, 0x00, 0xf1, 0xd9, 0xdc, 0xe9, 0xd1, 0x3c, 0xcf, 0xa4, 0xa9, 0x4f, 0x54, 0x02,
+  0xcf, 0xa1, 0x40, 0x49, 0x61, 0x2a, 0x07, 0xa2, 0x44, 0x35, 0x20, 0x20, 0x56, 0x1c, 0x27, 0xa2,
+  0xff, 0x07, 0x3e, 0x8b, 0xfe, 0x60, 0x42, 0x75, 0x0c, 0xe3, 0x8f, 0xee, 0x33, 0x8d, 0xfc, 0x3b,
+  0x53, 0x36, 0x39, 0x10, 0x1a, 0xe3, 0xd2, 0x09, 0x7b, 0x00, 0xd0, 0xbd, 0x39, 0xf4, 0xcc, 0xe3,
+  0x42, 0xd4, 0xa5, 0x2d, 0x0b, 0x58, 0xdf, 0x24, 0x7f, 0x85, 0x0a, 0xf2, 0x17, 0x76, 0xdd,
+};
+
+UNIT_TEST_STATUS
+EFIAPI
+TestVerifyX509 (
+  IN UNIT_TEST_CONTEXT  Context
+  )
+{
+  BOOLEAN      Status;
+  CONST UINT8  *LeafCert;
+  UINTN        LeafCertLen;
+  UINTN        CertVersion;
+  UINT8        Asn1Buffer[1024];
+  UINTN        Asn1BufferLen;
+  UINTN        SubjectSize;
+  UINT8        *Subject;
+  UINT8        EndEertFrom[64];
+  UINTN        EndEertFromLen;
+  UINT8        EndEertTo[64];
+  UINTN        EndEertToLen;
+  UINT8        DateTime1[64];
+  UINT8        DateTime2[64];
+
+  //
+  // X509 Certificate Verification.
+  //
+  Status = X509VerifyCert (mTestCert, sizeof (mTestCert), mTestCaCert, sizeof (mTestCaCert));
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // X509 Certificate Chain Verification.
+  //
+  Status = X509VerifyCertChain (mTestCaCert, sizeof (mTestCaCert), mTestBundleCert, sizeof (mTestBundleCert));
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // X509 Get leaf certificate from cert_chain Verificate.
+  //
+  Status = X509GetCertFromCertChain (mTestBundleCert, sizeof (mTestBundleCert), -1, &LeafCert, &LeafCertLen);
+  UT_ASSERT_TRUE (Status);
+
+  UT_ASSERT_EQUAL (LeafCertLen, sizeof (mTestEndCert));
+  UT_ASSERT_MEM_EQUAL (LeafCert, mTestEndCert, LeafCertLen);
+
+  //
+  // X509 Get leaf certificate from cert_chain Verificate.
+  //
+  Status = X509GetCertFromCertChain (mTestBundleCert, sizeof (mTestBundleCert), 2, &LeafCert, &LeafCertLen);
+  UT_ASSERT_TRUE (Status);
+
+  UT_ASSERT_EQUAL (LeafCertLen, sizeof (mTestEndCert));
+  UT_ASSERT_MEM_EQUAL (LeafCert, mTestEndCert, LeafCertLen);
+
+  //
+  // X509 Get root certificate from cert_chain Verificate.
+  //
+  Status = X509GetCertFromCertChain (mTestBundleCert, sizeof (mTestBundleCert), 0, &LeafCert, &LeafCertLen);
+  UT_ASSERT_TRUE (Status);
+
+  UT_ASSERT_EQUAL (LeafCertLen, sizeof (mTestCaCert));
+  UT_ASSERT_MEM_EQUAL (LeafCert, mTestCaCert, LeafCertLen);
+
+  //
+  // Get version from X509 Certificate.
+  //
+  CertVersion = 0;
+  Status      = X509GetVersion (mTestCert, sizeof (mTestCert), &CertVersion);
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // Get Serial from X509 Certificate.
+  //
+  Asn1BufferLen = 1024;
+  ZeroMem (Asn1Buffer, Asn1BufferLen);
+  Status = X509GetSerialNumber (mTestCert, sizeof (mTestCert), Asn1Buffer, &Asn1BufferLen);
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // X509 Certificate subject Retrieving.
+  //
+  SubjectSize = 0;
+  Status      = X509GetIssuerName (mTestCert, sizeof (mTestCert), NULL, &SubjectSize);
+  UT_ASSERT_TRUE (!Status);
+  Subject = AllocatePool (SubjectSize);
+  Status  = X509GetIssuerName (mTestCert, sizeof (mTestCert), Subject, &SubjectSize);
+  UT_ASSERT_TRUE (Status);
+  FreePool (Subject);
+
+  //
+  // Get X509GetSubjectAltName.
+  //
+  Asn1BufferLen = 1024;
+  ZeroMem (Asn1Buffer, Asn1BufferLen);
+  Status = X509GetExtensionData (mTestEndCert, sizeof (mTestEndCert), mOidSubjectAltName, sizeof (mOidSubjectAltName), Asn1Buffer, &Asn1BufferLen);
+  UT_ASSERT_TRUE (Status);
+
+  //
+  // Get X509 Validity.
+  //
+  EndEertFromLen = 64;
+  EndEertToLen   = 64;
+  Status         = X509GetValidity (
+                     mTestEndCert,
+                     sizeof (mTestEndCert),
+                     EndEertFrom,
+                     &EndEertFromLen,
+                     EndEertTo,
+                     &EndEertToLen
+                     );
+  UT_ASSERT_TRUE (Status);
+
+  Asn1BufferLen = 64;
+  Status        = X509FormatDateTime (
+                    "19700101000000Z",
+                    DateTime1,
+                    &Asn1BufferLen
+                    );
+  UT_ASSERT_TRUE (Status && (Asn1BufferLen != 0));
+
+  Asn1BufferLen = 64;
+  Status        = X509FormatDateTime (
+                    "19700201000000Z",
+                    DateTime2,
+                    &Asn1BufferLen
+                    );
+  UT_ASSERT_TRUE (Status && (Asn1BufferLen != 0));
+
+  UT_ASSERT_TRUE (X509CompareDateTime (DateTime1, DateTime2) < 0);
+
+  return UNIT_TEST_PASSED;
+}
+
+TEST_DESC  mX509Test[] = {
+  //
+  // -----Description--------------------------------------Class----------------------Function---------------------------------Pre---------------------Post---------Context
+  //
+  { "TestVerifyX509()", "CryptoPkg.BaseCryptLib.Hkdf", TestVerifyX509, NULL, NULL, NULL },
+};
+
+UINTN  mX509TestNum = ARRAY_SIZE (mX509Test);
-- 
2.26.2.windows.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH V3 0/4] CryptoPkg: add more X509 functions.
  2022-10-12  4:35 [PATCH V3 0/4] CryptoPkg: add more X509 functions Qi Zhang
                   ` (3 preceding siblings ...)
  2022-10-12  4:36 ` [PATCH V3 4/4] CryptoPkg: add Unit Test for X509 new function Qi Zhang
@ 2022-10-12  6:43 ` Yao, Jiewen
  4 siblings, 0 replies; 6+ messages in thread
From: Yao, Jiewen @ 2022-10-12  6:43 UTC (permalink / raw)
  To: Zhang, Qi1, devel@edk2.groups.io; +Cc: Wang, Jian J, Lu, Xiaoyu1, Jiang, Guomin

Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com>

Merged https://github.com/tianocore/edk2/pull/3470

> -----Original Message-----
> From: Zhang, Qi1 <qi1.zhang@intel.com>
> Sent: Wednesday, October 12, 2022 12:36 PM
> To: devel@edk2.groups.io
> Cc: Zhang, Qi1 <qi1.zhang@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>; Wang, Jian J <jian.j.wang@intel.com>; Lu, Xiaoyu1
> <xiaoyu1.lu@intel.com>; Jiang, Guomin <guomin.jiang@intel.com>
> Subject: [PATCH V3 0/4] CryptoPkg: add more X509 functions.
> 
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4082
> 
> This patch serial is to add more CryptoX509 functions.
> 
> Tested by:
> 1. https://github.com/tianocore/edk2-staging/tree/DeviceSecurity.
> 2. Unit test: CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c
> 
> Review PR: https://github.com/tianocore/edk2/pull/3464.
> 
> V2 change: rename X509SetDateTime() to X509FormatDateTime().
> V3 change: rebase this patch serial with the patch serial
>            "CryptoPkg: Add EC key retrieving and signature interface."
>            So the merge order is Ec -> X509.
> 
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Xiaoyu Lu <xiaoyu1.lu@intel.com>
> Cc: Guomin Jiang <guomin.jiang@intel.com>
> Signed-off-by: Qi Zhang <qi1.zhang@intel.com>
> 
> Qi Zhang (4):
>   CryptoPkg: add new X509 function definition.
>   CryptoPkg: add new X509 function.
>   CryptoPkg: add new X509 function to Crypto Service.
>   CryptoPkg: add Unit Test for X509 new function.
> 
>  CryptoPkg/Driver/Crypto.c                     |  432 ++++++-
>  CryptoPkg/Include/Library/BaseCryptLib.h      |  374 ++++++
>  .../Pcd/PcdCryptoServiceFamilyEnable.h        |   34 +-
>  CryptoPkg/Library/BaseCryptLib/Pk/CryptX509.c | 1036
> +++++++++++++++++
>  .../Library/BaseCryptLib/Pk/CryptX509Null.c   |  429 +++++++
>  .../BaseCryptLibNull/Pk/CryptX509Null.c       |  429 +++++++
>  .../BaseCryptLibOnProtocolPpi/CryptLib.c      |  415 +++++++
>  CryptoPkg/Private/Protocol/Crypto.h           |  392 ++++++-
>  .../BaseCryptLib/BaseCryptLibUnitTests.c      |    1 +
>  .../Library/BaseCryptLib/TestBaseCryptLib.h   |    4 +
>  .../BaseCryptLib/TestBaseCryptLibHost.inf     |    1 +
>  .../BaseCryptLib/TestBaseCryptLibShell.inf    |    1 +
>  .../UnitTest/Library/BaseCryptLib/X509Tests.c |  631 ++++++++++
>  13 files changed, 4167 insertions(+), 12 deletions(-)
>  create mode 100644
> CryptoPkg/Test/UnitTest/Library/BaseCryptLib/X509Tests.c
> 
> --
> 2.26.2.windows.1


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-10-12  6:43 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-12  4:35 [PATCH V3 0/4] CryptoPkg: add more X509 functions Qi Zhang
2022-10-12  4:35 ` [PATCH V3 1/4] CryptoPkg: add new X509 function definition Qi Zhang
2022-10-12  4:35 ` [PATCH V3 2/4] CryptoPkg: add new X509 function Qi Zhang
2022-10-12  4:36 ` [PATCH V3 3/4] CryptoPkg: add new X509 function to Crypto Service Qi Zhang
2022-10-12  4:36 ` [PATCH V3 4/4] CryptoPkg: add Unit Test for X509 new function Qi Zhang
2022-10-12  6:43 ` [PATCH V3 0/4] CryptoPkg: add more X509 functions Yao, Jiewen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox