/** @file\r
Miscellaneous routines specific to Https for HttpDxe driver.\r
\r
-Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
Dst = *SearchStringTmp;\r
\r
if ((Src >= 'A') && (Src <= 'Z')) {\r
- Src -= ('A' - 'a');\r
+ Src += ('a' - 'A');\r
}\r
\r
if ((Dst >= 'A') && (Dst <= 'Z')) {\r
- Dst -= ('A' - 'a');\r
+ Dst += ('a' - 'A');\r
}\r
\r
if (Src != Dst) {\r
UINT32 Index;\r
EFI_SIGNATURE_LIST *CertList;\r
EFI_SIGNATURE_DATA *Cert;\r
+ UINTN CertArraySizeInBytes;\r
UINTN CertCount;\r
UINT32 ItemDataSize;\r
\r
if (EFI_ERROR (Status)) {\r
//\r
// GetVariable still error or the variable is corrupted.\r
- // Fall back to the default value.\r
//\r
- FreePool (CACert);\r
-\r
- return EFI_NOT_FOUND;\r
+ goto FreeCACert;\r
}\r
\r
ASSERT (CACert != NULL);\r
\r
+ //\r
+ // Sanity check\r
+ //\r
+ Status = EFI_INVALID_PARAMETER;\r
+ CertCount = 0;\r
+ ItemDataSize = (UINT32) CACertSize;\r
+ while (ItemDataSize > 0) {\r
+ if (ItemDataSize < sizeof (EFI_SIGNATURE_LIST)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: truncated EFI_SIGNATURE_LIST header\n",\r
+ __FUNCTION__));\r
+ goto FreeCACert;\r
+ }\r
+\r
+ CertList = (EFI_SIGNATURE_LIST *) (CACert + (CACertSize - ItemDataSize));\r
+\r
+ if (CertList->SignatureListSize < sizeof (EFI_SIGNATURE_LIST)) {\r
+ DEBUG ((DEBUG_ERROR,\r
+ "%a: SignatureListSize too small for EFI_SIGNATURE_LIST\n",\r
+ __FUNCTION__));\r
+ goto FreeCACert;\r
+ }\r
+\r
+ if (CertList->SignatureListSize > ItemDataSize) {\r
+ DEBUG ((DEBUG_ERROR, "%a: truncated EFI_SIGNATURE_LIST body\n",\r
+ __FUNCTION__));\r
+ goto FreeCACert;\r
+ }\r
+\r
+ if (!CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {\r
+ DEBUG ((DEBUG_ERROR, "%a: only X509 certificates are supported\n",\r
+ __FUNCTION__));\r
+ Status = EFI_UNSUPPORTED;\r
+ goto FreeCACert;\r
+ }\r
+\r
+ if (CertList->SignatureHeaderSize != 0) {\r
+ DEBUG ((DEBUG_ERROR, "%a: SignatureHeaderSize must be 0 for X509\n",\r
+ __FUNCTION__));\r
+ goto FreeCACert;\r
+ }\r
+\r
+ if (CertList->SignatureSize < sizeof (EFI_SIGNATURE_DATA)) {\r
+ DEBUG ((DEBUG_ERROR,\r
+ "%a: SignatureSize too small for EFI_SIGNATURE_DATA\n", __FUNCTION__));\r
+ goto FreeCACert;\r
+ }\r
+\r
+ CertArraySizeInBytes = (CertList->SignatureListSize -\r
+ sizeof (EFI_SIGNATURE_LIST));\r
+ if (CertArraySizeInBytes % CertList->SignatureSize != 0) {\r
+ DEBUG ((DEBUG_ERROR,\r
+ "%a: EFI_SIGNATURE_DATA array not a multiple of SignatureSize\n",\r
+ __FUNCTION__));\r
+ goto FreeCACert;\r
+ }\r
+\r
+ CertCount += CertArraySizeInBytes / CertList->SignatureSize;\r
+ ItemDataSize -= CertList->SignatureListSize;\r
+ }\r
+ if (CertCount == 0) {\r
+ DEBUG ((DEBUG_ERROR, "%a: no X509 certificates provided\n", __FUNCTION__));\r
+ goto FreeCACert;\r
+ }\r
+\r
//\r
// Enumerate all data and erasing the target item.\r
//\r
CertList->SignatureSize - sizeof (Cert->SignatureOwner)\r
);\r
if (EFI_ERROR (Status)) {\r
- FreePool (CACert);\r
- return Status;\r
+ goto FreeCACert;\r
}\r
\r
Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);\r
CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);\r
}\r
\r
+FreeCACert:\r
FreePool (CACert);\r
return Status;\r
}\r
\r
+/**\r
+ Read the HttpTlsCipherList variable and configure it for HTTPS session.\r
+\r
+ @param[in, out] HttpInstance The HTTP instance private data.\r
+\r
+ @retval EFI_SUCCESS The prefered HTTP TLS CipherList is configured.\r
+ @retval EFI_NOT_FOUND Fail to get 'HttpTlsCipherList' variable.\r
+ @retval EFI_INVALID_PARAMETER The contents of variable are invalid.\r
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
+\r
+ @retval Others Other error as indicated.\r
+\r
+**/\r
+EFI_STATUS\r
+TlsConfigCipherList (\r
+ IN OUT HTTP_PROTOCOL *HttpInstance\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINT8 *CipherList;\r
+ UINTN CipherListSize;\r
+\r
+ CipherList = NULL;\r
+ CipherListSize = 0;\r
+\r
+ //\r
+ // Try to read the HttpTlsCipherList variable.\r
+ //\r
+ Status = gRT->GetVariable (\r
+ EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE,\r
+ &gEdkiiHttpTlsCipherListGuid,\r
+ NULL,\r
+ &CipherListSize,\r
+ NULL\r
+ );\r
+ ASSERT (EFI_ERROR (Status));\r
+ if (Status != EFI_BUFFER_TOO_SMALL) {\r
+ return Status;\r
+ }\r
+\r
+ if (CipherListSize % sizeof (EFI_TLS_CIPHER) != 0) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ //\r
+ // Allocate buffer and read the config variable.\r
+ //\r
+ CipherList = AllocatePool (CipherListSize);\r
+ if (CipherList == NULL) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+\r
+ Status = gRT->GetVariable (\r
+ EDKII_HTTP_TLS_CIPHER_LIST_VARIABLE,\r
+ &gEdkiiHttpTlsCipherListGuid,\r
+ NULL,\r
+ &CipherListSize,\r
+ CipherList\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // GetVariable still error or the variable is corrupted.\r
+ //\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ ASSERT (CipherList != NULL);\r
+\r
+ Status = HttpInstance->Tls->SetSessionData (\r
+ HttpInstance->Tls,\r
+ EfiTlsCipherList,\r
+ CipherList,\r
+ CipherListSize\r
+ );\r
+\r
+ON_EXIT:\r
+ FreePool (CipherList);\r
+\r
+ return Status;\r
+}\r
+\r
/**\r
Configure TLS session data.\r
\r
return Status;\r
}\r
\r
+ //\r
+ // Tls Cipher List\r
+ //\r
+ Status = TlsConfigCipherList (HttpInstance);\r
+ if (EFI_ERROR (Status) && Status != EFI_NOT_FOUND) {\r
+ DEBUG ((EFI_D_ERROR, "TlsConfigCipherList: return %r error.\n", Status));\r
+ return Status;\r
+ }\r
+\r
//\r
// Tls Config Certificate\r
//\r
//\r
// Allocate buffer to receive one TLS header.\r
//\r
- Len = sizeof (TLS_RECORD_HEADER);\r
+ Len = TLS_RECORD_HEADER_LENGTH;\r
PduHdr = NetbufAlloc (Len);\r
if (PduHdr == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
\r
@param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.\r
@param[in] Message Pointer to the message buffer needed to processed.\r
+ If ProcessMode is EfiTlsEncrypt, the message contain the TLS\r
+ header and plain text TLS APP payload.\r
+ If ProcessMode is EfiTlsDecrypt, the message contain the TLS\r
+ header and cipher text TLS APP payload.\r
@param[in] MessageSize Pointer to the message buffer size.\r
@param[in] ProcessMode Process mode.\r
@param[in, out] Fragment Only one Fragment returned after the Message is\r
processed successfully.\r
+ If ProcessMode is EfiTlsEncrypt, the fragment contain the TLS\r
+ header and cipher text TLS APP payload.\r
+ If ProcessMode is EfiTlsDecrypt, the fragment contain the TLS\r
+ header and plain text TLS APP payload.\r
\r
@retval EFI_SUCCESS Message is processed successfully.\r
@retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.\r
ON_EXIT:\r
\r
if (OriginalFragmentTable != NULL) {\r
+ if( FragmentTable == OriginalFragmentTable) {\r
+ FragmentTable = NULL;\r
+ }\r
FreePool (OriginalFragmentTable);\r
OriginalFragmentTable = NULL;\r
}\r
return Status;\r
}\r
\r
- CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLS_RECORD_HEADER), BufferInSize);\r
+ CopyMem (BufferIn, TempFragment.Bulk + TLS_RECORD_HEADER_LENGTH, BufferInSize);\r
\r
//\r
// Free the buffer in TempFragment.\r