TianoCore EDK2 master
Loading...
Searching...
No Matches
CryptX509.c
Go to the documentation of this file.
1
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>
15
16/* OID*/
17#define OID_EXT_KEY_USAGE { 0x55, 0x1D, 0x25 }
18#define OID_BASIC_CONSTRAINTS { 0x55, 0x1D, 0x13 }
19
20static CONST UINT8 mOidExtKeyUsage[] = OID_EXT_KEY_USAGE;
21static CONST UINT8 mOidBasicConstraints[] = OID_BASIC_CONSTRAINTS;
22
23#define CRYPTO_ASN1_TAG_CLASS_MASK 0xC0
24#define CRYPTO_ASN1_TAG_PC_MASK 0x20
25#define CRYPTO_ASN1_TAG_VALUE_MASK 0x1F
26
41BOOLEAN
42EFIAPI
44 IN CONST UINT8 *Cert,
45 IN UINTN CertSize,
46 OUT UINT8 **SingleX509Cert
47 )
48{
49 X509 *X509Cert;
50 CONST UINT8 *Temp;
51
52 //
53 // Check input parameters.
54 //
55 if ((Cert == NULL) || (SingleX509Cert == NULL) || (CertSize > INT_MAX)) {
56 return FALSE;
57 }
58
59 //
60 // Read DER-encoded X509 Certificate and Construct X509 object.
61 //
62 Temp = Cert;
63 X509Cert = d2i_X509 (NULL, &Temp, (long)CertSize);
64 if (X509Cert == NULL) {
65 return FALSE;
66 }
67
68 *SingleX509Cert = (UINT8 *)X509Cert;
69
70 return TRUE;
71}
72
92BOOLEAN
93EFIAPI
95 IN OUT UINT8 **X509Stack,
96 IN VA_LIST Args
97 )
98{
99 UINT8 *Cert;
100 UINTN CertSize;
101 X509 *X509Cert;
102
103 STACK_OF (X509) *CertStack;
104 BOOLEAN Status;
105
106 //
107 // Check input parameters.
108 //
109 if (X509Stack == NULL) {
110 return FALSE;
111 }
112
113 Status = FALSE;
114
115 //
116 // Initialize X509 stack object.
117 //
118 CertStack = (STACK_OF (X509) *)(*X509Stack);
119 if (CertStack == NULL) {
120 CertStack = sk_X509_new_null ();
121 if (CertStack == NULL) {
122 return Status;
123 }
124 }
125
126 while (TRUE) {
127 //
128 // If Cert is NULL, then it is the end of the list.
129 //
130 Cert = VA_ARG (Args, UINT8 *);
131 if (Cert == NULL) {
132 break;
133 }
134
135 CertSize = VA_ARG (Args, UINTN);
136 if (CertSize == 0) {
137 break;
138 }
139
140 //
141 // Construct X509 Object from the given DER-encoded certificate data.
142 //
143 X509Cert = NULL;
144 Status = X509ConstructCertificate (
145 (CONST UINT8 *)Cert,
146 CertSize,
147 (UINT8 **)&X509Cert
148 );
149 if (!Status) {
150 if (X509Cert != NULL) {
151 X509_free (X509Cert);
152 }
153
154 break;
155 }
156
157 //
158 // Insert the new X509 object into X509 stack object.
159 //
160 sk_X509_push (CertStack, X509Cert);
161 }
162
163 if (!Status) {
164 sk_X509_pop_free (CertStack, X509_free);
165 } else {
166 *X509Stack = (UINT8 *)CertStack;
167 }
168
169 return Status;
170}
171
188BOOLEAN
189EFIAPI
191 IN OUT UINT8 **X509Stack,
192 ...
193 )
194{
195 VA_LIST Args;
196 BOOLEAN Result;
197
198 VA_START (Args, X509Stack);
199 Result = X509ConstructCertificateStackV (X509Stack, Args);
200 VA_END (Args);
201 return Result;
202}
203
212VOID
213EFIAPI
215 IN VOID *X509Cert
216 )
217{
218 //
219 // Check input parameters.
220 //
221 if (X509Cert == NULL) {
222 return;
223 }
224
225 //
226 // Free OpenSSL X509 object.
227 //
228 X509_free ((X509 *)X509Cert);
229}
230
239VOID
240EFIAPI
242 IN VOID *X509Stack
243 )
244{
245 //
246 // Check input parameters.
247 //
248 if (X509Stack == NULL) {
249 return;
250 }
251
252 //
253 // Free OpenSSL X509 stack object.
254 //
255 sk_X509_pop_free ((STACK_OF (X509) *) X509Stack, X509_free);
256}
257
275BOOLEAN
276EFIAPI
278 IN CONST UINT8 *Cert,
279 IN UINTN CertSize,
280 OUT UINT8 *CertSubject,
281 IN OUT UINTN *SubjectSize
282 )
283{
284 BOOLEAN Status;
285 X509 *X509Cert;
286 X509_NAME *X509Name;
287 UINTN X509NameSize;
288
289 //
290 // Check input parameters.
291 //
292 if ((Cert == NULL) || (SubjectSize == NULL)) {
293 return FALSE;
294 }
295
296 X509Cert = NULL;
297
298 //
299 // Read DER-encoded X509 Certificate and Construct X509 object.
300 //
301 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
302 if ((X509Cert == NULL) || (!Status)) {
303 Status = FALSE;
304 goto _Exit;
305 }
306
307 Status = FALSE;
308
309 //
310 // Retrieve subject name from certificate object.
311 //
312 X509Name = X509_get_subject_name (X509Cert);
313 if (X509Name == NULL) {
314 goto _Exit;
315 }
316
317 X509NameSize = i2d_X509_NAME (X509Name, NULL);
318 if (*SubjectSize < X509NameSize) {
319 *SubjectSize = X509NameSize;
320 goto _Exit;
321 }
322
323 *SubjectSize = X509NameSize;
324 if (CertSubject != NULL) {
325 i2d_X509_NAME (X509Name, &CertSubject);
326 Status = TRUE;
327 }
328
329_Exit:
330 //
331 // Release Resources.
332 //
333 if (X509Cert != NULL) {
334 X509_free (X509Cert);
335 }
336
337 return Status;
338}
339
367STATIC
368RETURN_STATUS
370 IN CONST UINT8 *Cert,
371 IN UINTN CertSize,
372 IN INT32 Request_NID,
373 OUT CHAR8 *CommonName OPTIONAL,
374 IN OUT UINTN *CommonNameSize
375 )
376{
377 RETURN_STATUS ReturnStatus;
378 BOOLEAN Status;
379 X509 *X509Cert;
380 X509_NAME *X509Name;
381 INT32 Index;
382 INTN Length;
383 X509_NAME_ENTRY *Entry;
384 ASN1_STRING *EntryData;
385 UINT8 *UTF8Name;
386
387 ReturnStatus = RETURN_INVALID_PARAMETER;
388 UTF8Name = NULL;
389
390 //
391 // Check input parameters.
392 //
393 if ((Cert == NULL) || (CertSize > INT_MAX) || (CommonNameSize == NULL)) {
394 return ReturnStatus;
395 }
396
397 if ((CommonName != NULL) && (*CommonNameSize == 0)) {
398 return ReturnStatus;
399 }
400
401 X509Cert = NULL;
402 //
403 // Read DER-encoded X509 Certificate and Construct X509 object.
404 //
405 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
406 if ((X509Cert == NULL) || (!Status)) {
407 //
408 // Invalid X.509 Certificate
409 //
410 goto _Exit;
411 }
412
413 Status = FALSE;
414
415 //
416 // Retrieve subject name from certificate object.
417 //
418 X509Name = X509_get_subject_name (X509Cert);
419 if (X509Name == NULL) {
420 //
421 // Fail to retrieve subject name content
422 //
423 goto _Exit;
424 }
425
426 //
427 // Retrive the string from X.509 Subject base on the Request_NID
428 //
429 Index = X509_NAME_get_index_by_NID (X509Name, Request_NID, -1);
430 if (Index < 0) {
431 //
432 // No Request_NID name entry exists in X509_NAME object
433 //
434 *CommonNameSize = 0;
435 ReturnStatus = RETURN_NOT_FOUND;
436 goto _Exit;
437 }
438
439 Entry = X509_NAME_get_entry (X509Name, Index);
440 if (Entry == NULL) {
441 //
442 // Fail to retrieve name entry data
443 //
444 *CommonNameSize = 0;
445 ReturnStatus = RETURN_NOT_FOUND;
446 goto _Exit;
447 }
448
449 EntryData = X509_NAME_ENTRY_get_data (Entry);
450
451 Length = ASN1_STRING_to_UTF8 (&UTF8Name, EntryData);
452 if (Length < 0) {
453 //
454 // Fail to convert the Name string
455 //
456 *CommonNameSize = 0;
457 ReturnStatus = RETURN_INVALID_PARAMETER;
458 goto _Exit;
459 }
460
461 if (CommonName == NULL) {
462 *CommonNameSize = Length + 1;
463 ReturnStatus = RETURN_BUFFER_TOO_SMALL;
464 } else {
465 *CommonNameSize = MIN ((UINTN)Length, *CommonNameSize - 1) + 1;
466 CopyMem (CommonName, UTF8Name, *CommonNameSize - 1);
467 CommonName[*CommonNameSize - 1] = '\0';
468 ReturnStatus = RETURN_SUCCESS;
469 }
470
471_Exit:
472 //
473 // Release Resources.
474 //
475 if (X509Cert != NULL) {
476 X509_free (X509Cert);
477 }
478
479 if (UTF8Name != NULL) {
480 OPENSSL_free (UTF8Name);
481 }
482
483 return ReturnStatus;
484}
485
512RETURN_STATUS
513EFIAPI
515 IN CONST UINT8 *Cert,
516 IN UINTN CertSize,
517 OUT CHAR8 *CommonName OPTIONAL,
518 IN OUT UINTN *CommonNameSize
519 )
520{
521 return InternalX509GetNIDName (Cert, CertSize, NID_commonName, CommonName, CommonNameSize);
522}
523
550RETURN_STATUS
551EFIAPI
553 IN CONST UINT8 *Cert,
554 IN UINTN CertSize,
555 OUT CHAR8 *NameBuffer OPTIONAL,
556 IN OUT UINTN *NameBufferSize
557 )
558{
559 return InternalX509GetNIDName (Cert, CertSize, NID_organizationName, NameBuffer, NameBufferSize);
560}
561
578BOOLEAN
579EFIAPI
581 IN CONST UINT8 *Cert,
582 IN UINTN CertSize,
583 OUT VOID **RsaContext
584 )
585{
586 BOOLEAN Status;
587 EVP_PKEY *Pkey;
588 X509 *X509Cert;
589
590 //
591 // Check input parameters.
592 //
593 if ((Cert == NULL) || (RsaContext == NULL)) {
594 return FALSE;
595 }
596
597 Pkey = NULL;
598 X509Cert = NULL;
599
600 //
601 // Read DER-encoded X509 Certificate and Construct X509 object.
602 //
603 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
604 if ((X509Cert == NULL) || (!Status)) {
605 Status = FALSE;
606 goto _Exit;
607 }
608
609 Status = FALSE;
610
611 //
612 // Retrieve and check EVP_PKEY data from X509 Certificate.
613 //
614 Pkey = X509_get_pubkey (X509Cert);
615 if ((Pkey == NULL) || (EVP_PKEY_id (Pkey) != EVP_PKEY_RSA)) {
616 goto _Exit;
617 }
618
619 //
620 // Duplicate RSA Context from the retrieved EVP_PKEY.
621 //
622 if ((*RsaContext = RSAPublicKey_dup (EVP_PKEY_get0_RSA (Pkey))) != NULL) {
623 Status = TRUE;
624 }
625
626_Exit:
627 //
628 // Release Resources.
629 //
630 if (X509Cert != NULL) {
631 X509_free (X509Cert);
632 }
633
634 if (Pkey != NULL) {
635 EVP_PKEY_free (Pkey);
636 }
637
638 return Status;
639}
640
657BOOLEAN
658EFIAPI
660 IN CONST UINT8 *Cert,
661 IN UINTN CertSize,
662 IN CONST UINT8 *CACert,
663 IN UINTN CACertSize
664 )
665{
666 BOOLEAN Status;
667 X509 *X509Cert;
668 X509 *X509CACert;
669 X509_STORE *CertStore;
670 X509_STORE_CTX *CertCtx;
671
672 //
673 // Check input parameters.
674 //
675 if ((Cert == NULL) || (CACert == NULL)) {
676 return FALSE;
677 }
678
679 Status = FALSE;
680 X509Cert = NULL;
681 X509CACert = NULL;
682 CertStore = NULL;
683 CertCtx = NULL;
684
685 //
686 // Register & Initialize necessary digest algorithms for certificate verification.
687 //
688 if (EVP_add_digest (EVP_md5 ()) == 0) {
689 goto _Exit;
690 }
691
692 if (EVP_add_digest (EVP_sha1 ()) == 0) {
693 goto _Exit;
694 }
695
696 if (EVP_add_digest (EVP_sha256 ()) == 0) {
697 goto _Exit;
698 }
699
700 //
701 // Read DER-encoded certificate to be verified and Construct X509 object.
702 //
703 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
704 if ((X509Cert == NULL) || (!Status)) {
705 Status = FALSE;
706 goto _Exit;
707 }
708
709 //
710 // Read DER-encoded root certificate and Construct X509 object.
711 //
712 Status = X509ConstructCertificate (CACert, CACertSize, (UINT8 **)&X509CACert);
713 if ((X509CACert == NULL) || (!Status)) {
714 Status = FALSE;
715 goto _Exit;
716 }
717
718 Status = FALSE;
719
720 //
721 // Set up X509 Store for trusted certificate.
722 //
723 CertStore = X509_STORE_new ();
724 if (CertStore == NULL) {
725 goto _Exit;
726 }
727
728 if (!(X509_STORE_add_cert (CertStore, X509CACert))) {
729 goto _Exit;
730 }
731
732 //
733 // Allow partial certificate chains, terminated by a non-self-signed but
734 // still trusted intermediate certificate. Also disable time checks.
735 //
736 X509_STORE_set_flags (
737 CertStore,
738 X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
739 );
740
741 //
742 // Set up X509_STORE_CTX for the subsequent verification operation.
743 //
744 CertCtx = X509_STORE_CTX_new ();
745 if (CertCtx == NULL) {
746 goto _Exit;
747 }
748
749 if (!X509_STORE_CTX_init (CertCtx, CertStore, X509Cert, NULL)) {
750 goto _Exit;
751 }
752
753 //
754 // X509 Certificate Verification.
755 //
756 Status = (BOOLEAN)X509_verify_cert (CertCtx);
757 X509_STORE_CTX_cleanup (CertCtx);
758
759_Exit:
760 //
761 // Release Resources.
762 //
763 if (X509Cert != NULL) {
764 X509_free (X509Cert);
765 }
766
767 if (X509CACert != NULL) {
768 X509_free (X509CACert);
769 }
770
771 if (CertStore != NULL) {
772 X509_STORE_free (CertStore);
773 }
774
775 X509_STORE_CTX_free (CertCtx);
776
777 return Status;
778}
779
796BOOLEAN
797EFIAPI
799 IN CONST UINT8 *Cert,
800 IN UINTN CertSize,
801 OUT UINT8 **TBSCert,
802 OUT UINTN *TBSCertSize
803 )
804{
805 CONST UINT8 *Temp;
806 UINT32 Asn1Tag;
807 UINT32 ObjClass;
808 UINTN Length;
809 UINTN Inf;
810
811 //
812 // Check input parameters.
813 //
814 if ((Cert == NULL) || (TBSCert == NULL) ||
815 (TBSCertSize == NULL) || (CertSize > INT_MAX))
816 {
817 return FALSE;
818 }
819
820 //
821 // An X.509 Certificate is: (defined in RFC3280)
822 // Certificate ::= SEQUENCE {
823 // tbsCertificate TBSCertificate,
824 // signatureAlgorithm AlgorithmIdentifier,
825 // signature BIT STRING }
826 //
827 // and
828 //
829 // TBSCertificate ::= SEQUENCE {
830 // version [0] Version DEFAULT v1,
831 // ...
832 // }
833 //
834 // So we can just ASN1-parse the x.509 DER-encoded data. If we strip
835 // the first SEQUENCE, the second SEQUENCE is the TBSCertificate.
836 //
837 Temp = Cert;
838 Length = 0;
839 Inf = ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)CertSize);
840
841 if (((Inf & 0x80) == 0x80) || (Asn1Tag != V_ASN1_SEQUENCE)) {
842 return FALSE;
843 }
844
845 *TBSCert = (UINT8 *)Temp;
846
847 Inf = ASN1_get_object (&Temp, (long *)&Length, (int *)&Asn1Tag, (int *)&ObjClass, (long)Length);
848 //
849 // Verify the parsed TBSCertificate is one correct SEQUENCE data.
850 //
851 if (((Inf & 0x80) == 0x80) || (Asn1Tag != V_ASN1_SEQUENCE)) {
852 return FALSE;
853 }
854
855 *TBSCertSize = Length + (Temp - *TBSCert);
856
857 return TRUE;
858}
859
876BOOLEAN
877EFIAPI
879 IN CONST UINT8 *Cert,
880 IN UINTN CertSize,
881 OUT VOID **EcContext
882 )
883{
884 BOOLEAN Status;
885 EVP_PKEY *Pkey;
886 X509 *X509Cert;
887
888 //
889 // Check input parameters.
890 //
891 if ((Cert == NULL) || (EcContext == NULL)) {
892 return FALSE;
893 }
894
895 Pkey = NULL;
896 X509Cert = NULL;
897
898 //
899 // Read DER-encoded X509 Certificate and Construct X509 object.
900 //
901 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
902 if ((X509Cert == NULL) || (!Status)) {
903 Status = FALSE;
904 goto _Exit;
905 }
906
907 Status = FALSE;
908
909 //
910 // Retrieve and check EVP_PKEY data from X509 Certificate.
911 //
912 Pkey = X509_get_pubkey (X509Cert);
913 if ((Pkey == NULL) || (EVP_PKEY_id (Pkey) != EVP_PKEY_EC)) {
914 goto _Exit;
915 }
916
917 //
918 // Duplicate EC Context from the retrieved EVP_PKEY.
919 //
920 if ((*EcContext = EC_KEY_dup (EVP_PKEY_get0_EC_KEY (Pkey))) != NULL) {
921 Status = TRUE;
922 }
923
924_Exit:
925 //
926 // Release Resources.
927 //
928 if (X509Cert != NULL) {
929 X509_free (X509Cert);
930 }
931
932 if (Pkey != NULL) {
933 EVP_PKEY_free (Pkey);
934 }
935
936 return Status;
937}
938
955BOOLEAN
956EFIAPI
958 IN CONST UINT8 *Cert,
959 IN UINTN CertSize,
960 OUT UINTN *Version
961 )
962{
963 BOOLEAN Status;
964 X509 *X509Cert;
965
966 X509Cert = NULL;
967 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
968 if ((X509Cert == NULL) || (!Status)) {
969 //
970 // Invalid X.509 Certificate
971 //
972 Status = FALSE;
973 }
974
975 if (Status) {
976 *Version = X509_get_version (X509Cert);
977 }
978
979 if (X509Cert != NULL) {
980 X509_free (X509Cert);
981 }
982
983 return Status;
984}
985
1009BOOLEAN
1010EFIAPI
1012 IN CONST UINT8 *Cert,
1013 IN UINTN CertSize,
1014 OUT UINT8 *SerialNumber, OPTIONAL
1015 IN OUT UINTN *SerialNumberSize
1016 )
1017{
1018 BOOLEAN Status;
1019 X509 *X509Cert;
1020 ASN1_INTEGER *Asn1Integer;
1021
1022 Status = FALSE;
1023 //
1024 // Check input parameters.
1025 //
1026 if ((Cert == NULL) || (SerialNumberSize == NULL)) {
1027 return Status;
1028 }
1029
1030 X509Cert = NULL;
1031
1032 //
1033 // Read DER-encoded X509 Certificate and Construct X509 object.
1034 //
1035 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
1036 if ((X509Cert == NULL) || (!Status)) {
1037 *SerialNumberSize = 0;
1038 Status = FALSE;
1039 goto _Exit;
1040 }
1041
1042 //
1043 // Retrieve subject name from certificate object.
1044 //
1045 Asn1Integer = X509_get_serialNumber (X509Cert);
1046 if (Asn1Integer == NULL) {
1047 *SerialNumberSize = 0;
1048 Status = FALSE;
1049 goto _Exit;
1050 }
1051
1052 if (*SerialNumberSize < (UINTN)Asn1Integer->length) {
1053 *SerialNumberSize = (UINTN)Asn1Integer->length;
1054 Status = FALSE;
1055 goto _Exit;
1056 }
1057
1058 if (SerialNumber != NULL) {
1059 CopyMem (SerialNumber, Asn1Integer->data, (UINTN)Asn1Integer->length);
1060 Status = TRUE;
1061 }
1062
1063 *SerialNumberSize = (UINTN)Asn1Integer->length;
1064
1065_Exit:
1066 //
1067 // Release Resources.
1068 //
1069 if (X509Cert != NULL) {
1070 X509_free (X509Cert);
1071 }
1072
1073 return Status;
1074}
1075
1095BOOLEAN
1096EFIAPI
1098 IN CONST UINT8 *Cert,
1099 IN UINTN CertSize,
1100 OUT UINT8 *CertIssuer,
1101 IN OUT UINTN *CertIssuerSize
1102 )
1103{
1104 BOOLEAN Status;
1105 X509 *X509Cert;
1106 X509_NAME *X509Name;
1107 UINTN X509NameSize;
1108
1109 //
1110 // Check input parameters.
1111 //
1112 if ((Cert == NULL) || (CertIssuerSize == NULL)) {
1113 return FALSE;
1114 }
1115
1116 X509Cert = NULL;
1117
1118 //
1119 // Read DER-encoded X509 Certificate and Construct X509 object.
1120 //
1121 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
1122 if ((X509Cert == NULL) || (!Status)) {
1123 Status = FALSE;
1124 goto _Exit;
1125 }
1126
1127 Status = FALSE;
1128
1129 //
1130 // Retrieve subject name from certificate object.
1131 //
1132 X509Name = X509_get_subject_name (X509Cert);
1133 if (X509Name == NULL) {
1134 goto _Exit;
1135 }
1136
1137 X509NameSize = i2d_X509_NAME (X509Name, NULL);
1138 if (*CertIssuerSize < X509NameSize) {
1139 *CertIssuerSize = X509NameSize;
1140 goto _Exit;
1141 }
1142
1143 *CertIssuerSize = X509NameSize;
1144 if (CertIssuer != NULL) {
1145 i2d_X509_NAME (X509Name, &CertIssuer);
1146 Status = TRUE;
1147 }
1148
1149_Exit:
1150 //
1151 // Release Resources.
1152 //
1153 if (X509Cert != NULL) {
1154 X509_free (X509Cert);
1155 }
1156
1157 return Status;
1158}
1159
1178BOOLEAN
1179EFIAPI
1181 IN CONST UINT8 *Cert,
1182 IN UINTN CertSize,
1183 OUT UINT8 *Oid, OPTIONAL
1184 IN OUT UINTN *OidSize
1185 )
1186{
1187 BOOLEAN Status;
1188 X509 *X509Cert;
1189 int Nid;
1190 ASN1_OBJECT *Asn1Obj;
1191
1192 //
1193 // Check input parameters.
1194 //
1195 if ((Cert == NULL) || (OidSize == NULL) || (CertSize == 0)) {
1196 return FALSE;
1197 }
1198
1199 X509Cert = NULL;
1200 Status = FALSE;
1201
1202 //
1203 // Read DER-encoded X509 Certificate and Construct X509 object.
1204 //
1205 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
1206 if ((X509Cert == NULL) || (!Status)) {
1207 Status = FALSE;
1208 goto _Exit;
1209 }
1210
1211 //
1212 // Retrieve subject name from certificate object.
1213 //
1214 Nid = X509_get_signature_nid (X509Cert);
1215 if (Nid == NID_undef) {
1216 *OidSize = 0;
1217 Status = FALSE;
1218 goto _Exit;
1219 }
1220
1221 Asn1Obj = OBJ_nid2obj (Nid);
1222 if (Asn1Obj == NULL) {
1223 *OidSize = 0;
1224 Status = FALSE;
1225 goto _Exit;
1226 }
1227
1228 if (*OidSize < (UINTN)Asn1Obj->length) {
1229 *OidSize = Asn1Obj->length;
1230 Status = FALSE;
1231 goto _Exit;
1232 }
1233
1234 if (Oid != NULL) {
1235 CopyMem (Oid, Asn1Obj->data, Asn1Obj->length);
1236 }
1237
1238 *OidSize = Asn1Obj->length;
1239 Status = TRUE;
1240
1241_Exit:
1242 //
1243 // Release Resources.
1244 //
1245 if (X509Cert != NULL) {
1246 X509_free (X509Cert);
1247 }
1248
1249 return Status;
1250}
1251
1272BOOLEAN
1273EFIAPI
1275 IN CONST UINT8 *Cert,
1276 IN UINTN CertSize,
1277 IN CONST UINT8 *Oid,
1278 IN UINTN OidSize,
1279 OUT UINT8 *ExtensionData,
1280 IN OUT UINTN *ExtensionDataSize
1281 )
1282{
1283 BOOLEAN Status;
1284 INTN i;
1285 X509 *X509Cert;
1286
1287 CONST STACK_OF (X509_EXTENSION) *Extensions;
1288 ASN1_OBJECT *Asn1Obj;
1289 ASN1_OCTET_STRING *Asn1Oct;
1290 X509_EXTENSION *Ext;
1291 UINTN ObjLength;
1292 UINTN OctLength;
1293
1294 //
1295 // Check input parameters.
1296 //
1297 if ((Cert == NULL) || (CertSize == 0) || (Oid == NULL) || (OidSize == 0) || (ExtensionDataSize == NULL)) {
1298 return FALSE;
1299 }
1300
1301 X509Cert = NULL;
1302 Status = FALSE;
1303
1304 //
1305 // Read DER-encoded X509 Certificate and Construct X509 object.
1306 //
1307 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
1308 if ((X509Cert == NULL) || (!Status)) {
1309 *ExtensionDataSize = 0;
1310 goto Cleanup;
1311 }
1312
1313 //
1314 // Retrieve Extensions from certificate object.
1315 //
1316 Extensions = X509_get0_extensions (X509Cert);
1317 if (sk_X509_EXTENSION_num (Extensions) <= 0) {
1318 *ExtensionDataSize = 0;
1319 goto Cleanup;
1320 }
1321
1322 //
1323 // Traverse Extensions
1324 //
1325 Status = FALSE;
1326 Asn1Oct = NULL;
1327 OctLength = 0;
1328 for (i = 0; i < sk_X509_EXTENSION_num (Extensions); i++) {
1329 Ext = sk_X509_EXTENSION_value (Extensions, (int)i);
1330 if (Ext == NULL) {
1331 continue;
1332 }
1333
1334 Asn1Obj = X509_EXTENSION_get_object (Ext);
1335 if (Asn1Obj == NULL) {
1336 continue;
1337 }
1338
1339 Asn1Oct = X509_EXTENSION_get_data (Ext);
1340 if (Asn1Oct == NULL) {
1341 continue;
1342 }
1343
1344 ObjLength = OBJ_length (Asn1Obj);
1345 OctLength = ASN1_STRING_length (Asn1Oct);
1346 if ((OidSize == ObjLength) && (CompareMem (OBJ_get0_data (Asn1Obj), Oid, OidSize) == 0)) {
1347 //
1348 // Extension Found
1349 //
1350 Status = TRUE;
1351 break;
1352 }
1353
1354 //
1355 // reset to 0 if not found
1356 //
1357 OctLength = 0;
1358 }
1359
1360 if (Status) {
1361 if (*ExtensionDataSize < OctLength) {
1362 *ExtensionDataSize = OctLength;
1363 Status = FALSE;
1364 goto Cleanup;
1365 }
1366
1367 if (Asn1Oct != NULL) {
1368 CopyMem (ExtensionData, ASN1_STRING_get0_data (Asn1Oct), OctLength);
1369 }
1370
1371 *ExtensionDataSize = OctLength;
1372 } else {
1373 *ExtensionDataSize = 0;
1374 }
1375
1376Cleanup:
1377 //
1378 // Release Resources.
1379 //
1380 if (X509Cert != NULL) {
1381 X509_free (X509Cert);
1382 }
1383
1384 return Status;
1385}
1386
1404BOOLEAN
1405EFIAPI
1407 IN CONST UINT8 *Cert,
1408 IN UINTN CertSize,
1409 OUT UINT8 *Usage,
1410 IN OUT UINTN *UsageSize
1411 )
1412{
1413 BOOLEAN Status;
1414
1415 Status = X509GetExtensionData (Cert, CertSize, mOidExtKeyUsage, sizeof (mOidExtKeyUsage), Usage, UsageSize);
1416 return Status;
1417}
1418
1440BOOLEAN
1441EFIAPI
1443 IN CONST UINT8 *Cert,
1444 IN UINTN CertSize,
1445 IN UINT8 *From,
1446 IN OUT UINTN *FromSize,
1447 IN UINT8 *To,
1448 IN OUT UINTN *ToSize
1449 )
1450{
1451 BOOLEAN Status;
1452 X509 *X509Cert;
1453 CONST ASN1_TIME *F;
1454 CONST ASN1_TIME *T;
1455 UINTN TSize;
1456 UINTN FSize;
1457
1458 //
1459 // Check input parameters.
1460 //
1461 if ((Cert == NULL) || (FromSize == NULL) || (ToSize == NULL) || (CertSize == 0)) {
1462 return FALSE;
1463 }
1464
1465 X509Cert = NULL;
1466 Status = FALSE;
1467
1468 //
1469 // Read DER-encoded X509 Certificate and Construct X509 object.
1470 //
1471 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
1472 if ((X509Cert == NULL) || (!Status)) {
1473 goto _Exit;
1474 }
1475
1476 //
1477 // Retrieve Validity from/to from certificate object.
1478 //
1479 F = X509_get0_notBefore (X509Cert);
1480 T = X509_get0_notAfter (X509Cert);
1481
1482 if ((F == NULL) || (T == NULL)) {
1483 goto _Exit;
1484 }
1485
1486 FSize = sizeof (ASN1_TIME) + F->length;
1487 if (*FromSize < FSize) {
1488 *FromSize = FSize;
1489 goto _Exit;
1490 }
1491
1492 *FromSize = FSize;
1493 if (From != NULL) {
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);
1497 }
1498
1499 TSize = sizeof (ASN1_TIME) + T->length;
1500 if (*ToSize < TSize) {
1501 *ToSize = TSize;
1502 goto _Exit;
1503 }
1504
1505 *ToSize = TSize;
1506 if (To != NULL) {
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);
1510 }
1511
1512 Status = TRUE;
1513
1514_Exit:
1515 //
1516 // Release Resources.
1517 //
1518 if (X509Cert != NULL) {
1519 X509_free (X509Cert);
1520 }
1521
1522 return Status;
1523}
1524
1548BOOLEAN
1549EFIAPI
1551 IN CONST CHAR8 *DateTimeStr,
1552 OUT VOID *DateTime,
1553 IN OUT UINTN *DateTimeSize
1554 )
1555{
1556 BOOLEAN Status;
1557 INT32 Ret;
1558 ASN1_TIME *Dt;
1559 UINTN DSize;
1560
1561 Dt = NULL;
1562 Status = FALSE;
1563
1564 Dt = ASN1_TIME_new ();
1565 if (Dt == NULL) {
1566 Status = FALSE;
1567 goto Cleanup;
1568 }
1569
1570 Ret = ASN1_TIME_set_string_X509 (Dt, DateTimeStr);
1571 if (Ret != 1) {
1572 Status = FALSE;
1573 goto Cleanup;
1574 }
1575
1576 DSize = sizeof (ASN1_TIME) + Dt->length;
1577 if (*DateTimeSize < DSize) {
1578 *DateTimeSize = DSize;
1579 Status = FALSE;
1580 goto Cleanup;
1581 }
1582
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);
1588 }
1589
1590 Status = TRUE;
1591
1592Cleanup:
1593 if (Dt != NULL) {
1594 ASN1_TIME_free (Dt);
1595 }
1596
1597 return Status;
1598}
1599
1616INT32
1617EFIAPI
1619 IN CONST VOID *DateTime1,
1620 IN CONST VOID *DateTime2
1621 )
1622{
1623 return (INT32)ASN1_TIME_compare (DateTime1, DateTime2);
1624}
1625
1637BOOLEAN
1638EFIAPI
1640 IN CONST UINT8 *Cert,
1641 IN UINTN CertSize,
1642 OUT UINTN *Usage
1643 )
1644{
1645 BOOLEAN Status;
1646 X509 *X509Cert;
1647
1648 //
1649 // Check input parameters.
1650 //
1651 if ((Cert == NULL) || (Usage == NULL)) {
1652 return FALSE;
1653 }
1654
1655 X509Cert = NULL;
1656 Status = FALSE;
1657
1658 //
1659 // Read DER-encoded X509 Certificate and Construct X509 object.
1660 //
1661 Status = X509ConstructCertificate (Cert, CertSize, (UINT8 **)&X509Cert);
1662 if ((X509Cert == NULL) || (!Status)) {
1663 goto _Exit;
1664 }
1665
1666 //
1667 // Retrieve subject name from certificate object.
1668 //
1669 *Usage = X509_get_key_usage (X509Cert);
1670 if (*Usage == NID_undef) {
1671 goto _Exit;
1672 }
1673
1674 Status = TRUE;
1675
1676_Exit:
1677 //
1678 // Release Resources.
1679 //
1680 if (X509Cert != NULL) {
1681 X509_free (X509Cert);
1682 }
1683
1684 return Status;
1685}
1686
1703BOOLEAN
1704EFIAPI
1706 IN CONST UINT8 *RootCert,
1707 IN UINTN RootCertLength,
1708 IN CONST UINT8 *CertChain,
1709 IN UINTN CertChainLength
1710 )
1711{
1712 CONST UINT8 *TmpPtr;
1713 UINTN Length;
1714 UINT32 Asn1Tag;
1715 UINT32 ObjClass;
1716 CONST UINT8 *CurrentCert;
1717 UINTN CurrentCertLen;
1718 CONST UINT8 *PrecedingCert;
1719 UINTN PrecedingCertLen;
1720 BOOLEAN VerifyFlag;
1721 INT32 Ret;
1722
1723 PrecedingCert = RootCert;
1724 PrecedingCertLen = RootCertLength;
1725
1726 CurrentCert = CertChain;
1727 Length = 0;
1728 CurrentCertLen = 0;
1729
1730 VerifyFlag = FALSE;
1731 while (TRUE) {
1732 TmpPtr = CurrentCert;
1733 Ret = ASN1_get_object (
1734 (CONST UINT8 **)&TmpPtr,
1735 (long *)&Length,
1736 (int *)&Asn1Tag,
1737 (int *)&ObjClass,
1738 (long)(CertChainLength + CertChain - TmpPtr)
1739 );
1740 if ((Asn1Tag != V_ASN1_SEQUENCE) || (Ret == 0x80)) {
1741 break;
1742 }
1743
1744 //
1745 // Calculate CurrentCert length;
1746 //
1747 CurrentCertLen = TmpPtr - CurrentCert + Length;
1748
1749 //
1750 // Verify CurrentCert with preceding cert;
1751 //
1752 VerifyFlag = X509VerifyCert (CurrentCert, CurrentCertLen, PrecedingCert, PrecedingCertLen);
1753 if (VerifyFlag == FALSE) {
1754 break;
1755 }
1756
1757 //
1758 // move Current cert to Preceding cert
1759 //
1760 PrecedingCertLen = CurrentCertLen;
1761 PrecedingCert = CurrentCert;
1762
1763 //
1764 // Move to next
1765 //
1766 CurrentCert = CurrentCert + CurrentCertLen;
1767 }
1768
1769 return VerifyFlag;
1770}
1771
1790BOOLEAN
1791EFIAPI
1793 IN CONST UINT8 *CertChain,
1794 IN UINTN CertChainLength,
1795 IN CONST INT32 CertIndex,
1796 OUT CONST UINT8 **Cert,
1797 OUT UINTN *CertLength
1798 )
1799{
1800 UINTN Asn1Len;
1801 INT32 CurrentIndex;
1802 UINTN CurrentCertLen;
1803 CONST UINT8 *CurrentCert;
1804 CONST UINT8 *TmpPtr;
1805 INT32 Ret;
1806 UINT32 Asn1Tag;
1807 UINT32 ObjClass;
1808
1809 //
1810 // Check input parameters.
1811 //
1812 if ((CertChain == NULL) || (Cert == NULL) ||
1813 (CertIndex < -1) || (CertLength == NULL))
1814 {
1815 return FALSE;
1816 }
1817
1818 Asn1Len = 0;
1819 CurrentCertLen = 0;
1820 CurrentCert = CertChain;
1821 CurrentIndex = -1;
1822
1823 //
1824 // Traverse the certificate chain
1825 //
1826 while (TRUE) {
1827 TmpPtr = CurrentCert;
1828
1829 // Get asn1 object and taglen
1830 Ret = ASN1_get_object (
1831 (CONST UINT8 **)&TmpPtr,
1832 (long *)&Asn1Len,
1833 (int *)&Asn1Tag,
1834 (int *)&ObjClass,
1835 (long)(CertChainLength + CertChain - TmpPtr)
1836 );
1837 if ((Asn1Tag != V_ASN1_SEQUENCE) || (Ret == 0x80)) {
1838 break;
1839 }
1840
1841 //
1842 // Calculate CurrentCert length;
1843 //
1844 CurrentCertLen = TmpPtr - CurrentCert + Asn1Len;
1845 CurrentIndex++;
1846
1847 if (CurrentIndex == CertIndex) {
1848 *Cert = CurrentCert;
1849 *CertLength = CurrentCertLen;
1850 return TRUE;
1851 }
1852
1853 //
1854 // Move to next
1855 //
1856 CurrentCert = CurrentCert + CurrentCertLen;
1857 }
1858
1859 //
1860 // If CertIndex is -1, Return the last certificate
1861 //
1862 if ((CertIndex == -1) && (CurrentIndex >= 0)) {
1863 *Cert = CurrentCert - CurrentCertLen;
1864 *CertLength = CurrentCertLen;
1865 return TRUE;
1866 }
1867
1868 return FALSE;
1869}
1870
1882BOOLEAN
1883EFIAPI
1885 IN OUT UINT8 **Ptr,
1886 IN CONST UINT8 *End,
1887 OUT UINTN *Length,
1888 IN UINT32 Tag
1889 )
1890{
1891 UINT8 *PtrOld;
1892 INT32 ObjTag;
1893 INT32 ObjCls;
1894 long ObjLength;
1895 UINT32 Inf;
1896
1897 //
1898 // Save Ptr position
1899 //
1900 PtrOld = *Ptr;
1901
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)))
1906 {
1907 *Length = (UINTN)ObjLength;
1908 return TRUE;
1909 } else {
1910 //
1911 // if doesn't match Tag, restore Ptr to origin Ptr
1912 //
1913 *Ptr = PtrOld;
1914 return FALSE;
1915 }
1916}
1917
1936BOOLEAN
1937EFIAPI
1939 CONST UINT8 *Cert,
1940 UINTN CertSize,
1941 UINT8 *BasicConstraints,
1942 UINTN *BasicConstraintsSize
1943 )
1944{
1945 BOOLEAN Status;
1946
1947 if ((Cert == NULL) || (CertSize == 0) || (BasicConstraintsSize == NULL)) {
1948 return FALSE;
1949 }
1950
1951 Status = X509GetExtensionData (
1952 (UINT8 *)Cert,
1953 CertSize,
1954 mOidBasicConstraints,
1955 sizeof (mOidBasicConstraints),
1956 BasicConstraints,
1957 BasicConstraintsSize
1958 );
1959
1960 return Status;
1961}
UINT64 UINTN
INT64 INTN
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 NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define RETURN_BUFFER_TOO_SMALL
Definition: Base.h:1093
#define STATIC
Definition: Base.h:264
#define RETURN_NOT_FOUND
Definition: Base.h:1142
#define MIN(a, b)
Definition: Base.h:1007
#define VA_ARG(Marker, TYPE)
Definition: Base.h:679
#define VA_START(Marker, Parameter)
Definition: Base.h:661
#define RETURN_SUCCESS
Definition: Base.h:1066
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
CHAR8 * VA_LIST
Definition: Base.h:643
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define RETURN_INVALID_PARAMETER
Definition: Base.h:1076
#define VA_END(Marker)
Definition: Base.h:691
BOOLEAN EFIAPI X509GetSerialNumber(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *SerialNumber, OPTIONAL IN OUT UINTN *SerialNumberSize)
Definition: CryptX509.c:1011
INT32 EFIAPI X509CompareDateTime(IN CONST VOID *DateTime1, IN CONST VOID *DateTime2)
Definition: CryptX509.c:1618
BOOLEAN EFIAPI X509GetVersion(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINTN *Version)
Definition: CryptX509.c:957
BOOLEAN EFIAPI X509GetExtensionData(IN CONST UINT8 *Cert, IN UINTN CertSize, IN CONST UINT8 *Oid, IN UINTN OidSize, OUT UINT8 *ExtensionData, IN OUT UINTN *ExtensionDataSize)
Definition: CryptX509.c:1274
BOOLEAN EFIAPI X509ConstructCertificateStack(IN OUT UINT8 **X509Stack,...)
Definition: CryptX509.c:190
BOOLEAN EFIAPI X509GetIssuerName(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *CertIssuer, IN OUT UINTN *CertIssuerSize)
Definition: CryptX509.c:1097
STATIC RETURN_STATUS InternalX509GetNIDName(IN CONST UINT8 *Cert, IN UINTN CertSize, IN INT32 Request_NID, OUT CHAR8 *CommonName OPTIONAL, IN OUT UINTN *CommonNameSize)
Definition: CryptX509.c:369
BOOLEAN EFIAPI X509FormatDateTime(IN CONST CHAR8 *DateTimeStr, OUT VOID *DateTime, IN OUT UINTN *DateTimeSize)
Definition: CryptX509.c:1550
BOOLEAN EFIAPI X509VerifyCert(IN CONST UINT8 *Cert, IN UINTN CertSize, IN CONST UINT8 *CACert, IN UINTN CACertSize)
Definition: CryptX509.c:659
BOOLEAN EFIAPI X509GetSignatureAlgorithm(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *Oid, OPTIONAL IN OUT UINTN *OidSize)
Definition: CryptX509.c:1180
BOOLEAN EFIAPI RsaGetPublicKeyFromX509(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT VOID **RsaContext)
Definition: CryptX509.c:580
RETURN_STATUS EFIAPI X509GetOrganizationName(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT CHAR8 *NameBuffer OPTIONAL, IN OUT UINTN *NameBufferSize)
Definition: CryptX509.c:552
VOID EFIAPI X509StackFree(IN VOID *X509Stack)
Definition: CryptX509.c:241
BOOLEAN EFIAPI X509GetExtendedKeyUsage(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *Usage, IN OUT UINTN *UsageSize)
Definition: CryptX509.c:1406
BOOLEAN EFIAPI X509GetValidity(IN CONST UINT8 *Cert, IN UINTN CertSize, IN UINT8 *From, IN OUT UINTN *FromSize, IN UINT8 *To, IN OUT UINTN *ToSize)
Definition: CryptX509.c:1442
BOOLEAN EFIAPI Asn1GetTag(IN OUT UINT8 **Ptr, IN CONST UINT8 *End, OUT UINTN *Length, IN UINT32 Tag)
Definition: CryptX509.c:1884
BOOLEAN EFIAPI EcGetPublicKeyFromX509(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT VOID **EcContext)
Definition: CryptX509.c:878
VOID EFIAPI X509Free(IN VOID *X509Cert)
Definition: CryptX509.c:214
BOOLEAN EFIAPI X509ConstructCertificateStackV(IN OUT UINT8 **X509Stack, IN VA_LIST Args)
Definition: CryptX509.c:94
BOOLEAN EFIAPI X509GetCertFromCertChain(IN CONST UINT8 *CertChain, IN UINTN CertChainLength, IN CONST INT32 CertIndex, OUT CONST UINT8 **Cert, OUT UINTN *CertLength)
Definition: CryptX509.c:1792
BOOLEAN EFIAPI X509GetSubjectName(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 *CertSubject, IN OUT UINTN *SubjectSize)
Definition: CryptX509.c:277
BOOLEAN EFIAPI X509GetKeyUsage(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINTN *Usage)
Definition: CryptX509.c:1639
BOOLEAN EFIAPI X509GetTBSCert(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 **TBSCert, OUT UINTN *TBSCertSize)
Definition: CryptX509.c:798
BOOLEAN EFIAPI X509GetExtendedBasicConstraints(CONST UINT8 *Cert, UINTN CertSize, UINT8 *BasicConstraints, UINTN *BasicConstraintsSize)
Definition: CryptX509.c:1938
RETURN_STATUS EFIAPI X509GetCommonName(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT CHAR8 *CommonName OPTIONAL, IN OUT UINTN *CommonNameSize)
Definition: CryptX509.c:514
BOOLEAN EFIAPI X509VerifyCertChain(IN CONST UINT8 *RootCert, IN UINTN RootCertLength, IN CONST UINT8 *CertChain, IN UINTN CertChainLength)
Definition: CryptX509.c:1705
BOOLEAN EFIAPI X509ConstructCertificate(IN CONST UINT8 *Cert, IN UINTN CertSize, OUT UINT8 **SingleX509Cert)
Definition: CryptX509.c:43