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