From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail05.groups.io (mail05.groups.io [45.79.224.7]) by spool.mail.gandi.net (Postfix) with ESMTPS id 02B329410E7 for ; Thu, 9 May 2024 06:27:10 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=8wKkTVbog1AVXLhY1lzrwficp0MBxyirGBFI19uiygE=; c=relaxed/simple; d=groups.io; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References:MIME-Version:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Resent-Date:Resent-From:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Transfer-Encoding; s=20240206; t=1715236029; v=1; b=ix9COsqxx2nQX1PFcJBXBdUNjsQ054eGLXFv8VNh3TC+EMc7JpR9ZQHBR/yhFZTTGCyy9DpU hDUZc6zd1OjfS/4gRM/HmZtj8cMwki5zqU851gqsOuBVKR5RasJKYWwWCDjImtlmMkRHofmoB0A 8G8KUl2uBYkS9CRU7iXv5b2xBarTF57I+bOEnwSUWmPsGg6r55CgakKM91rUMtLfAKfqW3kIj8I Cw4kWPepcu3ayrxmPfLfBa4TSv2ek2MLAt6txFbwhk9cuH/BuOyY8YTEv9WxGILz5JtrFxweGbD pZNIp/Tf7xTwJg0gTuXQhoeg13SUgBezSW5WdEhYhjyPg== X-Received: by 127.0.0.2 with SMTP id hTWWYY7687511xMPWFcmvQZy; Wed, 08 May 2024 23:27:09 -0700 X-Received: from mgamail.intel.com (mgamail.intel.com [192.198.163.12]) by mx.groups.io with SMTP id smtpd.web10.3998.1715236024155799791 for ; Wed, 08 May 2024 23:27:09 -0700 X-CSE-ConnectionGUID: JrI2KW4ISGu+1tHNRuZRzQ== X-CSE-MsgGUID: PQFfsmqpTLa4b4tdkJRV4w== X-IronPort-AV: E=McAfee;i="6600,9927,11067"; a="14946403" X-IronPort-AV: E=Sophos;i="6.08,147,1712646000"; d="scan'208";a="14946403" X-Received: from fmviesa001.fm.intel.com ([10.60.135.141]) by fmvoesa106.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 08 May 2024 23:27:09 -0700 X-CSE-ConnectionGUID: 1Iikb+MhSl67N3U7PLmNkw== X-CSE-MsgGUID: bF5tbnkXR5GtNTPQtHdHGA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,147,1712646000"; d="scan'208";a="60305905" X-Received: from shwdejointd777.ccr.corp.intel.com ([10.239.58.116]) by fmviesa001.fm.intel.com with ESMTP; 08 May 2024 23:27:07 -0700 From: "Wenxing Hou" To: devel@edk2.groups.io Cc: Jiewen Yao , Yi Li Subject: [edk2-devel] [PATCH v3 04/11] CryptoPkg: Add X509 functions based on Mbedtls Date: Thu, 9 May 2024 14:26:53 +0800 Message-Id: <20240509062700.2062-5-wenxing.hou@intel.com> In-Reply-To: <20240509062700.2062-1-wenxing.hou@intel.com> References: <20240509062700.2062-1-wenxing.hou@intel.com> MIME-Version: 1.0 Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Resent-Date: Wed, 08 May 2024 23:27:09 -0700 Resent-From: wenxing.hou@intel.com Reply-To: devel@edk2.groups.io,wenxing.hou@intel.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: X-Gm-Message-State: nep1M0A4tVzN0C2ikMB4CO3Wx7686176AA= Content-Transfer-Encoding: quoted-printable X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20240206 header.b=ix9COsqx; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=intel.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 45.79.224.7 as permitted sender) smtp.mailfrom=bounce@groups.io REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D4177 X.509 Certificate Handler Wrapper Implementation over MbedTLS. Cc: Jiewen Yao Cc: Yi Li Signed-off-by: Wenxing Hou --- .../BaseCryptLibMbedTls/Pk/CryptX509.c | 1940 +++++++++++++++++ 1 file changed, 1940 insertions(+) create mode 100644 CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c diff --git a/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c b/CryptoP= kg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c new file mode 100644 index 0000000000..84b67c8f0a --- /dev/null +++ b/CryptoPkg/Library/BaseCryptLibMbedTls/Pk/CryptX509.c @@ -0,0 +1,1940 @@ +/** @file=0D + X.509 Certificate Handler Wrapper Implementation over MbedTLS.=0D +=0D +Copyright (c) 2024, Intel Corporation. All rights reserved.
=0D +SPDX-License-Identifier: BSD-2-Clause-Patent=0D +=0D +**/=0D +=0D +#include "InternalCryptLib.h"=0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +#include =0D +=0D +///=0D +/// OID=0D +///=0D +STATIC CONST UINT8 OID_commonName[] =3D {=0D + 0x55, 0x04, 0x03=0D +};=0D +STATIC CONST UINT8 OID_organizationName[] =3D {=0D + 0x55, 0x04, 0x0A=0D +};=0D +STATIC CONST UINT8 OID_extKeyUsage[] =3D {=0D + 0x55, 0x1D, 0x25=0D +};=0D +STATIC CONST UINT8 OID_BasicConstraints[] =3D {=0D + 0x55, 0x1D, 0x13=0D +};=0D +=0D +/* Profile for backward compatibility. Allows RSA 1024, unlike the default= =0D + profile. */=0D +STATIC mbedtls_x509_crt_profile gCompatProfile =3D=0D +{=0D + /* Hashes from SHA-256 and above. Note that this selection=0D + * should be aligned with ssl_preset_default_hashes in ssl_tls.c. */=0D + MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA256) |=0D + MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA384) |=0D + MBEDTLS_X509_ID_FLAG (MBEDTLS_MD_SHA512),=0D + 0xFFFFFFF, /* Any PK alg */=0D +=0D + /* Curves at or above 128-bit security level. Note that this selection=0D + * should be aligned with ssl_preset_default_curves in ssl_tls.c. */=0D + MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_SECP256R1) |=0D + MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_SECP384R1) |=0D + MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_SECP521R1) |=0D + MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_BP256R1) |=0D + MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_BP384R1) |=0D + MBEDTLS_X509_ID_FLAG (MBEDTLS_ECP_DP_BP512R1) |=0D + 0,=0D + 1024,=0D +};=0D +=0D +/**=0D + Construct a X509 object from DER-encoded certificate data.=0D +=0D + If Cert is NULL, then return FALSE.=0D + If SingleX509Cert is NULL, then return FALSE.=0D +=0D + @param[in] Cert Pointer to the DER-encoded certificate data.= =0D + @param[in] CertSize The size of certificate data in bytes.=0D + @param[out] SingleX509Cert The generated X509 object.=0D +=0D + @retval TRUE The X509 object generation succeeded.=0D + @retval FALSE The operation failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509ConstructCertificate (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT UINT8 **SingleX509Cert=0D + )=0D +{=0D + mbedtls_x509_crt *MbedTlsCert;=0D + INT32 Ret;=0D +=0D + if ((Cert =3D=3D NULL) || (SingleX509Cert =3D=3D NULL) || (CertSize =3D= =3D 0)) {=0D + return FALSE;=0D + }=0D +=0D + MbedTlsCert =3D AllocateZeroPool (sizeof (mbedtls_x509_crt));=0D + if (MbedTlsCert =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_x509_crt_init (MbedTlsCert);=0D +=0D + *SingleX509Cert =3D (UINT8 *)(VOID *)MbedTlsCert;=0D + Ret =3D mbedtls_x509_crt_parse_der (MbedTlsCert, Cert, CertS= ize);=0D + if (Ret =3D=3D 0) {=0D + return TRUE;=0D + } else {=0D + mbedtls_x509_crt_free (MbedTlsCert);=0D + FreePool (MbedTlsCert);=0D + return FALSE;=0D + }=0D +}=0D +=0D +/**=0D + Construct a X509 stack object from a list of DER-encoded certificate dat= a.=0D +=0D + If X509Stack is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in, out] X509Stack On input, pointer to an existing or NULL X50= 9 stack object.=0D + On output, pointer to the X509 stack object = with new=0D + inserted X509 certificate.=0D + @param[in] Args VA_LIST marker for the variable argument lis= t.=0D + A list of DER-encoded single certificate dat= a followed=0D + by certificate size. A NULL terminates the l= ist. The=0D + pairs are the arguments to X509ConstructCert= ificate().=0D +=0D + @retval TRUE The X509 stack construction succeeded.=0D + @retval FALSE The construction operation failed.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509ConstructCertificateStackV (=0D + IN OUT UINT8 **X509Stack,=0D + IN VA_LIST Args=0D + )=0D +{=0D + UINT8 *Cert;=0D + UINTN CertSize;=0D + INT32 Index;=0D + INT32 Ret;=0D + mbedtls_x509_crt *Crt;=0D +=0D + if (X509Stack =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + Ret =3D 0;=0D + Crt =3D NULL;=0D + if (*X509Stack =3D=3D NULL) {=0D + Crt =3D AllocateZeroPool (sizeof (mbedtls_x509_crt));=0D + if (Crt =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_x509_crt_init (Crt);=0D + *X509Stack =3D (UINT8 *)Crt;=0D + }=0D +=0D + for (Index =3D 0; ; Index++) {=0D + //=0D + // If Cert is NULL, then it is the end of the list.=0D + //=0D + Cert =3D VA_ARG (Args, UINT8 *);=0D + if (Cert =3D=3D NULL) {=0D + break;=0D + }=0D +=0D + CertSize =3D VA_ARG (Args, UINTN);=0D + if (CertSize =3D=3D 0) {=0D + break;=0D + }=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der ((mbedtls_x509_crt *)*X509Stack, Ce= rt, CertSize);=0D +=0D + if (Ret !=3D 0) {=0D + break;=0D + }=0D + }=0D +=0D + if (Ret =3D=3D 0) {=0D + return TRUE;=0D + } else {=0D + if (Crt !=3D NULL) {=0D + mbedtls_x509_crt_free (Crt);=0D + FreePool (Crt);=0D + *X509Stack =3D NULL;=0D + }=0D +=0D + return FALSE;=0D + }=0D +}=0D +=0D +/**=0D + Construct a X509 stack object from a list of DER-encoded certificate dat= a.=0D +=0D + If X509Stack is NULL, then return FALSE.=0D +=0D + @param[in, out] X509Stack On input, pointer to an existing or NULL X50= 9 stack object.=0D + On output, pointer to the X509 stack object = with new=0D + inserted X509 certificate.=0D + @param ... A list of DER-encoded single certificate dat= a followed=0D + by certificate size. A NULL terminates the l= ist. The=0D + pairs are the arguments to X509ConstructCert= ificate().=0D +=0D + @retval TRUE The X509 stack construction succeeded.=0D + @retval FALSE The construction operation failed.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509ConstructCertificateStack (=0D + IN OUT UINT8 **X509Stack,=0D + ...=0D + )=0D +{=0D + VA_LIST Args;=0D + BOOLEAN Result;=0D +=0D + VA_START (Args, X509Stack);=0D + Result =3D X509ConstructCertificateStackV (X509Stack, Args);=0D + VA_END (Args);=0D + return Result;=0D +}=0D +=0D +/**=0D + Release the specified X509 object.=0D +=0D + If X509Cert is NULL, then return FALSE.=0D +=0D + @param[in] X509Cert Pointer to the X509 object to be released.=0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +X509Free (=0D + IN VOID *X509Cert=0D + )=0D +{=0D + if (X509Cert !=3D NULL) {=0D + mbedtls_x509_crt_free (X509Cert);=0D + FreePool (X509Cert);=0D + }=0D +}=0D +=0D +/**=0D + Release the specified X509 stack object.=0D +=0D + If X509Stack is NULL, then return FALSE.=0D +=0D + @param[in] X509Stack Pointer to the X509 stack object to be released.= =0D +=0D +**/=0D +VOID=0D +EFIAPI=0D +X509StackFree (=0D + IN VOID *X509Stack=0D + )=0D +{=0D + if (X509Stack =3D=3D NULL) {=0D + return;=0D + }=0D +=0D + mbedtls_x509_crt_free (X509Stack);=0D +}=0D +=0D +/**=0D + Retrieve the tag and length of the tag.=0D +=0D + @param Ptr The position in the ASN.1 data=0D + @param End End of data=0D + @param Length The variable that will receive the length=0D + @param Tag The expected tag=0D +=0D + @retval TRUE Get tag successful=0D + @retval FALSe Failed to get tag or tag not match=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +Asn1GetTag (=0D + IN OUT UINT8 **Ptr,=0D + IN CONST UINT8 *End,=0D + OUT UINTN *Length,=0D + IN UINT32 Tag=0D + )=0D +{=0D + if (mbedtls_asn1_get_tag (Ptr, End, Length, (INT32)Tag) =3D=3D 0) {=0D + return TRUE;=0D + } else {=0D + return FALSE;=0D + }=0D +}=0D +=0D +/**=0D + Retrieve the subject bytes from one X.509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certificate= .=0D + @param[in] CertSize Size of the X509 certificate in bytes.=0D + @param[out] CertSubject Pointer to the retrieved certificate subjec= t bytes.=0D + @param[in, out] SubjectSize The size in bytes of the CertSubject buffer= on input,=0D + and the size of buffer returned CertSubject= on output.=0D +=0D + If Cert is NULL, then return FALSE.=0D + If SubjectSize is NULL, then return FALSE.=0D +=0D + @retval TRUE The certificate subject retrieved successfully.=0D + @retval FALSE Invalid certificate, or the SubjectSize is too small for= the result.=0D + The SubjectSize will be updated with the required size.= =0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetSubjectName (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT UINT8 *CertSubject,=0D + IN OUT UINTN *SubjectSize=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D +=0D + if (Cert =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + if (CertSubject !=3D NULL) {=0D + CopyMem (CertSubject, Crt.subject_raw.p, Crt.subject_raw.len);=0D + }=0D +=0D + *SubjectSize =3D Crt.subject_raw.len;=0D + }=0D +=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return Ret =3D=3D 0;=0D +}=0D +=0D +/**=0D + Retrieve a string from one X.509 certificate base on the Request_NID.=0D +=0D + @param[in] Name mbedtls_x509_name=0D + @param[in] Oid Oid=0D + @param[in] OidSize Size of Oid=0D + @param[in,out] CommonName Buffer to contain the retrieved certifi= cate common=0D + name string (UTF8). At most CommonNameS= ize bytes will be=0D + written and the string will be null ter= minated. May be=0D + NULL in order to determine the size buf= fer needed.=0D + @param[in,out] CommonNameSize The size in bytes of the CommonName buf= fer on input,=0D + and the size of buffer returned CommonN= ame on output.=0D + If CommonName is NULL then the amount o= f space needed=0D + in buffer (including the final null) is= returned.=0D +=0D + @retval RETURN_SUCCESS The certificate CommonName retrieved su= ccessfully.=0D + @retval RETURN_INVALID_PARAMETER If Cert is NULL.=0D + If CommonNameSize is NULL.=0D + If CommonName is not NULL and *CommonNa= meSize is 0.=0D + If Certificate is invalid.=0D + @retval RETURN_NOT_FOUND If no NID Name entry exists.=0D + @retval RETURN_BUFFER_TOO_SMALL If the CommonName is NULL. The required= buffer size=0D + (including the final null) is returned = in the=0D + CommonNameSize parameter.=0D + @retval RETURN_UNSUPPORTED The operation is not supported.=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +InternalX509GetNIDName (=0D + IN mbedtls_x509_name *Name,=0D + IN CHAR8 *Oid,=0D + IN UINTN OidSize,=0D + IN OUT CHAR8 *CommonName OPTIONAL,=0D + IN OUT UINTN *CommonNameSize=0D + )=0D +{=0D + CONST mbedtls_asn1_named_data *data;=0D +=0D + data =3D mbedtls_asn1_find_named_data (Name, Oid, OidSize);=0D + if (data !=3D NULL) {=0D + if (*CommonNameSize <=3D data->val.len) {=0D + *CommonNameSize =3D data->val.len + 1;=0D + return RETURN_BUFFER_TOO_SMALL;=0D + }=0D +=0D + if (CommonName !=3D NULL) {=0D + CopyMem (CommonName, data->val.p, data->val.len);=0D + CommonName[data->val.len] =3D '\0';=0D + }=0D +=0D + *CommonNameSize =3D data->val.len + 1;=0D + return RETURN_SUCCESS;=0D + } else {=0D + return RETURN_NOT_FOUND;=0D + }=0D +}=0D +=0D +/**=0D + Get X509 SubjectNIDName by OID.=0D +=0D + @param[in] Cert certificate=0D + @param[in] CertSize certificate size.=0D + @param[in] Oid Oid=0D + @param[in] OidSize Size of Oid=0D + @param[in,out] CommonName Buffer to contain the retrieved certifi= cate common=0D + name string (UTF8). At most CommonNameS= ize bytes will be=0D + written and the string will be null ter= minated. May be=0D + NULL in order to determine the size buf= fer needed.=0D + @param[in,out] CommonNameSize The size in bytes of the CommonName buf= fer on input,=0D + and the size of buffer returned CommonN= ame on output.=0D + If CommonName is NULL then the amount o= f space needed=0D + in buffer (including the final null) is= returned.=0D +=0D + @retval RETURN_SUCCESS The certificate CommonName retrieved su= ccessfully.=0D + @retval RETURN_INVALID_PARAMETER If Cert is NULL.=0D + If CommonNameSize is NULL.=0D + If CommonName is not NULL and *CommonNa= meSize is 0.=0D + If Certificate is invalid.=0D + @retval RETURN_NOT_FOUND If no NID Name entry exists.=0D + @retval RETURN_BUFFER_TOO_SMALL If the CommonName is NULL. The required= buffer size=0D + (including the final null) is returned = in the=0D + CommonNameSize parameter.=0D + @retval RETURN_UNSUPPORTED The operation is not supported.=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +InternalX509GetSubjectNIDName (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + IN CHAR8 *Oid,=0D + IN UINTN OidSize,=0D + IN OUT CHAR8 *CommonName OPTIONAL,=0D + IN OUT UINTN *CommonNameSize=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D + mbedtls_x509_name *Name;=0D + RETURN_STATUS ReturnStatus;=0D +=0D + if (Cert =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + ReturnStatus =3D RETURN_INVALID_PARAMETER;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + Name =3D &(Crt.subject);=0D + ReturnStatus =3D InternalX509GetNIDName (Name, Oid, OidSize, CommonNam= e, CommonNameSize);=0D + }=0D +=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return ReturnStatus;=0D +}=0D +=0D +/**=0D + Get X509 IssuerNIDName by OID.=0D +=0D + @param[in] Cert certificate=0D + @param[in] CertSize certificate size.=0D + @param[in] Oid Oid=0D + @param[in] OidSize Size of Oid=0D + @param[out] CommonName Buffer to contain the retrieved certifi= cate common=0D + name string (UTF8). At most CommonNameS= ize bytes will be=0D + written and the string will be null ter= minated. May be=0D + NULL in order to determine the size buf= fer needed.=0D + @param[in,out] CommonNameSize The size in bytes of the CommonName buf= fer on input,=0D + and the size of buffer returned CommonN= ame on output.=0D + If CommonName is NULL then the amount o= f space needed=0D + in buffer (including the final null) is= returned.=0D +=0D + @retval RETURN_SUCCESS The certificate CommonName retrieved su= ccessfully.=0D + @retval RETURN_INVALID_PARAMETER If Cert is NULL.=0D + If CommonNameSize is NULL.=0D + If CommonName is not NULL and *CommonNa= meSize is 0.=0D + If Certificate is invalid.=0D + @retval RETURN_NOT_FOUND If no NID Name entry exists.=0D + @retval RETURN_BUFFER_TOO_SMALL If the CommonName is NULL. The required= buffer size=0D + (including the final null) is returned = in the=0D + CommonNameSize parameter.=0D + @retval RETURN_UNSUPPORTED The operation is not supported.=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +InternalX509GetIssuerNIDName (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + IN CHAR8 *Oid,=0D + IN UINTN OidSize,=0D + OUT CHAR8 *CommonName OPTIONAL,=0D + IN OUT UINTN *CommonNameSize=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D + mbedtls_x509_name *Name;=0D + RETURN_STATUS ReturnStatus;=0D +=0D + if (Cert =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + ReturnStatus =3D RETURN_INVALID_PARAMETER;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + Name =3D &(Crt.issuer);=0D + ReturnStatus =3D InternalX509GetNIDName (Name, Oid, OidSize, CommonNam= e, CommonNameSize);=0D + }=0D +=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return ReturnStatus;=0D +}=0D +=0D +/**=0D + Retrieve the common name (CN) string from one X.509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certifi= cate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.= =0D + @param[out] CommonName Buffer to contain the retrieved certifi= cate common=0D + name string. At most CommonNameSize byt= es will be=0D + written and the string will be null ter= minated. May be=0D + NULL in order to determine the size buf= fer needed.=0D + @param[in,out] CommonNameSize The size in bytes of the CommonName buf= fer on input,=0D + and the size of buffer returned CommonN= ame on output.=0D + If CommonName is NULL then the amount o= f space needed=0D + in buffer (including the final null) is= returned.=0D +=0D + @retval RETURN_SUCCESS The certificate CommonName retrieved su= ccessfully.=0D + @retval RETURN_INVALID_PARAMETER If Cert is NULL.=0D + If CommonNameSize is NULL.=0D + If CommonName is not NULL and *CommonNa= meSize is 0.=0D + If Certificate is invalid.=0D + @retval RETURN_NOT_FOUND If no CommonName entry exists.=0D + @retval RETURN_BUFFER_TOO_SMALL If the CommonName is NULL. The required= buffer size=0D + (including the final null) is returned = in the=0D + CommonNameSize parameter.=0D + @retval RETURN_UNSUPPORTED The operation is not supported.=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +X509GetCommonName (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT CHAR8 *CommonName OPTIONAL,=0D + IN OUT UINTN *CommonNameSize=0D + )=0D +{=0D + return InternalX509GetSubjectNIDName (Cert, CertSize, (CHAR8 *)OID_commo= nName, sizeof (OID_commonName), CommonName, CommonNameSize);=0D +}=0D +=0D +/**=0D + Retrieve the organization name (O) string from one X.509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certifi= cate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.= =0D + @param[out] NameBuffer Buffer to contain the retrieved certifi= cate organization=0D + name string. At most NameBufferSize byt= es will be=0D + written and the string will be null ter= minated. May be=0D + NULL in order to determine the size buf= fer needed.=0D + @param[in,out] NameBufferSize The size in bytes of the Name buffer on= input,=0D + and the size of buffer returned Name on= output.=0D + If NameBuffer is NULL then the amount o= f space needed=0D + in buffer (including the final null) is= returned.=0D +=0D + @retval RETURN_SUCCESS The certificate Organization Name retri= eved successfully.=0D + @retval RETURN_INVALID_PARAMETER If Cert is NULL.=0D + If NameBufferSize is NULL.=0D + If NameBuffer is not NULL and *CommonNa= meSize is 0.=0D + If Certificate is invalid.=0D + @retval RETURN_NOT_FOUND If no Organization Name entry exists.=0D + @retval RETURN_BUFFER_TOO_SMALL If the NameBuffer is NULL. The required= buffer size=0D + (including the final null) is returned = in the=0D + CommonNameSize parameter.=0D + @retval RETURN_UNSUPPORTED The operation is not supported.=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +X509GetOrganizationName (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT CHAR8 *NameBuffer OPTIONAL,=0D + IN OUT UINTN *NameBufferSize=0D + )=0D +{=0D + return InternalX509GetSubjectNIDName (Cert, CertSize, (CHAR8 *)OID_organ= izationName, sizeof (OID_organizationName), NameBuffer, NameBufferSize);=0D +}=0D +=0D +/**=0D + Retrieve the RSA Public Key from one DER-encoded X509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certificate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.=0D + @param[out] RsaContext Pointer to new-generated RSA context which cont= ain the retrieved=0D + RSA public key component. Use RsaFree() functio= n to free the=0D + resource.=0D +=0D + If Cert is NULL, then return FALSE.=0D + If RsaContext is NULL, then return FALSE.=0D +=0D + @retval TRUE RSA Public Key was retrieved successfully.=0D + @retval FALSE Fail to retrieve RSA public key from X509 certificate.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +RsaGetPublicKeyFromX509 (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT VOID **RsaContext=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + mbedtls_rsa_context *Rsa;=0D + INT32 Ret;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + if (mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize) !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + if (mbedtls_pk_get_type (&Crt.pk) !=3D MBEDTLS_PK_RSA) {=0D + mbedtls_x509_crt_free (&Crt);=0D + return FALSE;=0D + }=0D +=0D + Rsa =3D RsaNew ();=0D + if (Rsa =3D=3D NULL) {=0D + mbedtls_x509_crt_free (&Crt);=0D + return FALSE;=0D + }=0D +=0D + Ret =3D mbedtls_rsa_copy (Rsa, mbedtls_pk_rsa (Crt.pk));=0D + if (Ret !=3D 0) {=0D + RsaFree (Rsa);=0D + mbedtls_x509_crt_free (&Crt);=0D + return FALSE;=0D + }=0D +=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + *RsaContext =3D Rsa;=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Retrieve the EC Public Key from one DER-encoded X509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certificate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.=0D + @param[out] EcContext Pointer to new-generated EC DSA context which c= ontain the retrieved=0D + EC public key component. Use EcFree() function = to free the=0D + resource.=0D +=0D + If Cert is NULL, then return FALSE.=0D + If EcContext is NULL, then return FALSE.=0D +=0D + @retval TRUE EC Public Key was retrieved successfully.=0D + @retval FALSE Fail to retrieve EC public key from X509 certificate.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +EcGetPublicKeyFromX509 (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT VOID **EcContext=0D + )=0D +{=0D + ASSERT (FALSE);=0D + return FALSE;=0D +}=0D +=0D +/**=0D + Verify one X509 certificate was issued by the trusted CA.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certificate= to be verified.=0D + @param[in] CertSize Size of the X509 certificate in bytes.=0D + @param[in] CACert Pointer to the DER-encoded trusted CA certi= ficate.=0D + @param[in] CACertSize Size of the CA Certificate in bytes.=0D +=0D + If Cert is NULL, then return FALSE.=0D + If CACert is NULL, then return FALSE.=0D +=0D + @retval TRUE The certificate was issued by the trusted CA.=0D + @retval FALSE Invalid certificate or the certificate was not issued by= the given=0D + trusted CA.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509VerifyCert (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + IN CONST UINT8 *CACert,=0D + IN UINTN CACertSize=0D + )=0D +{=0D + INT32 Ret;=0D + mbedtls_x509_crt Ca;=0D + mbedtls_x509_crt End;=0D + UINT32 VFlag;=0D + mbedtls_x509_crt_profile Profile;=0D +=0D + if ((Cert =3D=3D NULL) || (CACert =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + VFlag =3D 0;=0D + CopyMem (&Profile, &gCompatProfile, sizeof (mbedtls_x509_crt_profile));= =0D +=0D + mbedtls_x509_crt_init (&Ca);=0D + mbedtls_x509_crt_init (&End);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Ca, CACert, CACertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + Ret =3D mbedtls_x509_crt_parse_der (&End, Cert, CertSize);=0D + }=0D +=0D + if (Ret =3D=3D 0) {=0D + Ret =3D mbedtls_x509_crt_verify_with_profile (&End, &Ca, NULL, &Profil= e, NULL, &VFlag, NULL, NULL);=0D + }=0D +=0D + mbedtls_x509_crt_free (&Ca);=0D + mbedtls_x509_crt_free (&End);=0D +=0D + return Ret =3D=3D 0;=0D +}=0D +=0D +/**=0D + Verify one X509 certificate was issued by the trusted CA.=0D +=0D + @param[in] RootCert Trusted Root Certificate buffer=0D + @param[in] RootCertLength Trusted Root Certificate buffer length= =0D + @param[in] CertChain One or more ASN.1 DER-encoded X.509 ce= rtificates=0D + where the first certificate is signed = by the Root=0D + Certificate or is the Root Cerificate = itself. and=0D + subsequent cerificate is signed by the= preceding=0D + cerificate.=0D + @param[in] CertChainLength Total length of the certificate chain,= in bytes.=0D +=0D + @retval TRUE All cerificates was issued by the first certificate in X= 509Certchain.=0D + @retval FALSE Invalid certificate or the certificate was not issued by= the given=0D + trusted CA.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509VerifyCertChain (=0D + IN CONST UINT8 *RootCert,=0D + IN UINTN RootCertLength,=0D + IN CONST UINT8 *CertChain,=0D + IN UINTN CertChainLength=0D + )=0D +{=0D + UINTN Asn1Len;=0D + UINTN PrecedingCertLen;=0D + CONST UINT8 *PrecedingCert;=0D + UINTN CurrentCertLen;=0D + CONST UINT8 *CurrentCert;=0D + CONST UINT8 *TmpPtr;=0D + UINT32 Ret;=0D + BOOLEAN VerifyFlag;=0D +=0D + VerifyFlag =3D FALSE;=0D + PrecedingCert =3D RootCert;=0D + PrecedingCertLen =3D RootCertLength;=0D +=0D + CurrentCert =3D CertChain;=0D +=0D + //=0D + // Get Current certificate from Certificates buffer and Verify with prec= iding cert=0D + //=0D + do {=0D + TmpPtr =3D CurrentCert;=0D + Ret =3D mbedtls_asn1_get_tag ((UINT8 **)&TmpPtr, CertChain + CertCh= ainLength, &Asn1Len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);=0D + if (Ret !=3D 0) {=0D + break;=0D + }=0D +=0D + CurrentCertLen =3D Asn1Len + (TmpPtr - CurrentCert);=0D +=0D + if (!X509VerifyCert (CurrentCert, CurrentCertLen, PrecedingCert, Prece= dingCertLen)) {=0D + VerifyFlag =3D FALSE;=0D + break;=0D + } else {=0D + VerifyFlag =3D TRUE;=0D + }=0D +=0D + //=0D + // Save preceding certificate=0D + //=0D + PrecedingCert =3D CurrentCert;=0D + PrecedingCertLen =3D CurrentCertLen;=0D +=0D + //=0D + // Move current certificate to next;=0D + //=0D + CurrentCert =3D CurrentCert + CurrentCertLen;=0D + } while (1);=0D +=0D + return VerifyFlag;=0D +}=0D +=0D +/**=0D + Get one X509 certificate from CertChain.=0D +=0D + @param[in] CertChain One or more ASN.1 DER-encoded X.509 ce= rtificates=0D + where the first certificate is signed = by the Root=0D + Certificate or is the Root Cerificate = itself. and=0D + subsequent cerificate is signed by the= preceding=0D + cerificate.=0D + @param[in] CertChainLength Total length of the certificate chain,= in bytes.=0D +=0D + @param[in] CertIndex Index of certificate.=0D +=0D + @param[out] Cert The certificate at the index of CertCh= ain.=0D + @param[out] CertLength The length certificate at the index of= CertChain.=0D +=0D + @retval TRUE Success.=0D + @retval FALSE Failed to get certificate from certificate chain.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetCertFromCertChain (=0D + IN CONST UINT8 *CertChain,=0D + IN UINTN CertChainLength,=0D + IN CONST INT32 CertIndex,=0D + OUT CONST UINT8 **Cert,=0D + OUT UINTN *CertLength=0D + )=0D +{=0D + UINTN Asn1Len;=0D + INT32 CurrentIndex;=0D + UINTN CurrentCertLen;=0D + CONST UINT8 *CurrentCert;=0D + CONST UINT8 *TmpPtr;=0D + INT32 Ret;=0D +=0D + //=0D + // Check input parameters.=0D + //=0D + if ((CertChain =3D=3D NULL) || (Cert =3D=3D NULL) ||=0D + (CertIndex < -1) || (CertLength =3D=3D NULL))=0D + {=0D + return FALSE;=0D + }=0D +=0D + CurrentCert =3D CertChain;=0D + CurrentIndex =3D -1;=0D +=0D + //=0D + // Traverse the certificate chain=0D + //=0D + while (TRUE) {=0D + //=0D + // Get asn1 tag len=0D + //=0D + TmpPtr =3D CurrentCert;=0D + Ret =3D mbedtls_asn1_get_tag ((UINT8 **)&TmpPtr, CertChain + CertCh= ainLength, &Asn1Len, MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);=0D + if (Ret !=3D 0) {=0D + break;=0D + }=0D +=0D + CurrentCertLen =3D Asn1Len + (TmpPtr - CurrentCert);=0D + CurrentIndex++;=0D +=0D + if (CurrentIndex =3D=3D CertIndex) {=0D + *Cert =3D CurrentCert;=0D + *CertLength =3D CurrentCertLen;=0D + return TRUE;=0D + }=0D +=0D + //=0D + // Move to next=0D + //=0D + CurrentCert =3D CurrentCert + CurrentCertLen;=0D + }=0D +=0D + //=0D + // If CertIndex is -1, Return the last certificate=0D + //=0D + if ((CertIndex =3D=3D -1) && (CurrentIndex >=3D 0)) {=0D + *Cert =3D CurrentCert - CurrentCertLen;=0D + *CertLength =3D CurrentCertLen;=0D + return TRUE;=0D + }=0D +=0D + return FALSE;=0D +}=0D +=0D +/**=0D + Retrieve the TBSCertificate from one given X.509 certificate.=0D +=0D + @param[in] Cert Pointer to the given DER-encoded X509 certi= ficate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.=0D + @param[out] TBSCert DER-Encoded To-Be-Signed certificate.=0D + @param[out] TBSCertSize Size of the TBS certificate in bytes.=0D +=0D + If Cert is NULL, then return FALSE.=0D + If TBSCert is NULL, then return FALSE.=0D + If TBSCertSize is NULL, then return FALSE.=0D +=0D + @retval TRUE The TBSCertificate was retrieved successfully.=0D + @retval FALSE Invalid X.509 certificate.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetTBSCert (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT UINT8 **TBSCert,=0D + OUT UINTN *TBSCertSize=0D + )=0D +{=0D + UINTN Length;=0D + UINTN Ret;=0D + UINT8 *Ptr;=0D + CONST UINT8 *Temp;=0D + CONST UINT8 *End;=0D +=0D + //=0D + // Check input parameters.=0D + //=0D + if ((Cert =3D=3D NULL) || (TBSCert =3D=3D NULL) ||=0D + (TBSCertSize =3D=3D NULL) || (CertSize > INT_MAX))=0D + {=0D + return FALSE;=0D + }=0D +=0D + //=0D + // An X.509 Certificate is: (defined in RFC3280)=0D + // Certificate ::=3D SEQUENCE {=0D + // tbsCertificate TBSCertificate,=0D + // signatureAlgorithm AlgorithmIdentifier,=0D + // signature BIT STRING }=0D + //=0D + // and=0D + //=0D + // TBSCertificate ::=3D SEQUENCE {=0D + // version [0] Version DEFAULT v1,=0D + // ...=0D + // }=0D + //=0D + // So we can just ASN1-parse the x.509 DER-encoded data. If we strip=0D + // the first SEQUENCE, the second SEQUENCE is the TBSCertificate.=0D + //=0D +=0D + Length =3D 0;=0D +=0D + Ptr =3D (UINT8 *)Cert;=0D + End =3D Cert + CertSize;=0D +=0D + Ret =3D mbedtls_asn1_get_tag (&Ptr, End, &Length, MBEDTLS_ASN1_CONSTRUCT= ED | MBEDTLS_ASN1_SEQUENCE);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + Temp =3D Ptr;=0D + End =3D Ptr + Length;=0D + Ret =3D mbedtls_asn1_get_tag (&Ptr, End, &Length, MBEDTLS_ASN1_CONSTRUC= TED | MBEDTLS_ASN1_SEQUENCE);=0D + if (Ret !=3D 0) {=0D + return FALSE;=0D + }=0D +=0D + *TBSCert =3D (UINT8 *)Temp;=0D + *TBSCertSize =3D Length + (Ptr - Temp);=0D +=0D + return TRUE;=0D +}=0D +=0D +/**=0D + Retrieve the version from one X.509 certificate.=0D +=0D + If Cert is NULL, then return FALSE.=0D + If CertSize is 0, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certificate= .=0D + @param[in] CertSize Size of the X509 certificate in bytes.=0D + @param[out] Version Pointer to the retrieved version integer.=0D +=0D + @retval TRUE The certificate version retrieved successfully.=0D + @retval FALSE If Cert is NULL or CertSize is Zero.=0D + @retval FALSE The operation is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetVersion (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT UINTN *Version=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D + BOOLEAN ReturnStatus;=0D +=0D + if (Cert =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + ReturnStatus =3D FALSE;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + *Version =3D Crt.version - 1;=0D + ReturnStatus =3D TRUE;=0D + }=0D +=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return ReturnStatus;=0D +}=0D +=0D +/**=0D + Retrieve the serialNumber from one X.509 certificate.=0D +=0D + If Cert is NULL, then return FALSE.=0D + If CertSize is 0, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certificate= .=0D + @param[in] CertSize Size of the X509 certificate in bytes.=0D + @param[out] SerialNumber Pointer to the retrieved certificate Seria= lNumber bytes.=0D + @param[in, out] SerialNumberSize The size in bytes of the SerialNumber = buffer on input,=0D + and the size of buffer returned SerialNumbe= r on output.=0D +=0D + @retval TRUE The certificate serialNumber retrieved = successfully.=0D + @retval FALSE If Cert is NULL or CertSize is Zero.=0D + If SerialNumberSize is NULL.=0D + If Certificate is invalid.=0D + @retval FALSE If no SerialNumber exists.=0D + @retval FALSE If the SerialNumber is NULL. The requir= ed buffer size=0D + (including the final null) is returned = in the=0D + SerialNumberSize parameter.=0D + @retval FALSE The operation is not supported.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetSerialNumber (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT UINT8 *SerialNumber OPTIONAL,=0D + IN OUT UINTN *SerialNumberSize=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D + BOOLEAN ReturnStatus;=0D +=0D + if (Cert =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + ReturnStatus =3D FALSE;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + if (*SerialNumberSize <=3D Crt.serial.len) {=0D + *SerialNumberSize =3D Crt.serial.len + 1;=0D + ReturnStatus =3D FALSE;=0D + goto Cleanup;=0D + }=0D +=0D + if (SerialNumber !=3D NULL) {=0D + CopyMem (SerialNumber, Crt.serial.p, Crt.serial.len);=0D + SerialNumber[Crt.serial.len] =3D '\0';=0D + }=0D +=0D + *SerialNumberSize =3D Crt.serial.len + 1;=0D + ReturnStatus =3D TRUE;=0D + }=0D +=0D +Cleanup:=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return ReturnStatus;=0D +}=0D +=0D +/**=0D + Retrieve the issuer bytes from one X.509 certificate.=0D +=0D + If Cert is NULL, then return FALSE.=0D + If CertIssuerSize is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certificate= .=0D + @param[in] CertSize Size of the X509 certificate in bytes.=0D + @param[out] CertIssuer Pointer to the retrieved certificate subject= bytes.=0D + @param[in, out] CertIssuerSize The size in bytes of the CertIssuer buff= er on input,=0D + and the size of buffer returned CertSubject= on output.=0D +=0D + @retval TRUE The certificate issuer retrieved successfully.=0D + @retval FALSE Invalid certificate, or the CertIssuerSize is too small = for the result.=0D + The CertIssuerSize will be updated with the required siz= e.=0D + @retval FALSE This interface is not supported.=0D +=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetIssuerName (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT UINT8 *CertIssuer,=0D + IN OUT UINTN *CertIssuerSize=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D + BOOLEAN Status;=0D +=0D + if (Cert =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + Status =3D FALSE;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + if (*CertIssuerSize < Crt.serial.len) {=0D + *CertIssuerSize =3D Crt.serial.len;=0D + Status =3D FALSE;=0D + goto Cleanup;=0D + }=0D +=0D + if (CertIssuer !=3D NULL) {=0D + CopyMem (CertIssuer, Crt.serial.p, Crt.serial.len);=0D + }=0D +=0D + *CertIssuerSize =3D Crt.serial.len;=0D + Status =3D TRUE;=0D + }=0D +=0D +Cleanup:=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Retrieve the issuer common name (CN) string from one X.509 certificate.= =0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certifi= cate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.= =0D + @param[out] CommonName Buffer to contain the retrieved certifi= cate issuer common=0D + name string. At most CommonNameSize byt= es will be=0D + written and the string will be null ter= minated. May be=0D + NULL in order to determine the size buf= fer needed.=0D + @param[in,out] CommonNameSize The size in bytes of the CommonName buf= fer on input,=0D + and the size of buffer returned CommonN= ame on output.=0D + If CommonName is NULL then the amount o= f space needed=0D + in buffer (including the final null) is= returned.=0D +=0D + @retval RETURN_SUCCESS The certificate Issuer CommonName retri= eved successfully.=0D + @retval RETURN_INVALID_PARAMETER If Cert is NULL.=0D + If CommonNameSize is NULL.=0D + If CommonName is not NULL and *CommonNa= meSize is 0.=0D + If Certificate is invalid.=0D + @retval RETURN_NOT_FOUND If no CommonName entry exists.=0D + @retval RETURN_BUFFER_TOO_SMALL If the CommonName is NULL. The required= buffer size=0D + (including the final null) is returned = in the=0D + CommonNameSize parameter.=0D + @retval RETURN_UNSUPPORTED The operation is not supported.=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +X509GetIssuerCommonName (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT CHAR8 *CommonName OPTIONAL,=0D + IN OUT UINTN *CommonNameSize=0D + )=0D +{=0D + return InternalX509GetIssuerNIDName (Cert, CertSize, (CHAR8 *)OID_common= Name, sizeof (OID_commonName), CommonName, CommonNameSize);=0D +}=0D +=0D +/**=0D + Retrieve the issuer organization name (O) string from one X.509 certific= ate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certifi= cate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.= =0D + @param[out] NameBuffer Buffer to contain the retrieved certifi= cate issuer organization=0D + name string. At most NameBufferSize byt= es will be=0D + written and the string will be null ter= minated. May be=0D + NULL in order to determine the size buf= fer needed.=0D + @param[in,out] NameBufferSize The size in bytes of the Name buffer on= input,=0D + and the size of buffer returned Name on= output.=0D + If NameBuffer is NULL then the amount o= f space needed=0D + in buffer (including the final null) is= returned.=0D +=0D + @retval RETURN_SUCCESS The certificate issuer Organization Nam= e retrieved successfully.=0D + @retval RETURN_INVALID_PARAMETER If Cert is NULL.=0D + If NameBufferSize is NULL.=0D + If NameBuffer is not NULL and *CommonNa= meSize is 0.=0D + If Certificate is invalid.=0D + @retval RETURN_NOT_FOUND If no Organization Name entry exists.=0D + @retval RETURN_BUFFER_TOO_SMALL If the NameBuffer is NULL. The required= buffer size=0D + (including the final null) is returned = in the=0D + CommonNameSize parameter.=0D + @retval RETURN_UNSUPPORTED The operation is not supported.=0D +=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +X509GetIssuerOrganizationName (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT CHAR8 *NameBuffer OPTIONAL,=0D + IN OUT UINTN *NameBufferSize=0D + )=0D +{=0D + return InternalX509GetIssuerNIDName (Cert, CertSize, (CHAR8 *)OID_organi= zationName, sizeof (OID_organizationName), NameBuffer, NameBufferSize);=0D +}=0D +=0D +/**=0D + Retrieve the Signature Algorithm from one X.509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certifi= cate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.= =0D + @param[out] Oid Signature Algorithm Object identifier b= uffer.=0D + @param[in,out] OidSize Signature Algorithm Object identifier b= uffer size=0D +=0D + @retval TRUE The certificate Extension data retrieved successf= ully.=0D + @retval FALSE If Cert is NULL.=0D + If OidSize is NULL.=0D + If Oid is not NULL and *OidSize is 0.=0D + If Certificate is invalid.=0D + @retval FALSE If no SignatureType.=0D + @retval FALSE If the Oid is NULL. The required buffer= size=0D + is returned in the OidSize.=0D + @retval FALSE The operation is not supported.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetSignatureAlgorithm (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT UINT8 *Oid OPTIONAL,=0D + IN OUT UINTN *OidSize=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D + BOOLEAN ReturnStatus;=0D +=0D + if ((Cert =3D=3D NULL) || (CertSize =3D=3D 0) || (OidSize =3D=3D NULL)) = {=0D + return FALSE;=0D + }=0D +=0D + ReturnStatus =3D FALSE;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + if (*OidSize < Crt.sig_oid.len) {=0D + *OidSize =3D Crt.serial.len;=0D + ReturnStatus =3D FALSE;=0D + goto Cleanup;=0D + }=0D +=0D + if (Oid !=3D NULL) {=0D + CopyMem (Oid, Crt.sig_oid.p, Crt.sig_oid.len);=0D + }=0D +=0D + *OidSize =3D Crt.sig_oid.len;=0D + ReturnStatus =3D TRUE;=0D + }=0D +=0D +Cleanup:=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return ReturnStatus;=0D +}=0D +=0D +/**=0D + Find first Extension data match with given OID=0D +=0D + @param[in] Start Pointer to the DER-encoded Extensions = Data=0D + @param[in] End Extensions Data size in bytes=0D + @param[in ] Oid OID for match=0D + @param[in ] OidSize OID size in bytes=0D + @param[out] FindExtensionData output matched extension data.=0D + @param[out] FindExtensionDataLen matched extension data size.=0D +=0D + **/=0D +STATIC=0D +RETURN_STATUS=0D +InternalX509FindExtensionData (=0D + UINT8 *Start,=0D + UINT8 *End,=0D + CONST UINT8 *Oid,=0D + UINTN OidSize,=0D + UINT8 **FindExtensionData,=0D + UINTN *FindExtensionDataLen=0D + )=0D +{=0D + UINT8 *Ptr;=0D + UINT8 *ExtensionPtr;=0D + size_t ObjLen;=0D + INT32 Ret;=0D + RETURN_STATUS ReturnStatus;=0D + size_t FindExtensionLen;=0D + size_t HeaderLen;=0D +=0D + ReturnStatus =3D RETURN_INVALID_PARAMETER;=0D + Ptr =3D Start;=0D +=0D + Ret =3D 0;=0D +=0D + while (TRUE) {=0D + /*=0D + * Extension ::=3D SEQUENCE {=0D + * extnID OBJECT IDENTIFIER,=0D + * critical BOOLEAN DEFAULT FALSE,=0D + * extnValue OCTET STRING }=0D + */=0D + ExtensionPtr =3D Ptr;=0D + Ret =3D mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN= 1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE);=0D + if (Ret =3D=3D 0) {=0D + HeaderLen =3D (size_t)(Ptr - ExtensionPtr);=0D + FindExtensionLen =3D ObjLen;=0D + // Get Object Identifier=0D + Ret =3D mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OID);= =0D + } else {=0D + break;=0D + }=0D +=0D + if ((Ret =3D=3D 0) && (CompareMem (Ptr, Oid, OidSize) =3D=3D 0)) {=0D + Ptr +=3D ObjLen;=0D +=0D + Ret =3D mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_BOOLE= AN);=0D + if (Ret =3D=3D 0) {=0D + Ptr +=3D ObjLen;=0D + }=0D +=0D + Ret =3D mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_OCTET= _STRING);=0D + } else {=0D + Ret =3D 1;=0D + }=0D +=0D + if (Ret =3D=3D 0) {=0D + *FindExtensionData =3D Ptr;=0D + *FindExtensionDataLen =3D ObjLen;=0D + ReturnStatus =3D RETURN_SUCCESS;=0D + break;=0D + }=0D +=0D + // move to next=0D + Ptr =3D ExtensionPtr + HeaderLen + FindExtensionLen;=0D + Ret =3D 0;=0D + }=0D +=0D + return ReturnStatus;=0D +}=0D +=0D +/**=0D + Retrieve Extension data from one X.509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certifi= cate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.= =0D + @param[in] Oid Object identifier buffer=0D + @param[in] OidSize Object identifier buffer size=0D + @param[out] ExtensionData Extension bytes.=0D + @param[in, out] ExtensionDataSize Extension bytes size.=0D +=0D + @retval TRUE The certificate Extension data retrieve= d successfully.=0D + @retval FALSE If Cert is NULL.=0D + If ExtensionDataSize is NULL.=0D + If ExtensionData is not NULL and *Exten= sionDataSize is 0.=0D + If Certificate is invalid.=0D + @retval FALSE If no Extension entry match Oid.=0D + @retval FALSE If the ExtensionData is NULL. The requi= red buffer size=0D + is returned in the ExtensionDataSize pa= rameter.=0D + @retval FALSE The operation is not supported.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetExtensionData (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + IN CONST UINT8 *Oid,=0D + IN UINTN OidSize,=0D + OUT UINT8 *ExtensionData,=0D + IN OUT UINTN *ExtensionDataSize=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D + RETURN_STATUS ReturnStatus;=0D + BOOLEAN Status;=0D + UINT8 *Ptr;=0D + UINT8 *End;=0D + size_t ObjLen;=0D +=0D + if ((Cert =3D=3D NULL) ||=0D + (CertSize =3D=3D 0) ||=0D + (Oid =3D=3D NULL) ||=0D + (OidSize =3D=3D 0) ||=0D + (ExtensionDataSize =3D=3D NULL))=0D + {=0D + return FALSE;=0D + }=0D +=0D + ReturnStatus =3D RETURN_INVALID_PARAMETER;=0D + Status =3D FALSE;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + Ptr =3D Crt.v3_ext.p;=0D + End =3D Crt.v3_ext.p + Crt.v3_ext.len;=0D + Ret =3D mbedtls_asn1_get_tag (&Ptr, End, &ObjLen, MBEDTLS_ASN1_CONSTRU= CTED | MBEDTLS_ASN1_SEQUENCE);=0D + }=0D +=0D + if (Ret =3D=3D 0) {=0D + ReturnStatus =3D InternalX509FindExtensionData (Ptr, End, Oid, OidSize= , &Ptr, &ObjLen);=0D + }=0D +=0D + if (ReturnStatus =3D=3D RETURN_SUCCESS) {=0D + if (*ExtensionDataSize < ObjLen) {=0D + *ExtensionDataSize =3D ObjLen;=0D + Status =3D FALSE;=0D + goto Cleanup;=0D + }=0D +=0D + if (Oid !=3D NULL) {=0D + CopyMem (ExtensionData, Ptr, ObjLen);=0D + }=0D +=0D + *ExtensionDataSize =3D ObjLen;=0D + Status =3D TRUE;=0D + }=0D +=0D +Cleanup:=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Retrieve the Validity from one X.509 certificate=0D +=0D + If Cert is NULL, then return FALSE.=0D + If CertIssuerSize is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certificate= .=0D + @param[in] CertSize Size of the X509 certificate in bytes.=0D + @param[in] From notBefore Pointer to DateTime object.=0D + @param[in,out] FromSize notBefore DateTime object size.=0D + @param[in] To notAfter Pointer to DateTime object.=0D + @param[in,out] ToSize notAfter DateTime object size.=0D +=0D + Note: X509CompareDateTime to compare DateTime oject=0D + x509SetDateTime to get a DateTime object from a DateTimeStr=0D +=0D + @retval TRUE The certificate Validity retrieved successfully.=0D + @retval FALSE Invalid certificate, or Validity retrieve failed.=0D + @retval FALSE This interface is not supported.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetValidity (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + IN UINT8 *From,=0D + IN OUT UINTN *FromSize,=0D + IN UINT8 *To,=0D + IN OUT UINTN *ToSize=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D + BOOLEAN Status;=0D + UINTN TSize;=0D + UINTN FSize;=0D +=0D + if (Cert =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + Status =3D FALSE;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + FSize =3D sizeof (mbedtls_x509_time);=0D + if (*FromSize < FSize) {=0D + *FromSize =3D FSize;=0D + goto _Exit;=0D + }=0D +=0D + *FromSize =3D FSize;=0D + if (From !=3D NULL) {=0D + CopyMem (From, &(Crt.valid_from), FSize);=0D + }=0D +=0D + TSize =3D sizeof (mbedtls_x509_time);=0D + if (*ToSize < TSize) {=0D + *ToSize =3D TSize;=0D + goto _Exit;=0D + }=0D +=0D + *ToSize =3D TSize;=0D + if (To !=3D NULL) {=0D + CopyMem (To, &(Crt.valid_to), sizeof (mbedtls_x509_time));=0D + }=0D +=0D + Status =3D TRUE;=0D + }=0D +=0D +_Exit:=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Retrieve the Key Usage from one X.509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certifi= cate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.= =0D + @param[out] Usage Key Usage (CRYPTO_X509_KU_*)=0D +=0D + @retval TRUE The certificate Key Usage retrieved successfully.=0D + @retval FALSE Invalid certificate, or Usage is NULL=0D + @retval FALSE This interface is not supported.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetKeyUsage (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT UINTN *Usage=0D + )=0D +{=0D + mbedtls_x509_crt Crt;=0D + INT32 Ret;=0D + BOOLEAN Status;=0D +=0D + if (Cert =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + Status =3D FALSE;=0D +=0D + mbedtls_x509_crt_init (&Crt);=0D +=0D + Ret =3D mbedtls_x509_crt_parse_der (&Crt, Cert, CertSize);=0D +=0D + if (Ret =3D=3D 0) {=0D + *Usage =3D Crt.key_usage;=0D + Status =3D TRUE;=0D + }=0D +=0D + mbedtls_x509_crt_free (&Crt);=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Retrieve the Extended Key Usage from one X.509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509 certifi= cate.=0D + @param[in] CertSize Size of the X509 certificate in bytes.= =0D + @param[out] Usage Key Usage bytes.=0D + @param[in, out] UsageSize Key Usage buffer sizs in bytes.=0D +=0D + @retval TRUE The Usage bytes retrieve successfully.= =0D + @retval FALSE If Cert is NULL.=0D + If CertSize is NULL.=0D + If Usage is not NULL and *UsageSize is = 0.=0D + If Cert is invalid.=0D + @retval FALSE If the Usage is NULL. The required buff= er size=0D + is returned in the UsageSize parameter.= =0D + @retval FALSE The operation is not supported.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetExtendedKeyUsage (=0D + IN CONST UINT8 *Cert,=0D + IN UINTN CertSize,=0D + OUT UINT8 *Usage,=0D + IN OUT UINTN *UsageSize=0D + )=0D +{=0D + BOOLEAN ReturnStatus;=0D +=0D + if ((Cert =3D=3D NULL) || (CertSize =3D=3D 0) || (UsageSize =3D=3D NULL)= ) {=0D + return FALSE;=0D + }=0D +=0D + ReturnStatus =3D X509GetExtensionData ((UINT8 *)Cert, CertSize, (UINT8 *= )OID_extKeyUsage, sizeof (OID_extKeyUsage), Usage, UsageSize);=0D +=0D + return ReturnStatus;=0D +}=0D +=0D +/**=0D + Compare DateTime1 object and DateTime2 object time.=0D +=0D + @param[in] Before Pointer to a DateTime Ojbect=0D + @param[in] After Pointer to a DateTime Object=0D +=0D + @retval 0 If DateTime1 <=3D DateTime2=0D + @retval 1 If DateTime1 > DateTime2=0D +**/=0D +STATIC=0D +INTN=0D +InternalX509CheckTime (=0D + CONST mbedtls_x509_time *Before,=0D + CONST mbedtls_x509_time *After=0D + )=0D +{=0D + if (Before->year > After->year) {=0D + return (1);=0D + }=0D +=0D + if ((Before->year =3D=3D After->year) &&=0D + (Before->mon > After->mon))=0D + {=0D + return (1);=0D + }=0D +=0D + if ((Before->year =3D=3D After->year) &&=0D + (Before->mon =3D=3D After->mon) &&=0D + (Before->day > After->day))=0D + {=0D + return (1);=0D + }=0D +=0D + if ((Before->year =3D=3D After->year) &&=0D + (Before->mon =3D=3D After->mon) &&=0D + (Before->day =3D=3D After->day) &&=0D + (Before->hour > After->hour))=0D + {=0D + return (1);=0D + }=0D +=0D + if ((Before->year =3D=3D After->year) &&=0D + (Before->mon =3D=3D After->mon) &&=0D + (Before->day =3D=3D After->day) &&=0D + (Before->hour =3D=3D After->hour) &&=0D + (Before->min > After->min))=0D + {=0D + return (1);=0D + }=0D +=0D + if ((Before->year =3D=3D After->year) &&=0D + (Before->mon =3D=3D After->mon) &&=0D + (Before->day =3D=3D After->day) &&=0D + (Before->hour =3D=3D After->hour) &&=0D + (Before->min =3D=3D After->min) &&=0D + (Before->sec > After->sec))=0D + {=0D + return (1);=0D + }=0D +=0D + return (0);=0D +}=0D +=0D +/**=0D + change string to int.=0D +=0D + @param[in] PStart Pointer to a string Start=0D + @param[in] PEnd Pointer to a string End=0D +=0D + @return number=0D +**/=0D +STATIC=0D +INT32=0D +InternalAtoI (=0D + CHAR8 *PStart,=0D + CHAR8 *PEnd=0D + )=0D +{=0D + CHAR8 *Ptr;=0D + INT32 Knum;=0D +=0D + Knum =3D 0;=0D + Ptr =3D PStart;=0D +=0D + while (Ptr < PEnd) {=0D + ///=0D + /// k =3D k * 2^3 + k * 2^1 =3D k * 8 + k * 2 =3D k * 10=0D + ///=0D + Knum =3D (Knum << 3) + (Knum << 1) + (*Ptr) - '0';=0D + Ptr++;=0D + }=0D +=0D + return Knum;=0D +}=0D +=0D +/**=0D + Format a DateTime object into DataTime Buffer=0D +=0D + If DateTimeStr is NULL, then return FALSE.=0D + If DateTimeSize is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] DateTimeStr DateTime string like YYYYMMDDhhmmssZ=0D + Ref: https://www.w3.org/TR/NOTE-datetim= e=0D + Z stand for UTC time=0D + @param[in,out] DateTime Pointer to a DateTime object.=0D + @param[in,out] DateTimeSize DateTime object buffer size.=0D +=0D + @retval RETURN_SUCCESS The DateTime object create successfully= .=0D + @retval RETURN_INVALID_PARAMETER If DateTimeStr is NULL.=0D + If DateTimeSize is NULL.=0D + If DateTime is not NULL and *DateTimeSi= ze is 0.=0D + If Year Month Day Hour Minute Second co= mbination is invalid datetime.=0D + @retval RETURN_BUFFER_TOO_SMALL If the DateTime is NULL. The required b= uffer size=0D + (including the final null) is returned = in the=0D + DateTimeSize parameter.=0D + @retval RETURN_UNSUPPORTED The operation is not supported.=0D +**/=0D +RETURN_STATUS=0D +EFIAPI=0D +X509SetDateTime (=0D + CHAR8 *DateTimeStr,=0D + IN OUT VOID *DateTime,=0D + IN OUT UINTN *DateTimeSize=0D + )=0D +{=0D + mbedtls_x509_time Dt;=0D +=0D + INT32 Year;=0D + INT32 Month;=0D + INT32 Day;=0D + INT32 Hour;=0D + INT32 Minute;=0D + INT32 Second;=0D + RETURN_STATUS ReturnStatus;=0D + CHAR8 *Ptr;=0D +=0D + Ptr =3D DateTimeStr;=0D +=0D + Year =3D InternalAtoI (Ptr, Ptr + 4);=0D + Ptr +=3D 4;=0D + Month =3D InternalAtoI (Ptr, Ptr + 2);=0D + Ptr +=3D 2;=0D + Day =3D InternalAtoI (Ptr, Ptr + 2);=0D + Ptr +=3D 2;=0D + Hour =3D InternalAtoI (Ptr, Ptr + 2);=0D + Ptr +=3D 2;=0D + Minute =3D InternalAtoI (Ptr, Ptr + 2);=0D + Ptr +=3D 2;=0D + Second =3D InternalAtoI (Ptr, Ptr + 2);=0D + Ptr +=3D 2;=0D + Dt.year =3D (int)Year;=0D + Dt.mon =3D (int)Month;=0D + Dt.day =3D (int)Day;=0D + Dt.hour =3D (int)Hour;=0D + Dt.min =3D (int)Minute;=0D + Dt.sec =3D (int)Second;=0D +=0D + if (*DateTimeSize < sizeof (mbedtls_x509_time)) {=0D + *DateTimeSize =3D sizeof (mbedtls_x509_time);=0D + ReturnStatus =3D RETURN_BUFFER_TOO_SMALL;=0D + goto Cleanup;=0D + }=0D +=0D + if (DateTime !=3D NULL) {=0D + CopyMem (DateTime, &Dt, sizeof (mbedtls_x509_time));=0D + }=0D +=0D + *DateTimeSize =3D sizeof (mbedtls_x509_time);=0D + ReturnStatus =3D RETURN_SUCCESS;=0D +Cleanup:=0D + return ReturnStatus;=0D +}=0D +=0D +/**=0D + Compare DateTime1 object and DateTime2 object.=0D +=0D + If DateTime1 is NULL, then return -2.=0D + If DateTime2 is NULL, then return -2.=0D + If DateTime1 =3D=3D DateTime2, then return 0=0D + If DateTime1 > DateTime2, then return 1=0D + If DateTime1 < DateTime2, then return -1=0D +=0D + @param[in] DateTime1 Pointer to a DateTime Ojbect=0D + @param[in] DateTime2 Pointer to a DateTime Object=0D +=0D + @retval 0 If DateTime1 =3D=3D DateTime2=0D + @retval 1 If DateTime1 > DateTime2=0D + @retval -1 If DateTime1 < DateTime2=0D +**/=0D +INT32=0D +EFIAPI=0D +X509CompareDateTime (=0D + IN CONST VOID *DateTime1,=0D + IN CONST VOID *DateTime2=0D + )=0D +{=0D + if ((DateTime1 =3D=3D NULL) || (DateTime2 =3D=3D NULL)) {=0D + return -2;=0D + }=0D +=0D + if (CompareMem (DateTime2, DateTime1, sizeof (mbedtls_x509_time)) =3D=3D= 0) {=0D + return 0;=0D + }=0D +=0D + if (InternalX509CheckTime ((mbedtls_x509_time *)DateTime1, (mbedtls_x509= _time *)DateTime2) =3D=3D 0) {=0D + return -1;=0D + } else {=0D + return 1;=0D + }=0D +}=0D +=0D +/**=0D + Retrieve the basic constraints from one X.509 certificate.=0D +=0D + @param[in] Cert Pointer to the DER-encoded X509= certificate.=0D + @param[in] CertSize size of the X509 certificate in= bytes.=0D + @param[out] BasicConstraints basic constraints bytes.=0D + @param[in, out] BasicConstraintsSize basic constraints buffer sizs i= n bytes.=0D +=0D + @retval TRUE The basic constraints retrieve successf= ully.=0D + @retval FALSE If cert is NULL.=0D + If cert_size is NULL.=0D + If basic_constraints is not NULL and *b= asic_constraints_size is 0.=0D + If cert is invalid.=0D + @retval FALSE The required buffer size is small.=0D + The return buffer size is basic_constra= ints_size parameter.=0D + @retval FALSE If no Extension entry match oid.=0D + @retval FALSE The operation is not supported.=0D + **/=0D +BOOLEAN=0D +EFIAPI=0D +X509GetExtendedBasicConstraints (=0D + CONST UINT8 *Cert,=0D + UINTN CertSize,=0D + UINT8 *BasicConstraints,=0D + UINTN *BasicConstraintsSize=0D + )=0D +{=0D + BOOLEAN Status;=0D +=0D + if ((Cert =3D=3D NULL) || (CertSize =3D=3D 0) || (BasicConstraintsSize = =3D=3D NULL)) {=0D + return FALSE;=0D + }=0D +=0D + Status =3D X509GetExtensionData (=0D + (UINT8 *)Cert,=0D + CertSize,=0D + OID_BasicConstraints,=0D + sizeof (OID_BasicConstraints),=0D + BasicConstraints,=0D + BasicConstraintsSize=0D + );=0D +=0D + return Status;=0D +}=0D +=0D +/**=0D + Format a DateTimeStr to DataTime object in DataTime Buffer=0D +=0D + If DateTimeStr is NULL, then return FALSE.=0D + If DateTimeSize is NULL, then return FALSE.=0D + If this interface is not supported, then return FALSE.=0D +=0D + @param[in] DateTimeStr DateTime string like YYYYMMDDhhmmssZ=0D + Ref: https://www.w3.org/TR/NOTE-datetim= e=0D + Z stand for UTC time=0D + @param[out] DateTime Pointer to a DateTime object.=0D + @param[in,out] DateTimeSize DateTime object buffer size.=0D +=0D + @retval TRUE The DateTime object create successfully= .=0D + @retval FALSE If DateTimeStr is NULL.=0D + If DateTimeSize is NULL.=0D + If DateTime is not NULL and *DateTimeSi= ze is 0.=0D + If Year Month Day Hour Minute Second co= mbination is invalid datetime.=0D + @retval FALSE If the DateTime is NULL. The required b= uffer size=0D + (including the final null) is returned = in the=0D + DateTimeSize parameter.=0D + @retval FALSE The operation is not supported.=0D +**/=0D +BOOLEAN=0D +EFIAPI=0D +X509FormatDateTime (=0D + IN CONST CHAR8 *DateTimeStr,=0D + OUT VOID *DateTime,=0D + IN OUT UINTN *DateTimeSize=0D + )=0D +{=0D + mbedtls_x509_time *Tm;=0D +=0D + if (*DateTimeSize < sizeof (mbedtls_x509_time)) {=0D + return FALSE;=0D + }=0D +=0D + if (DateTime =3D=3D NULL) {=0D + return FALSE;=0D + }=0D +=0D + Tm =3D (mbedtls_x509_time *)DateTime;=0D +=0D + Tm->year =3D (DateTimeStr[0] + '0') * 1000 + (DateTimeStr[1] + '0') * 10= 0 +=0D + (DateTimeStr[2] + '0') * 10 + (DateTimeStr[3] + '0') * 1;=0D +=0D + Tm->mon =3D (DateTimeStr[4] + '0') * 10 + (DateTimeStr[5] + '0') * 1;=0D +=0D + Tm->day =3D (DateTimeStr[6] + '0') * 10 + (DateTimeStr[7] + '0') * 1;=0D +=0D + Tm->hour =3D (DateTimeStr[8] + '0') * 10 + (DateTimeStr[9] + '0') * 1;=0D +=0D + Tm->min =3D (DateTimeStr[10] + '0') * 10 + (DateTimeStr[11] + '0') * 1;= =0D +=0D + Tm->sec =3D (DateTimeStr[12] + '0') * 10 + (DateTimeStr[13] + '0') * 1;= =0D +=0D + return TRUE;=0D +}=0D --=20 2.26.2.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#118735): https://edk2.groups.io/g/devel/message/118735 Mute This Topic: https://groups.io/mt/105996830/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=-=-=-=-=-=-=-=-=-=-=-