+/**\r
+ Retrieve a string from one X.509 certificate base on the Request_NID.\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] Request_NID NID of string to obtain\r
+ @param[out] CommonName Buffer to contain the retrieved certificate common\r
+ name string (UTF8). At most CommonNameSize bytes will be\r
+ written and the string will be null terminated. May be\r
+ NULL in order to determine the size buffer needed.\r
+ @param[in,out] CommonNameSize The size in bytes of the CommonName buffer on input,\r
+ and the size of buffer returned CommonName on output.\r
+ If CommonName is NULL then the amount of space needed\r
+ in buffer (including the final null) is returned.\r
+\r
+ @retval RETURN_SUCCESS The certificate CommonName retrieved successfully.\r
+ @retval RETURN_INVALID_PARAMETER If Cert is NULL.\r
+ If CommonNameSize is NULL.\r
+ If CommonName is not NULL and *CommonNameSize is 0.\r
+ If Certificate is invalid.\r
+ @retval RETURN_NOT_FOUND If no NID Name entry exists.\r
+ @retval RETURN_BUFFER_TOO_SMALL If the CommonName is NULL. The required buffer size\r
+ (including the final null) is returned in the\r
+ CommonNameSize parameter.\r
+ @retval RETURN_UNSUPPORTED The operation is not supported.\r
+\r
+**/\r
+STATIC\r
+RETURN_STATUS\r
+InternalX509GetNIDName (\r
+ IN CONST UINT8 *Cert,\r
+ IN UINTN CertSize,\r
+ IN INT32 Request_NID,\r
+ OUT CHAR8 *CommonName OPTIONAL,\r
+ IN OUT UINTN *CommonNameSize\r
+ )\r
+{\r
+ RETURN_STATUS ReturnStatus;\r
+ BOOLEAN Status;\r
+ X509 *X509Cert;\r
+ X509_NAME *X509Name;\r
+ INT32 Index;\r
+ INTN Length;\r
+ X509_NAME_ENTRY *Entry;\r
+ ASN1_STRING *EntryData;\r
+ UINT8 *UTF8Name;\r
+\r
+ ReturnStatus = RETURN_INVALID_PARAMETER;\r
+ UTF8Name = NULL;\r
+\r
+ //\r
+ // Check input parameters.\r
+ //\r
+ if ((Cert == NULL) || (CertSize > INT_MAX) || (CommonNameSize == NULL)) {\r
+ return ReturnStatus;\r
+ }\r
+ if ((CommonName != NULL) && (*CommonNameSize == 0)) {\r
+ return ReturnStatus;\r
+ }\r
+\r
+ X509Cert = NULL;\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
+ //\r
+ // Invalid X.509 Certificate\r
+ //\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
+ //\r
+ // Fail to retrieve subject name content\r
+ //\r
+ goto _Exit;\r
+ }\r
+\r
+ //\r
+ // Retrive the string from X.509 Subject base on the Request_NID\r
+ //\r
+ Index = X509_NAME_get_index_by_NID (X509Name, Request_NID, -1);\r
+ if (Index < 0) {\r
+ //\r
+ // No Request_NID name entry exists in X509_NAME object\r
+ //\r
+ *CommonNameSize = 0;\r
+ ReturnStatus = RETURN_NOT_FOUND;\r
+ goto _Exit;\r
+ }\r
+\r
+ Entry = X509_NAME_get_entry (X509Name, Index);\r
+ if (Entry == NULL) {\r
+ //\r
+ // Fail to retrieve name entry data\r
+ //\r
+ *CommonNameSize = 0;\r
+ ReturnStatus = RETURN_NOT_FOUND;\r
+ goto _Exit;\r
+ }\r
+\r
+ EntryData = X509_NAME_ENTRY_get_data (Entry);\r
+\r
+ Length = ASN1_STRING_to_UTF8 (&UTF8Name, EntryData);\r
+ if (Length < 0) {\r
+ //\r
+ // Fail to convert the Name string\r
+ //\r
+ *CommonNameSize = 0;\r
+ ReturnStatus = RETURN_INVALID_PARAMETER;\r
+ goto _Exit;\r
+ }\r
+\r
+ if (CommonName == NULL) {\r
+ *CommonNameSize = Length + 1;\r
+ ReturnStatus = RETURN_BUFFER_TOO_SMALL;\r
+ } else {\r
+ *CommonNameSize = MIN ((UINTN)Length, *CommonNameSize - 1) + 1;\r
+ CopyMem (CommonName, UTF8Name, *CommonNameSize - 1);\r
+ CommonName[*CommonNameSize - 1] = '\0';\r
+ ReturnStatus = RETURN_SUCCESS;\r
+ }\r
+\r
+_Exit:\r
+ //\r
+ // Release Resources.\r
+ //\r
+ if (X509Cert != NULL) {\r
+ X509_free (X509Cert);\r
+ }\r
+ if (UTF8Name != NULL) {\r
+ OPENSSL_free (UTF8Name);\r
+ }\r
+\r
+ return ReturnStatus;\r
+}\r
+\r
+/**\r
+ Retrieve the common name (CN) string 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] CommonName Buffer to contain the retrieved certificate common\r
+ name string. At most CommonNameSize bytes will be\r
+ written and the string will be null terminated. May be\r
+ NULL in order to determine the size buffer needed.\r
+ @param[in,out] CommonNameSize The size in bytes of the CommonName buffer on input,\r
+ and the size of buffer returned CommonName on output.\r
+ If CommonName is NULL then the amount of space needed\r
+ in buffer (including the final null) is returned.\r
+\r
+ @retval RETURN_SUCCESS The certificate CommonName retrieved successfully.\r
+ @retval RETURN_INVALID_PARAMETER If Cert is NULL.\r
+ If CommonNameSize is NULL.\r
+ If CommonName is not NULL and *CommonNameSize is 0.\r
+ If Certificate is invalid.\r
+ @retval RETURN_NOT_FOUND If no CommonName entry exists.\r
+ @retval RETURN_BUFFER_TOO_SMALL If the CommonName is NULL. The required buffer size\r
+ (including the final null) is returned in the\r
+ CommonNameSize parameter.\r
+ @retval RETURN_UNSUPPORTED The operation is not supported.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+X509GetCommonName (\r
+ IN CONST UINT8 *Cert,\r
+ IN UINTN CertSize,\r
+ OUT CHAR8 *CommonName OPTIONAL,\r
+ IN OUT UINTN *CommonNameSize\r
+ )\r
+{\r
+ return InternalX509GetNIDName (Cert, CertSize, NID_commonName, CommonName, CommonNameSize);\r
+}\r
+\r
+/**\r
+ Retrieve the organization name (O) string 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] NameBuffer Buffer to contain the retrieved certificate organization\r
+ name string. At most NameBufferSize bytes will be\r
+ written and the string will be null terminated. May be\r
+ NULL in order to determine the size buffer needed.\r
+ @param[in,out] NameBufferSize The size in bytes of the Name buffer on input,\r
+ and the size of buffer returned Name on output.\r
+ If NameBuffer is NULL then the amount of space needed\r
+ in buffer (including the final null) is returned.\r
+\r
+ @retval RETURN_SUCCESS The certificate Organization Name retrieved successfully.\r
+ @retval RETURN_INVALID_PARAMETER If Cert is NULL.\r
+ If NameBufferSize is NULL.\r
+ If NameBuffer is not NULL and *CommonNameSize is 0.\r
+ If Certificate is invalid.\r
+ @retval RETURN_NOT_FOUND If no Organization Name entry exists.\r
+ @retval RETURN_BUFFER_TOO_SMALL If the NameBuffer is NULL. The required buffer size\r
+ (including the final null) is returned in the\r
+ CommonNameSize parameter.\r
+ @retval RETURN_UNSUPPORTED The operation is not supported.\r
+\r
+**/\r
+RETURN_STATUS\r
+EFIAPI\r
+X509GetOrganizationName (\r
+ IN CONST UINT8 *Cert,\r
+ IN UINTN CertSize,\r
+ OUT CHAR8 *NameBuffer OPTIONAL,\r
+ IN OUT UINTN *NameBufferSize\r
+ )\r
+{\r
+ return InternalX509GetNIDName (Cert, CertSize, NID_organizationName, NameBuffer, NameBufferSize);\r
+}\r
+\r