9#include "InternalCryptLib.h"
10#include <openssl/x509.h>
11#include <openssl/x509v3.h>
12#include <crypto/asn1.h>
13#include <openssl/asn1.h>
14#include <openssl/rsa.h>
17#define OID_EXT_KEY_USAGE { 0x55, 0x1D, 0x25 }
18#define OID_BASIC_CONSTRAINTS { 0x55, 0x1D, 0x13 }
20static CONST UINT8 mOidExtKeyUsage[] = OID_EXT_KEY_USAGE;
21static CONST UINT8 mOidBasicConstraints[] = OID_BASIC_CONSTRAINTS;
23#define CRYPTO_ASN1_TAG_CLASS_MASK 0xC0
24#define CRYPTO_ASN1_TAG_PC_MASK 0x20
25#define CRYPTO_ASN1_TAG_VALUE_MASK 0x1F
46 OUT UINT8 **SingleX509Cert
55 if ((Cert ==
NULL) || (SingleX509Cert ==
NULL) || (CertSize > INT_MAX)) {
63 X509Cert = d2i_X509 (
NULL, &Temp, (
long)CertSize);
64 if (X509Cert ==
NULL) {
68 *SingleX509Cert = (UINT8 *)X509Cert;
95 IN OUT UINT8 **X509Stack,
103 STACK_OF (X509) *CertStack;
109 if (X509Stack ==
NULL) {
118 CertStack = (STACK_OF (X509) *)(*X509Stack);
119 if (CertStack ==
NULL) {
120 CertStack = sk_X509_new_null ();
121 if (CertStack ==
NULL) {
130 Cert =
VA_ARG (Args, UINT8 *);
150 if (X509Cert !=
NULL) {
151 X509_free (X509Cert);
160 sk_X509_push (CertStack, X509Cert);
164 sk_X509_pop_free (CertStack, X509_free);
166 *X509Stack = (UINT8 *)CertStack;
191 IN OUT UINT8 **X509Stack,
221 if (X509Cert ==
NULL) {
228 X509_free ((X509 *)X509Cert);
248 if (X509Stack ==
NULL) {
255 sk_X509_pop_free ((STACK_OF (X509) *) X509Stack, X509_free);
280 OUT UINT8 *CertSubject,
292 if ((Cert ==
NULL) || (SubjectSize ==
NULL)) {
302 if ((X509Cert ==
NULL) || (!Status)) {
312 X509Name = X509_get_subject_name (X509Cert);
313 if (X509Name ==
NULL) {
317 X509NameSize = i2d_X509_NAME (X509Name,
NULL);
318 if (*SubjectSize < X509NameSize) {
319 *SubjectSize = X509NameSize;
323 *SubjectSize = X509NameSize;
324 if (CertSubject !=
NULL) {
325 i2d_X509_NAME (X509Name, &CertSubject);
333 if (X509Cert !=
NULL) {
334 X509_free (X509Cert);
372 IN INT32 Request_NID,
373 OUT CHAR8 *CommonName OPTIONAL,
377 RETURN_STATUS ReturnStatus;
383 X509_NAME_ENTRY *Entry;
384 ASN1_STRING *EntryData;
393 if ((Cert ==
NULL) || (CertSize > INT_MAX) || (CommonNameSize ==
NULL)) {
397 if ((CommonName !=
NULL) && (*CommonNameSize == 0)) {
406 if ((X509Cert ==
NULL) || (!Status)) {
418 X509Name = X509_get_subject_name (X509Cert);
419 if (X509Name ==
NULL) {
429 Index = X509_NAME_get_index_by_NID (X509Name, Request_NID, -1);
439 Entry = X509_NAME_get_entry (X509Name, Index);
449 EntryData = X509_NAME_ENTRY_get_data (Entry);
451 Length = ASN1_STRING_to_UTF8 (&UTF8Name, EntryData);
461 if (CommonName ==
NULL) {
462 *CommonNameSize = Length + 1;
465 *CommonNameSize =
MIN ((
UINTN)Length, *CommonNameSize - 1) + 1;
466 CopyMem (CommonName, UTF8Name, *CommonNameSize - 1);
467 CommonName[*CommonNameSize - 1] =
'\0';
475 if (X509Cert !=
NULL) {
476 X509_free (X509Cert);
479 if (UTF8Name !=
NULL) {
480 OPENSSL_free (UTF8Name);
517 OUT CHAR8 *CommonName OPTIONAL,
555 OUT CHAR8 *NameBuffer OPTIONAL,
583 OUT VOID **RsaContext
593 if ((Cert ==
NULL) || (RsaContext ==
NULL)) {
604 if ((X509Cert ==
NULL) || (!Status)) {
614 Pkey = X509_get_pubkey (X509Cert);
615 if ((Pkey ==
NULL) || (EVP_PKEY_id (Pkey) != EVP_PKEY_RSA)) {
622 if ((*RsaContext = RSAPublicKey_dup (EVP_PKEY_get0_RSA (Pkey))) !=
NULL) {
630 if (X509Cert !=
NULL) {
631 X509_free (X509Cert);
635 EVP_PKEY_free (Pkey);
669 X509_STORE *CertStore;
670 X509_STORE_CTX *CertCtx;
675 if ((Cert ==
NULL) || (CACert ==
NULL)) {
688 if (EVP_add_digest (EVP_md5 ()) == 0) {
692 if (EVP_add_digest (EVP_sha1 ()) == 0) {
696 if (EVP_add_digest (EVP_sha256 ()) == 0) {
704 if ((X509Cert ==
NULL) || (!Status)) {
713 if ((X509CACert ==
NULL) || (!Status)) {
723 CertStore = X509_STORE_new ();
724 if (CertStore ==
NULL) {
728 if (!(X509_STORE_add_cert (CertStore, X509CACert))) {
736 X509_STORE_set_flags (
738 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
744 CertCtx = X509_STORE_CTX_new ();
745 if (CertCtx ==
NULL) {
749 if (!X509_STORE_CTX_init (CertCtx, CertStore, X509Cert,
NULL)) {
756 Status = (BOOLEAN)X509_verify_cert (CertCtx);
757 X509_STORE_CTX_cleanup (CertCtx);
763 if (X509Cert !=
NULL) {
764 X509_free (X509Cert);
767 if (X509CACert !=
NULL) {
768 X509_free (X509CACert);
771 if (CertStore !=
NULL) {
772 X509_STORE_free (CertStore);
775 X509_STORE_CTX_free (CertCtx);
814 if ((Cert ==
NULL) || (TBSCert ==
NULL) ||
815 (TBSCertSize ==
NULL) || (CertSize > INT_MAX))
839 Inf = ASN1_get_object (&Temp, (
long *)&Length, (
int *)&Asn1Tag, (
int *)&ObjClass, (
long)CertSize);
841 if (((Inf & 0x80) == 0x80) || (Asn1Tag != V_ASN1_SEQUENCE)) {
845 *TBSCert = (UINT8 *)Temp;
847 Inf = ASN1_get_object (&Temp, (
long *)&Length, (
int *)&Asn1Tag, (
int *)&ObjClass, (
long)Length);
851 if (((Inf & 0x80) == 0x80) || (Asn1Tag != V_ASN1_SEQUENCE)) {
855 *TBSCertSize = Length + (Temp - *TBSCert);
891 if ((Cert ==
NULL) || (EcContext ==
NULL)) {
902 if ((X509Cert ==
NULL) || (!Status)) {
912 Pkey = X509_get_pubkey (X509Cert);
913 if ((Pkey ==
NULL) || (EVP_PKEY_id (Pkey) != EVP_PKEY_EC)) {
920 if ((*EcContext = EC_KEY_dup (EVP_PKEY_get0_EC_KEY (Pkey))) !=
NULL) {
928 if (X509Cert !=
NULL) {
929 X509_free (X509Cert);
933 EVP_PKEY_free (Pkey);
968 if ((X509Cert ==
NULL) || (!Status)) {
976 *Version = X509_get_version (X509Cert);
979 if (X509Cert !=
NULL) {
980 X509_free (X509Cert);
1014 OUT UINT8 *SerialNumber, OPTIONAL
1020 ASN1_INTEGER *Asn1Integer;
1026 if ((Cert ==
NULL) || (SerialNumberSize ==
NULL)) {
1036 if ((X509Cert ==
NULL) || (!Status)) {
1037 *SerialNumberSize = 0;
1045 Asn1Integer = X509_get_serialNumber (X509Cert);
1046 if (Asn1Integer ==
NULL) {
1047 *SerialNumberSize = 0;
1052 if (*SerialNumberSize < (
UINTN)Asn1Integer->length) {
1053 *SerialNumberSize = (
UINTN)Asn1Integer->length;
1058 if (SerialNumber !=
NULL) {
1059 CopyMem (SerialNumber, Asn1Integer->data, (
UINTN)Asn1Integer->length);
1063 *SerialNumberSize = (
UINTN)Asn1Integer->length;
1069 if (X509Cert !=
NULL) {
1070 X509_free (X509Cert);
1100 OUT UINT8 *CertIssuer,
1106 X509_NAME *X509Name;
1112 if ((Cert ==
NULL) || (CertIssuerSize ==
NULL)) {
1122 if ((X509Cert ==
NULL) || (!Status)) {
1132 X509Name = X509_get_subject_name (X509Cert);
1133 if (X509Name ==
NULL) {
1137 X509NameSize = i2d_X509_NAME (X509Name,
NULL);
1138 if (*CertIssuerSize < X509NameSize) {
1139 *CertIssuerSize = X509NameSize;
1143 *CertIssuerSize = X509NameSize;
1144 if (CertIssuer !=
NULL) {
1145 i2d_X509_NAME (X509Name, &CertIssuer);
1153 if (X509Cert !=
NULL) {
1154 X509_free (X509Cert);
1183 OUT UINT8 *Oid, OPTIONAL
1190 ASN1_OBJECT *Asn1Obj;
1195 if ((Cert ==
NULL) || (OidSize ==
NULL) || (CertSize == 0)) {
1206 if ((X509Cert ==
NULL) || (!Status)) {
1214 Nid = X509_get_signature_nid (X509Cert);
1215 if (Nid == NID_undef) {
1221 Asn1Obj = OBJ_nid2obj (Nid);
1222 if (Asn1Obj ==
NULL) {
1228 if (*OidSize < (
UINTN)Asn1Obj->length) {
1229 *OidSize = Asn1Obj->length;
1235 CopyMem (Oid, Asn1Obj->data, Asn1Obj->length);
1238 *OidSize = Asn1Obj->length;
1245 if (X509Cert !=
NULL) {
1246 X509_free (X509Cert);
1279 OUT UINT8 *ExtensionData,
1287 CONST STACK_OF (X509_EXTENSION) *Extensions;
1288 ASN1_OBJECT *Asn1Obj;
1289 ASN1_OCTET_STRING *Asn1Oct;
1290 X509_EXTENSION *Ext;
1297 if ((Cert ==
NULL) || (CertSize == 0) || (Oid ==
NULL) || (OidSize == 0) || (ExtensionDataSize ==
NULL)) {
1308 if ((X509Cert ==
NULL) || (!Status)) {
1309 *ExtensionDataSize = 0;
1316 Extensions = X509_get0_extensions (X509Cert);
1317 if (sk_X509_EXTENSION_num (Extensions) <= 0) {
1318 *ExtensionDataSize = 0;
1328 for (i = 0; i < sk_X509_EXTENSION_num (Extensions); i++) {
1329 Ext = sk_X509_EXTENSION_value (Extensions, (
int)i);
1334 Asn1Obj = X509_EXTENSION_get_object (Ext);
1335 if (Asn1Obj ==
NULL) {
1339 Asn1Oct = X509_EXTENSION_get_data (Ext);
1340 if (Asn1Oct ==
NULL) {
1344 ObjLength = OBJ_length (Asn1Obj);
1345 OctLength = ASN1_STRING_length (Asn1Oct);
1346 if ((OidSize == ObjLength) && (
CompareMem (OBJ_get0_data (Asn1Obj), Oid, OidSize) == 0)) {
1361 if (*ExtensionDataSize < OctLength) {
1362 *ExtensionDataSize = OctLength;
1367 if (Asn1Oct !=
NULL) {
1368 CopyMem (ExtensionData, ASN1_STRING_get0_data (Asn1Oct), OctLength);
1371 *ExtensionDataSize = OctLength;
1373 *ExtensionDataSize = 0;
1380 if (X509Cert !=
NULL) {
1381 X509_free (X509Cert);
1415 Status =
X509GetExtensionData (Cert, CertSize, mOidExtKeyUsage,
sizeof (mOidExtKeyUsage), Usage, UsageSize);
1461 if ((Cert ==
NULL) || (FromSize ==
NULL) || (ToSize ==
NULL) || (CertSize == 0)) {
1472 if ((X509Cert ==
NULL) || (!Status)) {
1479 F = X509_get0_notBefore (X509Cert);
1480 T = X509_get0_notAfter (X509Cert);
1486 FSize =
sizeof (ASN1_TIME) + F->length;
1487 if (*FromSize < FSize) {
1494 CopyMem (From, F,
sizeof (ASN1_TIME));
1495 ((ASN1_TIME *)From)->data = From +
sizeof (ASN1_TIME);
1496 CopyMem (From +
sizeof (ASN1_TIME), F->data, F->length);
1499 TSize =
sizeof (ASN1_TIME) + T->length;
1500 if (*ToSize < TSize) {
1507 CopyMem (To, T,
sizeof (ASN1_TIME));
1508 ((ASN1_TIME *)To)->data = To +
sizeof (ASN1_TIME);
1509 CopyMem (To +
sizeof (ASN1_TIME), T->data, T->length);
1518 if (X509Cert !=
NULL) {
1519 X509_free (X509Cert);
1564 Dt = ASN1_TIME_new ();
1570 Ret = ASN1_TIME_set_string_X509 (Dt, DateTimeStr);
1576 DSize =
sizeof (ASN1_TIME) + Dt->length;
1577 if (*DateTimeSize < DSize) {
1578 *DateTimeSize = DSize;
1583 *DateTimeSize = DSize;
1584 if (DateTime !=
NULL) {
1585 CopyMem (DateTime, Dt,
sizeof (ASN1_TIME));
1586 ((ASN1_TIME *)DateTime)->data = (UINT8 *)DateTime +
sizeof (ASN1_TIME);
1587 CopyMem ((UINT8 *)DateTime +
sizeof (ASN1_TIME), Dt->data, Dt->length);
1594 ASN1_TIME_free (Dt);
1623 return (INT32)ASN1_TIME_compare (DateTime1, DateTime2);
1651 if ((Cert ==
NULL) || (Usage ==
NULL)) {
1662 if ((X509Cert ==
NULL) || (!Status)) {
1669 *Usage = X509_get_key_usage (X509Cert);
1670 if (*Usage == NID_undef) {
1680 if (X509Cert !=
NULL) {
1681 X509_free (X509Cert);
1712 CONST UINT8 *TmpPtr;
1716 CONST UINT8 *CurrentCert;
1717 UINTN CurrentCertLen;
1718 CONST UINT8 *PrecedingCert;
1719 UINTN PrecedingCertLen;
1723 PrecedingCert = RootCert;
1724 PrecedingCertLen = RootCertLength;
1726 CurrentCert = CertChain;
1732 TmpPtr = CurrentCert;
1733 Ret = ASN1_get_object (
1734 (
CONST UINT8 **)&TmpPtr,
1738 (
long)(CertChainLength + CertChain - TmpPtr)
1740 if ((Asn1Tag != V_ASN1_SEQUENCE) || (Ret == 0x80)) {
1747 CurrentCertLen = TmpPtr - CurrentCert + Length;
1752 VerifyFlag =
X509VerifyCert (CurrentCert, CurrentCertLen, PrecedingCert, PrecedingCertLen);
1753 if (VerifyFlag ==
FALSE) {
1760 PrecedingCertLen = CurrentCertLen;
1761 PrecedingCert = CurrentCert;
1766 CurrentCert = CurrentCert + CurrentCertLen;
1802 UINTN CurrentCertLen;
1803 CONST UINT8 *CurrentCert;
1804 CONST UINT8 *TmpPtr;
1812 if ((CertChain ==
NULL) || (Cert ==
NULL) ||
1813 (CertIndex < -1) || (CertLength ==
NULL))
1820 CurrentCert = CertChain;
1827 TmpPtr = CurrentCert;
1830 Ret = ASN1_get_object (
1831 (
CONST UINT8 **)&TmpPtr,
1835 (
long)(CertChainLength + CertChain - TmpPtr)
1837 if ((Asn1Tag != V_ASN1_SEQUENCE) || (Ret == 0x80)) {
1844 CurrentCertLen = TmpPtr - CurrentCert + Asn1Len;
1847 if (CurrentIndex == CertIndex) {
1848 *Cert = CurrentCert;
1849 *CertLength = CurrentCertLen;
1856 CurrentCert = CurrentCert + CurrentCertLen;
1862 if ((CertIndex == -1) && (CurrentIndex >= 0)) {
1863 *Cert = CurrentCert - CurrentCertLen;
1864 *CertLength = CurrentCertLen;
1902 Inf = ASN1_get_object ((
CONST UINT8 **)Ptr, &ObjLength, &ObjTag, &ObjCls, (INT32)(End - (*Ptr)));
1903 if (((Inf & 0x80) == 0x00) &&
1904 (ObjTag == (INT32)(Tag & CRYPTO_ASN1_TAG_VALUE_MASK)) &&
1905 (ObjCls == (INT32)(Tag & CRYPTO_ASN1_TAG_CLASS_MASK)))
1907 *Length = (
UINTN)ObjLength;
1941 UINT8 *BasicConstraints,
1942 UINTN *BasicConstraintsSize
1947 if ((Cert ==
NULL) || (CertSize == 0) || (BasicConstraintsSize ==
NULL)) {
1954 mOidBasicConstraints,
1955 sizeof (mOidBasicConstraints),
1957 BasicConstraintsSize
INTN EFIAPI CompareMem(IN CONST VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define RETURN_BUFFER_TOO_SMALL
#define VA_ARG(Marker, TYPE)
#define VA_START(Marker, Parameter)
#define RETURN_INVALID_PARAMETER
BOOLEAN EFIAPI X509GetSerialNumber(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *SerialNumber, OPTIONAL IN OUT UINTN *SerialNumberSize)
INT32 EFIAPI X509CompareDateTime(IN CONST VOID *DateTime1, IN CONST VOID *DateTime2)
BOOLEAN EFIAPI X509GetVersion(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINTN *Version)
BOOLEAN EFIAPI X509GetExtensionData(IN CONST UINT8 *Cert, IN UINTN CertSize, IN CONST UINT8 *Oid, IN UINTN OidSize, OUT UINT8 *ExtensionData, IN OUT UINTN *ExtensionDataSize)
BOOLEAN EFIAPI X509ConstructCertificateStack(IN OUT UINT8 **X509Stack,...)
BOOLEAN EFIAPI X509GetIssuerName(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *CertIssuer, IN OUT UINTN *CertIssuerSize)
STATIC RETURN_STATUS InternalX509GetNIDName(IN CONST UINT8 *Cert, IN UINTN CertSize, IN INT32 Request_NID, OUT CHAR8 *CommonName OPTIONAL, IN OUT UINTN *CommonNameSize)
BOOLEAN EFIAPI X509FormatDateTime(IN CONST CHAR8 *DateTimeStr, OUT VOID *DateTime, IN OUT UINTN *DateTimeSize)
BOOLEAN EFIAPI X509VerifyCert(IN CONST UINT8 *Cert, IN UINTN CertSize, IN CONST UINT8 *CACert, IN UINTN CACertSize)
BOOLEAN EFIAPI X509GetSignatureAlgorithm(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *Oid, OPTIONAL IN OUT UINTN *OidSize)
BOOLEAN EFIAPI RsaGetPublicKeyFromX509(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT VOID **RsaContext)
RETURN_STATUS EFIAPI X509GetOrganizationName(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT CHAR8 *NameBuffer OPTIONAL, IN OUT UINTN *NameBufferSize)
VOID EFIAPI X509StackFree(IN VOID *X509Stack)
BOOLEAN EFIAPI X509GetExtendedKeyUsage(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *Usage, IN OUT UINTN *UsageSize)
BOOLEAN EFIAPI X509GetValidity(IN CONST UINT8 *Cert, IN UINTN CertSize, IN UINT8 *From, IN OUT UINTN *FromSize, IN UINT8 *To, IN OUT UINTN *ToSize)
BOOLEAN EFIAPI Asn1GetTag(IN OUT UINT8 **Ptr, IN CONST UINT8 *End, OUT UINTN *Length, IN UINT32 Tag)
BOOLEAN EFIAPI EcGetPublicKeyFromX509(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT VOID **EcContext)
VOID EFIAPI X509Free(IN VOID *X509Cert)
BOOLEAN EFIAPI X509ConstructCertificateStackV(IN OUT UINT8 **X509Stack, IN VA_LIST Args)
BOOLEAN EFIAPI X509GetCertFromCertChain(IN CONST UINT8 *CertChain, IN UINTN CertChainLength, IN CONST INT32 CertIndex, OUT CONST UINT8 **Cert, OUT UINTN *CertLength)
BOOLEAN EFIAPI X509GetSubjectName(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *CertSubject, IN OUT UINTN *SubjectSize)
BOOLEAN EFIAPI X509GetKeyUsage(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINTN *Usage)
BOOLEAN EFIAPI X509GetTBSCert(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 **TBSCert, OUT UINTN *TBSCertSize)
BOOLEAN EFIAPI X509GetExtendedBasicConstraints(CONST UINT8 *Cert, UINTN CertSize, UINT8 *BasicConstraints, UINTN *BasicConstraintsSize)
RETURN_STATUS EFIAPI X509GetCommonName(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT CHAR8 *CommonName OPTIONAL, IN OUT UINTN *CommonNameSize)
BOOLEAN EFIAPI X509VerifyCertChain(IN CONST UINT8 *RootCert, IN UINTN RootCertLength, IN CONST UINT8 *CertChain, IN UINTN CertChainLength)
BOOLEAN EFIAPI X509ConstructCertificate(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 **SingleX509Cert)