* [Patch 01/10] MdePkg: Add TLS related protocol definition
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-14 8:36 ` Long, Qin
2016-12-14 8:43 ` Fu, Siyuan
2016-12-14 7:34 ` [Patch 02/10] MdePkg: Add a header to standardize TLS definitions Jiaxin Wu
` (8 subsequent siblings)
9 siblings, 2 replies; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Long Qin, Ye Ting, Fu Siyuan, Zhang Lubo, Liming Gao,
Michael D Kinney, Thomas Palmer, Wu Jiaxin
This patch is used to add Tls.h and TlsConfig.h header
files to define EFI TLS Configuration Protocol,
EFI TLS Service Binding Protocol and
EFI TLS Configuration Protocol.
Cc: Long Qin <qin.long@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
MdePkg/Include/Protocol/Tls.h | 460 ++++++++++++++++++++++++++++++++++++
MdePkg/Include/Protocol/TlsConfig.h | 132 +++++++++++
MdePkg/MdePkg.dec | 9 +
3 files changed, 601 insertions(+)
create mode 100644 MdePkg/Include/Protocol/Tls.h
create mode 100644 MdePkg/Include/Protocol/TlsConfig.h
diff --git a/MdePkg/Include/Protocol/Tls.h b/MdePkg/Include/Protocol/Tls.h
new file mode 100644
index 0000000..51a3cda
--- /dev/null
+++ b/MdePkg/Include/Protocol/Tls.h
@@ -0,0 +1,460 @@
+/** @file
+ EFI TLS Protocols as defined in UEFI 2.5.
+
+ The EFI TLS Service Binding Protocol is used to locate EFI TLS Protocol drivers
+ to create and destroy child of the driver to communicate with other host using
+ TLS protocol.
+ The EFI TLS Protocol provides the ability to manage TLS session.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This Protocol is introduced in UEFI Specification 2.5
+
+**/
+
+#ifndef __EFI_TLS_PROTOCOL_H__
+#define __EFI_TLS_PROTOCOL_H__
+
+///
+/// The EFI TLS Service Binding Protocol is used to locate EFI TLS Protocol drivers to
+/// create and destroy child of the driver to communicate with other host using TLS
+/// protocol.
+///
+#define EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID \
+ { \
+ 0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d } \
+ }
+
+///
+/// The EFI TLS protocol provides the ability to manage TLS session.
+///
+#define EFI_TLS_PROTOCOL_GUID \
+ { \
+ 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc, 0xe4, 0x6c, 0x47, 0x51, 0x43, 0x90 } \
+ }
+
+typedef struct _EFI_TLS_PROTOCOL EFI_TLS_PROTOCOL;
+
+///
+/// EFI_TLS_SESSION_DATA_TYPE
+///
+typedef enum {
+ ///
+ /// Session Configuration
+ ///
+
+ ///
+ /// TLS session Version. The corresponding Data is of type EFI_TLS_VERSION.
+ ///
+ EfiTlsVersion,
+ ///
+ /// TLS session as client or as server. The corresponding Data is of
+ /// EFI_TLS_CONNECTION_END.
+ ///
+ EfiTlsConnectionEnd,
+ ///
+ /// A priority list of preferred algorithms for the TLS session.
+ /// The corresponding Data is a list of EFI_TLS_CIPHER.
+ ///
+ EfiTlsCipherList,
+ ///
+ /// TLS session compression method.
+ /// The corresponding Data is of type EFI_TLS_COMPRESSION.
+ ///
+ EfiTlsCompressionMethod,
+ ///
+ /// TLS session extension data.
+ /// The corresponding Data is a list of type EFI_TLS_EXTENDION.
+ ///
+ EfiTlsExtensionData,
+ ///
+ /// TLS session verify method.
+ /// The corresponding Data is of type EFI_TLS_VERIFY.
+ ///
+ EfiTlsVerifyMethod,
+ ///
+ /// TLS session data session ID.
+ /// For SetSessionData(), it is TLS session ID used for session resumption.
+ /// For GetSessionData(), it is the TLS session ID used for current session.
+ /// The corresponding Data is of type EFI_TLS_SESSION_ID.
+ ///
+ EfiTlsSessionID,
+ ///
+ /// TLS session data session state.
+ /// The corresponding Data is of type EFI_TLS_SESSION_STATE.
+ ///
+ EfiTlsSessionState,
+
+ ///
+ /// Session information
+ ///
+
+ ///
+ /// TLS session data client random.
+ /// The corresponding Data is of type EFI_TLS_RANDOM.
+ ///
+ EfiTlsClientRandom,
+ ///
+ /// TLS session data server random.
+ /// The corresponding Data is of type EFI_TLS_RANDOM.
+ ///
+ EfiTlsServerRandom,
+ ///
+ /// TLS session data key material.
+ /// The corresponding Data is of type EFI_TLS_MASTER_SECRET.
+ ///
+ EfiTlsKeyMaterial,
+
+ EfiTlsSessionDataTypeMaximum
+
+} EFI_TLS_SESSION_DATA_TYPE;
+
+///
+/// EFI_TLS_VERSION
+/// Note: The TLS version definition is from SSL3.0 to the latest TLS (e.g. 1.2).
+/// SSL2.0 is obsolete and should not be used.
+///
+typedef struct {
+ UINT8 Major;
+ UINT8 Minor;
+} EFI_TLS_VERSION;
+
+///
+/// EFI_TLS_CONNECTION_END to define TLS session as client or server.
+///
+typedef enum {
+ EfiTlsClient,
+ EfiTlsServer,
+} EFI_TLS_CONNECTION_END;
+
+///
+/// EFI_TLS_CIPHER
+/// Note: The definition of EFI_TLS_CIPHER definition is from "RFC 5246, A.4.1.
+/// Hello Messages". The value of EFI_TLS_CIPHER is from TLS Cipher
+/// Suite Registry of IANA.
+///
+typedef struct {
+ UINT8 Data1;
+ UINT8 Data2;
+} EFI_TLS_CIPHER;
+
+///
+/// EFI_TLS_COMPRESSION
+/// Note: The value of EFI_TLS_COMPRESSION definition is from "RFC 3749".
+///
+typedef UINT8 EFI_TLS_COMPRESSION;
+
+///
+/// EFI_TLS_EXTENSION
+/// Note: The definition of EFI_TLS_EXTENSION if from "RFC 5246 A.4.1.
+/// Hello Messages".
+///
+typedef struct {
+ UINT16 ExtensionType;
+ UINT16 Length;
+ UINT8 Data[1];
+} EFI_TLS_EXTENSION;
+
+///
+/// EFI_TLS_VERIFY
+/// Use either EFI_TLS_VERIFY_NONE or EFI_TLS_VERIFY_PEER, the last two options
+/// are 'ORed' with EFI_TLS_VERIFY_PEER if they are desired.
+///
+typedef UINT32 EFI_TLS_VERIFY;
+///
+/// No certificates will be sent or the TLS/SSLhandshake will be continued regardless
+/// of the certificate verification result.
+///
+#define EFI_TLS_VERIFY_NONE 0x0
+///
+/// The TLS/SSL handshake is immediately terminated with an alert message containing
+/// the reason for the certificate verification failure.
+///
+#define EFI_TLS_VERIFY_PEER 0x1
+///
+/// TLS session will fail peer certificate is absent.
+///
+#define EFI_TLS_VERIFY_FAIL_IF_NO_PEER_CERT 0x2
+///
+/// TLS session only verify client once, and doesn't request cerfificate during
+/// re-negotiation.
+///
+#define EFI_TLS_VERIFY_CLIENT_ONCE 0x4
+
+///
+/// EFI_TLS_RANDOM
+/// Note: The definition of EFI_TLS_RANDOM is from "RFC 5246 A.4.1.
+/// Hello Messages".
+///
+typedef struct {
+ UINT32 GmtUnixTime;
+ UINT8 RandomBytes[28];
+} EFI_TLS_RANDOM;
+
+///
+/// EFI_TLS_MASTER_SECRET
+/// Note: The definition of EFI_TLS_MASTER_SECRET is from "RFC 5246 8.1.
+/// Computing the Master Secret".
+///
+typedef struct {
+ UINT8 Data[48];
+} EFI_TLS_MASTER_SECRET;
+
+///
+/// EFI_TLS_SESSION_ID
+/// Note: The definition of EFI_TLS_SESSION_ID is from "RFC 5246 A.4.1. Hello Messages".
+///
+#define MAX_TLS_SESSION_ID_LENGTH 32
+typedef struct {
+ UINT16 Length;
+ UINT8 Data[MAX_TLS_SESSION_ID_LENGTH];
+} EFI_TLS_SESSION_ID;
+
+///
+/// EFI_TLS_SESSION_STATE
+///
+typedef enum {
+ ///
+ /// When a new child of TLS protocol is created, the initial state of TLS session
+ /// is EfiTlsSessionNotStarted.
+ ///
+ EfiTlsSessionNotStarted,
+ ///
+ /// The consumer can call BuildResponsePacket() with NULL to get ClientHello to
+ /// start the TLS session. Then the status is EfiTlsSessionHandShaking.
+ ///
+ EfiTlsSessionHandShaking,
+ ///
+ /// During handshake, the consumer need call BuildResponsePacket() with input
+ /// data from peer, then get response packet and send to peer. After handshake
+ /// finish, the TLS session status becomes EfiTlsSessionDataTransferring, and
+ /// consumer can use ProcessPacket() for data transferring.
+ ///
+ EfiTlsSessionDataTransferring,
+ ///
+ /// Finally, if consumer wants to active close TLS session, consumer need
+ /// call SetSessionData to set TLS session state to EfiTlsSessionClosing, and
+ /// call BuildResponsePacket() with NULL to get CloseNotify alert message,
+ /// and sent it out.
+ ///
+ EfiTlsSessionClosing,
+ ///
+ /// If any error happen during parsing ApplicationData content type, EFI_ABORT
+ /// will be returned by ProcessPacket(), and TLS session state will become
+ /// EfiTlsSessionError. Then consumer need call BuildResponsePacket() with
+ /// NULL to get alert message and sent it out.
+ ///
+ EfiTlsSessionError,
+
+ EfiTlsSessionStateMaximum
+
+} EFI_TLS_SESSION_STATE;
+
+///
+/// EFI_TLS_FRAGMENT_DATA
+///
+typedef struct {
+ ///
+ /// Length of data buffer in the fragment.
+ ///
+ UINT32 FragmentLength;
+ ///
+ /// Pointer to the data buffer in the fragment.
+ ///
+ VOID *FragmentBuffer;
+} EFI_TLS_FRAGMENT_DATA;
+
+///
+/// EFI_TLS_CRYPT_MODE
+///
+typedef enum {
+ ///
+ /// Encrypt data provided in the fragment buffers.
+ ///
+ EfiTlsEncrypt,
+ ///
+ /// Decrypt data provided in the fragment buffers.
+ ///
+ EfiTlsDecrypt,
+} EFI_TLS_CRYPT_MODE;
+
+/**
+ Set TLS session data.
+
+ The SetSessionData() function set data for a new TLS session. All session data should
+ be set before BuildResponsePacket() invoked.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in] Data Pointer to session data.
+ @param[in] DataSize Total size of session data.
+
+ @retval EFI_SUCCESS The TLS session data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_ACCESS_DENIED If the DataType is one of below:
+ EfiTlsClientRandom
+ EfiTlsServerRandom
+ EfiTlsKeyMaterial
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionStateNotStarted.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_SET_SESSION_DATA) (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Get TLS session data.
+
+ The GetSessionData() function return the TLS session information.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in, out] Data Pointer to session data.
+ @param[in, out] DataSize Total size of session data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS session data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS session data is not found.
+ @retval EFI_NOT_READY The DataType is not ready in current session state.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_GET_SESSION_DATA) (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Build response packet according to TLS state machine. This function is only valid for
+ alert, handshake and change_cipher_spec content type.
+
+ The BuildResponsePacket() function builds TLS response packet in response to the TLS
+ request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
+ RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
+ will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
+ session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
+ session has errors and the response packet needs to be Alert message based on error
+ type.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL
+ means TLS need initiate the TLS session and response
+ packet need to be ClientHello.
+ @param[in] RequestSize Packet size in bytes for the most recently received TLS
+ packet. 0 is only valid when RequestBuffer is NULL.
+ @param[out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ RequestBuffer is NULL but RequestSize is NOT 0.
+ RequestSize is 0 but RequestBuffer is NOT NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+ @retval EFI_NOT_READY Current TLS session state is NOT ready to build
+ ResponsePacket.
+ @retval EFI_ABORTED Something wrong build response packet.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_BUILD_RESPONSE_PACKET) (
+ IN EFI_TLS_PROTOCOL *This,
+ IN UINT8 *RequestBuffer, OPTIONAL
+ IN UINTN RequestSize, OPTIONAL
+ OUT UINT8 *Buffer, OPTIONAL
+ IN OUT UINTN *BufferSize
+ );
+
+/**
+ Decrypt or encrypt TLS packet during session. This function is only valid after
+ session connected and for application_data content type.
+
+ The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take
+ responsible to handle the original FragmentTable while
+ it may be reallocated in TLS driver. If CryptMode is
+ EfiTlsEncrypt, on input these fragments contain the TLS
+ header and plain text TLS APP payload; on output these
+ fragments contain the TLS header and cypher text TLS
+ APP payload. If CryptMode is EfiTlsDecrypt, on input
+ these fragments contain the TLS header and cypher text
+ TLS APP payload; on output these fragments contain the
+ TLS header and plain text TLS APP payload.
+ @param[in] FragmentCount Number of fragment.
+ @param[in] CryptMode Crypt mode.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ FragmentTable is NULL.
+ FragmentCount is NULL.
+ CryptoMode is invalid.
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionDataTransferring.
+ @retval EFI_ABORTED Something wrong decryption the message. TLS session
+ status will become EfiTlsSessionError. The caller need
+ call BuildResponsePacket() to generate Error Alert
+ message and send it out.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_PROCESS_PACKET) (
+ IN EFI_TLS_PROTOCOL *This,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount,
+ IN EFI_TLS_CRYPT_MODE CryptMode
+ );
+
+///
+/// The EFI_TLS_PROTOCOL is used to create, destroy and manage TLS session.
+/// For detail of TLS, please refer to TLS related RFC.
+///
+struct _EFI_TLS_PROTOCOL {
+ EFI_TLS_SET_SESSION_DATA SetSessionData;
+ EFI_TLS_GET_SESSION_DATA GetSessionData;
+ EFI_TLS_BUILD_RESPONSE_PACKET BuildResponsePacket;
+ EFI_TLS_PROCESS_PACKET ProcessPacket;
+};
+
+extern EFI_GUID gEfiTlsServiceBindingProtocolGuid;
+extern EFI_GUID gEfiTlsProtocolGuid;
+
+#endif // __EFI_TLS_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/TlsConfig.h b/MdePkg/Include/Protocol/TlsConfig.h
new file mode 100644
index 0000000..4b62bf5
--- /dev/null
+++ b/MdePkg/Include/Protocol/TlsConfig.h
@@ -0,0 +1,132 @@
+/** @file
+ EFI TLS Configuration Protocol as defined in UEFI 2.5.
+ The EFI TLS Configuration Protocol provides a way to set and get TLS configuration.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This Protocol is introduced in UEFI Specification 2.5
+
+**/
+#ifndef __EFI_TLS_CONFIGURATION_PROTOCOL_H__
+#define __EFI_TLS_CONFIGURATION_PROTOCOL_H__
+
+///
+/// The EFI Configuration protocol provides a way to set and get TLS configuration.
+///
+#define EFI_TLS_CONFIGURATION_PROTOCOL_GUID \
+ { \
+ 0x1682fe44, 0xbd7a, 0x4407, { 0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d } \
+ }
+
+typedef struct _EFI_TLS_CONFIGURATION_PROTOCOL EFI_TLS_CONFIGURATION_PROTOCOL;
+
+///
+/// EFI_TLS_CONFIG_DATA_TYPE
+///
+typedef enum {
+ ///
+ /// Local host configuration data: public certificate data.
+ /// This data should be DER-encoded binaryX.509 certificate
+ /// or PEMencoded X.509 certificate.
+ ///
+ EfiTlsConfigDataTypeHostPublicCert,
+ ///
+ /// Local host configuration data: private key data.
+ ///
+ EfiTlsConfigDataTypeHostPrivateKey,
+ ///
+ /// CA certificate to verify peer. This data should be PEM-encoded
+ /// RSA or PKCS#8 private key.
+ ///
+ EfiTlsConfigDataTypeCACertificate,
+ ///
+ /// CA-supplied Certificate Revocation List data. This data should
+ /// be DER-encoded CRL data.
+ ///
+ EfiTlsConfigDataTypeCertRevocationList,
+
+ EfiTlsConfigDataTypeMaximum
+
+} EFI_TLS_CONFIG_DATA_TYPE;
+
+/**
+ Set TLS configuration data.
+
+ The SetData() function sets TLS configuration to non-volatile storage or volatile
+ storage.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in] Data Pointer to configuration data.
+ @param[in] DataSize Total size of configuration data.
+
+ @retval EFI_SUCCESS The TLS configuration data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_CONFIGURATION_SET_DATA)(
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Get TLS configuration data.
+
+ The GetData() function gets TLS configuration.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in, out] Data Pointer to configuration data.
+ @param[in, out] DataSize Total size of configuration data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS configuration data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS configuration data is not found.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_CONFIGURATION_GET_DATA)(
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ );
+
+///
+/// The EFI_TLS_CONFIGURATION_PROTOCOL is designed to provide a way to set and get
+/// TLS configuration, such as Certificate, private key data.
+///
+struct _EFI_TLS_CONFIGURATION_PROTOCOL {
+ EFI_TLS_CONFIGURATION_SET_DATA SetData;
+ EFI_TLS_CONFIGURATION_GET_DATA GetData;
+};
+
+extern EFI_GUID gEfiTlsConfigurationProtocolGuid;
+
+#endif //__EFI_TLS_CONFIGURATION_PROTOCOL_H__
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 3e08bed..f2bdb30 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1607,10 +1607,19 @@
gEfiHttpProtocolGuid = { 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b }}
## Include/Protocol/HttpUtilities.h
gEfiHttpUtilitiesProtocolGuid = { 0x3e35c163, 0x4074, 0x45dd, {0x43, 0x1e, 0x23, 0x98, 0x9d, 0xd8, 0x6b, 0x32 }}
+ ## Include/Protocol/Tls.h
+ gEfiTlsServiceBindingProtocolGuid = { 0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d }}
+
+ ## Include/Protocol/Tls.h
+ gEfiTlsProtocolGuid = { 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc, 0xe4, 0x6c, 0x47, 0x51, 0x43, 0x90 }}
+
+ ## Include/Protocol/TlsConfig.h
+ gEfiTlsConfigurationProtocolGuid = { 0x1682fe44, 0xbd7a, 0x4407, { 0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d }}
+
## Include/Protocol/Rest.h
gEfiRestProtocolGuid = { 0x0db48a36, 0x4e54, 0xea9c, {0x9b, 0x09, 0x1e, 0xa5, 0xbe, 0x3a, 0x66, 0x0b }}
## Include/Protocol/Supplicant.h
gEfiSupplicantServiceBindingProtocolGuid = { 0x45bcd98e, 0x59ad, 0x4174, { 0x95, 0x46, 0x34, 0x4a, 0x7, 0x48, 0x58, 0x98 }}
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 01/10] MdePkg: Add TLS related protocol definition
2016-12-14 7:34 ` [Patch 01/10] MdePkg: Add TLS related protocol definition Jiaxin Wu
@ 2016-12-14 8:36 ` Long, Qin
2016-12-14 8:39 ` Wu, Jiaxin
2016-12-14 8:43 ` Fu, Siyuan
1 sibling, 1 reply; 37+ messages in thread
From: Long, Qin @ 2016-12-14 8:36 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Ye, Ting, Fu, Siyuan, Zhang, Lubo, Gao, Liming, Kinney, Michael D,
Thomas Palmer
Reviewed-by: Qin Long <qin.long@intel.com>
Please correct some typos later:
EFI_TLS_EXTENDION --> EFI_TLS_EXTENSION
TLS/SSLhandshake --> TLS/SSL handshake
cerfificate --> certificate
cypher --> cipher
binaryX.509 --> binary X.509
PEMencoded --> PEM-encoded
Best Regards & Thanks,
LONG, Qin
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: Wednesday, December 14, 2016 3:34 PM
> To: edk2-devel@lists.01.org
> Cc: Long, Qin; Ye, Ting; Fu, Siyuan; Zhang, Lubo; Gao, Liming; Kinney, Michael
> D; Thomas Palmer; Wu, Jiaxin
> Subject: [Patch 01/10] MdePkg: Add TLS related protocol definition
>
> This patch is used to add Tls.h and TlsConfig.h header files to define EFI TLS
> Configuration Protocol, EFI TLS Service Binding Protocol and EFI TLS
> Configuration Protocol.
>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> MdePkg/Include/Protocol/Tls.h | 460
> ++++++++++++++++++++++++++++++++++++
> MdePkg/Include/Protocol/TlsConfig.h | 132 +++++++++++
> MdePkg/MdePkg.dec | 9 +
> 3 files changed, 601 insertions(+)
> create mode 100644 MdePkg/Include/Protocol/Tls.h create mode 100644
> MdePkg/Include/Protocol/TlsConfig.h
>
> diff --git a/MdePkg/Include/Protocol/Tls.h b/MdePkg/Include/Protocol/Tls.h
> new file mode 100644 index 0000000..51a3cda
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/Tls.h
> @@ -0,0 +1,460 @@
> +/** @file
> + EFI TLS Protocols as defined in UEFI 2.5.
> +
> + The EFI TLS Service Binding Protocol is used to locate EFI TLS
> + Protocol drivers to create and destroy child of the driver to
> + communicate with other host using TLS protocol.
> + The EFI TLS Protocol provides the ability to manage TLS session.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> This
> + program and the accompanying materials are licensed and made
> + available under the terms and conditions of the BSD License which
> + accompanies this distribution. The full text of the license may be
> + found at http://opensource.org/licenses/bsd-license.php
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> + @par Revision Reference:
> + This Protocol is introduced in UEFI Specification 2.5
> +
> +**/
> +
> +#ifndef __EFI_TLS_PROTOCOL_H__
> +#define __EFI_TLS_PROTOCOL_H__
> +
> +///
> +/// The EFI TLS Service Binding Protocol is used to locate EFI TLS
> +Protocol drivers to /// create and destroy child of the driver to
> +communicate with other host using TLS /// protocol.
> +///
> +#define EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID \
> + { \
> + 0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6,
> +0xab, 0x8d } \
> + }
> +
> +///
> +/// The EFI TLS protocol provides the ability to manage TLS session.
> +///
> +#define EFI_TLS_PROTOCOL_GUID \
> + { \
> + 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc, 0xe4, 0x6c, 0x47, 0x51,
> +0x43, 0x90 } \
> + }
> +
> +typedef struct _EFI_TLS_PROTOCOL EFI_TLS_PROTOCOL;
> +
> +///
> +/// EFI_TLS_SESSION_DATA_TYPE
> +///
> +typedef enum {
> + ///
> + /// Session Configuration
> + ///
> +
> + ///
> + /// TLS session Version. The corresponding Data is of type
> EFI_TLS_VERSION.
> + ///
> + EfiTlsVersion,
> + ///
> + /// TLS session as client or as server. The corresponding Data is of
> + /// EFI_TLS_CONNECTION_END.
> + ///
> + EfiTlsConnectionEnd,
> + ///
> + /// A priority list of preferred algorithms for the TLS session.
> + /// The corresponding Data is a list of EFI_TLS_CIPHER.
> + ///
> + EfiTlsCipherList,
> + ///
> + /// TLS session compression method.
> + /// The corresponding Data is of type EFI_TLS_COMPRESSION.
> + ///
> + EfiTlsCompressionMethod,
> + ///
> + /// TLS session extension data.
> + /// The corresponding Data is a list of type EFI_TLS_EXTENDION.
> + ///
> + EfiTlsExtensionData,
> + ///
> + /// TLS session verify method.
> + /// The corresponding Data is of type EFI_TLS_VERIFY.
> + ///
> + EfiTlsVerifyMethod,
> + ///
> + /// TLS session data session ID.
> + /// For SetSessionData(), it is TLS session ID used for session resumption.
> + /// For GetSessionData(), it is the TLS session ID used for current session.
> + /// The corresponding Data is of type EFI_TLS_SESSION_ID.
> + ///
> + EfiTlsSessionID,
> + ///
> + /// TLS session data session state.
> + /// The corresponding Data is of type EFI_TLS_SESSION_STATE.
> + ///
> + EfiTlsSessionState,
> +
> + ///
> + /// Session information
> + ///
> +
> + ///
> + /// TLS session data client random.
> + /// The corresponding Data is of type EFI_TLS_RANDOM.
> + ///
> + EfiTlsClientRandom,
> + ///
> + /// TLS session data server random.
> + /// The corresponding Data is of type EFI_TLS_RANDOM.
> + ///
> + EfiTlsServerRandom,
> + ///
> + /// TLS session data key material.
> + /// The corresponding Data is of type EFI_TLS_MASTER_SECRET.
> + ///
> + EfiTlsKeyMaterial,
> +
> + EfiTlsSessionDataTypeMaximum
> +
> +} EFI_TLS_SESSION_DATA_TYPE;
> +
> +///
> +/// EFI_TLS_VERSION
> +/// Note: The TLS version definition is from SSL3.0 to the latest TLS (e.g. 1.2).
> +/// SSL2.0 is obsolete and should not be used.
> +///
> +typedef struct {
> + UINT8 Major;
> + UINT8 Minor;
> +} EFI_TLS_VERSION;
> +
> +///
> +/// EFI_TLS_CONNECTION_END to define TLS session as client or server.
> +///
> +typedef enum {
> + EfiTlsClient,
> + EfiTlsServer,
> +} EFI_TLS_CONNECTION_END;
> +
> +///
> +/// EFI_TLS_CIPHER
> +/// Note: The definition of EFI_TLS_CIPHER definition is from "RFC 5246,
> A.4.1.
> +/// Hello Messages". The value of EFI_TLS_CIPHER is from TLS Cipher
> +/// Suite Registry of IANA.
> +///
> +typedef struct {
> + UINT8 Data1;
> + UINT8 Data2;
> +} EFI_TLS_CIPHER;
> +
> +///
> +/// EFI_TLS_COMPRESSION
> +/// Note: The value of EFI_TLS_COMPRESSION definition is from "RFC 3749".
> +///
> +typedef UINT8 EFI_TLS_COMPRESSION;
> +
> +///
> +/// EFI_TLS_EXTENSION
> +/// Note: The definition of EFI_TLS_EXTENSION if from "RFC 5246 A.4.1.
> +/// Hello Messages".
> +///
> +typedef struct {
> + UINT16 ExtensionType;
> + UINT16 Length;
> + UINT8 Data[1];
> +} EFI_TLS_EXTENSION;
> +
> +///
> +/// EFI_TLS_VERIFY
> +/// Use either EFI_TLS_VERIFY_NONE or EFI_TLS_VERIFY_PEER, the last two
> +options /// are 'ORed' with EFI_TLS_VERIFY_PEER if they are desired.
> +///
> +typedef UINT32 EFI_TLS_VERIFY;
> +///
> +/// No certificates will be sent or the TLS/SSLhandshake will be
> +continued regardless /// of the certificate verification result.
> +///
> +#define EFI_TLS_VERIFY_NONE 0x0
> +///
> +/// The TLS/SSL handshake is immediately terminated with an alert
> +message containing /// the reason for the certificate verification failure.
> +///
> +#define EFI_TLS_VERIFY_PEER 0x1
> +///
> +/// TLS session will fail peer certificate is absent.
> +///
> +#define EFI_TLS_VERIFY_FAIL_IF_NO_PEER_CERT 0x2 /// /// TLS session
> +only verify client once, and doesn't request cerfificate during ///
> +re-negotiation.
> +///
> +#define EFI_TLS_VERIFY_CLIENT_ONCE 0x4
> +
> +///
> +/// EFI_TLS_RANDOM
> +/// Note: The definition of EFI_TLS_RANDOM is from "RFC 5246 A.4.1.
> +/// Hello Messages".
> +///
> +typedef struct {
> + UINT32 GmtUnixTime;
> + UINT8 RandomBytes[28];
> +} EFI_TLS_RANDOM;
> +
> +///
> +/// EFI_TLS_MASTER_SECRET
> +/// Note: The definition of EFI_TLS_MASTER_SECRET is from "RFC 5246 8.1.
> +/// Computing the Master Secret".
> +///
> +typedef struct {
> + UINT8 Data[48];
> +} EFI_TLS_MASTER_SECRET;
> +
> +///
> +/// EFI_TLS_SESSION_ID
> +/// Note: The definition of EFI_TLS_SESSION_ID is from "RFC 5246 A.4.1.
> Hello Messages".
> +///
> +#define MAX_TLS_SESSION_ID_LENGTH 32
> +typedef struct {
> + UINT16 Length;
> + UINT8 Data[MAX_TLS_SESSION_ID_LENGTH];
> +} EFI_TLS_SESSION_ID;
> +
> +///
> +/// EFI_TLS_SESSION_STATE
> +///
> +typedef enum {
> + ///
> + /// When a new child of TLS protocol is created, the initial state of
> +TLS session
> + /// is EfiTlsSessionNotStarted.
> + ///
> + EfiTlsSessionNotStarted,
> + ///
> + /// The consumer can call BuildResponsePacket() with NULL to get
> +ClientHello to
> + /// start the TLS session. Then the status is EfiTlsSessionHandShaking.
> + ///
> + EfiTlsSessionHandShaking,
> + ///
> + /// During handshake, the consumer need call BuildResponsePacket()
> +with input
> + /// data from peer, then get response packet and send to peer. After
> +handshake
> + /// finish, the TLS session status becomes
> +EfiTlsSessionDataTransferring, and
> + /// consumer can use ProcessPacket() for data transferring.
> + ///
> + EfiTlsSessionDataTransferring,
> + ///
> + /// Finally, if consumer wants to active close TLS session, consumer
> +need
> + /// call SetSessionData to set TLS session state to
> +EfiTlsSessionClosing, and
> + /// call BuildResponsePacket() with NULL to get CloseNotify alert
> +message,
> + /// and sent it out.
> + ///
> + EfiTlsSessionClosing,
> + ///
> + /// If any error happen during parsing ApplicationData content type,
> +EFI_ABORT
> + /// will be returned by ProcessPacket(), and TLS session state will
> +become
> + /// EfiTlsSessionError. Then consumer need call BuildResponsePacket()
> +with
> + /// NULL to get alert message and sent it out.
> + ///
> + EfiTlsSessionError,
> +
> + EfiTlsSessionStateMaximum
> +
> +} EFI_TLS_SESSION_STATE;
> +
> +///
> +/// EFI_TLS_FRAGMENT_DATA
> +///
> +typedef struct {
> + ///
> + /// Length of data buffer in the fragment.
> + ///
> + UINT32 FragmentLength;
> + ///
> + /// Pointer to the data buffer in the fragment.
> + ///
> + VOID *FragmentBuffer;
> +} EFI_TLS_FRAGMENT_DATA;
> +
> +///
> +/// EFI_TLS_CRYPT_MODE
> +///
> +typedef enum {
> + ///
> + /// Encrypt data provided in the fragment buffers.
> + ///
> + EfiTlsEncrypt,
> + ///
> + /// Decrypt data provided in the fragment buffers.
> + ///
> + EfiTlsDecrypt,
> +} EFI_TLS_CRYPT_MODE;
> +
> +/**
> + Set TLS session data.
> +
> + The SetSessionData() function set data for a new TLS session. All
> + session data should be set before BuildResponsePacket() invoked.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in] Data Pointer to session data.
> + @param[in] DataSize Total size of session data.
> +
> + @retval EFI_SUCCESS The TLS session data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_ACCESS_DENIED If the DataType is one of below:
> + EfiTlsClientRandom
> + EfiTlsServerRandom
> + EfiTlsKeyMaterial
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionStateNotStarted.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TLS_SET_SESSION_DATA) (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Get TLS session data.
> +
> + The GetSessionData() function return the TLS session information.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in, out] Data Pointer to session data.
> + @param[in, out] DataSize Total size of session data. On input, it means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS session data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS session data is not found.
> + @retval EFI_NOT_READY The DataType is not ready in current session
> state.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TLS_GET_SESSION_DATA) (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + );
> +
> +/**
> + Build response packet according to TLS state machine. This function
> +is only valid for
> + alert, handshake and change_cipher_spec content type.
> +
> + The BuildResponsePacket() function builds TLS response packet in
> + response to the TLS request packet specified by RequestBuffer and
> + RequestSize. If RequestBuffer is NULL and RequestSize is 0, and TLS
> + session status is EfiTlsSessionNotStarted, the TLS session will be
> + initiated and the response packet needs to be ClientHello. If
> + RequestBuffer is NULL and RequestSize is 0, and TLS session status is
> + EfiTlsSessionClosing, the TLS session will be closed and response
> + packet needs to be CloseNotify. If RequestBuffer is NULL and
> + RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
> session has errors and the response packet needs to be Alert message based
> on error type.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] RequestBuffer Pointer to the most recently received TLS
> packet. NULL
> + means TLS need initiate the TLS session and response
> + packet need to be ClientHello.
> + @param[in] RequestSize Packet size in bytes for the most recently
> received TLS
> + packet. 0 is only valid when RequestBuffer is NULL.
> + @param[out] Buffer Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferSize Pointer to the buffer size in bytes. On input,
> it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + RequestBuffer is NULL but RequestSize is NOT 0.
> + RequestSize is 0 but RequestBuffer is NOT NULL.
> + BufferSize is NULL.
> + Buffer is NULL if *BufferSize is not zero.
> + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the
> response packet.
> + @retval EFI_NOT_READY Current TLS session state is NOT ready to
> build
> + ResponsePacket.
> + @retval EFI_ABORTED Something wrong build response packet.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TLS_BUILD_RESPONSE_PACKET) (
> + IN EFI_TLS_PROTOCOL *This,
> + IN UINT8 *RequestBuffer, OPTIONAL
> + IN UINTN RequestSize, OPTIONAL
> + OUT UINT8 *Buffer, OPTIONAL
> + IN OUT UINTN *BufferSize
> + );
> +
> +/**
> + Decrypt or encrypt TLS packet during session. This function is only
> +valid after
> + session connected and for application_data content type.
> +
> + The ProcessPacket () function process each inbound or outbound TLS APP
> packet.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment. The caller
> will take
> + responsible to handle the original FragmentTable while
> + it may be reallocated in TLS driver. If CryptMode is
> + EfiTlsEncrypt, on input these fragments contain the TLS
> + header and plain text TLS APP payload; on output these
> + fragments contain the TLS header and cypher text TLS
> + APP payload. If CryptMode is EfiTlsDecrypt, on input
> + these fragments contain the TLS header and cypher text
> + TLS APP payload; on output these fragments contain the
> + TLS header and plain text TLS APP payload.
> + @param[in] FragmentCount Number of fragment.
> + @param[in] CryptMode Crypt mode.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + FragmentTable is NULL.
> + FragmentCount is NULL.
> + CryptoMode is invalid.
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionDataTransferring.
> + @retval EFI_ABORTED Something wrong decryption the message.
> TLS session
> + status will become EfiTlsSessionError. The caller need
> + call BuildResponsePacket() to generate Error Alert
> + message and send it out.
> + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the
> operation.
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TLS_PROCESS_PACKET) (
> + IN EFI_TLS_PROTOCOL *This,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount,
> + IN EFI_TLS_CRYPT_MODE CryptMode
> + );
> +
> +///
> +/// The EFI_TLS_PROTOCOL is used to create, destroy and manage TLS
> session.
> +/// For detail of TLS, please refer to TLS related RFC.
> +///
> +struct _EFI_TLS_PROTOCOL {
> + EFI_TLS_SET_SESSION_DATA SetSessionData;
> + EFI_TLS_GET_SESSION_DATA GetSessionData;
> + EFI_TLS_BUILD_RESPONSE_PACKET BuildResponsePacket;
> + EFI_TLS_PROCESS_PACKET ProcessPacket;
> +};
> +
> +extern EFI_GUID gEfiTlsServiceBindingProtocolGuid;
> +extern EFI_GUID gEfiTlsProtocolGuid;
> +
> +#endif // __EFI_TLS_PROTOCOL_H__
> diff --git a/MdePkg/Include/Protocol/TlsConfig.h
> b/MdePkg/Include/Protocol/TlsConfig.h
> new file mode 100644
> index 0000000..4b62bf5
> --- /dev/null
> +++ b/MdePkg/Include/Protocol/TlsConfig.h
> @@ -0,0 +1,132 @@
> +/** @file
> + EFI TLS Configuration Protocol as defined in UEFI 2.5.
> + The EFI TLS Configuration Protocol provides a way to set and get TLS
> configuration.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> This
> + program and the accompanying materials are licensed and made
> + available under the terms and conditions of the BSD License which
> + accompanies this distribution. The full text of the license may be
> + found at http://opensource.org/licenses/bsd-license.php
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> + @par Revision Reference:
> + This Protocol is introduced in UEFI Specification 2.5
> +
> +**/
> +#ifndef __EFI_TLS_CONFIGURATION_PROTOCOL_H__
> +#define __EFI_TLS_CONFIGURATION_PROTOCOL_H__
> +
> +///
> +/// The EFI Configuration protocol provides a way to set and get TLS
> configuration.
> +///
> +#define EFI_TLS_CONFIGURATION_PROTOCOL_GUID \
> + { \
> + 0x1682fe44, 0xbd7a, 0x4407, { 0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3,
> +0x92, 0x2d } \
> + }
> +
> +typedef struct _EFI_TLS_CONFIGURATION_PROTOCOL
> +EFI_TLS_CONFIGURATION_PROTOCOL;
> +
> +///
> +/// EFI_TLS_CONFIG_DATA_TYPE
> +///
> +typedef enum {
> + ///
> + /// Local host configuration data: public certificate data.
> + /// This data should be DER-encoded binaryX.509 certificate
> + /// or PEMencoded X.509 certificate.
> + ///
> + EfiTlsConfigDataTypeHostPublicCert,
> + ///
> + /// Local host configuration data: private key data.
> + ///
> + EfiTlsConfigDataTypeHostPrivateKey,
> + ///
> + /// CA certificate to verify peer. This data should be PEM-encoded
> + /// RSA or PKCS#8 private key.
> + ///
> + EfiTlsConfigDataTypeCACertificate,
> + ///
> + /// CA-supplied Certificate Revocation List data. This data should
> + /// be DER-encoded CRL data.
> + ///
> + EfiTlsConfigDataTypeCertRevocationList,
> +
> + EfiTlsConfigDataTypeMaximum
> +
> +} EFI_TLS_CONFIG_DATA_TYPE;
> +
> +/**
> + Set TLS configuration data.
> +
> + The SetData() function sets TLS configuration to non-volatile storage
> + or volatile storage.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in] Data Pointer to configuration data.
> + @param[in] DataSize Total size of configuration data.
> +
> + @retval EFI_SUCCESS The TLS configuration data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TLS_CONFIGURATION_SET_DATA)(
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Get TLS configuration data.
> +
> + The GetData() function gets TLS configuration.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in, out] Data Pointer to configuration data.
> + @param[in, out] DataSize Total size of configuration data. On input, it
> means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS configuration data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS configuration data is not found.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +
> +**/
> +typedef
> +EFI_STATUS
> +(EFIAPI *EFI_TLS_CONFIGURATION_GET_DATA)(
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + );
> +
> +///
> +/// The EFI_TLS_CONFIGURATION_PROTOCOL is designed to provide a way
> to
> +set and get /// TLS configuration, such as Certificate, private key data.
> +///
> +struct _EFI_TLS_CONFIGURATION_PROTOCOL {
> + EFI_TLS_CONFIGURATION_SET_DATA SetData;
> + EFI_TLS_CONFIGURATION_GET_DATA GetData;
> +};
> +
> +extern EFI_GUID gEfiTlsConfigurationProtocolGuid;
> +
> +#endif //__EFI_TLS_CONFIGURATION_PROTOCOL_H__
> diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index
> 3e08bed..f2bdb30 100644
> --- a/MdePkg/MdePkg.dec
> +++ b/MdePkg/MdePkg.dec
> @@ -1607,10 +1607,19 @@
> gEfiHttpProtocolGuid = { 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42,
> 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b }}
>
> ## Include/Protocol/HttpUtilities.h
> gEfiHttpUtilitiesProtocolGuid = { 0x3e35c163, 0x4074, 0x45dd, {0x43,
> 0x1e, 0x23, 0x98, 0x9d, 0xd8, 0x6b, 0x32 }}
>
> + ## Include/Protocol/Tls.h
> + gEfiTlsServiceBindingProtocolGuid = { 0x952cb795, 0xff36, 0x48cf, {0xa2,
> 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d }}
> +
> + ## Include/Protocol/Tls.h
> + gEfiTlsProtocolGuid = { 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc, 0xe4,
> 0x6c, 0x47, 0x51, 0x43, 0x90 }}
> +
> + ## Include/Protocol/TlsConfig.h
> + gEfiTlsConfigurationProtocolGuid = { 0x1682fe44, 0xbd7a, 0x4407, { 0xb7,
> 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d }}
> +
> ## Include/Protocol/Rest.h
> gEfiRestProtocolGuid = { 0x0db48a36, 0x4e54, 0xea9c, {0x9b, 0x09,
> 0x1e, 0xa5, 0xbe, 0x3a, 0x66, 0x0b }}
>
> ## Include/Protocol/Supplicant.h
> gEfiSupplicantServiceBindingProtocolGuid = { 0x45bcd98e, 0x59ad, 0x4174,
> { 0x95, 0x46, 0x34, 0x4a, 0x7, 0x48, 0x58, 0x98 }}
> --
> 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Patch 01/10] MdePkg: Add TLS related protocol definition
2016-12-14 8:36 ` Long, Qin
@ 2016-12-14 8:39 ` Wu, Jiaxin
2016-12-15 8:34 ` Ye, Ting
0 siblings, 1 reply; 37+ messages in thread
From: Wu, Jiaxin @ 2016-12-14 8:39 UTC (permalink / raw)
To: Long, Qin, edk2-devel@lists.01.org
Cc: Ye, Ting, Fu, Siyuan, Zhang, Lubo, Gao, Liming, Kinney, Michael D,
Thomas Palmer
Thanks Qin, I will correct it before commit this patch.
Best Regards!
Jiaxin
> -----Original Message-----
> From: Long, Qin
> Sent: Wednesday, December 14, 2016 4:36 PM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang,
> Lubo <lubo.zhang@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney,
> Michael D <michael.d.kinney@intel.com>; Thomas Palmer
> <thomas.palmer@hpe.com>
> Subject: RE: [Patch 01/10] MdePkg: Add TLS related protocol definition
>
> Reviewed-by: Qin Long <qin.long@intel.com>
>
> Please correct some typos later:
> EFI_TLS_EXTENDION --> EFI_TLS_EXTENSION TLS/SSLhandshake --> TLS/SSL
> handshake cerfificate --> certificate cypher --> cipher
> binaryX.509 --> binary X.509
> PEMencoded --> PEM-encoded
>
> Best Regards & Thanks,
> LONG, Qin
>
> > -----Original Message-----
> > From: Wu, Jiaxin
> > Sent: Wednesday, December 14, 2016 3:34 PM
> > To: edk2-devel@lists.01.org
> > Cc: Long, Qin; Ye, Ting; Fu, Siyuan; Zhang, Lubo; Gao, Liming; Kinney,
> > Michael D; Thomas Palmer; Wu, Jiaxin
> > Subject: [Patch 01/10] MdePkg: Add TLS related protocol definition
> >
> > This patch is used to add Tls.h and TlsConfig.h header files to define
> > EFI TLS Configuration Protocol, EFI TLS Service Binding Protocol and
> > EFI TLS Configuration Protocol.
> >
> > Cc: Long Qin <qin.long@intel.com>
> > Cc: Ye Ting <ting.ye@intel.com>
> > Cc: Fu Siyuan <siyuan.fu@intel.com>
> > Cc: Zhang Lubo <lubo.zhang@intel.com>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Thomas Palmer <thomas.palmer@hpe.com>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> > ---
> > MdePkg/Include/Protocol/Tls.h | 460
> > ++++++++++++++++++++++++++++++++++++
> > MdePkg/Include/Protocol/TlsConfig.h | 132 +++++++++++
> > MdePkg/MdePkg.dec | 9 +
> > 3 files changed, 601 insertions(+)
> > create mode 100644 MdePkg/Include/Protocol/Tls.h create mode 100644
> > MdePkg/Include/Protocol/TlsConfig.h
> >
> > diff --git a/MdePkg/Include/Protocol/Tls.h
> > b/MdePkg/Include/Protocol/Tls.h new file mode 100644 index
> > 0000000..51a3cda
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/Tls.h
> > @@ -0,0 +1,460 @@
> > +/** @file
> > + EFI TLS Protocols as defined in UEFI 2.5.
> > +
> > + The EFI TLS Service Binding Protocol is used to locate EFI TLS
> > + Protocol drivers to create and destroy child of the driver to
> > + communicate with other host using TLS protocol.
> > + The EFI TLS Protocol provides the ability to manage TLS session.
> > +
> > + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > + This program and the accompanying materials are licensed and made
> > + available under the terms and conditions of the BSD License which
> > + accompanies this distribution. The full text of the license may be
> > + found at http://opensource.org/licenses/bsd-license.php
> > +
> > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> > BASIS,
> > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> > EXPRESS OR IMPLIED.
> > +
> > + @par Revision Reference:
> > + This Protocol is introduced in UEFI Specification 2.5
> > +
> > +**/
> > +
> > +#ifndef __EFI_TLS_PROTOCOL_H__
> > +#define __EFI_TLS_PROTOCOL_H__
> > +
> > +///
> > +/// The EFI TLS Service Binding Protocol is used to locate EFI TLS
> > +Protocol drivers to /// create and destroy child of the driver to
> > +communicate with other host using TLS /// protocol.
> > +///
> > +#define EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID \
> > + { \
> > + 0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6,
> > +0xab, 0x8d } \
> > + }
> > +
> > +///
> > +/// The EFI TLS protocol provides the ability to manage TLS session.
> > +///
> > +#define EFI_TLS_PROTOCOL_GUID \
> > + { \
> > + 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc, 0xe4, 0x6c, 0x47, 0x51,
> > +0x43, 0x90 } \
> > + }
> > +
> > +typedef struct _EFI_TLS_PROTOCOL EFI_TLS_PROTOCOL;
> > +
> > +///
> > +/// EFI_TLS_SESSION_DATA_TYPE
> > +///
> > +typedef enum {
> > + ///
> > + /// Session Configuration
> > + ///
> > +
> > + ///
> > + /// TLS session Version. The corresponding Data is of type
> > EFI_TLS_VERSION.
> > + ///
> > + EfiTlsVersion,
> > + ///
> > + /// TLS session as client or as server. The corresponding Data is
> > + of /// EFI_TLS_CONNECTION_END.
> > + ///
> > + EfiTlsConnectionEnd,
> > + ///
> > + /// A priority list of preferred algorithms for the TLS session.
> > + /// The corresponding Data is a list of EFI_TLS_CIPHER.
> > + ///
> > + EfiTlsCipherList,
> > + ///
> > + /// TLS session compression method.
> > + /// The corresponding Data is of type EFI_TLS_COMPRESSION.
> > + ///
> > + EfiTlsCompressionMethod,
> > + ///
> > + /// TLS session extension data.
> > + /// The corresponding Data is a list of type EFI_TLS_EXTENDION.
> > + ///
> > + EfiTlsExtensionData,
> > + ///
> > + /// TLS session verify method.
> > + /// The corresponding Data is of type EFI_TLS_VERIFY.
> > + ///
> > + EfiTlsVerifyMethod,
> > + ///
> > + /// TLS session data session ID.
> > + /// For SetSessionData(), it is TLS session ID used for session resumption.
> > + /// For GetSessionData(), it is the TLS session ID used for current session.
> > + /// The corresponding Data is of type EFI_TLS_SESSION_ID.
> > + ///
> > + EfiTlsSessionID,
> > + ///
> > + /// TLS session data session state.
> > + /// The corresponding Data is of type EFI_TLS_SESSION_STATE.
> > + ///
> > + EfiTlsSessionState,
> > +
> > + ///
> > + /// Session information
> > + ///
> > +
> > + ///
> > + /// TLS session data client random.
> > + /// The corresponding Data is of type EFI_TLS_RANDOM.
> > + ///
> > + EfiTlsClientRandom,
> > + ///
> > + /// TLS session data server random.
> > + /// The corresponding Data is of type EFI_TLS_RANDOM.
> > + ///
> > + EfiTlsServerRandom,
> > + ///
> > + /// TLS session data key material.
> > + /// The corresponding Data is of type EFI_TLS_MASTER_SECRET.
> > + ///
> > + EfiTlsKeyMaterial,
> > +
> > + EfiTlsSessionDataTypeMaximum
> > +
> > +} EFI_TLS_SESSION_DATA_TYPE;
> > +
> > +///
> > +/// EFI_TLS_VERSION
> > +/// Note: The TLS version definition is from SSL3.0 to the latest TLS (e.g.
> 1.2).
> > +/// SSL2.0 is obsolete and should not be used.
> > +///
> > +typedef struct {
> > + UINT8 Major;
> > + UINT8 Minor;
> > +} EFI_TLS_VERSION;
> > +
> > +///
> > +/// EFI_TLS_CONNECTION_END to define TLS session as client or server.
> > +///
> > +typedef enum {
> > + EfiTlsClient,
> > + EfiTlsServer,
> > +} EFI_TLS_CONNECTION_END;
> > +
> > +///
> > +/// EFI_TLS_CIPHER
> > +/// Note: The definition of EFI_TLS_CIPHER definition is from "RFC
> > +5246,
> > A.4.1.
> > +/// Hello Messages". The value of EFI_TLS_CIPHER is from TLS Cipher
> > +/// Suite Registry of IANA.
> > +///
> > +typedef struct {
> > + UINT8 Data1;
> > + UINT8 Data2;
> > +} EFI_TLS_CIPHER;
> > +
> > +///
> > +/// EFI_TLS_COMPRESSION
> > +/// Note: The value of EFI_TLS_COMPRESSION definition is from "RFC
> 3749".
> > +///
> > +typedef UINT8 EFI_TLS_COMPRESSION;
> > +
> > +///
> > +/// EFI_TLS_EXTENSION
> > +/// Note: The definition of EFI_TLS_EXTENSION if from "RFC 5246 A.4.1.
> > +/// Hello Messages".
> > +///
> > +typedef struct {
> > + UINT16 ExtensionType;
> > + UINT16 Length;
> > + UINT8 Data[1];
> > +} EFI_TLS_EXTENSION;
> > +
> > +///
> > +/// EFI_TLS_VERIFY
> > +/// Use either EFI_TLS_VERIFY_NONE or EFI_TLS_VERIFY_PEER, the last
> > +two options /// are 'ORed' with EFI_TLS_VERIFY_PEER if they are desired.
> > +///
> > +typedef UINT32 EFI_TLS_VERIFY;
> > +///
> > +/// No certificates will be sent or the TLS/SSLhandshake will be
> > +continued regardless /// of the certificate verification result.
> > +///
> > +#define EFI_TLS_VERIFY_NONE 0x0
> > +///
> > +/// The TLS/SSL handshake is immediately terminated with an alert
> > +message containing /// the reason for the certificate verification failure.
> > +///
> > +#define EFI_TLS_VERIFY_PEER 0x1
> > +///
> > +/// TLS session will fail peer certificate is absent.
> > +///
> > +#define EFI_TLS_VERIFY_FAIL_IF_NO_PEER_CERT 0x2 /// /// TLS session
> > +only verify client once, and doesn't request cerfificate during ///
> > +re-negotiation.
> > +///
> > +#define EFI_TLS_VERIFY_CLIENT_ONCE 0x4
> > +
> > +///
> > +/// EFI_TLS_RANDOM
> > +/// Note: The definition of EFI_TLS_RANDOM is from "RFC 5246 A.4.1.
> > +/// Hello Messages".
> > +///
> > +typedef struct {
> > + UINT32 GmtUnixTime;
> > + UINT8 RandomBytes[28];
> > +} EFI_TLS_RANDOM;
> > +
> > +///
> > +/// EFI_TLS_MASTER_SECRET
> > +/// Note: The definition of EFI_TLS_MASTER_SECRET is from "RFC 5246 8.1.
> > +/// Computing the Master Secret".
> > +///
> > +typedef struct {
> > + UINT8 Data[48];
> > +} EFI_TLS_MASTER_SECRET;
> > +
> > +///
> > +/// EFI_TLS_SESSION_ID
> > +/// Note: The definition of EFI_TLS_SESSION_ID is from "RFC 5246 A.4.1.
> > Hello Messages".
> > +///
> > +#define MAX_TLS_SESSION_ID_LENGTH 32 typedef struct {
> > + UINT16 Length;
> > + UINT8 Data[MAX_TLS_SESSION_ID_LENGTH];
> > +} EFI_TLS_SESSION_ID;
> > +
> > +///
> > +/// EFI_TLS_SESSION_STATE
> > +///
> > +typedef enum {
> > + ///
> > + /// When a new child of TLS protocol is created, the initial state
> > +of TLS session
> > + /// is EfiTlsSessionNotStarted.
> > + ///
> > + EfiTlsSessionNotStarted,
> > + ///
> > + /// The consumer can call BuildResponsePacket() with NULL to get
> > +ClientHello to
> > + /// start the TLS session. Then the status is EfiTlsSessionHandShaking.
> > + ///
> > + EfiTlsSessionHandShaking,
> > + ///
> > + /// During handshake, the consumer need call BuildResponsePacket()
> > +with input
> > + /// data from peer, then get response packet and send to peer.
> > +After handshake
> > + /// finish, the TLS session status becomes
> > +EfiTlsSessionDataTransferring, and
> > + /// consumer can use ProcessPacket() for data transferring.
> > + ///
> > + EfiTlsSessionDataTransferring,
> > + ///
> > + /// Finally, if consumer wants to active close TLS session,
> > +consumer need
> > + /// call SetSessionData to set TLS session state to
> > +EfiTlsSessionClosing, and
> > + /// call BuildResponsePacket() with NULL to get CloseNotify alert
> > +message,
> > + /// and sent it out.
> > + ///
> > + EfiTlsSessionClosing,
> > + ///
> > + /// If any error happen during parsing ApplicationData content
> > +type, EFI_ABORT
> > + /// will be returned by ProcessPacket(), and TLS session state will
> > +become
> > + /// EfiTlsSessionError. Then consumer need call
> > +BuildResponsePacket() with
> > + /// NULL to get alert message and sent it out.
> > + ///
> > + EfiTlsSessionError,
> > +
> > + EfiTlsSessionStateMaximum
> > +
> > +} EFI_TLS_SESSION_STATE;
> > +
> > +///
> > +/// EFI_TLS_FRAGMENT_DATA
> > +///
> > +typedef struct {
> > + ///
> > + /// Length of data buffer in the fragment.
> > + ///
> > + UINT32 FragmentLength;
> > + ///
> > + /// Pointer to the data buffer in the fragment.
> > + ///
> > + VOID *FragmentBuffer;
> > +} EFI_TLS_FRAGMENT_DATA;
> > +
> > +///
> > +/// EFI_TLS_CRYPT_MODE
> > +///
> > +typedef enum {
> > + ///
> > + /// Encrypt data provided in the fragment buffers.
> > + ///
> > + EfiTlsEncrypt,
> > + ///
> > + /// Decrypt data provided in the fragment buffers.
> > + ///
> > + EfiTlsDecrypt,
> > +} EFI_TLS_CRYPT_MODE;
> > +
> > +/**
> > + Set TLS session data.
> > +
> > + The SetSessionData() function set data for a new TLS session. All
> > + session data should be set before BuildResponsePacket() invoked.
> > +
> > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> > + @param[in] DataType TLS session data type.
> > + @param[in] Data Pointer to session data.
> > + @param[in] DataSize Total size of session data.
> > +
> > + @retval EFI_SUCCESS The TLS session data is set successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + Data is NULL.
> > + DataSize is 0.
> > + @retval EFI_UNSUPPORTED The DataType is unsupported.
> > + @retval EFI_ACCESS_DENIED If the DataType is one of below:
> > + EfiTlsClientRandom
> > + EfiTlsServerRandom
> > + EfiTlsKeyMaterial
> > + @retval EFI_NOT_READY Current TLS session state is NOT
> > + EfiTlsSessionStateNotStarted.
> > + @retval EFI_OUT_OF_RESOURCES Required system resources could
> not
> > be allocated.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_SET_SESSION_DATA) (
> > + IN EFI_TLS_PROTOCOL *This,
> > + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> > + IN VOID *Data,
> > + IN UINTN DataSize
> > + );
> > +
> > +/**
> > + Get TLS session data.
> > +
> > + The GetSessionData() function return the TLS session information.
> > +
> > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> > + @param[in] DataType TLS session data type.
> > + @param[in, out] Data Pointer to session data.
> > + @param[in, out] DataSize Total size of session data. On input, it
> means
> > + the size of Data buffer. On output, it means the size
> > + of copied Data buffer if EFI_SUCCESS, and means the
> > + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> > +
> > + @retval EFI_SUCCESS The TLS session data is got successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + DataSize is NULL.
> > + Data is NULL if *DataSize is not zero.
> > + @retval EFI_UNSUPPORTED The DataType is unsupported.
> > + @retval EFI_NOT_FOUND The TLS session data is not found.
> > + @retval EFI_NOT_READY The DataType is not ready in current
> session
> > state.
> > + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the
> data.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_GET_SESSION_DATA) (
> > + IN EFI_TLS_PROTOCOL *This,
> > + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> > + IN OUT VOID *Data, OPTIONAL
> > + IN OUT UINTN *DataSize
> > + );
> > +
> > +/**
> > + Build response packet according to TLS state machine. This function
> > +is only valid for
> > + alert, handshake and change_cipher_spec content type.
> > +
> > + The BuildResponsePacket() function builds TLS response packet in
> > + response to the TLS request packet specified by RequestBuffer and
> > + RequestSize. If RequestBuffer is NULL and RequestSize is 0, and TLS
> > + session status is EfiTlsSessionNotStarted, the TLS session will be
> > + initiated and the response packet needs to be ClientHello. If
> > + RequestBuffer is NULL and RequestSize is 0, and TLS session status
> > + is EfiTlsSessionClosing, the TLS session will be closed and
> > + response packet needs to be CloseNotify. If RequestBuffer is NULL
> > + and RequestSize is 0, and TLS session status is EfiTlsSessionError,
> > + the TLS
> > session has errors and the response packet needs to be Alert message
> > based on error type.
> > +
> > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> > + @param[in] RequestBuffer Pointer to the most recently received TLS
> > packet. NULL
> > + means TLS need initiate the TLS session and response
> > + packet need to be ClientHello.
> > + @param[in] RequestSize Packet size in bytes for the most recently
> > received TLS
> > + packet. 0 is only valid when RequestBuffer is NULL.
> > + @param[out] Buffer Pointer to the buffer to hold the built packet.
> > + @param[in, out] BufferSize Pointer to the buffer size in bytes. On
> input,
> > it is
> > + the buffer size provided by the caller. On output, it
> > + is the buffer size in fact needed to contain the
> > + packet.
> > +
> > + @retval EFI_SUCCESS The required TLS packet is built successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + RequestBuffer is NULL but RequestSize is NOT 0.
> > + RequestSize is 0 but RequestBuffer is NOT NULL.
> > + BufferSize is NULL.
> > + Buffer is NULL if *BufferSize is not zero.
> > + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the
> > response packet.
> > + @retval EFI_NOT_READY Current TLS session state is NOT ready to
> > build
> > + ResponsePacket.
> > + @retval EFI_ABORTED Something wrong build response packet.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_BUILD_RESPONSE_PACKET) (
> > + IN EFI_TLS_PROTOCOL *This,
> > + IN UINT8 *RequestBuffer, OPTIONAL
> > + IN UINTN RequestSize, OPTIONAL
> > + OUT UINT8 *Buffer, OPTIONAL
> > + IN OUT UINTN *BufferSize
> > + );
> > +
> > +/**
> > + Decrypt or encrypt TLS packet during session. This function is only
> > +valid after
> > + session connected and for application_data content type.
> > +
> > + The ProcessPacket () function process each inbound or outbound TLS
> > + APP
> > packet.
> > +
> > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> > + @param[in, out] FragmentTable Pointer to a list of fragment. The
> > + caller
> > will take
> > + responsible to handle the original FragmentTable while
> > + it may be reallocated in TLS driver. If CryptMode is
> > + EfiTlsEncrypt, on input these fragments contain the TLS
> > + header and plain text TLS APP payload; on output these
> > + fragments contain the TLS header and cypher text TLS
> > + APP payload. If CryptMode is EfiTlsDecrypt, on input
> > + these fragments contain the TLS header and cypher text
> > + TLS APP payload; on output these fragments contain the
> > + TLS header and plain text TLS APP payload.
> > + @param[in] FragmentCount Number of fragment.
> > + @param[in] CryptMode Crypt mode.
> > +
> > + @retval EFI_SUCCESS The operation completed successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + FragmentTable is NULL.
> > + FragmentCount is NULL.
> > + CryptoMode is invalid.
> > + @retval EFI_NOT_READY Current TLS session state is NOT
> > + EfiTlsSessionDataTransferring.
> > + @retval EFI_ABORTED Something wrong decryption the message.
> > TLS session
> > + status will become EfiTlsSessionError. The caller need
> > + call BuildResponsePacket() to generate Error Alert
> > + message and send it out.
> > + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the
> > operation.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_PROCESS_PACKET) (
> > + IN EFI_TLS_PROTOCOL *This,
> > + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> > + IN UINT32 *FragmentCount,
> > + IN EFI_TLS_CRYPT_MODE CryptMode
> > + );
> > +
> > +///
> > +/// The EFI_TLS_PROTOCOL is used to create, destroy and manage TLS
> > session.
> > +/// For detail of TLS, please refer to TLS related RFC.
> > +///
> > +struct _EFI_TLS_PROTOCOL {
> > + EFI_TLS_SET_SESSION_DATA SetSessionData;
> > + EFI_TLS_GET_SESSION_DATA GetSessionData;
> > + EFI_TLS_BUILD_RESPONSE_PACKET BuildResponsePacket;
> > + EFI_TLS_PROCESS_PACKET ProcessPacket;
> > +};
> > +
> > +extern EFI_GUID gEfiTlsServiceBindingProtocolGuid;
> > +extern EFI_GUID gEfiTlsProtocolGuid;
> > +
> > +#endif // __EFI_TLS_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/TlsConfig.h
> > b/MdePkg/Include/Protocol/TlsConfig.h
> > new file mode 100644
> > index 0000000..4b62bf5
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/TlsConfig.h
> > @@ -0,0 +1,132 @@
> > +/** @file
> > + EFI TLS Configuration Protocol as defined in UEFI 2.5.
> > + The EFI TLS Configuration Protocol provides a way to set and get
> > +TLS
> > configuration.
> > +
> > + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > + This program and the accompanying materials are licensed and made
> > + available under the terms and conditions of the BSD License which
> > + accompanies this distribution. The full text of the license may be
> > + found at http://opensource.org/licenses/bsd-license.php
> > +
> > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> > BASIS,
> > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> > EXPRESS OR IMPLIED.
> > +
> > + @par Revision Reference:
> > + This Protocol is introduced in UEFI Specification 2.5
> > +
> > +**/
> > +#ifndef __EFI_TLS_CONFIGURATION_PROTOCOL_H__
> > +#define __EFI_TLS_CONFIGURATION_PROTOCOL_H__
> > +
> > +///
> > +/// The EFI Configuration protocol provides a way to set and get TLS
> > configuration.
> > +///
> > +#define EFI_TLS_CONFIGURATION_PROTOCOL_GUID \
> > + { \
> > + 0x1682fe44, 0xbd7a, 0x4407, { 0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3,
> > +0x92, 0x2d } \
> > + }
> > +
> > +typedef struct _EFI_TLS_CONFIGURATION_PROTOCOL
> > +EFI_TLS_CONFIGURATION_PROTOCOL;
> > +
> > +///
> > +/// EFI_TLS_CONFIG_DATA_TYPE
> > +///
> > +typedef enum {
> > + ///
> > + /// Local host configuration data: public certificate data.
> > + /// This data should be DER-encoded binaryX.509 certificate
> > + /// or PEMencoded X.509 certificate.
> > + ///
> > + EfiTlsConfigDataTypeHostPublicCert,
> > + ///
> > + /// Local host configuration data: private key data.
> > + ///
> > + EfiTlsConfigDataTypeHostPrivateKey,
> > + ///
> > + /// CA certificate to verify peer. This data should be PEM-encoded
> > + /// RSA or PKCS#8 private key.
> > + ///
> > + EfiTlsConfigDataTypeCACertificate,
> > + ///
> > + /// CA-supplied Certificate Revocation List data. This data should
> > + /// be DER-encoded CRL data.
> > + ///
> > + EfiTlsConfigDataTypeCertRevocationList,
> > +
> > + EfiTlsConfigDataTypeMaximum
> > +
> > +} EFI_TLS_CONFIG_DATA_TYPE;
> > +
> > +/**
> > + Set TLS configuration data.
> > +
> > + The SetData() function sets TLS configuration to non-volatile
> > + storage or volatile storage.
> > +
> > + @param[in] This Pointer to the
> > EFI_TLS_CONFIGURATION_PROTOCOL instance.
> > + @param[in] DataType Configuration data type.
> > + @param[in] Data Pointer to configuration data.
> > + @param[in] DataSize Total size of configuration data.
> > +
> > + @retval EFI_SUCCESS The TLS configuration data is set successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + Data is NULL.
> > + DataSize is 0.
> > + @retval EFI_UNSUPPORTED The DataType is unsupported.
> > + @retval EFI_OUT_OF_RESOURCES Required system resources could
> not
> > be allocated.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_CONFIGURATION_SET_DATA)(
> > + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> > + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> > + IN VOID *Data,
> > + IN UINTN DataSize
> > + );
> > +
> > +/**
> > + Get TLS configuration data.
> > +
> > + The GetData() function gets TLS configuration.
> > +
> > + @param[in] This Pointer to the
> > EFI_TLS_CONFIGURATION_PROTOCOL instance.
> > + @param[in] DataType Configuration data type.
> > + @param[in, out] Data Pointer to configuration data.
> > + @param[in, out] DataSize Total size of configuration data. On input, it
> > means
> > + the size of Data buffer. On output, it means the size
> > + of copied Data buffer if EFI_SUCCESS, and means the
> > + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> > +
> > + @retval EFI_SUCCESS The TLS configuration data is got successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + DataSize is NULL.
> > + Data is NULL if *DataSize is not zero.
> > + @retval EFI_UNSUPPORTED The DataType is unsupported.
> > + @retval EFI_NOT_FOUND The TLS configuration data is not found.
> > + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the
> data.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_CONFIGURATION_GET_DATA)(
> > + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> > + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> > + IN OUT VOID *Data, OPTIONAL
> > + IN OUT UINTN *DataSize
> > + );
> > +
> > +///
> > +/// The EFI_TLS_CONFIGURATION_PROTOCOL is designed to provide a
> way
> > to
> > +set and get /// TLS configuration, such as Certificate, private key data.
> > +///
> > +struct _EFI_TLS_CONFIGURATION_PROTOCOL {
> > + EFI_TLS_CONFIGURATION_SET_DATA SetData;
> > + EFI_TLS_CONFIGURATION_GET_DATA GetData;
> > +};
> > +
> > +extern EFI_GUID gEfiTlsConfigurationProtocolGuid;
> > +
> > +#endif //__EFI_TLS_CONFIGURATION_PROTOCOL_H__
> > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index
> > 3e08bed..f2bdb30 100644
> > --- a/MdePkg/MdePkg.dec
> > +++ b/MdePkg/MdePkg.dec
> > @@ -1607,10 +1607,19 @@
> > gEfiHttpProtocolGuid = { 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42,
> > 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b }}
> >
> > ## Include/Protocol/HttpUtilities.h
> > gEfiHttpUtilitiesProtocolGuid = { 0x3e35c163, 0x4074, 0x45dd, {0x43,
> > 0x1e, 0x23, 0x98, 0x9d, 0xd8, 0x6b, 0x32 }}
> >
> > + ## Include/Protocol/Tls.h
> > + gEfiTlsServiceBindingProtocolGuid = { 0x952cb795, 0xff36, 0x48cf, {0xa2,
> > 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d }}
> > +
> > + ## Include/Protocol/Tls.h
> > + gEfiTlsProtocolGuid = { 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc,
> 0xe4,
> > 0x6c, 0x47, 0x51, 0x43, 0x90 }}
> > +
> > + ## Include/Protocol/TlsConfig.h
> > + gEfiTlsConfigurationProtocolGuid = { 0x1682fe44, 0xbd7a, 0x4407, { 0xb7,
> > 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d }}
> > +
> > ## Include/Protocol/Rest.h
> > gEfiRestProtocolGuid = { 0x0db48a36, 0x4e54, 0xea9c, {0x9b, 0x09,
> > 0x1e, 0xa5, 0xbe, 0x3a, 0x66, 0x0b }}
> >
> > ## Include/Protocol/Supplicant.h
> > gEfiSupplicantServiceBindingProtocolGuid = { 0x45bcd98e, 0x59ad,
> > 0x4174, { 0x95, 0x46, 0x34, 0x4a, 0x7, 0x48, 0x58, 0x98 }}
> > --
> > 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Patch 01/10] MdePkg: Add TLS related protocol definition
2016-12-14 8:39 ` Wu, Jiaxin
@ 2016-12-15 8:34 ` Ye, Ting
0 siblings, 0 replies; 37+ messages in thread
From: Ye, Ting @ 2016-12-15 8:34 UTC (permalink / raw)
To: Wu, Jiaxin, Long, Qin, edk2-devel@lists.01.org
Cc: Fu, Siyuan, Zhang, Lubo, Gao, Liming, Kinney, Michael D,
Thomas Palmer
Reviewed-by: Ye Ting <ting.ye@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: Wednesday, December 14, 2016 4:39 PM
To: Long, Qin <qin.long@intel.com>; edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
Subject: RE: [Patch 01/10] MdePkg: Add TLS related protocol definition
Thanks Qin, I will correct it before commit this patch.
Best Regards!
Jiaxin
> -----Original Message-----
> From: Long, Qin
> Sent: Wednesday, December 14, 2016 4:36 PM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>;
> Zhang, Lubo <lubo.zhang@intel.com>; Gao, Liming
> <liming.gao@intel.com>; Kinney, Michael D
> <michael.d.kinney@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [Patch 01/10] MdePkg: Add TLS related protocol definition
>
> Reviewed-by: Qin Long <qin.long@intel.com>
>
> Please correct some typos later:
> EFI_TLS_EXTENDION --> EFI_TLS_EXTENSION TLS/SSLhandshake --> TLS/SSL
> handshake cerfificate --> certificate cypher --> cipher
> binaryX.509 --> binary X.509
> PEMencoded --> PEM-encoded
>
> Best Regards & Thanks,
> LONG, Qin
>
> > -----Original Message-----
> > From: Wu, Jiaxin
> > Sent: Wednesday, December 14, 2016 3:34 PM
> > To: edk2-devel@lists.01.org
> > Cc: Long, Qin; Ye, Ting; Fu, Siyuan; Zhang, Lubo; Gao, Liming;
> > Kinney, Michael D; Thomas Palmer; Wu, Jiaxin
> > Subject: [Patch 01/10] MdePkg: Add TLS related protocol definition
> >
> > This patch is used to add Tls.h and TlsConfig.h header files to
> > define EFI TLS Configuration Protocol, EFI TLS Service Binding
> > Protocol and EFI TLS Configuration Protocol.
> >
> > Cc: Long Qin <qin.long@intel.com>
> > Cc: Ye Ting <ting.ye@intel.com>
> > Cc: Fu Siyuan <siyuan.fu@intel.com>
> > Cc: Zhang Lubo <lubo.zhang@intel.com>
> > Cc: Liming Gao <liming.gao@intel.com>
> > Cc: Michael D Kinney <michael.d.kinney@intel.com>
> > Cc: Thomas Palmer <thomas.palmer@hpe.com>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> > ---
> > MdePkg/Include/Protocol/Tls.h | 460
> > ++++++++++++++++++++++++++++++++++++
> > MdePkg/Include/Protocol/TlsConfig.h | 132 +++++++++++
> > MdePkg/MdePkg.dec | 9 +
> > 3 files changed, 601 insertions(+)
> > create mode 100644 MdePkg/Include/Protocol/Tls.h create mode
> > 100644 MdePkg/Include/Protocol/TlsConfig.h
> >
> > diff --git a/MdePkg/Include/Protocol/Tls.h
> > b/MdePkg/Include/Protocol/Tls.h new file mode 100644 index
> > 0000000..51a3cda
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/Tls.h
> > @@ -0,0 +1,460 @@
> > +/** @file
> > + EFI TLS Protocols as defined in UEFI 2.5.
> > +
> > + The EFI TLS Service Binding Protocol is used to locate EFI TLS
> > + Protocol drivers to create and destroy child of the driver to
> > + communicate with other host using TLS protocol.
> > + The EFI TLS Protocol provides the ability to manage TLS session.
> > +
> > + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > + This program and the accompanying materials are licensed and made
> > + available under the terms and conditions of the BSD License which
> > + accompanies this distribution. The full text of the license may be
> > + found at http://opensource.org/licenses/bsd-license.php
> > +
> > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> > BASIS,
> > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> > EXPRESS OR IMPLIED.
> > +
> > + @par Revision Reference:
> > + This Protocol is introduced in UEFI Specification 2.5
> > +
> > +**/
> > +
> > +#ifndef __EFI_TLS_PROTOCOL_H__
> > +#define __EFI_TLS_PROTOCOL_H__
> > +
> > +///
> > +/// The EFI TLS Service Binding Protocol is used to locate EFI TLS
> > +Protocol drivers to /// create and destroy child of the driver to
> > +communicate with other host using TLS /// protocol.
> > +///
> > +#define EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID \
> > + { \
> > + 0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86,
> > +0xd6, 0xab, 0x8d } \
> > + }
> > +
> > +///
> > +/// The EFI TLS protocol provides the ability to manage TLS session.
> > +///
> > +#define EFI_TLS_PROTOCOL_GUID \
> > + { \
> > + 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc, 0xe4, 0x6c, 0x47, 0x51,
> > +0x43, 0x90 } \
> > + }
> > +
> > +typedef struct _EFI_TLS_PROTOCOL EFI_TLS_PROTOCOL;
> > +
> > +///
> > +/// EFI_TLS_SESSION_DATA_TYPE
> > +///
> > +typedef enum {
> > + ///
> > + /// Session Configuration
> > + ///
> > +
> > + ///
> > + /// TLS session Version. The corresponding Data is of type
> > EFI_TLS_VERSION.
> > + ///
> > + EfiTlsVersion,
> > + ///
> > + /// TLS session as client or as server. The corresponding Data is
> > + of /// EFI_TLS_CONNECTION_END.
> > + ///
> > + EfiTlsConnectionEnd,
> > + ///
> > + /// A priority list of preferred algorithms for the TLS session.
> > + /// The corresponding Data is a list of EFI_TLS_CIPHER.
> > + ///
> > + EfiTlsCipherList,
> > + ///
> > + /// TLS session compression method.
> > + /// The corresponding Data is of type EFI_TLS_COMPRESSION.
> > + ///
> > + EfiTlsCompressionMethod,
> > + ///
> > + /// TLS session extension data.
> > + /// The corresponding Data is a list of type EFI_TLS_EXTENDION.
> > + ///
> > + EfiTlsExtensionData,
> > + ///
> > + /// TLS session verify method.
> > + /// The corresponding Data is of type EFI_TLS_VERIFY.
> > + ///
> > + EfiTlsVerifyMethod,
> > + ///
> > + /// TLS session data session ID.
> > + /// For SetSessionData(), it is TLS session ID used for session resumption.
> > + /// For GetSessionData(), it is the TLS session ID used for current session.
> > + /// The corresponding Data is of type EFI_TLS_SESSION_ID.
> > + ///
> > + EfiTlsSessionID,
> > + ///
> > + /// TLS session data session state.
> > + /// The corresponding Data is of type EFI_TLS_SESSION_STATE.
> > + ///
> > + EfiTlsSessionState,
> > +
> > + ///
> > + /// Session information
> > + ///
> > +
> > + ///
> > + /// TLS session data client random.
> > + /// The corresponding Data is of type EFI_TLS_RANDOM.
> > + ///
> > + EfiTlsClientRandom,
> > + ///
> > + /// TLS session data server random.
> > + /// The corresponding Data is of type EFI_TLS_RANDOM.
> > + ///
> > + EfiTlsServerRandom,
> > + ///
> > + /// TLS session data key material.
> > + /// The corresponding Data is of type EFI_TLS_MASTER_SECRET.
> > + ///
> > + EfiTlsKeyMaterial,
> > +
> > + EfiTlsSessionDataTypeMaximum
> > +
> > +} EFI_TLS_SESSION_DATA_TYPE;
> > +
> > +///
> > +/// EFI_TLS_VERSION
> > +/// Note: The TLS version definition is from SSL3.0 to the latest TLS (e.g.
> 1.2).
> > +/// SSL2.0 is obsolete and should not be used.
> > +///
> > +typedef struct {
> > + UINT8 Major;
> > + UINT8 Minor;
> > +} EFI_TLS_VERSION;
> > +
> > +///
> > +/// EFI_TLS_CONNECTION_END to define TLS session as client or server.
> > +///
> > +typedef enum {
> > + EfiTlsClient,
> > + EfiTlsServer,
> > +} EFI_TLS_CONNECTION_END;
> > +
> > +///
> > +/// EFI_TLS_CIPHER
> > +/// Note: The definition of EFI_TLS_CIPHER definition is from "RFC
> > +5246,
> > A.4.1.
> > +/// Hello Messages". The value of EFI_TLS_CIPHER is from TLS Cipher
> > +/// Suite Registry of IANA.
> > +///
> > +typedef struct {
> > + UINT8 Data1;
> > + UINT8 Data2;
> > +} EFI_TLS_CIPHER;
> > +
> > +///
> > +/// EFI_TLS_COMPRESSION
> > +/// Note: The value of EFI_TLS_COMPRESSION definition is from "RFC
> 3749".
> > +///
> > +typedef UINT8 EFI_TLS_COMPRESSION;
> > +
> > +///
> > +/// EFI_TLS_EXTENSION
> > +/// Note: The definition of EFI_TLS_EXTENSION if from "RFC 5246 A.4.1.
> > +/// Hello Messages".
> > +///
> > +typedef struct {
> > + UINT16 ExtensionType;
> > + UINT16 Length;
> > + UINT8 Data[1];
> > +} EFI_TLS_EXTENSION;
> > +
> > +///
> > +/// EFI_TLS_VERIFY
> > +/// Use either EFI_TLS_VERIFY_NONE or EFI_TLS_VERIFY_PEER, the last
> > +two options /// are 'ORed' with EFI_TLS_VERIFY_PEER if they are desired.
> > +///
> > +typedef UINT32 EFI_TLS_VERIFY;
> > +///
> > +/// No certificates will be sent or the TLS/SSLhandshake will be
> > +continued regardless /// of the certificate verification result.
> > +///
> > +#define EFI_TLS_VERIFY_NONE 0x0
> > +///
> > +/// The TLS/SSL handshake is immediately terminated with an alert
> > +message containing /// the reason for the certificate verification failure.
> > +///
> > +#define EFI_TLS_VERIFY_PEER 0x1
> > +///
> > +/// TLS session will fail peer certificate is absent.
> > +///
> > +#define EFI_TLS_VERIFY_FAIL_IF_NO_PEER_CERT 0x2 /// /// TLS
> > +session only verify client once, and doesn't request cerfificate
> > +during /// re-negotiation.
> > +///
> > +#define EFI_TLS_VERIFY_CLIENT_ONCE 0x4
> > +
> > +///
> > +/// EFI_TLS_RANDOM
> > +/// Note: The definition of EFI_TLS_RANDOM is from "RFC 5246 A.4.1.
> > +/// Hello Messages".
> > +///
> > +typedef struct {
> > + UINT32 GmtUnixTime;
> > + UINT8 RandomBytes[28];
> > +} EFI_TLS_RANDOM;
> > +
> > +///
> > +/// EFI_TLS_MASTER_SECRET
> > +/// Note: The definition of EFI_TLS_MASTER_SECRET is from "RFC 5246 8.1.
> > +/// Computing the Master Secret".
> > +///
> > +typedef struct {
> > + UINT8 Data[48];
> > +} EFI_TLS_MASTER_SECRET;
> > +
> > +///
> > +/// EFI_TLS_SESSION_ID
> > +/// Note: The definition of EFI_TLS_SESSION_ID is from "RFC 5246 A.4.1.
> > Hello Messages".
> > +///
> > +#define MAX_TLS_SESSION_ID_LENGTH 32 typedef struct {
> > + UINT16 Length;
> > + UINT8 Data[MAX_TLS_SESSION_ID_LENGTH];
> > +} EFI_TLS_SESSION_ID;
> > +
> > +///
> > +/// EFI_TLS_SESSION_STATE
> > +///
> > +typedef enum {
> > + ///
> > + /// When a new child of TLS protocol is created, the initial
> > +state of TLS session
> > + /// is EfiTlsSessionNotStarted.
> > + ///
> > + EfiTlsSessionNotStarted,
> > + ///
> > + /// The consumer can call BuildResponsePacket() with NULL to get
> > +ClientHello to
> > + /// start the TLS session. Then the status is EfiTlsSessionHandShaking.
> > + ///
> > + EfiTlsSessionHandShaking,
> > + ///
> > + /// During handshake, the consumer need call
> > +BuildResponsePacket() with input
> > + /// data from peer, then get response packet and send to peer.
> > +After handshake
> > + /// finish, the TLS session status becomes
> > +EfiTlsSessionDataTransferring, and
> > + /// consumer can use ProcessPacket() for data transferring.
> > + ///
> > + EfiTlsSessionDataTransferring,
> > + ///
> > + /// Finally, if consumer wants to active close TLS session,
> > +consumer need
> > + /// call SetSessionData to set TLS session state to
> > +EfiTlsSessionClosing, and
> > + /// call BuildResponsePacket() with NULL to get CloseNotify alert
> > +message,
> > + /// and sent it out.
> > + ///
> > + EfiTlsSessionClosing,
> > + ///
> > + /// If any error happen during parsing ApplicationData content
> > +type, EFI_ABORT
> > + /// will be returned by ProcessPacket(), and TLS session state
> > +will become
> > + /// EfiTlsSessionError. Then consumer need call
> > +BuildResponsePacket() with
> > + /// NULL to get alert message and sent it out.
> > + ///
> > + EfiTlsSessionError,
> > +
> > + EfiTlsSessionStateMaximum
> > +
> > +} EFI_TLS_SESSION_STATE;
> > +
> > +///
> > +/// EFI_TLS_FRAGMENT_DATA
> > +///
> > +typedef struct {
> > + ///
> > + /// Length of data buffer in the fragment.
> > + ///
> > + UINT32 FragmentLength;
> > + ///
> > + /// Pointer to the data buffer in the fragment.
> > + ///
> > + VOID *FragmentBuffer;
> > +} EFI_TLS_FRAGMENT_DATA;
> > +
> > +///
> > +/// EFI_TLS_CRYPT_MODE
> > +///
> > +typedef enum {
> > + ///
> > + /// Encrypt data provided in the fragment buffers.
> > + ///
> > + EfiTlsEncrypt,
> > + ///
> > + /// Decrypt data provided in the fragment buffers.
> > + ///
> > + EfiTlsDecrypt,
> > +} EFI_TLS_CRYPT_MODE;
> > +
> > +/**
> > + Set TLS session data.
> > +
> > + The SetSessionData() function set data for a new TLS session. All
> > + session data should be set before BuildResponsePacket() invoked.
> > +
> > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> > + @param[in] DataType TLS session data type.
> > + @param[in] Data Pointer to session data.
> > + @param[in] DataSize Total size of session data.
> > +
> > + @retval EFI_SUCCESS The TLS session data is set successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + Data is NULL.
> > + DataSize is 0.
> > + @retval EFI_UNSUPPORTED The DataType is unsupported.
> > + @retval EFI_ACCESS_DENIED If the DataType is one of below:
> > + EfiTlsClientRandom
> > + EfiTlsServerRandom
> > + EfiTlsKeyMaterial
> > + @retval EFI_NOT_READY Current TLS session state is NOT
> > + EfiTlsSessionStateNotStarted.
> > + @retval EFI_OUT_OF_RESOURCES Required system resources could
> not
> > be allocated.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_SET_SESSION_DATA) (
> > + IN EFI_TLS_PROTOCOL *This,
> > + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> > + IN VOID *Data,
> > + IN UINTN DataSize
> > + );
> > +
> > +/**
> > + Get TLS session data.
> > +
> > + The GetSessionData() function return the TLS session information.
> > +
> > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> > + @param[in] DataType TLS session data type.
> > + @param[in, out] Data Pointer to session data.
> > + @param[in, out] DataSize Total size of session data. On input, it
> means
> > + the size of Data buffer. On output, it means the size
> > + of copied Data buffer if EFI_SUCCESS, and means the
> > + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> > +
> > + @retval EFI_SUCCESS The TLS session data is got successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + DataSize is NULL.
> > + Data is NULL if *DataSize is not zero.
> > + @retval EFI_UNSUPPORTED The DataType is unsupported.
> > + @retval EFI_NOT_FOUND The TLS session data is not found.
> > + @retval EFI_NOT_READY The DataType is not ready in current
> session
> > state.
> > + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the
> data.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_GET_SESSION_DATA) (
> > + IN EFI_TLS_PROTOCOL *This,
> > + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> > + IN OUT VOID *Data, OPTIONAL
> > + IN OUT UINTN *DataSize
> > + );
> > +
> > +/**
> > + Build response packet according to TLS state machine. This
> > +function is only valid for
> > + alert, handshake and change_cipher_spec content type.
> > +
> > + The BuildResponsePacket() function builds TLS response packet in
> > + response to the TLS request packet specified by RequestBuffer and
> > + RequestSize. If RequestBuffer is NULL and RequestSize is 0, and
> > + TLS session status is EfiTlsSessionNotStarted, the TLS session
> > + will be initiated and the response packet needs to be ClientHello.
> > + If RequestBuffer is NULL and RequestSize is 0, and TLS session
> > + status is EfiTlsSessionClosing, the TLS session will be closed
> > + and response packet needs to be CloseNotify. If RequestBuffer is
> > + NULL and RequestSize is 0, and TLS session status is
> > + EfiTlsSessionError, the TLS
> > session has errors and the response packet needs to be Alert message
> > based on error type.
> > +
> > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> > + @param[in] RequestBuffer Pointer to the most recently received TLS
> > packet. NULL
> > + means TLS need initiate the TLS session and response
> > + packet need to be ClientHello.
> > + @param[in] RequestSize Packet size in bytes for the most recently
> > received TLS
> > + packet. 0 is only valid when RequestBuffer is NULL.
> > + @param[out] Buffer Pointer to the buffer to hold the built packet.
> > + @param[in, out] BufferSize Pointer to the buffer size in bytes. On
> input,
> > it is
> > + the buffer size provided by the caller. On output, it
> > + is the buffer size in fact needed to contain the
> > + packet.
> > +
> > + @retval EFI_SUCCESS The required TLS packet is built successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + RequestBuffer is NULL but RequestSize is NOT 0.
> > + RequestSize is 0 but RequestBuffer is NOT NULL.
> > + BufferSize is NULL.
> > + Buffer is NULL if *BufferSize is not zero.
> > + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the
> > response packet.
> > + @retval EFI_NOT_READY Current TLS session state is NOT ready to
> > build
> > + ResponsePacket.
> > + @retval EFI_ABORTED Something wrong build response packet.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_BUILD_RESPONSE_PACKET) (
> > + IN EFI_TLS_PROTOCOL *This,
> > + IN UINT8 *RequestBuffer, OPTIONAL
> > + IN UINTN RequestSize, OPTIONAL
> > + OUT UINT8 *Buffer, OPTIONAL
> > + IN OUT UINTN *BufferSize
> > + );
> > +
> > +/**
> > + Decrypt or encrypt TLS packet during session. This function is
> > +only valid after
> > + session connected and for application_data content type.
> > +
> > + The ProcessPacket () function process each inbound or outbound
> > + TLS APP
> > packet.
> > +
> > + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> > + @param[in, out] FragmentTable Pointer to a list of fragment.
> > + The caller
> > will take
> > + responsible to handle the original FragmentTable while
> > + it may be reallocated in TLS driver. If CryptMode is
> > + EfiTlsEncrypt, on input these fragments contain the TLS
> > + header and plain text TLS APP payload; on output these
> > + fragments contain the TLS header and cypher text TLS
> > + APP payload. If CryptMode is EfiTlsDecrypt, on input
> > + these fragments contain the TLS header and cypher text
> > + TLS APP payload; on output these fragments contain the
> > + TLS header and plain text TLS APP payload.
> > + @param[in] FragmentCount Number of fragment.
> > + @param[in] CryptMode Crypt mode.
> > +
> > + @retval EFI_SUCCESS The operation completed successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + FragmentTable is NULL.
> > + FragmentCount is NULL.
> > + CryptoMode is invalid.
> > + @retval EFI_NOT_READY Current TLS session state is NOT
> > + EfiTlsSessionDataTransferring.
> > + @retval EFI_ABORTED Something wrong decryption the message.
> > TLS session
> > + status will become EfiTlsSessionError. The caller need
> > + call BuildResponsePacket() to generate Error Alert
> > + message and send it out.
> > + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the
> > operation.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_PROCESS_PACKET) (
> > + IN EFI_TLS_PROTOCOL *This,
> > + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> > + IN UINT32 *FragmentCount,
> > + IN EFI_TLS_CRYPT_MODE CryptMode
> > + );
> > +
> > +///
> > +/// The EFI_TLS_PROTOCOL is used to create, destroy and manage TLS
> > session.
> > +/// For detail of TLS, please refer to TLS related RFC.
> > +///
> > +struct _EFI_TLS_PROTOCOL {
> > + EFI_TLS_SET_SESSION_DATA SetSessionData;
> > + EFI_TLS_GET_SESSION_DATA GetSessionData;
> > + EFI_TLS_BUILD_RESPONSE_PACKET BuildResponsePacket;
> > + EFI_TLS_PROCESS_PACKET ProcessPacket;
> > +};
> > +
> > +extern EFI_GUID gEfiTlsServiceBindingProtocolGuid;
> > +extern EFI_GUID gEfiTlsProtocolGuid;
> > +
> > +#endif // __EFI_TLS_PROTOCOL_H__
> > diff --git a/MdePkg/Include/Protocol/TlsConfig.h
> > b/MdePkg/Include/Protocol/TlsConfig.h
> > new file mode 100644
> > index 0000000..4b62bf5
> > --- /dev/null
> > +++ b/MdePkg/Include/Protocol/TlsConfig.h
> > @@ -0,0 +1,132 @@
> > +/** @file
> > + EFI TLS Configuration Protocol as defined in UEFI 2.5.
> > + The EFI TLS Configuration Protocol provides a way to set and get
> > +TLS
> > configuration.
> > +
> > + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> > + This program and the accompanying materials are licensed and made
> > + available under the terms and conditions of the BSD License which
> > + accompanies this distribution. The full text of the license may be
> > + found at http://opensource.org/licenses/bsd-license.php
> > +
> > + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> > BASIS,
> > + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> > EXPRESS OR IMPLIED.
> > +
> > + @par Revision Reference:
> > + This Protocol is introduced in UEFI Specification 2.5
> > +
> > +**/
> > +#ifndef __EFI_TLS_CONFIGURATION_PROTOCOL_H__
> > +#define __EFI_TLS_CONFIGURATION_PROTOCOL_H__
> > +
> > +///
> > +/// The EFI Configuration protocol provides a way to set and get
> > +TLS
> > configuration.
> > +///
> > +#define EFI_TLS_CONFIGURATION_PROTOCOL_GUID \
> > + { \
> > + 0x1682fe44, 0xbd7a, 0x4407, { 0xb7, 0xc7, 0xdc, 0xa3, 0x7c,
> > +0xa3, 0x92, 0x2d } \
> > + }
> > +
> > +typedef struct _EFI_TLS_CONFIGURATION_PROTOCOL
> > +EFI_TLS_CONFIGURATION_PROTOCOL;
> > +
> > +///
> > +/// EFI_TLS_CONFIG_DATA_TYPE
> > +///
> > +typedef enum {
> > + ///
> > + /// Local host configuration data: public certificate data.
> > + /// This data should be DER-encoded binaryX.509 certificate
> > + /// or PEMencoded X.509 certificate.
> > + ///
> > + EfiTlsConfigDataTypeHostPublicCert,
> > + ///
> > + /// Local host configuration data: private key data.
> > + ///
> > + EfiTlsConfigDataTypeHostPrivateKey,
> > + ///
> > + /// CA certificate to verify peer. This data should be
> > +PEM-encoded
> > + /// RSA or PKCS#8 private key.
> > + ///
> > + EfiTlsConfigDataTypeCACertificate,
> > + ///
> > + /// CA-supplied Certificate Revocation List data. This data
> > +should
> > + /// be DER-encoded CRL data.
> > + ///
> > + EfiTlsConfigDataTypeCertRevocationList,
> > +
> > + EfiTlsConfigDataTypeMaximum
> > +
> > +} EFI_TLS_CONFIG_DATA_TYPE;
> > +
> > +/**
> > + Set TLS configuration data.
> > +
> > + The SetData() function sets TLS configuration to non-volatile
> > + storage or volatile storage.
> > +
> > + @param[in] This Pointer to the
> > EFI_TLS_CONFIGURATION_PROTOCOL instance.
> > + @param[in] DataType Configuration data type.
> > + @param[in] Data Pointer to configuration data.
> > + @param[in] DataSize Total size of configuration data.
> > +
> > + @retval EFI_SUCCESS The TLS configuration data is set successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + Data is NULL.
> > + DataSize is 0.
> > + @retval EFI_UNSUPPORTED The DataType is unsupported.
> > + @retval EFI_OUT_OF_RESOURCES Required system resources could
> not
> > be allocated.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_CONFIGURATION_SET_DATA)(
> > + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> > + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> > + IN VOID *Data,
> > + IN UINTN DataSize
> > + );
> > +
> > +/**
> > + Get TLS configuration data.
> > +
> > + The GetData() function gets TLS configuration.
> > +
> > + @param[in] This Pointer to the
> > EFI_TLS_CONFIGURATION_PROTOCOL instance.
> > + @param[in] DataType Configuration data type.
> > + @param[in, out] Data Pointer to configuration data.
> > + @param[in, out] DataSize Total size of configuration data. On input, it
> > means
> > + the size of Data buffer. On output, it means the size
> > + of copied Data buffer if EFI_SUCCESS, and means the
> > + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> > +
> > + @retval EFI_SUCCESS The TLS configuration data is got successfully.
> > + @retval EFI_INVALID_PARAMETER One or more of the following
> > conditions is TRUE:
> > + This is NULL.
> > + DataSize is NULL.
> > + Data is NULL if *DataSize is not zero.
> > + @retval EFI_UNSUPPORTED The DataType is unsupported.
> > + @retval EFI_NOT_FOUND The TLS configuration data is not found.
> > + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the
> data.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_TLS_CONFIGURATION_GET_DATA)(
> > + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> > + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> > + IN OUT VOID *Data, OPTIONAL
> > + IN OUT UINTN *DataSize
> > + );
> > +
> > +///
> > +/// The EFI_TLS_CONFIGURATION_PROTOCOL is designed to provide a
> way
> > to
> > +set and get /// TLS configuration, such as Certificate, private key data.
> > +///
> > +struct _EFI_TLS_CONFIGURATION_PROTOCOL {
> > + EFI_TLS_CONFIGURATION_SET_DATA SetData;
> > + EFI_TLS_CONFIGURATION_GET_DATA GetData;
> > +};
> > +
> > +extern EFI_GUID gEfiTlsConfigurationProtocolGuid;
> > +
> > +#endif //__EFI_TLS_CONFIGURATION_PROTOCOL_H__
> > diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index
> > 3e08bed..f2bdb30 100644
> > --- a/MdePkg/MdePkg.dec
> > +++ b/MdePkg/MdePkg.dec
> > @@ -1607,10 +1607,19 @@
> > gEfiHttpProtocolGuid = { 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42,
> > 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b }}
> >
> > ## Include/Protocol/HttpUtilities.h
> > gEfiHttpUtilitiesProtocolGuid = { 0x3e35c163, 0x4074, 0x45dd, {0x43,
> > 0x1e, 0x23, 0x98, 0x9d, 0xd8, 0x6b, 0x32 }}
> >
> > + ## Include/Protocol/Tls.h
> > + gEfiTlsServiceBindingProtocolGuid = { 0x952cb795, 0xff36, 0x48cf, {0xa2,
> > 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d }}
> > +
> > + ## Include/Protocol/Tls.h
> > + gEfiTlsProtocolGuid = { 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc,
> 0xe4,
> > 0x6c, 0x47, 0x51, 0x43, 0x90 }}
> > +
> > + ## Include/Protocol/TlsConfig.h
> > + gEfiTlsConfigurationProtocolGuid = { 0x1682fe44, 0xbd7a, 0x4407, { 0xb7,
> > 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d }}
> > +
> > ## Include/Protocol/Rest.h
> > gEfiRestProtocolGuid = { 0x0db48a36, 0x4e54, 0xea9c, {0x9b, 0x09,
> > 0x1e, 0xa5, 0xbe, 0x3a, 0x66, 0x0b }}
> >
> > ## Include/Protocol/Supplicant.h
> > gEfiSupplicantServiceBindingProtocolGuid = { 0x45bcd98e, 0x59ad,
> > 0x4174, { 0x95, 0x46, 0x34, 0x4a, 0x7, 0x48, 0x58, 0x98 }}
> > --
> > 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Patch 01/10] MdePkg: Add TLS related protocol definition
2016-12-14 7:34 ` [Patch 01/10] MdePkg: Add TLS related protocol definition Jiaxin Wu
2016-12-14 8:36 ` Long, Qin
@ 2016-12-14 8:43 ` Fu, Siyuan
1 sibling, 0 replies; 37+ messages in thread
From: Fu, Siyuan @ 2016-12-14 8:43 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Long, Qin, Ye, Ting, Zhang, Lubo, Gao, Liming, Kinney, Michael D,
Thomas Palmer
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: 2016年12月14日 15:34
To: edk2-devel@lists.01.org
Cc: Long, Qin <qin.long@intel.com>; Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 01/10] MdePkg: Add TLS related protocol definition
This patch is used to add Tls.h and TlsConfig.h header files to define EFI TLS Configuration Protocol, EFI TLS Service Binding Protocol and EFI TLS Configuration Protocol.
Cc: Long Qin <qin.long@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
MdePkg/Include/Protocol/Tls.h | 460 ++++++++++++++++++++++++++++++++++++
MdePkg/Include/Protocol/TlsConfig.h | 132 +++++++++++
MdePkg/MdePkg.dec | 9 +
3 files changed, 601 insertions(+)
create mode 100644 MdePkg/Include/Protocol/Tls.h create mode 100644 MdePkg/Include/Protocol/TlsConfig.h
diff --git a/MdePkg/Include/Protocol/Tls.h b/MdePkg/Include/Protocol/Tls.h new file mode 100644 index 0000000..51a3cda
--- /dev/null
+++ b/MdePkg/Include/Protocol/Tls.h
@@ -0,0 +1,460 @@
+/** @file
+ EFI TLS Protocols as defined in UEFI 2.5.
+
+ The EFI TLS Service Binding Protocol is used to locate EFI TLS
+ Protocol drivers to create and destroy child of the driver to
+ communicate with other host using TLS protocol.
+ The EFI TLS Protocol provides the ability to manage TLS session.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> This
+ program and the accompanying materials are licensed and made
+ available under the terms and conditions of the BSD License which
+ accompanies this distribution. The full text of the license may be
+ found at http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This Protocol is introduced in UEFI Specification 2.5
+
+**/
+
+#ifndef __EFI_TLS_PROTOCOL_H__
+#define __EFI_TLS_PROTOCOL_H__
+
+///
+/// The EFI TLS Service Binding Protocol is used to locate EFI TLS
+Protocol drivers to /// create and destroy child of the driver to
+communicate with other host using TLS /// protocol.
+///
+#define EFI_TLS_SERVICE_BINDING_PROTOCOL_GUID \
+ { \
+ 0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6,
+0xab, 0x8d } \
+ }
+
+///
+/// The EFI TLS protocol provides the ability to manage TLS session.
+///
+#define EFI_TLS_PROTOCOL_GUID \
+ { \
+ 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc, 0xe4, 0x6c, 0x47, 0x51,
+0x43, 0x90 } \
+ }
+
+typedef struct _EFI_TLS_PROTOCOL EFI_TLS_PROTOCOL;
+
+///
+/// EFI_TLS_SESSION_DATA_TYPE
+///
+typedef enum {
+ ///
+ /// Session Configuration
+ ///
+
+ ///
+ /// TLS session Version. The corresponding Data is of type EFI_TLS_VERSION.
+ ///
+ EfiTlsVersion,
+ ///
+ /// TLS session as client or as server. The corresponding Data is of
+ /// EFI_TLS_CONNECTION_END.
+ ///
+ EfiTlsConnectionEnd,
+ ///
+ /// A priority list of preferred algorithms for the TLS session.
+ /// The corresponding Data is a list of EFI_TLS_CIPHER.
+ ///
+ EfiTlsCipherList,
+ ///
+ /// TLS session compression method.
+ /// The corresponding Data is of type EFI_TLS_COMPRESSION.
+ ///
+ EfiTlsCompressionMethod,
+ ///
+ /// TLS session extension data.
+ /// The corresponding Data is a list of type EFI_TLS_EXTENDION.
+ ///
+ EfiTlsExtensionData,
+ ///
+ /// TLS session verify method.
+ /// The corresponding Data is of type EFI_TLS_VERIFY.
+ ///
+ EfiTlsVerifyMethod,
+ ///
+ /// TLS session data session ID.
+ /// For SetSessionData(), it is TLS session ID used for session resumption.
+ /// For GetSessionData(), it is the TLS session ID used for current session.
+ /// The corresponding Data is of type EFI_TLS_SESSION_ID.
+ ///
+ EfiTlsSessionID,
+ ///
+ /// TLS session data session state.
+ /// The corresponding Data is of type EFI_TLS_SESSION_STATE.
+ ///
+ EfiTlsSessionState,
+
+ ///
+ /// Session information
+ ///
+
+ ///
+ /// TLS session data client random.
+ /// The corresponding Data is of type EFI_TLS_RANDOM.
+ ///
+ EfiTlsClientRandom,
+ ///
+ /// TLS session data server random.
+ /// The corresponding Data is of type EFI_TLS_RANDOM.
+ ///
+ EfiTlsServerRandom,
+ ///
+ /// TLS session data key material.
+ /// The corresponding Data is of type EFI_TLS_MASTER_SECRET.
+ ///
+ EfiTlsKeyMaterial,
+
+ EfiTlsSessionDataTypeMaximum
+
+} EFI_TLS_SESSION_DATA_TYPE;
+
+///
+/// EFI_TLS_VERSION
+/// Note: The TLS version definition is from SSL3.0 to the latest TLS (e.g. 1.2).
+/// SSL2.0 is obsolete and should not be used.
+///
+typedef struct {
+ UINT8 Major;
+ UINT8 Minor;
+} EFI_TLS_VERSION;
+
+///
+/// EFI_TLS_CONNECTION_END to define TLS session as client or server.
+///
+typedef enum {
+ EfiTlsClient,
+ EfiTlsServer,
+} EFI_TLS_CONNECTION_END;
+
+///
+/// EFI_TLS_CIPHER
+/// Note: The definition of EFI_TLS_CIPHER definition is from "RFC 5246, A.4.1.
+/// Hello Messages". The value of EFI_TLS_CIPHER is from TLS Cipher
+/// Suite Registry of IANA.
+///
+typedef struct {
+ UINT8 Data1;
+ UINT8 Data2;
+} EFI_TLS_CIPHER;
+
+///
+/// EFI_TLS_COMPRESSION
+/// Note: The value of EFI_TLS_COMPRESSION definition is from "RFC 3749".
+///
+typedef UINT8 EFI_TLS_COMPRESSION;
+
+///
+/// EFI_TLS_EXTENSION
+/// Note: The definition of EFI_TLS_EXTENSION if from "RFC 5246 A.4.1.
+/// Hello Messages".
+///
+typedef struct {
+ UINT16 ExtensionType;
+ UINT16 Length;
+ UINT8 Data[1];
+} EFI_TLS_EXTENSION;
+
+///
+/// EFI_TLS_VERIFY
+/// Use either EFI_TLS_VERIFY_NONE or EFI_TLS_VERIFY_PEER, the last two
+options /// are 'ORed' with EFI_TLS_VERIFY_PEER if they are desired.
+///
+typedef UINT32 EFI_TLS_VERIFY;
+///
+/// No certificates will be sent or the TLS/SSLhandshake will be
+continued regardless /// of the certificate verification result.
+///
+#define EFI_TLS_VERIFY_NONE 0x0
+///
+/// The TLS/SSL handshake is immediately terminated with an alert
+message containing /// the reason for the certificate verification failure.
+///
+#define EFI_TLS_VERIFY_PEER 0x1
+///
+/// TLS session will fail peer certificate is absent.
+///
+#define EFI_TLS_VERIFY_FAIL_IF_NO_PEER_CERT 0x2 /// /// TLS session
+only verify client once, and doesn't request cerfificate during ///
+re-negotiation.
+///
+#define EFI_TLS_VERIFY_CLIENT_ONCE 0x4
+
+///
+/// EFI_TLS_RANDOM
+/// Note: The definition of EFI_TLS_RANDOM is from "RFC 5246 A.4.1.
+/// Hello Messages".
+///
+typedef struct {
+ UINT32 GmtUnixTime;
+ UINT8 RandomBytes[28];
+} EFI_TLS_RANDOM;
+
+///
+/// EFI_TLS_MASTER_SECRET
+/// Note: The definition of EFI_TLS_MASTER_SECRET is from "RFC 5246 8.1.
+/// Computing the Master Secret".
+///
+typedef struct {
+ UINT8 Data[48];
+} EFI_TLS_MASTER_SECRET;
+
+///
+/// EFI_TLS_SESSION_ID
+/// Note: The definition of EFI_TLS_SESSION_ID is from "RFC 5246 A.4.1. Hello Messages".
+///
+#define MAX_TLS_SESSION_ID_LENGTH 32
+typedef struct {
+ UINT16 Length;
+ UINT8 Data[MAX_TLS_SESSION_ID_LENGTH];
+} EFI_TLS_SESSION_ID;
+
+///
+/// EFI_TLS_SESSION_STATE
+///
+typedef enum {
+ ///
+ /// When a new child of TLS protocol is created, the initial state of
+TLS session
+ /// is EfiTlsSessionNotStarted.
+ ///
+ EfiTlsSessionNotStarted,
+ ///
+ /// The consumer can call BuildResponsePacket() with NULL to get
+ClientHello to
+ /// start the TLS session. Then the status is EfiTlsSessionHandShaking.
+ ///
+ EfiTlsSessionHandShaking,
+ ///
+ /// During handshake, the consumer need call BuildResponsePacket()
+with input
+ /// data from peer, then get response packet and send to peer. After
+handshake
+ /// finish, the TLS session status becomes
+EfiTlsSessionDataTransferring, and
+ /// consumer can use ProcessPacket() for data transferring.
+ ///
+ EfiTlsSessionDataTransferring,
+ ///
+ /// Finally, if consumer wants to active close TLS session, consumer
+need
+ /// call SetSessionData to set TLS session state to
+EfiTlsSessionClosing, and
+ /// call BuildResponsePacket() with NULL to get CloseNotify alert
+message,
+ /// and sent it out.
+ ///
+ EfiTlsSessionClosing,
+ ///
+ /// If any error happen during parsing ApplicationData content type,
+EFI_ABORT
+ /// will be returned by ProcessPacket(), and TLS session state will
+become
+ /// EfiTlsSessionError. Then consumer need call BuildResponsePacket()
+with
+ /// NULL to get alert message and sent it out.
+ ///
+ EfiTlsSessionError,
+
+ EfiTlsSessionStateMaximum
+
+} EFI_TLS_SESSION_STATE;
+
+///
+/// EFI_TLS_FRAGMENT_DATA
+///
+typedef struct {
+ ///
+ /// Length of data buffer in the fragment.
+ ///
+ UINT32 FragmentLength;
+ ///
+ /// Pointer to the data buffer in the fragment.
+ ///
+ VOID *FragmentBuffer;
+} EFI_TLS_FRAGMENT_DATA;
+
+///
+/// EFI_TLS_CRYPT_MODE
+///
+typedef enum {
+ ///
+ /// Encrypt data provided in the fragment buffers.
+ ///
+ EfiTlsEncrypt,
+ ///
+ /// Decrypt data provided in the fragment buffers.
+ ///
+ EfiTlsDecrypt,
+} EFI_TLS_CRYPT_MODE;
+
+/**
+ Set TLS session data.
+
+ The SetSessionData() function set data for a new TLS session. All
+ session data should be set before BuildResponsePacket() invoked.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in] Data Pointer to session data.
+ @param[in] DataSize Total size of session data.
+
+ @retval EFI_SUCCESS The TLS session data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_ACCESS_DENIED If the DataType is one of below:
+ EfiTlsClientRandom
+ EfiTlsServerRandom
+ EfiTlsKeyMaterial
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionStateNotStarted.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_SET_SESSION_DATA) (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Get TLS session data.
+
+ The GetSessionData() function return the TLS session information.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in, out] Data Pointer to session data.
+ @param[in, out] DataSize Total size of session data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS session data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS session data is not found.
+ @retval EFI_NOT_READY The DataType is not ready in current session state.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_GET_SESSION_DATA) (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Build response packet according to TLS state machine. This function
+is only valid for
+ alert, handshake and change_cipher_spec content type.
+
+ The BuildResponsePacket() function builds TLS response packet in
+ response to the TLS request packet specified by RequestBuffer and
+ RequestSize. If RequestBuffer is NULL and RequestSize is 0, and TLS
+ session status is EfiTlsSessionNotStarted, the TLS session will be
+ initiated and the response packet needs to be ClientHello. If
+ RequestBuffer is NULL and RequestSize is 0, and TLS session status is
+ EfiTlsSessionClosing, the TLS session will be closed and response
+ packet needs to be CloseNotify. If RequestBuffer is NULL and
+ RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS session has errors and the response packet needs to be Alert message based on error type.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL
+ means TLS need initiate the TLS session and response
+ packet need to be ClientHello.
+ @param[in] RequestSize Packet size in bytes for the most recently received TLS
+ packet. 0 is only valid when RequestBuffer is NULL.
+ @param[out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ RequestBuffer is NULL but RequestSize is NOT 0.
+ RequestSize is 0 but RequestBuffer is NOT NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+ @retval EFI_NOT_READY Current TLS session state is NOT ready to build
+ ResponsePacket.
+ @retval EFI_ABORTED Something wrong build response packet.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_BUILD_RESPONSE_PACKET) (
+ IN EFI_TLS_PROTOCOL *This,
+ IN UINT8 *RequestBuffer, OPTIONAL
+ IN UINTN RequestSize, OPTIONAL
+ OUT UINT8 *Buffer, OPTIONAL
+ IN OUT UINTN *BufferSize
+ );
+
+/**
+ Decrypt or encrypt TLS packet during session. This function is only
+valid after
+ session connected and for application_data content type.
+
+ The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take
+ responsible to handle the original FragmentTable while
+ it may be reallocated in TLS driver. If CryptMode is
+ EfiTlsEncrypt, on input these fragments contain the TLS
+ header and plain text TLS APP payload; on output these
+ fragments contain the TLS header and cypher text TLS
+ APP payload. If CryptMode is EfiTlsDecrypt, on input
+ these fragments contain the TLS header and cypher text
+ TLS APP payload; on output these fragments contain the
+ TLS header and plain text TLS APP payload.
+ @param[in] FragmentCount Number of fragment.
+ @param[in] CryptMode Crypt mode.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ FragmentTable is NULL.
+ FragmentCount is NULL.
+ CryptoMode is invalid.
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionDataTransferring.
+ @retval EFI_ABORTED Something wrong decryption the message. TLS session
+ status will become EfiTlsSessionError. The caller need
+ call BuildResponsePacket() to generate Error Alert
+ message and send it out.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation.
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_PROCESS_PACKET) (
+ IN EFI_TLS_PROTOCOL *This,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount,
+ IN EFI_TLS_CRYPT_MODE CryptMode
+ );
+
+///
+/// The EFI_TLS_PROTOCOL is used to create, destroy and manage TLS session.
+/// For detail of TLS, please refer to TLS related RFC.
+///
+struct _EFI_TLS_PROTOCOL {
+ EFI_TLS_SET_SESSION_DATA SetSessionData;
+ EFI_TLS_GET_SESSION_DATA GetSessionData;
+ EFI_TLS_BUILD_RESPONSE_PACKET BuildResponsePacket;
+ EFI_TLS_PROCESS_PACKET ProcessPacket;
+};
+
+extern EFI_GUID gEfiTlsServiceBindingProtocolGuid;
+extern EFI_GUID gEfiTlsProtocolGuid;
+
+#endif // __EFI_TLS_PROTOCOL_H__
diff --git a/MdePkg/Include/Protocol/TlsConfig.h b/MdePkg/Include/Protocol/TlsConfig.h
new file mode 100644
index 0000000..4b62bf5
--- /dev/null
+++ b/MdePkg/Include/Protocol/TlsConfig.h
@@ -0,0 +1,132 @@
+/** @file
+ EFI TLS Configuration Protocol as defined in UEFI 2.5.
+ The EFI TLS Configuration Protocol provides a way to set and get TLS configuration.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> This
+ program and the accompanying materials are licensed and made
+ available under the terms and conditions of the BSD License which
+ accompanies this distribution. The full text of the license may be
+ found at http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This Protocol is introduced in UEFI Specification 2.5
+
+**/
+#ifndef __EFI_TLS_CONFIGURATION_PROTOCOL_H__
+#define __EFI_TLS_CONFIGURATION_PROTOCOL_H__
+
+///
+/// The EFI Configuration protocol provides a way to set and get TLS configuration.
+///
+#define EFI_TLS_CONFIGURATION_PROTOCOL_GUID \
+ { \
+ 0x1682fe44, 0xbd7a, 0x4407, { 0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3,
+0x92, 0x2d } \
+ }
+
+typedef struct _EFI_TLS_CONFIGURATION_PROTOCOL
+EFI_TLS_CONFIGURATION_PROTOCOL;
+
+///
+/// EFI_TLS_CONFIG_DATA_TYPE
+///
+typedef enum {
+ ///
+ /// Local host configuration data: public certificate data.
+ /// This data should be DER-encoded binaryX.509 certificate
+ /// or PEMencoded X.509 certificate.
+ ///
+ EfiTlsConfigDataTypeHostPublicCert,
+ ///
+ /// Local host configuration data: private key data.
+ ///
+ EfiTlsConfigDataTypeHostPrivateKey,
+ ///
+ /// CA certificate to verify peer. This data should be PEM-encoded
+ /// RSA or PKCS#8 private key.
+ ///
+ EfiTlsConfigDataTypeCACertificate,
+ ///
+ /// CA-supplied Certificate Revocation List data. This data should
+ /// be DER-encoded CRL data.
+ ///
+ EfiTlsConfigDataTypeCertRevocationList,
+
+ EfiTlsConfigDataTypeMaximum
+
+} EFI_TLS_CONFIG_DATA_TYPE;
+
+/**
+ Set TLS configuration data.
+
+ The SetData() function sets TLS configuration to non-volatile storage
+ or volatile storage.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in] Data Pointer to configuration data.
+ @param[in] DataSize Total size of configuration data.
+
+ @retval EFI_SUCCESS The TLS configuration data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_CONFIGURATION_SET_DATA)(
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Get TLS configuration data.
+
+ The GetData() function gets TLS configuration.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in, out] Data Pointer to configuration data.
+ @param[in, out] DataSize Total size of configuration data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS configuration data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS configuration data is not found.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TLS_CONFIGURATION_GET_DATA)(
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ );
+
+///
+/// The EFI_TLS_CONFIGURATION_PROTOCOL is designed to provide a way to
+set and get /// TLS configuration, such as Certificate, private key data.
+///
+struct _EFI_TLS_CONFIGURATION_PROTOCOL {
+ EFI_TLS_CONFIGURATION_SET_DATA SetData;
+ EFI_TLS_CONFIGURATION_GET_DATA GetData;
+};
+
+extern EFI_GUID gEfiTlsConfigurationProtocolGuid;
+
+#endif //__EFI_TLS_CONFIGURATION_PROTOCOL_H__
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 3e08bed..f2bdb30 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -1607,10 +1607,19 @@
gEfiHttpProtocolGuid = { 0x7a59b29b, 0x910b, 0x4171, {0x82, 0x42, 0xa8, 0x5a, 0x0d, 0xf2, 0x5b, 0x5b }}
## Include/Protocol/HttpUtilities.h
gEfiHttpUtilitiesProtocolGuid = { 0x3e35c163, 0x4074, 0x45dd, {0x43, 0x1e, 0x23, 0x98, 0x9d, 0xd8, 0x6b, 0x32 }}
+ ## Include/Protocol/Tls.h
+ gEfiTlsServiceBindingProtocolGuid = { 0x952cb795, 0xff36, 0x48cf, {0xa2, 0x49, 0x4d, 0xf4, 0x86, 0xd6, 0xab, 0x8d }}
+
+ ## Include/Protocol/Tls.h
+ gEfiTlsProtocolGuid = { 0xca959f, 0x6cfa, 0x4db1, {0x95, 0xbc, 0xe4, 0x6c, 0x47, 0x51, 0x43, 0x90 }}
+
+ ## Include/Protocol/TlsConfig.h
+ gEfiTlsConfigurationProtocolGuid = { 0x1682fe44, 0xbd7a, 0x4407, { 0xb7, 0xc7, 0xdc, 0xa3, 0x7c, 0xa3, 0x92, 0x2d }}
+
## Include/Protocol/Rest.h
gEfiRestProtocolGuid = { 0x0db48a36, 0x4e54, 0xea9c, {0x9b, 0x09, 0x1e, 0xa5, 0xbe, 0x3a, 0x66, 0x0b }}
## Include/Protocol/Supplicant.h
gEfiSupplicantServiceBindingProtocolGuid = { 0x45bcd98e, 0x59ad, 0x4174, { 0x95, 0x46, 0x34, 0x4a, 0x7, 0x48, 0x58, 0x98 }}
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Patch 02/10] MdePkg: Add a header to standardize TLS definitions
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
2016-12-14 7:34 ` [Patch 01/10] MdePkg: Add TLS related protocol definition Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-14 8:42 ` Long, Qin
` (2 more replies)
2016-12-14 7:34 ` [Patch 03/10] CryptoPkg: Enable ssl build in OpensslLib directly Jiaxin Wu
` (7 subsequent siblings)
9 siblings, 3 replies; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Long Qin, Ye Ting, Fu Siyuan, Zhang Lubo, Liming Gao,
Michael D Kinney, Thomas Palmer, Wu Jiaxin
This path is used to standardize TLS definitions from related
RFCs. Including TLS Cipher Suites, TLS Version, TLS Content Type
and TLS Record Header, etc.
Cc: Long Qin <qin.long@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
MdePkg/Include/IndustryStandard/Tls1.h | 93 ++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 MdePkg/Include/IndustryStandard/Tls1.h
diff --git a/MdePkg/Include/IndustryStandard/Tls1.h b/MdePkg/Include/IndustryStandard/Tls1.h
new file mode 100644
index 0000000..14eb265
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/Tls1.h
@@ -0,0 +1,93 @@
+/** @file
+ Transport Layer Security -- TLS 1.0/1.1/1.2 Standard definitions, from RFC 2246/4346/5246
+
+ This file contains common TLS 1.0/1.1/1.2 definitions from RFC 2246/4346/5246
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef __TLS_1_H__
+#define __TLS_1_H__
+
+#pragma pack(1)
+
+///
+/// TLS Cipher Suite, refers to A.5 of rfc-2246, rfc-4346 and rfc-5246.
+///
+#define TLS_RSA_WITH_NULL_MD5 {0x00, 0x01}
+#define TLS_RSA_WITH_NULL_SHA {0x00, 0x02}
+#define TLS_RSA_WITH_RC4_128_MD5 {0x00, 0x04}
+#define TLS_RSA_WITH_RC4_128_SHA {0x00, 0x05}
+#define TLS_RSA_WITH_IDEA_CBC_SHA {0x00, 0x07}
+#define TLS_RSA_WITH_DES_CBC_SHA {0x00, 0x09}
+#define TLS_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x0A}
+#define TLS_DH_DSS_WITH_DES_CBC_SHA {0x00, 0x0C}
+#define TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA {0x00, 0x0D}
+#define TLS_DH_RSA_WITH_DES_CBC_SHA {0x00, 0x0F}
+#define TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x10}
+#define TLS_DHE_DSS_WITH_DES_CBC_SHA {0x00, 0x12}
+#define TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA {0x00, 0x13}
+#define TLS_DHE_RSA_WITH_DES_CBC_SHA {0x00, 0x15}
+#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x16}
+#define TLS_RSA_WITH_AES_128_CBC_SHA {0x00, 0x2F}
+#define TLS_DH_DSS_WITH_AES_128_CBC_SHA {0x00, 0x30}
+#define TLS_DH_RSA_WITH_AES_128_CBC_SHA {0x00, 0x31}
+#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA {0x00, 0x32}
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA {0x00, 0x33}
+#define TLS_RSA_WITH_AES_256_CBC_SHA {0x00, 0x35}
+#define TLS_DH_DSS_WITH_AES_256_CBC_SHA {0x00, 0x36}
+#define TLS_DH_RSA_WITH_AES_256_CBC_SHA {0x00, 0x37}
+#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA {0x00, 0x38}
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA {0x00, 0x39}
+#define TLS_RSA_WITH_NULL_SHA256 {0x00, 0x3B}
+#define TLS_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x3C}
+#define TLS_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x3D}
+#define TLS_DH_DSS_WITH_AES_128_CBC_SHA256 {0x00, 0x3E}
+#define TLS_DH_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x3F}
+#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 {0x00, 0x40}
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x67}
+#define TLS_DH_DSS_WITH_AES_256_CBC_SHA256 {0x00, 0x68}
+#define TLS_DH_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x69}
+#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 {0x00, 0x6A}
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x6B}
+
+///
+/// TLS Version, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
+///
+#define TLS10_PROTOCOL_VERSION_MAJOR 0x03
+#define TLS10_PROTOCOL_VERSION_MINOR 0x01
+#define TLS11_PROTOCOL_VERSION_MAJOR 0x03
+#define TLS11_PROTOCOL_VERSION_MINOR 0x02
+#define TLS12_PROTOCOL_VERSION_MAJOR 0x03
+#define TLS12_PROTOCOL_VERSION_MINOR 0x03
+
+///
+/// TLS Content Type, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
+///
+typedef enum {
+ TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC = 20,
+ TLS_CONTENT_TYPE_ALERT = 21,
+ TLS_CONTENT_TYPE_HANDSHAKE = 22,
+ TLS_CONTENT_TYPE_APPLICATION_DATA = 23,
+} TLS_CONTENT_TYPE;
+
+///
+/// TLS Record Header, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
+///
+typedef struct {
+ UINT8 ContentType;
+ EFI_TLS_VERSION Version;
+ UINT16 Length;
+} TLS_RECORD_HEADER;
+
+#pragma pack()
+
+#endif
+
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 02/10] MdePkg: Add a header to standardize TLS definitions
2016-12-14 7:34 ` [Patch 02/10] MdePkg: Add a header to standardize TLS definitions Jiaxin Wu
@ 2016-12-14 8:42 ` Long, Qin
2016-12-14 8:43 ` Fu, Siyuan
2016-12-15 8:35 ` Ye, Ting
2 siblings, 0 replies; 37+ messages in thread
From: Long, Qin @ 2016-12-14 8:42 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Ye, Ting, Fu, Siyuan, Zhang, Lubo, Gao, Liming, Kinney, Michael D,
Thomas Palmer
Reviewed-by: Qin Long <qin.long@intel.com>
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: Wednesday, December 14, 2016 3:34 PM
> To: edk2-devel@lists.01.org
> Cc: Long, Qin; Ye, Ting; Fu, Siyuan; Zhang, Lubo; Gao, Liming; Kinney, Michael
> D; Thomas Palmer; Wu, Jiaxin
> Subject: [Patch 02/10] MdePkg: Add a header to standardize TLS definitions
>
> This path is used to standardize TLS definitions from related RFCs. Including
> TLS Cipher Suites, TLS Version, TLS Content Type and TLS Record Header, etc.
>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Liming Gao <liming.gao@intel.com>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> MdePkg/Include/IndustryStandard/Tls1.h | 93
> ++++++++++++++++++++++++++++++++++
> 1 file changed, 93 insertions(+)
> create mode 100644 MdePkg/Include/IndustryStandard/Tls1.h
>
> diff --git a/MdePkg/Include/IndustryStandard/Tls1.h
> b/MdePkg/Include/IndustryStandard/Tls1.h
> new file mode 100644
> index 0000000..14eb265
> --- /dev/null
> +++ b/MdePkg/Include/IndustryStandard/Tls1.h
> @@ -0,0 +1,93 @@
> +/** @file
> + Transport Layer Security -- TLS 1.0/1.1/1.2 Standard definitions, from RFC
> 2246/4346/5246
> +
> + This file contains common TLS 1.0/1.1/1.2 definitions from RFC
> + 2246/4346/5246
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> This
> + program and the accompanying materials are licensed and made
> + available under the terms and conditions of the BSD License which
> + accompanies this distribution. The full text of the license may be
> + found at http://opensource.org/licenses/bsd-license.php
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +**/
> +
> +#ifndef __TLS_1_H__
> +#define __TLS_1_H__
> +
> +#pragma pack(1)
> +
> +///
> +/// TLS Cipher Suite, refers to A.5 of rfc-2246, rfc-4346 and rfc-5246.
> +///
> +#define TLS_RSA_WITH_NULL_MD5 {0x00, 0x01}
> +#define TLS_RSA_WITH_NULL_SHA {0x00, 0x02}
> +#define TLS_RSA_WITH_RC4_128_MD5 {0x00, 0x04}
> +#define TLS_RSA_WITH_RC4_128_SHA {0x00, 0x05}
> +#define TLS_RSA_WITH_IDEA_CBC_SHA {0x00, 0x07}
> +#define TLS_RSA_WITH_DES_CBC_SHA {0x00, 0x09}
> +#define TLS_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x0A}
> +#define TLS_DH_DSS_WITH_DES_CBC_SHA {0x00, 0x0C}
> +#define TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA {0x00, 0x0D}
> +#define TLS_DH_RSA_WITH_DES_CBC_SHA {0x00, 0x0F}
> +#define TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x10}
> +#define TLS_DHE_DSS_WITH_DES_CBC_SHA {0x00, 0x12}
> +#define TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA {0x00, 0x13}
> +#define TLS_DHE_RSA_WITH_DES_CBC_SHA {0x00, 0x15}
> +#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x16}
> +#define TLS_RSA_WITH_AES_128_CBC_SHA {0x00, 0x2F}
> +#define TLS_DH_DSS_WITH_AES_128_CBC_SHA {0x00, 0x30}
> +#define TLS_DH_RSA_WITH_AES_128_CBC_SHA {0x00, 0x31}
> +#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA {0x00, 0x32}
> +#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA {0x00, 0x33}
> +#define TLS_RSA_WITH_AES_256_CBC_SHA {0x00, 0x35}
> +#define TLS_DH_DSS_WITH_AES_256_CBC_SHA {0x00, 0x36}
> +#define TLS_DH_RSA_WITH_AES_256_CBC_SHA {0x00, 0x37}
> +#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA {0x00, 0x38}
> +#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA {0x00, 0x39}
> +#define TLS_RSA_WITH_NULL_SHA256 {0x00, 0x3B}
> +#define TLS_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x3C}
> +#define TLS_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x3D}
> +#define TLS_DH_DSS_WITH_AES_128_CBC_SHA256 {0x00, 0x3E}
> +#define TLS_DH_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x3F}
> +#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 {0x00, 0x40}
> +#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x67}
> +#define TLS_DH_DSS_WITH_AES_256_CBC_SHA256 {0x00, 0x68}
> +#define TLS_DH_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x69}
> +#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 {0x00, 0x6A}
> +#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x6B}
> +
> +///
> +/// TLS Version, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
> +///
> +#define TLS10_PROTOCOL_VERSION_MAJOR 0x03 #define
> +TLS10_PROTOCOL_VERSION_MINOR 0x01 #define
> TLS11_PROTOCOL_VERSION_MAJOR
> +0x03 #define TLS11_PROTOCOL_VERSION_MINOR 0x02 #define
> +TLS12_PROTOCOL_VERSION_MAJOR 0x03 #define
> TLS12_PROTOCOL_VERSION_MINOR
> +0x03
> +
> +///
> +/// TLS Content Type, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
> +///
> +typedef enum {
> + TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC = 20,
> + TLS_CONTENT_TYPE_ALERT = 21,
> + TLS_CONTENT_TYPE_HANDSHAKE = 22,
> + TLS_CONTENT_TYPE_APPLICATION_DATA = 23,
> +} TLS_CONTENT_TYPE;
> +
> +///
> +/// TLS Record Header, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
> +///
> +typedef struct {
> + UINT8 ContentType;
> + EFI_TLS_VERSION Version;
> + UINT16 Length;
> +} TLS_RECORD_HEADER;
> +
> +#pragma pack()
> +
> +#endif
> +
> --
> 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Patch 02/10] MdePkg: Add a header to standardize TLS definitions
2016-12-14 7:34 ` [Patch 02/10] MdePkg: Add a header to standardize TLS definitions Jiaxin Wu
2016-12-14 8:42 ` Long, Qin
@ 2016-12-14 8:43 ` Fu, Siyuan
2016-12-15 8:35 ` Ye, Ting
2 siblings, 0 replies; 37+ messages in thread
From: Fu, Siyuan @ 2016-12-14 8:43 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Long, Qin, Ye, Ting, Zhang, Lubo, Gao, Liming, Kinney, Michael D,
Thomas Palmer
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: 2016年12月14日 15:34
To: edk2-devel@lists.01.org
Cc: Long, Qin <qin.long@intel.com>; Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 02/10] MdePkg: Add a header to standardize TLS definitions
This path is used to standardize TLS definitions from related RFCs. Including TLS Cipher Suites, TLS Version, TLS Content Type and TLS Record Header, etc.
Cc: Long Qin <qin.long@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
MdePkg/Include/IndustryStandard/Tls1.h | 93 ++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 MdePkg/Include/IndustryStandard/Tls1.h
diff --git a/MdePkg/Include/IndustryStandard/Tls1.h b/MdePkg/Include/IndustryStandard/Tls1.h
new file mode 100644
index 0000000..14eb265
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/Tls1.h
@@ -0,0 +1,93 @@
+/** @file
+ Transport Layer Security -- TLS 1.0/1.1/1.2 Standard definitions, from RFC 2246/4346/5246
+
+ This file contains common TLS 1.0/1.1/1.2 definitions from RFC
+ 2246/4346/5246
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> This
+ program and the accompanying materials are licensed and made
+ available under the terms and conditions of the BSD License which
+ accompanies this distribution. The full text of the license may be
+ found at http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef __TLS_1_H__
+#define __TLS_1_H__
+
+#pragma pack(1)
+
+///
+/// TLS Cipher Suite, refers to A.5 of rfc-2246, rfc-4346 and rfc-5246.
+///
+#define TLS_RSA_WITH_NULL_MD5 {0x00, 0x01}
+#define TLS_RSA_WITH_NULL_SHA {0x00, 0x02}
+#define TLS_RSA_WITH_RC4_128_MD5 {0x00, 0x04}
+#define TLS_RSA_WITH_RC4_128_SHA {0x00, 0x05}
+#define TLS_RSA_WITH_IDEA_CBC_SHA {0x00, 0x07}
+#define TLS_RSA_WITH_DES_CBC_SHA {0x00, 0x09}
+#define TLS_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x0A}
+#define TLS_DH_DSS_WITH_DES_CBC_SHA {0x00, 0x0C}
+#define TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA {0x00, 0x0D}
+#define TLS_DH_RSA_WITH_DES_CBC_SHA {0x00, 0x0F}
+#define TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x10}
+#define TLS_DHE_DSS_WITH_DES_CBC_SHA {0x00, 0x12}
+#define TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA {0x00, 0x13}
+#define TLS_DHE_RSA_WITH_DES_CBC_SHA {0x00, 0x15}
+#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x16}
+#define TLS_RSA_WITH_AES_128_CBC_SHA {0x00, 0x2F}
+#define TLS_DH_DSS_WITH_AES_128_CBC_SHA {0x00, 0x30}
+#define TLS_DH_RSA_WITH_AES_128_CBC_SHA {0x00, 0x31}
+#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA {0x00, 0x32}
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA {0x00, 0x33}
+#define TLS_RSA_WITH_AES_256_CBC_SHA {0x00, 0x35}
+#define TLS_DH_DSS_WITH_AES_256_CBC_SHA {0x00, 0x36}
+#define TLS_DH_RSA_WITH_AES_256_CBC_SHA {0x00, 0x37}
+#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA {0x00, 0x38}
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA {0x00, 0x39}
+#define TLS_RSA_WITH_NULL_SHA256 {0x00, 0x3B}
+#define TLS_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x3C}
+#define TLS_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x3D}
+#define TLS_DH_DSS_WITH_AES_128_CBC_SHA256 {0x00, 0x3E}
+#define TLS_DH_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x3F}
+#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 {0x00, 0x40}
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x67}
+#define TLS_DH_DSS_WITH_AES_256_CBC_SHA256 {0x00, 0x68}
+#define TLS_DH_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x69}
+#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 {0x00, 0x6A}
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x6B}
+
+///
+/// TLS Version, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
+///
+#define TLS10_PROTOCOL_VERSION_MAJOR 0x03 #define
+TLS10_PROTOCOL_VERSION_MINOR 0x01 #define TLS11_PROTOCOL_VERSION_MAJOR
+0x03 #define TLS11_PROTOCOL_VERSION_MINOR 0x02 #define
+TLS12_PROTOCOL_VERSION_MAJOR 0x03 #define TLS12_PROTOCOL_VERSION_MINOR
+0x03
+
+///
+/// TLS Content Type, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
+///
+typedef enum {
+ TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC = 20,
+ TLS_CONTENT_TYPE_ALERT = 21,
+ TLS_CONTENT_TYPE_HANDSHAKE = 22,
+ TLS_CONTENT_TYPE_APPLICATION_DATA = 23,
+} TLS_CONTENT_TYPE;
+
+///
+/// TLS Record Header, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
+///
+typedef struct {
+ UINT8 ContentType;
+ EFI_TLS_VERSION Version;
+ UINT16 Length;
+} TLS_RECORD_HEADER;
+
+#pragma pack()
+
+#endif
+
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 02/10] MdePkg: Add a header to standardize TLS definitions
2016-12-14 7:34 ` [Patch 02/10] MdePkg: Add a header to standardize TLS definitions Jiaxin Wu
2016-12-14 8:42 ` Long, Qin
2016-12-14 8:43 ` Fu, Siyuan
@ 2016-12-15 8:35 ` Ye, Ting
2 siblings, 0 replies; 37+ messages in thread
From: Ye, Ting @ 2016-12-15 8:35 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Long, Qin, Fu, Siyuan, Zhang, Lubo, Gao, Liming,
Kinney, Michael D, Thomas Palmer
Reviewed-by: Ye Ting <ting.ye@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: Wednesday, December 14, 2016 3:34 PM
To: edk2-devel@lists.01.org
Cc: Long, Qin <qin.long@intel.com>; Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Gao, Liming <liming.gao@intel.com>; Kinney, Michael D <michael.d.kinney@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 02/10] MdePkg: Add a header to standardize TLS definitions
This path is used to standardize TLS definitions from related RFCs. Including TLS Cipher Suites, TLS Version, TLS Content Type and TLS Record Header, etc.
Cc: Long Qin <qin.long@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
MdePkg/Include/IndustryStandard/Tls1.h | 93 ++++++++++++++++++++++++++++++++++
1 file changed, 93 insertions(+)
create mode 100644 MdePkg/Include/IndustryStandard/Tls1.h
diff --git a/MdePkg/Include/IndustryStandard/Tls1.h b/MdePkg/Include/IndustryStandard/Tls1.h
new file mode 100644
index 0000000..14eb265
--- /dev/null
+++ b/MdePkg/Include/IndustryStandard/Tls1.h
@@ -0,0 +1,93 @@
+/** @file
+ Transport Layer Security -- TLS 1.0/1.1/1.2 Standard definitions, from RFC 2246/4346/5246
+
+ This file contains common TLS 1.0/1.1/1.2 definitions from RFC
+ 2246/4346/5246
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR> This
+ program and the accompanying materials are licensed and made
+ available under the terms and conditions of the BSD License which
+ accompanies this distribution. The full text of the license may be
+ found at http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+**/
+
+#ifndef __TLS_1_H__
+#define __TLS_1_H__
+
+#pragma pack(1)
+
+///
+/// TLS Cipher Suite, refers to A.5 of rfc-2246, rfc-4346 and rfc-5246.
+///
+#define TLS_RSA_WITH_NULL_MD5 {0x00, 0x01}
+#define TLS_RSA_WITH_NULL_SHA {0x00, 0x02}
+#define TLS_RSA_WITH_RC4_128_MD5 {0x00, 0x04}
+#define TLS_RSA_WITH_RC4_128_SHA {0x00, 0x05}
+#define TLS_RSA_WITH_IDEA_CBC_SHA {0x00, 0x07}
+#define TLS_RSA_WITH_DES_CBC_SHA {0x00, 0x09}
+#define TLS_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x0A}
+#define TLS_DH_DSS_WITH_DES_CBC_SHA {0x00, 0x0C}
+#define TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA {0x00, 0x0D}
+#define TLS_DH_RSA_WITH_DES_CBC_SHA {0x00, 0x0F}
+#define TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x10}
+#define TLS_DHE_DSS_WITH_DES_CBC_SHA {0x00, 0x12}
+#define TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA {0x00, 0x13}
+#define TLS_DHE_RSA_WITH_DES_CBC_SHA {0x00, 0x15}
+#define TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA {0x00, 0x16}
+#define TLS_RSA_WITH_AES_128_CBC_SHA {0x00, 0x2F}
+#define TLS_DH_DSS_WITH_AES_128_CBC_SHA {0x00, 0x30}
+#define TLS_DH_RSA_WITH_AES_128_CBC_SHA {0x00, 0x31}
+#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA {0x00, 0x32}
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA {0x00, 0x33}
+#define TLS_RSA_WITH_AES_256_CBC_SHA {0x00, 0x35}
+#define TLS_DH_DSS_WITH_AES_256_CBC_SHA {0x00, 0x36}
+#define TLS_DH_RSA_WITH_AES_256_CBC_SHA {0x00, 0x37}
+#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA {0x00, 0x38}
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA {0x00, 0x39}
+#define TLS_RSA_WITH_NULL_SHA256 {0x00, 0x3B}
+#define TLS_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x3C}
+#define TLS_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x3D}
+#define TLS_DH_DSS_WITH_AES_128_CBC_SHA256 {0x00, 0x3E}
+#define TLS_DH_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x3F}
+#define TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 {0x00, 0x40}
+#define TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 {0x00, 0x67}
+#define TLS_DH_DSS_WITH_AES_256_CBC_SHA256 {0x00, 0x68}
+#define TLS_DH_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x69}
+#define TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 {0x00, 0x6A}
+#define TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 {0x00, 0x6B}
+
+///
+/// TLS Version, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
+///
+#define TLS10_PROTOCOL_VERSION_MAJOR 0x03 #define
+TLS10_PROTOCOL_VERSION_MINOR 0x01 #define TLS11_PROTOCOL_VERSION_MAJOR
+0x03 #define TLS11_PROTOCOL_VERSION_MINOR 0x02 #define
+TLS12_PROTOCOL_VERSION_MAJOR 0x03 #define TLS12_PROTOCOL_VERSION_MINOR
+0x03
+
+///
+/// TLS Content Type, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
+///
+typedef enum {
+ TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC = 20,
+ TLS_CONTENT_TYPE_ALERT = 21,
+ TLS_CONTENT_TYPE_HANDSHAKE = 22,
+ TLS_CONTENT_TYPE_APPLICATION_DATA = 23,
+} TLS_CONTENT_TYPE;
+
+///
+/// TLS Record Header, refers to A.1 of rfc-2246, rfc-4346 and rfc-5246.
+///
+typedef struct {
+ UINT8 ContentType;
+ EFI_TLS_VERSION Version;
+ UINT16 Length;
+} TLS_RECORD_HEADER;
+
+#pragma pack()
+
+#endif
+
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Patch 03/10] CryptoPkg: Enable ssl build in OpensslLib directly
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
2016-12-14 7:34 ` [Patch 01/10] MdePkg: Add TLS related protocol definition Jiaxin Wu
2016-12-14 7:34 ` [Patch 02/10] MdePkg: Add a header to standardize TLS definitions Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-15 8:37 ` Ye, Ting
2016-12-14 7:34 ` [Patch 04/10] CryptoPkg: Add new TlsLib library Jiaxin Wu
` (6 subsequent siblings)
9 siblings, 1 reply; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Wu Jiaxin, Ye Ting, Long Qin, Fu Siyuan, Zhang Lubo,
Thomas Palmer
This patch is used to enable ssl build in OpensslLib module
directly.
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Long Qin <qin.long@intel.com>
Reviewed-by: Wu Jiaxin <jiaxin.wu@intel.com>
Tested-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
CryptoPkg/Include/OpenSslSupport.h | 11 ++++-
.../Library/BaseCryptLib/SysCall/CrtWrapper.c | 10 +++++
CryptoPkg/Library/OpensslLib/Install.cmd | 1 +
CryptoPkg/Library/OpensslLib/Install.sh | 1 +
CryptoPkg/Library/OpensslLib/OpensslLib.inf | 52 +++++++++++++++++++++-
CryptoPkg/Library/OpensslLib/process_files.sh | 7 +--
6 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/CryptoPkg/Include/OpenSslSupport.h b/CryptoPkg/Include/OpenSslSupport.h
index dad40e4..600578e 100644
--- a/CryptoPkg/Include/OpenSslSupport.h
+++ b/CryptoPkg/Include/OpenSslSupport.h
@@ -1,9 +1,9 @@
/** @file
Root include file to support building OpenSSL Crypto Library.
-Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
@@ -116,10 +116,12 @@ typedef UINT32 ino_t;
typedef UINT32 dev_t;
typedef UINT16 nlink_t;
typedef int pid_t;
typedef void *DIR;
typedef void __sighandler_t (int);
+typedef UINT8 __uint8_t;
+typedef UINT8 sa_family_t;
//
// Structures from EFI Application Toolkit required to build Open SSL
//
struct tm {
@@ -170,10 +172,16 @@ struct stat {
UINT32 st_gen; /* file generation number */
INT32 st_lspare;
INT64 st_qspare[2];
};
+struct sockaddr {
+ __uint8_t sa_len; /* total length */
+ sa_family_t sa_family; /* address family */
+ char sa_data[14]; /* actually longer; address value */
+};
+
//
// Externs from EFI Application Toolkit required to build Open SSL
//
extern int errno;
@@ -271,7 +279,8 @@ extern FILE *stdout;
#define abort() ASSERT (FALSE)
#define assert(expression)
#define localtime(timer) NULL
#define gmtime_r(timer,result) (result = NULL)
#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
+#define gettimeofday(tvp,tz) do { (tvp)->tv_sec = time(NULL); (tvp)->tv_usec = 0; } while (0)
#endif
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c
index c0ccc0e..a2386bc 100644
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c
@@ -382,10 +382,15 @@ FILE *fopen (const char *c, const char *m)
size_t fread (void *b, size_t c, size_t i, FILE *f)
{
return 0;
}
+int fputs (const char *s, FILE *f)
+{
+ return 0;
+}
+
int fprintf (FILE *f, const char *s, ...)
{
return 0;
}
@@ -446,5 +451,10 @@ void syslog (int a, const char *c, ...)
ssize_t write (int f, const void *b, size_t l)
{
return 0;
}
+
+int printf (char const *fmt, ...)
+{
+ return 0;
+}
diff --git a/CryptoPkg/Library/OpensslLib/Install.cmd b/CryptoPkg/Library/OpensslLib/Install.cmd
index 3d86bc7..093414d 100755
--- a/CryptoPkg/Library/OpensslLib/Install.cmd
+++ b/CryptoPkg/Library/OpensslLib/Install.cmd
@@ -6,10 +6,11 @@ copy crypto\crypto.h include\openssl
copy crypto\opensslv.h include\openssl
copy crypto\opensslconf.h include\openssl
copy crypto\ebcdic.h include\openssl
copy crypto\symhacks.h include\openssl
copy crypto\ossl_typ.h include\openssl
+copy crypto\o_dir.h include
copy crypto\objects\objects.h include\openssl
copy crypto\objects\obj_mac.h include\openssl
copy crypto\md4\md4.h include\openssl
copy crypto\md5\md5.h include\openssl
copy crypto\sha\sha.h include\openssl
diff --git a/CryptoPkg/Library/OpensslLib/Install.sh b/CryptoPkg/Library/OpensslLib/Install.sh
index e6703d1..7bd55f6 100755
--- a/CryptoPkg/Library/OpensslLib/Install.sh
+++ b/CryptoPkg/Library/OpensslLib/Install.sh
@@ -8,10 +8,11 @@ cp crypto/crypto.h include/openssl
cp crypto/opensslv.h include/openssl
cp crypto/opensslconf.h include/openssl
cp crypto/ebcdic.h include/openssl
cp crypto/symhacks.h include/openssl
cp crypto/ossl_typ.h include/openssl
+cp crypto/o_dir.h include
cp crypto/objects/objects.h include/openssl
cp crypto/objects/obj_mac.h include/openssl
cp crypto/md4/md4.h include/openssl
cp crypto/md5/md5.h include/openssl
cp crypto/sha/sha.h include/openssl
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
index 8121e83..c14e36d 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
@@ -468,13 +468,63 @@
$(OPENSSL_PATH)/crypto/ocsp/ocsp_srv.c
$(OPENSSL_PATH)/crypto/ocsp/ocsp_prn.c
$(OPENSSL_PATH)/crypto/ocsp/ocsp_vfy.c
$(OPENSSL_PATH)/crypto/ocsp/ocsp_err.c
$(OPENSSL_PATH)/crypto/krb5/krb5_asn.c
+ $(OPENSSL_PATH)/crypto/pqueue/pqueue.c
$(OPENSSL_PATH)/crypto/cmac/cmac.c
$(OPENSSL_PATH)/crypto/cmac/cm_ameth.c
$(OPENSSL_PATH)/crypto/cmac/cm_pmeth.c
+ $(OPENSSL_PATH)/ssl/s2_meth.c
+ $(OPENSSL_PATH)/ssl/s2_srvr.c
+ $(OPENSSL_PATH)/ssl/s2_clnt.c
+ $(OPENSSL_PATH)/ssl/s2_lib.c
+ $(OPENSSL_PATH)/ssl/s2_enc.c
+ $(OPENSSL_PATH)/ssl/s2_pkt.c
+ $(OPENSSL_PATH)/ssl/s3_meth.c
+ $(OPENSSL_PATH)/ssl/s3_srvr.c
+ $(OPENSSL_PATH)/ssl/s3_clnt.c
+ $(OPENSSL_PATH)/ssl/s3_lib.c
+ $(OPENSSL_PATH)/ssl/s3_enc.c
+ $(OPENSSL_PATH)/ssl/s3_pkt.c
+ $(OPENSSL_PATH)/ssl/s3_both.c
+ $(OPENSSL_PATH)/ssl/s3_cbc.c
+ $(OPENSSL_PATH)/ssl/s23_meth.c
+ $(OPENSSL_PATH)/ssl/s23_srvr.c
+ $(OPENSSL_PATH)/ssl/s23_clnt.c
+ $(OPENSSL_PATH)/ssl/s23_lib.c
+ $(OPENSSL_PATH)/ssl/s23_pkt.c
+ $(OPENSSL_PATH)/ssl/t1_meth.c
+ $(OPENSSL_PATH)/ssl/t1_srvr.c
+ $(OPENSSL_PATH)/ssl/t1_clnt.c
+ $(OPENSSL_PATH)/ssl/t1_lib.c
+ $(OPENSSL_PATH)/ssl/t1_enc.c
+ $(OPENSSL_PATH)/ssl/t1_ext.c
+ $(OPENSSL_PATH)/ssl/d1_meth.c
+ $(OPENSSL_PATH)/ssl/d1_srvr.c
+ $(OPENSSL_PATH)/ssl/d1_clnt.c
+ $(OPENSSL_PATH)/ssl/d1_lib.c
+ $(OPENSSL_PATH)/ssl/d1_pkt.c
+ $(OPENSSL_PATH)/ssl/d1_both.c
+ $(OPENSSL_PATH)/ssl/d1_srtp.c
+ $(OPENSSL_PATH)/ssl/ssl_lib.c
+ $(OPENSSL_PATH)/ssl/ssl_err2.c
+ $(OPENSSL_PATH)/ssl/ssl_cert.c
+ $(OPENSSL_PATH)/ssl/ssl_sess.c
+ $(OPENSSL_PATH)/ssl/ssl_ciph.c
+ $(OPENSSL_PATH)/ssl/ssl_stat.c
+ $(OPENSSL_PATH)/ssl/ssl_rsa.c
+ $(OPENSSL_PATH)/ssl/ssl_asn1.c
+ $(OPENSSL_PATH)/ssl/ssl_txt.c
+ $(OPENSSL_PATH)/ssl/ssl_algs.c
+ $(OPENSSL_PATH)/ssl/bio_ssl.c
+ $(OPENSSL_PATH)/ssl/ssl_err.c
+ $(OPENSSL_PATH)/ssl/kssl.c
+ $(OPENSSL_PATH)/ssl/t1_reneg.c
+ $(OPENSSL_PATH)/ssl/tls_srp.c
+ $(OPENSSL_PATH)/ssl/t1_trce.c
+ $(OPENSSL_PATH)/ssl/ssl_utst.c
# Autogenerated files list ends here
[Packages]
MdePkg/MdePkg.dec
@@ -498,11 +548,11 @@
# C4305: truncation from type1 to type2 of smaller size
# C4306: conversion from type1 to type2 of greater size
# C4702: Potentially uninitialized local variable name used
# C4311: pointer truncation from 'type' to 'type'
#
- MSFT:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /wd4244 /wd4701 /wd4702 /wd4706
+ MSFT:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /wd4244 /wd4245 /wd4701 /wd4702 /wd4706
MSFT:*_*_X64_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /wd4133 /wd4244 /wd4245 /wd4267 /wd4701 /wd4305 /wd4306 /wd4702 /wd4706 /wd4311
MSFT:*_*_IPF_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /wd4133 /wd4244 /wd4245 /wd4267 /wd4701 /wd4305 /wd4306 /wd4702 /wd4706
INTEL:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER -U__ICC $(OPENSSL_FLAGS) /w
INTEL:*_*_X64_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER -U__ICC $(OPENSSL_FLAGS) /w
diff --git a/CryptoPkg/Library/OpensslLib/process_files.sh b/CryptoPkg/Library/OpensslLib/process_files.sh
index 885adf3..6f069ce 100755
--- a/CryptoPkg/Library/OpensslLib/process_files.sh
+++ b/CryptoPkg/Library/OpensslLib/process_files.sh
@@ -40,11 +40,10 @@ fi
no-jpake \
no-krb5 \
no-locking \
no-mdc2 \
no-posix-io \
- no-pqueue \
no-rc2 \
no-rcs \
no-rfc3779 \
no-ripemd \
no-scrypt \
@@ -75,17 +74,15 @@ function filelist ()
RELATIVE_DIRECTORY=*)
eval "$LINE"
;;
LIBSRC=*)
LIBSRC=$(echo "$LINE" | sed s/^LIBSRC=//)
- if [ "$RELATIVE_DIRECTORY" != "ssl" ]; then
- for FILE in $LIBSRC; do
+ for FILE in $LIBSRC; do
if [ "$FILE" != "b_print.c" ]; then
echo -e ' $(OPENSSL_PATH)/'$RELATIVE_DIRECTORY/$FILE\\r\\
fi
- done
- fi
+ done
;;
esac
done
echo -e \\r
}
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 03/10] CryptoPkg: Enable ssl build in OpensslLib directly
2016-12-14 7:34 ` [Patch 03/10] CryptoPkg: Enable ssl build in OpensslLib directly Jiaxin Wu
@ 2016-12-15 8:37 ` Ye, Ting
0 siblings, 0 replies; 37+ messages in thread
From: Ye, Ting @ 2016-12-15 8:37 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Long, Qin, Fu, Siyuan, Zhang, Lubo, Thomas Palmer
Reviewed-by: Ye Ting <ting.ye@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: Wednesday, December 14, 2016 3:34 PM
To: edk2-devel@lists.01.org
Cc: Wu, Jiaxin <jiaxin.wu@intel.com>; Ye, Ting <ting.ye@intel.com>; Long, Qin <qin.long@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
Subject: [Patch 03/10] CryptoPkg: Enable ssl build in OpensslLib directly
This patch is used to enable ssl build in OpensslLib module directly.
Cc: Wu Jiaxin <jiaxin.wu@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Long Qin <qin.long@intel.com>
Reviewed-by: Wu Jiaxin <jiaxin.wu@intel.com>
Tested-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
CryptoPkg/Include/OpenSslSupport.h | 11 ++++-
.../Library/BaseCryptLib/SysCall/CrtWrapper.c | 10 +++++
CryptoPkg/Library/OpensslLib/Install.cmd | 1 +
CryptoPkg/Library/OpensslLib/Install.sh | 1 +
CryptoPkg/Library/OpensslLib/OpensslLib.inf | 52 +++++++++++++++++++++-
CryptoPkg/Library/OpensslLib/process_files.sh | 7 +--
6 files changed, 75 insertions(+), 7 deletions(-)
diff --git a/CryptoPkg/Include/OpenSslSupport.h b/CryptoPkg/Include/OpenSslSupport.h
index dad40e4..600578e 100644
--- a/CryptoPkg/Include/OpenSslSupport.h
+++ b/CryptoPkg/Include/OpenSslSupport.h
@@ -1,9 +1,9 @@
/** @file
Root include file to support building OpenSSL Crypto Library.
-Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at http://opensource.org/licenses/bsd-license.php
@@ -116,10 +116,12 @@ typedef UINT32 ino_t;
typedef UINT32 dev_t;
typedef UINT16 nlink_t;
typedef int pid_t;
typedef void *DIR;
typedef void __sighandler_t (int);
+typedef UINT8 __uint8_t;
+typedef UINT8 sa_family_t;
//
// Structures from EFI Application Toolkit required to build Open SSL // struct tm { @@ -170,10 +172,16 @@ struct stat {
UINT32 st_gen; /* file generation number */
INT32 st_lspare;
INT64 st_qspare[2];
};
+struct sockaddr {
+ __uint8_t sa_len; /* total length */
+ sa_family_t sa_family; /* address family */
+ char sa_data[14]; /* actually longer; address value */
+};
+
//
// Externs from EFI Application Toolkit required to build Open SSL // extern int errno;
@@ -271,7 +279,8 @@ extern FILE *stdout;
#define abort() ASSERT (FALSE)
#define assert(expression)
#define localtime(timer) NULL
#define gmtime_r(timer,result) (result = NULL)
#define atoi(nptr) AsciiStrDecimalToUintn(nptr)
+#define gettimeofday(tvp,tz) do { (tvp)->tv_sec = time(NULL); (tvp)->tv_usec = 0; } while (0)
#endif
diff --git a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c
index c0ccc0e..a2386bc 100644
--- a/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c
+++ b/CryptoPkg/Library/BaseCryptLib/SysCall/CrtWrapper.c
@@ -382,10 +382,15 @@ FILE *fopen (const char *c, const char *m) size_t fread (void *b, size_t c, size_t i, FILE *f) {
return 0;
}
+int fputs (const char *s, FILE *f)
+{
+ return 0;
+}
+
int fprintf (FILE *f, const char *s, ...) {
return 0;
}
@@ -446,5 +451,10 @@ void syslog (int a, const char *c, ...)
ssize_t write (int f, const void *b, size_t l) {
return 0;
}
+
+int printf (char const *fmt, ...)
+{
+ return 0;
+}
diff --git a/CryptoPkg/Library/OpensslLib/Install.cmd b/CryptoPkg/Library/OpensslLib/Install.cmd
index 3d86bc7..093414d 100755
--- a/CryptoPkg/Library/OpensslLib/Install.cmd
+++ b/CryptoPkg/Library/OpensslLib/Install.cmd
@@ -6,10 +6,11 @@ copy crypto\crypto.h include\openssl
copy crypto\opensslv.h include\openssl
copy crypto\opensslconf.h include\openssl
copy crypto\ebcdic.h include\openssl
copy crypto\symhacks.h include\openssl
copy crypto\ossl_typ.h include\openssl
+copy crypto\o_dir.h include
copy crypto\objects\objects.h include\openssl
copy crypto\objects\obj_mac.h include\openssl
copy crypto\md4\md4.h include\openssl
copy crypto\md5\md5.h include\openssl
copy crypto\sha\sha.h include\openssl
diff --git a/CryptoPkg/Library/OpensslLib/Install.sh b/CryptoPkg/Library/OpensslLib/Install.sh
index e6703d1..7bd55f6 100755
--- a/CryptoPkg/Library/OpensslLib/Install.sh
+++ b/CryptoPkg/Library/OpensslLib/Install.sh
@@ -8,10 +8,11 @@ cp crypto/crypto.h include/openssl
cp crypto/opensslv.h include/openssl
cp crypto/opensslconf.h include/openssl
cp crypto/ebcdic.h include/openssl
cp crypto/symhacks.h include/openssl
cp crypto/ossl_typ.h include/openssl
+cp crypto/o_dir.h include
cp crypto/objects/objects.h include/openssl
cp crypto/objects/obj_mac.h include/openssl
cp crypto/md4/md4.h include/openssl
cp crypto/md5/md5.h include/openssl
cp crypto/sha/sha.h include/openssl
diff --git a/CryptoPkg/Library/OpensslLib/OpensslLib.inf b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
index 8121e83..c14e36d 100644
--- a/CryptoPkg/Library/OpensslLib/OpensslLib.inf
+++ b/CryptoPkg/Library/OpensslLib/OpensslLib.inf
@@ -468,13 +468,63 @@
$(OPENSSL_PATH)/crypto/ocsp/ocsp_srv.c
$(OPENSSL_PATH)/crypto/ocsp/ocsp_prn.c
$(OPENSSL_PATH)/crypto/ocsp/ocsp_vfy.c
$(OPENSSL_PATH)/crypto/ocsp/ocsp_err.c
$(OPENSSL_PATH)/crypto/krb5/krb5_asn.c
+ $(OPENSSL_PATH)/crypto/pqueue/pqueue.c
$(OPENSSL_PATH)/crypto/cmac/cmac.c
$(OPENSSL_PATH)/crypto/cmac/cm_ameth.c
$(OPENSSL_PATH)/crypto/cmac/cm_pmeth.c
+ $(OPENSSL_PATH)/ssl/s2_meth.c
+ $(OPENSSL_PATH)/ssl/s2_srvr.c
+ $(OPENSSL_PATH)/ssl/s2_clnt.c
+ $(OPENSSL_PATH)/ssl/s2_lib.c
+ $(OPENSSL_PATH)/ssl/s2_enc.c
+ $(OPENSSL_PATH)/ssl/s2_pkt.c
+ $(OPENSSL_PATH)/ssl/s3_meth.c
+ $(OPENSSL_PATH)/ssl/s3_srvr.c
+ $(OPENSSL_PATH)/ssl/s3_clnt.c
+ $(OPENSSL_PATH)/ssl/s3_lib.c
+ $(OPENSSL_PATH)/ssl/s3_enc.c
+ $(OPENSSL_PATH)/ssl/s3_pkt.c
+ $(OPENSSL_PATH)/ssl/s3_both.c
+ $(OPENSSL_PATH)/ssl/s3_cbc.c
+ $(OPENSSL_PATH)/ssl/s23_meth.c
+ $(OPENSSL_PATH)/ssl/s23_srvr.c
+ $(OPENSSL_PATH)/ssl/s23_clnt.c
+ $(OPENSSL_PATH)/ssl/s23_lib.c
+ $(OPENSSL_PATH)/ssl/s23_pkt.c
+ $(OPENSSL_PATH)/ssl/t1_meth.c
+ $(OPENSSL_PATH)/ssl/t1_srvr.c
+ $(OPENSSL_PATH)/ssl/t1_clnt.c
+ $(OPENSSL_PATH)/ssl/t1_lib.c
+ $(OPENSSL_PATH)/ssl/t1_enc.c
+ $(OPENSSL_PATH)/ssl/t1_ext.c
+ $(OPENSSL_PATH)/ssl/d1_meth.c
+ $(OPENSSL_PATH)/ssl/d1_srvr.c
+ $(OPENSSL_PATH)/ssl/d1_clnt.c
+ $(OPENSSL_PATH)/ssl/d1_lib.c
+ $(OPENSSL_PATH)/ssl/d1_pkt.c
+ $(OPENSSL_PATH)/ssl/d1_both.c
+ $(OPENSSL_PATH)/ssl/d1_srtp.c
+ $(OPENSSL_PATH)/ssl/ssl_lib.c
+ $(OPENSSL_PATH)/ssl/ssl_err2.c
+ $(OPENSSL_PATH)/ssl/ssl_cert.c
+ $(OPENSSL_PATH)/ssl/ssl_sess.c
+ $(OPENSSL_PATH)/ssl/ssl_ciph.c
+ $(OPENSSL_PATH)/ssl/ssl_stat.c
+ $(OPENSSL_PATH)/ssl/ssl_rsa.c
+ $(OPENSSL_PATH)/ssl/ssl_asn1.c
+ $(OPENSSL_PATH)/ssl/ssl_txt.c
+ $(OPENSSL_PATH)/ssl/ssl_algs.c
+ $(OPENSSL_PATH)/ssl/bio_ssl.c
+ $(OPENSSL_PATH)/ssl/ssl_err.c
+ $(OPENSSL_PATH)/ssl/kssl.c
+ $(OPENSSL_PATH)/ssl/t1_reneg.c
+ $(OPENSSL_PATH)/ssl/tls_srp.c
+ $(OPENSSL_PATH)/ssl/t1_trce.c
+ $(OPENSSL_PATH)/ssl/ssl_utst.c
# Autogenerated files list ends here
[Packages]
MdePkg/MdePkg.dec
@@ -498,11 +548,11 @@
# C4305: truncation from type1 to type2 of smaller size
# C4306: conversion from type1 to type2 of greater size
# C4702: Potentially uninitialized local variable name used
# C4311: pointer truncation from 'type' to 'type'
#
- MSFT:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /wd4244 /wd4701 /wd4702 /wd4706
+ MSFT:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /wd4244 /wd4245 /wd4701 /wd4702 /wd4706
MSFT:*_*_X64_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /wd4133 /wd4244 /wd4245 /wd4267 /wd4701 /wd4305 /wd4306 /wd4702 /wd4706 /wd4311
MSFT:*_*_IPF_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER $(OPENSSL_FLAGS) /wd4133 /wd4244 /wd4245 /wd4267 /wd4701 /wd4305 /wd4306 /wd4702 /wd4706
INTEL:*_*_IA32_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER -U__ICC $(OPENSSL_FLAGS) /w
INTEL:*_*_X64_CC_FLAGS = -U_WIN32 -U_WIN64 -U_MSC_VER -U__ICC $(OPENSSL_FLAGS) /w
diff --git a/CryptoPkg/Library/OpensslLib/process_files.sh b/CryptoPkg/Library/OpensslLib/process_files.sh
index 885adf3..6f069ce 100755
--- a/CryptoPkg/Library/OpensslLib/process_files.sh
+++ b/CryptoPkg/Library/OpensslLib/process_files.sh
@@ -40,11 +40,10 @@ fi
no-jpake \
no-krb5 \
no-locking \
no-mdc2 \
no-posix-io \
- no-pqueue \
no-rc2 \
no-rcs \
no-rfc3779 \
no-ripemd \
no-scrypt \
@@ -75,17 +74,15 @@ function filelist ()
RELATIVE_DIRECTORY=*)
eval "$LINE"
;;
LIBSRC=*)
LIBSRC=$(echo "$LINE" | sed s/^LIBSRC=//)
- if [ "$RELATIVE_DIRECTORY" != "ssl" ]; then
- for FILE in $LIBSRC; do
+ for FILE in $LIBSRC; do
if [ "$FILE" != "b_print.c" ]; then
echo -e ' $(OPENSSL_PATH)/'$RELATIVE_DIRECTORY/$FILE\\r\\
fi
- done
- fi
+ done
;;
esac
done
echo -e \\r
}
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* [Patch 04/10] CryptoPkg: Add new TlsLib library
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
` (2 preceding siblings ...)
2016-12-14 7:34 ` [Patch 03/10] CryptoPkg: Enable ssl build in OpensslLib directly Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-16 2:10 ` Ye, Ting
2016-12-14 7:34 ` [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL Jiaxin Wu
` (5 subsequent siblings)
9 siblings, 1 reply; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Ye Ting, Long Qin, Fu Siyuan, Zhang Lubo, Thomas Palmer,
Wu Jiaxin
This patch is used to add new TlsLib library, which is wrapped
over OpenSSL. The implementation provides TLS library functions
for EFI TLS protocol and EFI TLS Configuration Protocol.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
CryptoPkg/CryptoPkg.dec | 4 +
CryptoPkg/CryptoPkg.dsc | 1 +
CryptoPkg/Include/Library/TlsLib.h | 785 +++++++++++++++++++++
CryptoPkg/Library/TlsLib/InternalTlsLib.h | 35 +
CryptoPkg/Library/TlsLib/TlsConfig.c | 1055 +++++++++++++++++++++++++++++
CryptoPkg/Library/TlsLib/TlsInit.c | 291 ++++++++
CryptoPkg/Library/TlsLib/TlsLib.inf | 49 ++
CryptoPkg/Library/TlsLib/TlsLib.uni | 19 +
CryptoPkg/Library/TlsLib/TlsProcess.c | 461 +++++++++++++
9 files changed, 2700 insertions(+)
create mode 100644 CryptoPkg/Include/Library/TlsLib.h
create mode 100644 CryptoPkg/Library/TlsLib/InternalTlsLib.h
create mode 100644 CryptoPkg/Library/TlsLib/TlsConfig.c
create mode 100644 CryptoPkg/Library/TlsLib/TlsInit.c
create mode 100644 CryptoPkg/Library/TlsLib/TlsLib.inf
create mode 100644 CryptoPkg/Library/TlsLib/TlsLib.uni
create mode 100644 CryptoPkg/Library/TlsLib/TlsProcess.c
diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec
index 80579b7..eee26cb 100644
--- a/CryptoPkg/CryptoPkg.dec
+++ b/CryptoPkg/CryptoPkg.dec
@@ -29,10 +29,14 @@
[LibraryClasses]
## @libraryclass Provides basic library functions for cryptographic primitives.
##
BaseCryptLib|Include/Library/BaseCryptLib.h
+ ## @libraryclass Provides TLS library functions for EFI TLS protocol.
+ ##
+ TlsLib|Include/Library/TlsLib.h
+
[Protocols]
## Include/Protocol/RuntimeCrypt.h
gEfiRuntimeCryptProtocolGuid = { 0xe1475e0c, 0x1746, 0x4802, {0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 }}
[UserExtensions.TianoCore."ExtraFiles"]
diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index 3c3e444..468e60b 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -121,10 +121,11 @@
###################################################################################################
[Components]
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+ CryptoPkg/Library/TlsLib/TlsLib.inf
CryptoPkg/Application/Cryptest/Cryptest.inf
CryptoPkg/CryptRuntimeDxe/CryptRuntimeDxe.inf
diff --git a/CryptoPkg/Include/Library/TlsLib.h b/CryptoPkg/Include/Library/TlsLib.h
new file mode 100644
index 0000000..38b861e
--- /dev/null
+++ b/CryptoPkg/Include/Library/TlsLib.h
@@ -0,0 +1,785 @@
+/** @file
+ Defines TLS Library APIs.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_LIB_H__
+#define __TLS_LIB_H__
+
+/**
+ Initializes the OpenSSL library.
+
+ This function registers ciphers and digests used directly and indirectly
+ by SSL/TLS, and initializes the readable error messages.
+ This function must be called before any other action takes places.
+
+**/
+VOID
+EFIAPI
+TlsInitialize (
+ VOID
+ );
+
+/**
+ Free an allocated SSL_CTX object.
+
+ @param[in] TlsCtx Pointer to the SSL_CTX object to be released.
+
+**/
+VOID
+EFIAPI
+TlsCtxFree (
+ IN VOID *TlsCtx
+ );
+
+/**
+ Creates a new SSL_CTX object as framework to establish TLS/SSL enabled
+ connections.
+
+ @param[in] MajorVer Major Version of TLS/SSL Protocol.
+ @param[in] MinorVer Minor Version of TLS/SSL Protocol.
+
+ @return Pointer to an allocated SSL_CTX object.
+ If the creation failed, TlsCtxNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsCtxNew (
+ IN UINT8 MajorVer,
+ IN UINT8 MinorVer
+ );
+
+/**
+ Free an allocated TLS object.
+
+ This function removes the TLS object pointed to by Tls and frees up the
+ allocated memory. If Tls is NULL, nothing is done.
+
+ @param[in] Tls Pointer to the TLS object to be freed.
+
+**/
+VOID
+EFIAPI
+TlsFree (
+ IN VOID *Tls
+ );
+
+/**
+ Create a new TLS object for a connection.
+
+ This function creates a new TLS object for a connection. The new object
+ inherits the setting of the underlying context TlsCtx: connection method,
+ options, verification setting.
+
+ @param[in] TlsCtx Pointer to the SSL_CTX object.
+
+ @return Pointer to an allocated SSL object.
+ If the creation failed, TlsNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsNew (
+ IN VOID *TlsCtx
+ );
+
+/**
+ Checks if the TLS handshake was done.
+
+ This function will check if the specified TLS handshake was done.
+
+ @param[in] Tls Pointer to the TLS object for handshake state checking.
+
+ @retval TRUE The TLS handshake was done.
+ @retval FALSE The TLS handshake was not done.
+
+**/
+BOOLEAN
+EFIAPI
+TlsInHandshake (
+ IN VOID *Tls
+ );
+
+/**
+ Perform a TLS/SSL handshake.
+
+ This function will perform a TLS/SSL handshake.
+
+ @param[in] Tls Pointer to the TLS object for handshake operation.
+ @param[in] BufferIn Pointer to the most recently received TLS Handshake packet.
+ @param[in] BufferInSize Packet size in bytes for the most recently received TLS
+ Handshake packet.
+ @param[out] BufferOut Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferIn is NULL but BufferInSize is NOT 0.
+ BufferInSize is 0 but BufferIn is NOT NULL.
+ BufferOutSize is NULL.
+ BufferOut is NULL if *BufferOutSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsDoHandshake (
+ IN VOID *Tls,
+ IN UINT8 *BufferIn, OPTIONAL
+ IN UINTN BufferInSize, OPTIONAL
+ OUT UINT8 *BufferOut, OPTIONAL
+ IN OUT UINTN *BufferOutSize
+ );
+
+/**
+ Hande Alert message recorded in BufferIn. If BufferIn is NULL and BufferInSize is zero,
+ TLS session has errors and the response packet needs to be Alert message based on error type.
+
+ @param[in] Tls Pointer to the TLS object for state checking.
+ @param[in] BufferIn Pointer to the most recently received TLS Alert packet.
+ @param[in] BufferInSize Packet size in bytes for the most recently received TLS
+ Alert packet.
+ @param[out] BufferOut Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferIn is NULL but BufferInSize is NOT 0.
+ BufferInSize is 0 but BufferIn is NOT NULL.
+ BufferOutSize is NULL.
+ BufferOut is NULL if *BufferOutSize is not zero.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsHandeAlert (
+ IN VOID *Tls,
+ IN UINT8 *BufferIn, OPTIONAL
+ IN UINTN BufferInSize, OPTIONAL
+ OUT UINT8 *BufferOut, OPTIONAL
+ IN OUT UINTN *BufferOutSize
+ );
+
+/**
+ Build the CloseNotify packet.
+
+ @param[in] Tls Pointer to the TLS object for state checking.
+ @param[in, out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseNotify (
+ IN VOID *Tls,
+ IN OUT UINT8 *Buffer,
+ IN OUT UINTN *BufferSize
+ );
+
+/**
+ Attempts to read bytes from one TLS object and places the data in Buffer.
+
+ This function will attempt to read BufferSize bytes from the TLS object
+ and places the data in Buffer.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] Buffer Pointer to the buffer to store the data.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The amount of data successfully read from the TLS object.
+ @retval <=0 No data was successfully read.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficOut (
+ IN VOID *Tls,
+ IN OUT VOID *Buffer,
+ IN UINTN BufferSize
+ );
+
+/**
+ Attempts to write data from the buffer to TLS object.
+
+ This function will attempt to write BufferSize bytes data from the Buffer
+ to the TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The amount of data successfully written to the TLS object.
+ @retval <=0 No data was successfully written.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficIn (
+ IN VOID *Tls,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ );
+
+/**
+ Attempts to read bytes from the specified TLS connection into the buffer.
+
+ This function tries to read BufferSize bytes data from the specified TLS
+ connection into the Buffer.
+
+ @param[in] Tls Pointer to the TLS connection for data reading.
+ @param[in,out] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The read operation was successful, and return value is the
+ number of bytes actually read from the TLS connection.
+ @retval <=0 The read operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsRead (
+ IN VOID *Tls,
+ IN OUT VOID *Buffer,
+ IN UINTN BufferSize
+ );
+
+/**
+ Attempts to write data to a TLS connection.
+
+ This function tries to write BufferSize bytes data from the Buffer into the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS connection for data writing.
+ @param[in] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The write operation was successful, and return value is the
+ number of bytes actually written to the TLS connection.
+ @retval <=0 The write operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsWrite (
+ IN VOID *Tls,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ );
+
+/**
+ Set a new TLS/SSL method for a particular TLS object.
+
+ This function sets a new TLS/SSL method for a particular TLS object.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] MajorVer Major Version of TLS/SSL Protocol.
+ @param[in] MinorVer Minor Version of TLS/SSL Protocol.
+
+ @retval EFI_SUCCESS The TLS/SSL method was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS/SSL method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetVersion (
+ IN VOID *Tls,
+ IN UINT8 MajorVer,
+ IN UINT8 MinorVer
+ );
+
+/**
+ Set TLS object to work in client or server mode.
+
+ This function prepares a TLS object to work in client or server mode.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] IsServer Work in server mode.
+
+ @retval EFI_SUCCESS The TLS/SSL work mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS/SSL work mode.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetConnectionEnd (
+ IN VOID *Tls,
+ IN BOOLEAN IsServer
+ );
+
+/**
+ Set the ciphers list to be used by the TLS object.
+
+ This function sets the ciphers for use by a specified TLS object.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] CipherId Pointer to a string that contains one or more
+ ciphers separated by a colon.
+ @param[in] CipherNum The number of cipher in the list.
+
+ @retval EFI_SUCCESS The ciphers list was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS cipher in the list.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCipherList (
+ IN VOID *Tls,
+ IN UINT16 *CipherId,
+ IN UINTN CipherNum
+ );
+
+/**
+ Set the compression method for TLS/SSL operations.
+
+ This function handles TLS/SSL integrated compression methods.
+
+ @param[in] CompMethod The compression method ID.
+
+ @retval EFI_SUCCESS The compression method for the communication was
+ set successfully.
+ @retval EFI_UNSUPPORTED Unsupported compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCompressionMethod (
+ IN UINT8 CompMethod
+ );
+
+/**
+ Set peer certificate verification mode for the TLS connection.
+
+ This function sets the verification mode flags for the TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] VerifyMode A set of logically or'ed verification mode flags.
+
+**/
+VOID
+EFIAPI
+TlsSetVerify (
+ IN VOID *Tls,
+ IN UINT32 VerifyMode
+ );
+
+/**
+ Sets a TLS/SSL session ID to be used during TLS/SSL connect.
+
+ This function sets a session ID to be used when the TLS/SSL connection is
+ to be established.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] SessionId Session ID data used for session resumption.
+ @param[in] SessionIdLen Length of Session ID in bytes.
+
+ @retval EFI_SUCCESS Session ID was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED No available session for ID setting.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionId (
+ IN VOID *Tls,
+ IN UINT8 *SessionId,
+ IN UINT16 SessionIdLen
+ );
+
+/**
+ Adds the CA to the cert store when requesting Server or Client authentication.
+
+ This function adds the CA certificate to the list of CAs when requesting
+ Server or Client authentication for the chosen TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a DER-encoded binary
+ X.509 certificate or PEM-encoded X.509 certificate.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
+ @retval EFI_ABORTED Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCaCertificate (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Loads the local public certificate into the specified TLS object.
+
+ This function loads the X.509 certificate into the specified TLS object
+ for TLS negotiation.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a DER-encoded binary
+ X.509 certificate or PEM-encoded X.509 certificate.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
+ @retval EFI_ABORTED Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPublicCert (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Adds the local private key to the specified TLS object.
+
+ This function adds the local private key (PEM-encoded RSA or PKCS#8 private
+ key) into the specified TLS object for TLS negotiation.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a PEM-encoded RSA
+ or PKCS#8 private key.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_ABORTED Invalid private key data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPrivateKey (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Adds the CA-supplied certificate revocation list for certificate validation.
+
+ This function adds the CA-supplied certificate revocation list data for
+ certificate validity checking.
+
+ @param[in] Data Pointer to the data buffer of a DER-encoded CRL data.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_ABORTED Invalid CRL data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCertRevocationList (
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Gets the protocol version used by the specified TLS connection.
+
+ This function returns the protocol version used by the specified TLS
+ connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The protocol version of the specified TLS connection.
+
+**/
+UINT16
+EFIAPI
+TlsGetVersion (
+ IN VOID *Tls
+ );
+
+/**
+ Gets the connection end of the specified TLS connection.
+
+ This function returns the connection end (as client or as server) used by
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The connection end used by the specified TLS connection.
+
+**/
+UINT8
+EFIAPI
+TlsGetConnectionEnd (
+ IN VOID *Tls
+ );
+
+/**
+ Gets the cipher suite used by the specified TLS connection.
+
+ This function returns current cipher suite used by the specified
+ TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] CipherId The cipher suite used by the TLS object.
+
+ @retval EFI_SUCCESS The cipher suite was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported cipher suite.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCipher (
+ IN VOID *Tls,
+ IN OUT UINT16 *CipherId
+ );
+
+/**
+ Gets the compression methods used by the specified TLS connection.
+
+ This function returns current integrated compression methods used by
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] CompressionId The current compression method used by
+ the TLS object.
+
+ @retval EFI_SUCCESS The compression method was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_ABORTED Invalid Compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCompressionId (
+ IN VOID *Tls,
+ IN OUT UINT8 *CompressionId
+ );
+
+/**
+ Gets the verification mode currently set in the TLS connection.
+
+ This function returns the peer verification mode currently set in the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The verification mode set in the specified TLS connection.
+
+**/
+UINT32
+EFIAPI
+TlsGetVerify (
+ IN VOID *Tls
+ );
+
+/**
+ Gets the session ID used by the specified TLS connection.
+
+ This function returns the TLS/SSL session ID currently used by the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] SessionId Buffer to contain the returned session ID.
+ @param[in,out] SessionIdLen The length of Session ID in bytes.
+
+ @retval EFI_SUCCESS The Session ID was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionId (
+ IN VOID *Tls,
+ IN OUT UINT8 *SessionId,
+ IN OUT UINT16 *SessionIdLen
+ );
+
+/**
+ Gets the client random data used in the specified TLS connection.
+
+ This function returns the TLS/SSL client random data currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] ClientRandom Buffer to contain the returned client
+ random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetClientRandom (
+ IN VOID *Tls,
+ IN OUT UINT8 *ClientRandom
+ );
+
+/**
+ Gets the server random data used in the specified TLS connection.
+
+ This function returns the TLS/SSL server random data currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] ServerRandom Buffer to contain the returned server
+ random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetServerRandom (
+ IN VOID *Tls,
+ IN OUT UINT8 *ServerRandom
+ );
+
+/**
+ Gets the master key data used in the specified TLS connection.
+
+ This function returns the TLS/SSL master key material currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] KeyMaterial Buffer to contain the returned key material.
+
+ @retval EFI_SUCCESS Key material was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetKeyMaterial (
+ IN VOID *Tls,
+ IN OUT UINT8 *KeyMaterial
+ );
+
+/**
+ Gets the CA Certificate from the cert store.
+
+ This function returns the CA certificate for the chosen
+ TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the CA
+ certificate data sent to the client.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCaCertificate (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Gets the local public Certificate set in the specified TLS object.
+
+ This function returns the local public certificate which was currently set
+ in the specified TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the local
+ public certificate.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_NOT_FOUND The certificate is not found.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPublicCert (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Gets the local private key set in the specified TLS object.
+
+ This function returns the local private key data which was currently set
+ in the specified TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the local
+ private key data.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPrivateKey (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Gets the CA-supplied certificate revocation list data set in the specified
+ TLS object.
+
+ This function returns the CA-supplied certificate revocation list data which
+ was currently set in the specified TLS object.
+
+ @param[out] Data Pointer to the data buffer to receive the CRL data.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCertRevocationList (
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ );
+
+#endif // __TLS_LIB_H__
diff --git a/CryptoPkg/Library/TlsLib/InternalTlsLib.h b/CryptoPkg/Library/TlsLib/InternalTlsLib.h
new file mode 100644
index 0000000..2438de9
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/InternalTlsLib.h
@@ -0,0 +1,35 @@
+/** @file
+ Internal include file for TlsLib.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseCryptLib.h>
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+typedef struct {
+ //
+ // Main SSL Connection which is created by a server or a client
+ // per established connection.
+ //
+ SSL *Ssl;
+ //
+ // Memory BIO for the TLS/SSL Reading operations.
+ //
+ BIO *InBio;
+ //
+ // Memory BIO for the TLS/SSL Writing operations.
+ //
+ BIO *OutBio;
+} TLS_CONNECTION;
+
diff --git a/CryptoPkg/Library/TlsLib/TlsConfig.c b/CryptoPkg/Library/TlsLib/TlsConfig.c
new file mode 100644
index 0000000..31220b3
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsConfig.c
@@ -0,0 +1,1055 @@
+/** @file
+ SSL/TLS Configuration Library Wrapper Implementation over OpenSSL.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalTlsLib.h"
+
+typedef struct {
+ //
+ // IANA/IETF defined Cipher Suite ID
+ //
+ UINT16 IanaCipher;
+ //
+ // OpenSSL-used Cipher Suite String
+ //
+ CONST CHAR8 *OpensslCipher;
+} TLS_CIPHER_PAIR;
+
+//
+// The mapping table between IANA/IETF Cipher Suite definitions and
+// OpenSSL-used Cipher Suite name.
+//
+STATIC CONST TLS_CIPHER_PAIR TlsCipherMappingTable[] = {
+ { 0x0001, "NULL-MD5" }, /// TLS_RSA_WITH_NULL_MD5
+ { 0x0002, "NULL-SHA" }, /// TLS_RSA_WITH_NULL_SHA
+ { 0x0004, "RC4-MD5" }, /// TLS_RSA_WITH_RC4_128_MD5
+ { 0x0005, "RC4-SHA" }, /// TLS_RSA_WITH_RC4_128_SHA
+ { 0x000A, "DES-CBC3-SHA" }, /// TLS_RSA_WITH_3DES_EDE_CBC_SHA, mandatory TLS 1.1
+ { 0x0016, "DHE-RSA-DES-CBC3-SHA" }, /// TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ { 0x002F, "AES128-SHA" }, /// TLS_RSA_WITH_AES_128_CBC_SHA, mandatory TLS 1.2
+ { 0x0030, "DH-DSS-AES128-SHA" }, /// TLS_DH_DSS_WITH_AES_128_CBC_SHA
+ { 0x0031, "DH-RSA-AES128-SHA" }, /// TLS_DH_RSA_WITH_AES_128_CBC_SHA
+ { 0x0033, "DHE-RSA-AES128-SHA" }, /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ { 0x0035, "AES256-SHA" }, /// TLS_RSA_WITH_AES_256_CBC_SHA
+ { 0x0036, "DH-DSS-AES256-SHA" }, /// TLS_DH_DSS_WITH_AES_256_CBC_SHA
+ { 0x0037, "DH-RSA-AES256-SHA" }, /// TLS_DH_RSA_WITH_AES_256_CBC_SHA
+ { 0x0039, "DHE-RSA-AES256-SHA" }, /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ { 0x003B, "NULL-SHA256" }, /// TLS_RSA_WITH_NULL_SHA256
+ { 0x003C, "AES128-SHA256" }, /// TLS_RSA_WITH_AES_128_CBC_SHA256
+ { 0x003D, "AES256-SHA256" }, /// TLS_RSA_WITH_AES_256_CBC_SHA256
+ { 0x003E, "DH-DSS-AES128-SHA256" }, /// TLS_DH_DSS_WITH_AES_128_CBC_SHA256
+ { 0x003F, "DH-RSA-AES128-SHA256" }, /// TLS_DH_RSA_WITH_AES_128_CBC_SHA256
+ { 0x0067, "DHE-RSA-AES128-SHA256" }, /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ { 0x0068, "DH-DSS-AES256-SHA256" }, /// TLS_DH_DSS_WITH_AES_256_CBC_SHA256
+ { 0x0069, "DH-RSA-AES256-SHA256" }, /// TLS_DH_RSA_WITH_AES_256_CBC_SHA256
+ { 0x006B, "DHE-RSA-AES256-SHA256" } /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+};
+
+/**
+ Gets the OpenSSL cipher suite string for the supplied IANA TLS cipher suite.
+
+ @param[in] CipherId The supplied IANA TLS cipher suite ID.
+
+ @return The corresponding OpenSSL cipher suite string if found,
+ NULL otherwise.
+
+**/
+STATIC
+CONST CHAR8 *
+TlsGetCipherString (
+ IN UINT16 CipherId
+ )
+{
+ CONST TLS_CIPHER_PAIR *CipherEntry;
+ UINTN TableSize;
+ UINTN Index;
+
+ CipherEntry = TlsCipherMappingTable;
+ TableSize = sizeof (TlsCipherMappingTable) / sizeof (TLS_CIPHER_PAIR);
+
+ //
+ // Search Cipher Mapping Table for IANA-OpenSSL Cipher Translation
+ //
+ for (Index = 0; Index < TableSize; Index++, CipherEntry++) {
+ //
+ // Translate IANA cipher suite name to OpenSSL name.
+ //
+ if (CipherEntry->IanaCipher == CipherId) {
+ return CipherEntry->OpensslCipher;
+ }
+ }
+
+ //
+ // No Cipher Mapping found, return NULL.
+ //
+ return NULL;
+}
+
+/**
+ Set a new TLS/SSL method for a particular TLS object.
+
+ This function sets a new TLS/SSL method for a particular TLS object.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] MajorVer Major Version of TLS/SSL Protocol.
+ @param[in] MinorVer Minor Version of TLS/SSL Protocol.
+
+ @retval EFI_SUCCESS The TLS/SSL method was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS/SSL method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetVersion (
+ IN VOID *Tls,
+ IN UINT8 MajorVer,
+ IN UINT8 MinorVer
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINT16 ProtoVersion;
+
+ TlsConn = (TLS_CONNECTION *)Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ProtoVersion = (MajorVer << 8) | MinorVer;
+
+ switch (ProtoVersion) {
+ case TLS1_VERSION:
+ //
+ // TLS 1.0
+ //
+ SSL_set_ssl_method (TlsConn->Ssl, TLSv1_method ());
+ break;
+ case TLS1_1_VERSION:
+ //
+ // TLS 1.1
+ //
+ SSL_set_ssl_method (TlsConn->Ssl, TLSv1_1_method ());
+ break;
+ case TLS1_2_VERSION:
+ //
+ // TLS 1.2
+ //
+ SSL_set_ssl_method (TlsConn->Ssl, TLSv1_2_method ());
+ break;
+ default:
+ //
+ // Unsupported Protocol Version
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;;
+}
+
+/**
+ Set TLS object to work in client or server mode.
+
+ This function prepares a TLS object to work in client or server mode.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] IsServer Work in server mode.
+
+ @retval EFI_SUCCESS The TLS/SSL work mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS/SSL work mode.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetConnectionEnd (
+ IN VOID *Tls,
+ IN BOOLEAN IsServer
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsServer) {
+ //
+ // Set TLS to work in Client mode.
+ //
+ SSL_set_connect_state (TlsConn->Ssl);
+ } else {
+ //
+ // Set TLS to work in Server mode.
+ // It is unsupported for UEFI version currently.
+ //
+ //SSL_set_accept_state (TlsConn->Ssl);
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set the ciphers list to be used by the TLS object.
+
+ This function sets the ciphers for use by a specified TLS object.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] CipherId Pointer to a UINT16 cipher Id.
+ @param[in] CipherNum The number of cipher in the list.
+
+ @retval EFI_SUCCESS The ciphers list was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS cipher in the list.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCipherList (
+ IN VOID *Tls,
+ IN UINT16 *CipherId,
+ IN UINTN CipherNum
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINTN Index;
+ CONST CHAR8 *MappingName;
+ CHAR8 CipherString[500];
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MappingName = NULL;
+
+ memset (CipherString, 0, sizeof (CipherString));
+
+ for (Index = 0; Index < CipherNum; Index++) {
+ //
+ // Handling OpenSSL / RFC Cipher name mapping.
+ //
+ MappingName = TlsGetCipherString (*(CipherId + Index));
+ if (MappingName == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Index != 0) {
+ //
+ // The ciphers were separated by a colon.
+ //
+ AsciiStrCatS (CipherString, sizeof (CipherString), ":");
+ }
+
+ AsciiStrCatS (CipherString, sizeof (CipherString), MappingName);
+ }
+
+ AsciiStrCatS (CipherString, sizeof (CipherString), ":@STRENGTH");
+
+ //
+ // Sets the ciphers for use by the Tls object.
+ //
+ if (SSL_set_cipher_list (TlsConn->Ssl, CipherString) <= 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set the compression method for TLS/SSL operations.
+
+ This function handles TLS/SSL integrated compression methods.
+
+ @param[in] CompMethod The compression method ID.
+
+ @retval EFI_SUCCESS The compression method for the communication was
+ set successfully.
+ @retval EFI_UNSUPPORTED Unsupported compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCompressionMethod (
+ IN UINT8 CompMethod
+ )
+{
+ COMP_METHOD *Cm;
+ INTN Ret;
+
+ Cm = NULL;
+ Ret = 0;
+
+ if (CompMethod == 0) {
+ //
+ // TLS defines one standard compression method, CompressionMethod.null (0),
+ // which specifies that data exchanged via the record protocol will not be compressed.
+ // So, return EFI_SUCCESS directly (RFC 3749).
+ //
+ return EFI_SUCCESS;
+ } else if (CompMethod == 1) {
+ Cm = COMP_zlib();
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Adds the compression method to the list of available
+ // compression methods.
+ //
+ Ret = SSL_COMP_add_compression_method (CompMethod, Cm);
+ if (Ret != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set peer certificate verification mode for the TLS connection.
+
+ This function sets the verification mode flags for the TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] VerifyMode A set of logically or'ed verification mode flags.
+
+**/
+VOID
+EFIAPI
+TlsSetVerify (
+ IN VOID *Tls,
+ IN UINT32 VerifyMode
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return;
+ }
+
+ //
+ // Set peer certificate verification parameters with NULL callback.
+ //
+ SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL);
+}
+
+/**
+ Sets a TLS/SSL session ID to be used during TLS/SSL connect.
+
+ This function sets a session ID to be used when the TLS/SSL connection is
+ to be established.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] SessionId Session ID data used for session resumption.
+ @param[in] SessionIdLen Length of Session ID in bytes.
+
+ @retval EFI_SUCCESS Session ID was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED No available session for ID setting.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionId (
+ IN VOID *Tls,
+ IN UINT8 *SessionId,
+ IN UINT16 SessionIdLen
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ SSL_SESSION *Session;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Session = NULL;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Session = SSL_get_session (TlsConn->Ssl);
+ if (Session == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Session->session_id_length = SessionIdLen;
+ CopyMem (Session->session_id, SessionId, Session->session_id_length);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Adds the CA to the cert store when requesting Server or Client authentication.
+
+ This function adds the CA certificate to the list of CAs when requesting
+ Server or Client authentication for the chosen TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a DER-encoded binary
+ X.509 certificate or PEM-encoded X.509 certificate.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
+ @retval EFI_ABORTED Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCaCertificate (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ BIO *BioCert;
+ X509 *Cert;
+ X509_STORE *X509Store;
+ EFI_STATUS Status;
+ TLS_CONNECTION *TlsConn;
+ SSL_CTX *SslCtx;
+ INTN Ret;
+ unsigned long ErrorCode;
+
+ BioCert = NULL;
+ Cert = NULL;
+ X509Store = NULL;
+ Status = EFI_SUCCESS;
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Ret = 0;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
+ // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
+ //
+ Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
+ if (Cert == NULL) {
+ //
+ // Certificate is from PEM encoding.
+ //
+ BioCert = BIO_new (BIO_s_mem ());
+ if (BioCert == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
+ if (Cert == NULL) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+ }
+
+ SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);
+ X509Store = SSL_CTX_get_cert_store (SslCtx);
+ if (X509Store == NULL) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ //
+ // Add certificate to X509 store
+ //
+ Ret = X509_STORE_add_cert (X509Store, Cert);
+ if (Ret != 1) {
+ ErrorCode = ERR_peek_last_error ();
+ //
+ // Ignore "already in table" errors
+ //
+ if (!(ERR_GET_FUNC (ErrorCode) == X509_F_X509_STORE_ADD_CERT &&
+ ERR_GET_REASON (ErrorCode) == X509_R_CERT_ALREADY_IN_HASH_TABLE)) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+ }
+
+ON_EXIT:
+ if (BioCert != NULL) {
+ BIO_free (BioCert);
+ }
+
+ if (Cert != NULL) {
+ X509_free (Cert);
+ }
+
+ return Status;
+}
+
+/**
+ Loads the local public certificate into the specified TLS object.
+
+ This function loads the X.509 certificate into the specified TLS object
+ for TLS negotiation.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a DER-encoded binary
+ X.509 certificate or PEM-encoded X.509 certificate.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
+ @retval EFI_ABORTED Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPublicCert (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ BIO *BioCert;
+ X509 *Cert;
+ EFI_STATUS Status;
+ TLS_CONNECTION *TlsConn;
+
+ BioCert = NULL;
+ Cert = NULL;
+ Status = EFI_SUCCESS;
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
+ // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
+ //
+ Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
+ if (Cert == NULL) {
+ //
+ // Certificate is from PEM encoding.
+ //
+ BioCert = BIO_new (BIO_s_mem ());
+ if (BioCert == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
+ if (Cert == NULL) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+ }
+
+ if (SSL_use_certificate (TlsConn->Ssl, Cert) != 1) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+ if (BioCert != NULL) {
+ BIO_free (BioCert);
+ }
+
+ if (Cert != NULL) {
+ X509_free (Cert);
+ }
+
+ return Status;
+}
+
+/**
+ Adds the local private key to the specified TLS object.
+
+ This function adds the local private key (PEM-encoded RSA or PKCS#8 private
+ key) into the specified TLS object for TLS negotiation.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a PEM-encoded RSA
+ or PKCS#8 private key.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_ABORTED Invalid private key data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPrivateKey (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Adds the CA-supplied certificate revocation list for certificate validation.
+
+ This function adds the CA-supplied certificate revocation list data for
+ certificate validity checking.
+
+ @param[in] Data Pointer to the data buffer of a DER-encoded CRL data.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_ABORTED Invalid CRL data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCertRevocationList (
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Gets the protocol version used by the specified TLS connection.
+
+ This function returns the protocol version used by the specified TLS
+ connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The protocol version of the specified TLS connection.
+
+**/
+UINT16
+EFIAPI
+TlsGetVersion (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ ASSERT (TlsConn != NULL);
+
+ return (UINT16)(SSL_version (TlsConn->Ssl));
+}
+
+/**
+ Gets the connection end of the specified TLS connection.
+
+ This function returns the connection end (as client or as server) used by
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The connection end used by the specified TLS connection.
+
+**/
+UINT8
+EFIAPI
+TlsGetConnectionEnd (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ ASSERT (TlsConn != NULL);
+
+ return (UINT8)SSL_is_server (TlsConn->Ssl);
+}
+
+/**
+ Gets the cipher suite used by the specified TLS connection.
+
+ This function returns current cipher suite used by the specified
+ TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] CipherId The cipher suite used by the TLS object.
+
+ @retval EFI_SUCCESS The cipher suite was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported cipher suite.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCipher (
+ IN VOID *Tls,
+ IN OUT UINT16 *CipherId
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ CONST SSL_CIPHER *Cipher;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Cipher = NULL;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Cipher = SSL_get_current_cipher (TlsConn->Ssl);
+ if (Cipher == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *CipherId = (SSL_CIPHER_get_id (Cipher)) & 0xFFFF;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the compression methods used by the specified TLS connection.
+
+ This function returns current integrated compression methods used by
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] CompressionId The current compression method used by
+ the TLS object.
+
+ @retval EFI_SUCCESS The compression method was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_ABORTED Invalid Compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCompressionId (
+ IN VOID *Tls,
+ IN OUT UINT8 *CompressionId
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Gets the verification mode currently set in the TLS connection.
+
+ This function returns the peer verification mode currently set in the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The verification mode set in the specified TLS connection.
+
+**/
+UINT32
+EFIAPI
+TlsGetVerify (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ ASSERT (TlsConn != NULL);
+
+ return SSL_get_verify_mode (TlsConn->Ssl);
+}
+
+/**
+ Gets the session ID used by the specified TLS connection.
+
+ This function returns the TLS/SSL session ID currently used by the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] SessionId Buffer to contain the returned session ID.
+ @param[in,out] SessionIdLen The length of Session ID in bytes.
+
+ @retval EFI_SUCCESS The Session ID was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionId (
+ IN VOID *Tls,
+ IN OUT UINT8 *SessionId,
+ IN OUT UINT16 *SessionIdLen
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ SSL_SESSION *Session;
+ CONST UINT8 *SslSessionId;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Session = NULL;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL || SessionIdLen == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Session = SSL_get_session (TlsConn->Ssl);
+ if (Session == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SslSessionId = SSL_SESSION_get_id (Session, (unsigned int *)SessionIdLen);
+ CopyMem (SessionId, SslSessionId, *SessionIdLen);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the client random data used in the specified TLS connection.
+
+ This function returns the TLS/SSL client random data currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] ClientRandom Buffer to contain the returned client
+ random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetClientRandom (
+ IN VOID *Tls,
+ IN OUT UINT8 *ClientRandom
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || ClientRandom == NULL) {
+ return;
+ }
+
+ CopyMem (ClientRandom, TlsConn->Ssl->s3->client_random, SSL3_RANDOM_SIZE);
+}
+
+/**
+ Gets the server random data used in the specified TLS connection.
+
+ This function returns the TLS/SSL server random data currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] ServerRandom Buffer to contain the returned server
+ random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetServerRandom (
+ IN VOID *Tls,
+ IN OUT UINT8 *ServerRandom
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || ServerRandom == NULL) {
+ return;
+ }
+
+ CopyMem (ServerRandom, TlsConn->Ssl->s3->server_random, SSL3_RANDOM_SIZE);
+}
+
+/**
+ Gets the master key data used in the specified TLS connection.
+
+ This function returns the TLS/SSL master key material currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] KeyMaterial Buffer to contain the returned key material.
+
+ @retval EFI_SUCCESS Key material was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetKeyMaterial (
+ IN VOID *Tls,
+ IN OUT UINT8 *KeyMaterial
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ SSL_SESSION *Session;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Session = NULL;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || KeyMaterial == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Session = SSL_get_session (TlsConn->Ssl);
+
+ if (Session == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CopyMem (KeyMaterial, Session->master_key, Session->master_key_length);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the CA Certificate from the cert store.
+
+ This function returns the CA certificate for the chosen
+ TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the CA
+ certificate data sent to the client.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCaCertificate (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Gets the local public Certificate set in the specified TLS object.
+
+ This function returns the local public certificate which was currently set
+ in the specified TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the local
+ public certificate.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_NOT_FOUND The certificate is not found.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPublicCert (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ )
+{
+ X509 *Cert;
+ EFI_STATUS Status;
+ TLS_CONNECTION *TlsConn;
+
+ Cert = NULL;
+ Status = EFI_SUCCESS;
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || DataSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Cert = SSL_get_certificate(TlsConn->Ssl);
+ if (Cert == NULL) {
+ Status = EFI_NOT_FOUND;
+ }
+
+ //
+ // Only DER encoding is supported currently.
+ //
+ if (*DataSize < (UINTN) i2d_X509 (Cert, NULL)) {
+ *DataSize = (UINTN) i2d_X509 (Cert, NULL);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *DataSize = (UINTN) i2d_X509 (Cert, (unsigned char **) &Data);
+
+ return Status;
+}
+
+/**
+ Gets the local private key set in the specified TLS object.
+
+ This function returns the local private key data which was currently set
+ in the specified TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the local
+ private key data.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPrivateKey (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Gets the CA-supplied certificate revocation list data set in the specified
+ TLS object.
+
+ This function returns the CA-supplied certificate revocation list data which
+ was currently set in the specified TLS object.
+
+ @param[out] Data Pointer to the data buffer to receive the CRL data.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCertRevocationList (
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/CryptoPkg/Library/TlsLib/TlsInit.c b/CryptoPkg/Library/TlsLib/TlsInit.c
new file mode 100644
index 0000000..6b1fd93
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsInit.c
@@ -0,0 +1,291 @@
+/** @file
+ SSL/TLS Initialization Library Wrapper Implementation over OpenSSL.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalTlsLib.h"
+
+/**
+ Initializes the OpenSSL library.
+
+ This function registers ciphers and digests used directly and indirectly
+ by SSL/TLS, and initializes the readable error messages.
+ This function must be called before any other action takes places.
+
+**/
+VOID
+EFIAPI
+TlsInitialize (
+ VOID
+ )
+{
+ //
+ // Performs initialization of crypto and ssl library, and loads required
+ // algorithms.
+ //
+ SSL_library_init ();
+
+ //
+ // Loads error strings from both crypto and ssl library.
+ //
+ SSL_load_error_strings ();
+
+ /// OpenSSL_add_all_algorithms();
+
+ //
+ // Initialize the pseudorandom number generator.
+ //
+ RandomSeed (NULL, 0);
+}
+
+/**
+ Free an allocated SSL_CTX object.
+
+ @param[in] TlsCtx Pointer to the SSL_CTX object to be released.
+
+**/
+VOID
+EFIAPI
+TlsCtxFree (
+ IN VOID *TlsCtx
+ )
+{
+ if (TlsCtx == NULL) {
+ return;
+ }
+
+ if (TlsCtx != NULL) {
+ SSL_CTX_free ((SSL_CTX *) (TlsCtx));
+ }
+}
+
+/**
+ Creates a new SSL_CTX object as framework to establish TLS/SSL enabled
+ connections.
+
+ @param[in] MajorVer Major Version of TLS/SSL Protocol.
+ @param[in] MinorVer Minor Version of TLS/SSL Protocol.
+
+ @return Pointer to an allocated SSL_CTX object.
+ If the creation failed, TlsCtxNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsCtxNew (
+ IN UINT8 MajorVer,
+ IN UINT8 MinorVer
+ )
+{
+ SSL_CTX *TlsCtx;
+ UINT16 ProtoVersion;
+
+ ProtoVersion = (MajorVer << 8) | MinorVer;
+
+ TlsCtx = SSL_CTX_new (SSLv23_client_method ());
+ if (TlsCtx == NULL) {
+ return NULL;
+ }
+
+ //
+ // Ensure SSLv3 is disabled
+ //
+ SSL_CTX_set_options (TlsCtx, SSL_OP_NO_SSLv3);
+
+ //
+ // Treat as minimum accepted versions. Client can use higher
+ // TLS version if server supports it
+ //
+ switch (ProtoVersion) {
+ case TLS1_VERSION:
+ //
+ // TLS 1.0
+ //
+ break;
+ case TLS1_1_VERSION:
+ //
+ // TLS 1.1
+ //
+ SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1);
+ break;
+ case TLS1_2_VERSION:
+ //
+ // TLS 1.2
+ //
+ SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1);
+ SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1_1);
+ break;
+ default:
+ //
+ // Unsupported TLS/SSL Protocol Version.
+ //
+ break;
+ }
+
+ return (VOID *) TlsCtx;
+}
+
+/**
+ Free an allocated TLS object.
+
+ This function removes the TLS object pointed to by Tls and frees up the
+ allocated memory. If Tls is NULL, nothing is done.
+
+ @param[in] Tls Pointer to the TLS object to be freed.
+
+**/
+VOID
+EFIAPI
+TlsFree (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL) {
+ return;
+ }
+
+ //
+ // Free the internal TLS and BIO objects.
+ //
+ if (TlsConn->Ssl != NULL) {
+ SSL_free (TlsConn->Ssl);
+ }
+
+ if (TlsConn->InBio != NULL) {
+ BIO_free (TlsConn->InBio);
+ }
+
+ if (TlsConn->OutBio != NULL) {
+ BIO_free (TlsConn->OutBio);
+ }
+
+ OPENSSL_free (Tls);
+}
+
+/**
+ Create a new TLS object for a connection.
+
+ This function creates a new TLS object for a connection. The new object
+ inherits the setting of the underlying context TlsCtx: connection method,
+ options, verification setting.
+
+ @param[in] TlsCtx Pointer to the SSL_CTX object.
+
+ @return Pointer to an allocated SSL object.
+ If the creation failed, TlsNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsNew (
+ IN VOID *TlsCtx
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ SSL_CTX *SslCtx;
+ X509_STORE *X509Store;
+
+ TlsConn = NULL;
+
+ //
+ // Allocate one new TLS_CONNECTION object
+ //
+ TlsConn = (TLS_CONNECTION *) OPENSSL_malloc (sizeof (TLS_CONNECTION));
+ if (TlsConn == NULL) {
+ return NULL;
+ }
+
+ TlsConn->Ssl = NULL;
+
+ //
+ // Create a new SSL Object
+ //
+ TlsConn->Ssl = SSL_new ((SSL_CTX *) TlsCtx);
+ if (TlsConn->Ssl == NULL) {
+ TlsFree ((VOID *) TlsConn);
+ return NULL;
+ }
+
+ //
+ // Initialize the created SSL Object
+ //
+ SSL_set_info_callback (TlsConn->Ssl, NULL);
+
+ TlsConn->InBio = NULL;
+
+ //
+ // Set up Reading BIO for TLS connection
+ //
+ TlsConn->InBio = BIO_new (BIO_s_mem ());
+ if (TlsConn->InBio == NULL) {
+ TlsFree ((VOID *) TlsConn);
+ return NULL;
+ }
+
+ //
+ // Sets the behaviour of memory BIO when it is empty. It will set the
+ // read retry flag.
+ //
+ BIO_set_mem_eof_return (TlsConn->InBio, -1);
+
+ TlsConn->OutBio = NULL;
+
+ //
+ // Set up Writing BIO for TLS connection
+ //
+ TlsConn->OutBio = BIO_new (BIO_s_mem ());
+ if (TlsConn->OutBio == NULL) {
+ TlsFree ((VOID *) TlsConn);
+ return NULL;
+ }
+
+ //
+ // Sets the behaviour of memory BIO when it is empty. It will set the
+ // write retry flag.
+ //
+ BIO_set_mem_eof_return (TlsConn->OutBio, -1);
+
+ ASSERT (TlsConn->Ssl != NULL && TlsConn->InBio != NULL && TlsConn->OutBio != NULL);
+
+ //
+ // Connects the InBio and OutBio for the read and write operations.
+ //
+ SSL_set_bio (TlsConn->Ssl, TlsConn->InBio, TlsConn->OutBio);
+
+ //
+ // Create new X509 store if needed
+ //
+ SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);
+ X509Store = SSL_CTX_get_cert_store (SslCtx);
+ if (X509Store == NULL) {
+ X509Store = X509_STORE_new ();
+ if (X509Store == NULL) {
+ TlsFree ((VOID *) TlsConn);
+ return NULL;
+ }
+ SSL_CTX_set1_verify_cert_store (SslCtx, X509Store);
+ X509_STORE_free (X509Store);
+ }
+
+ //
+ // Set X509_STORE flags used in certificate validation
+ //
+ X509_STORE_set_flags (
+ X509Store,
+ X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
+ );
+ return (VOID *) TlsConn;
+}
diff --git a/CryptoPkg/Library/TlsLib/TlsLib.inf b/CryptoPkg/Library/TlsLib/TlsLib.inf
new file mode 100644
index 0000000..2122b3b
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsLib.inf
@@ -0,0 +1,49 @@
+## @file
+# SSL/TLS Wrapper Library Instance based on OpenSSL.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TlsLib
+ MODULE_UNI_FILE = TlsLib.uni
+ FILE_GUID = CC729DC5-4E21-0B36-1A00-3A8E1B86A155
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TlsLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF ARM AARCH64
+#
+
+[Sources]
+ InternalTlsLib.h
+ TlsInit.c
+ TlsConfig.c
+ TlsProcess.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiRuntimeServicesTableLib
+ DebugLib
+ OpensslLib
+ IntrinsicLib
+ PrintLib
diff --git a/CryptoPkg/Library/TlsLib/TlsLib.uni b/CryptoPkg/Library/TlsLib/TlsLib.uni
new file mode 100644
index 0000000..9b79287
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsLib.uni
@@ -0,0 +1,19 @@
+// /** @file
+// SSL/TLS Wrapper Library Instance based on OpenSSL.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "SSL/TLS Wrapper Library Instance"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides SSL/TLS Wrapper Library Instance."
\ No newline at end of file
diff --git a/CryptoPkg/Library/TlsLib/TlsProcess.c b/CryptoPkg/Library/TlsLib/TlsProcess.c
new file mode 100644
index 0000000..52b55d7
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsProcess.c
@@ -0,0 +1,461 @@
+/** @file
+ SSL/TLS Process Library Wrapper Implementation over OpenSSL.
+ The process includes the TLS handshake and packet I/O.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalTlsLib.h"
+
+#define MAX_BUFFER_SIZE 32768
+
+/**
+ Checks if the TLS handshake was done.
+
+ This function will check if the specified TLS handshake was done.
+
+ @param[in] Tls Pointer to the TLS object for handshake state checking.
+
+ @retval TRUE The TLS handshake was done.
+ @retval FALSE The TLS handshake was not done.
+
+**/
+BOOLEAN
+EFIAPI
+TlsInHandshake (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Return the status which indicates if the TLS handshake was done.
+ //
+ return !SSL_is_init_finished (TlsConn->Ssl);
+}
+
+/**
+ Perform a TLS/SSL handshake.
+
+ This function will perform a TLS/SSL handshake.
+
+ @param[in] Tls Pointer to the TLS object for handshake operation.
+ @param[in] BufferIn Pointer to the most recently received TLS Handshake packet.
+ @param[in] BufferInSize Packet size in bytes for the most recently received TLS
+ Handshake packet.
+ @param[out] BufferOut Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferIn is NULL but BufferInSize is NOT 0.
+ BufferInSize is 0 but BufferIn is NOT NULL.
+ BufferOutSize is NULL.
+ BufferOut is NULL if *BufferOutSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsDoHandshake (
+ IN VOID *Tls,
+ IN UINT8 *BufferIn, OPTIONAL
+ IN UINTN BufferInSize, OPTIONAL
+ OUT UINT8 *BufferOut, OPTIONAL
+ IN OUT UINTN *BufferOutSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINTN PendingBufferSize;
+ INTN Ret;
+ unsigned long ErrorCode;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ PendingBufferSize = 0;
+ Ret = 1;
+
+ if (TlsConn == NULL || \
+ TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
+ BufferOutSize == NULL || \
+ (BufferIn == NULL && BufferInSize != 0) || \
+ (BufferIn != NULL && BufferInSize == 0) || \
+ (BufferOut == NULL && *BufferOutSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(BufferIn == NULL && BufferInSize == 0) {
+ //
+ // If RequestBuffer is NULL and RequestSize is 0, and TLS session
+ // status is EfiTlsSessionNotStarted, the TLS session will be initiated
+ // and the response packet needs to be ClientHello.
+ //
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ if (PendingBufferSize == 0) {
+ SSL_set_connect_state (TlsConn->Ssl);
+ Ret = SSL_do_handshake (TlsConn->Ssl);
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ }
+ } else {
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ if (PendingBufferSize == 0) {
+ BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
+ Ret = SSL_do_handshake (TlsConn->Ssl);
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ }
+ }
+
+ if (Ret < 1) {
+ Ret = SSL_get_error (TlsConn->Ssl, (int) Ret);
+ if (Ret == SSL_ERROR_SSL ||
+ Ret == SSL_ERROR_SYSCALL ||
+ Ret == SSL_ERROR_ZERO_RETURN) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a SSL_HANDSHAKE_ERROR State=0x%x SSL_ERROR_%a\n",
+ __FUNCTION__,
+ SSL_get_state (TlsConn->Ssl),
+ Ret == SSL_ERROR_SSL ? "SSL" : Ret == SSL_ERROR_SYSCALL ? "SYSCALL" : "ZERO_RETURN"
+ ));
+ DEBUG_CODE_BEGIN ();
+ while (TRUE) {
+ ErrorCode = ERR_get_error ();
+ if (ErrorCode == 0) {
+ break;
+ }
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a ERROR 0x%x=L%x:F%x:R%x\n",
+ __FUNCTION__,
+ ErrorCode,
+ ERR_GET_LIB (ErrorCode),
+ ERR_GET_FUNC (ErrorCode),
+ ERR_GET_REASON (ErrorCode)
+ ));
+ }
+ DEBUG_CODE_END ();
+ return EFI_PROTOCOL_ERROR;
+ }
+ }
+
+ if (PendingBufferSize > *BufferOutSize) {
+ *BufferOutSize = PendingBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (PendingBufferSize > 0) {
+ *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32) PendingBufferSize);
+ } else {
+ *BufferOutSize = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Hande Alert message recorded in BufferIn. If BufferIn is NULL and BufferInSize is zero,
+ TLS session has errors and the response packet needs to be Alert message based on error type.
+
+ @param[in] Tls Pointer to the TLS object for state checking.
+ @param[in] BufferIn Pointer to the most recently received TLS Alert packet.
+ @param[in] BufferInSize Packet size in bytes for the most recently received TLS
+ Alert packet.
+ @param[out] BufferOut Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferIn is NULL but BufferInSize is NOT 0.
+ BufferInSize is 0 but BufferIn is NOT NULL.
+ BufferOutSize is NULL.
+ BufferOut is NULL if *BufferOutSize is not zero.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsHandeAlert (
+ IN VOID *Tls,
+ IN UINT8 *BufferIn, OPTIONAL
+ IN UINTN BufferInSize, OPTIONAL
+ OUT UINT8 *BufferOut, OPTIONAL
+ IN OUT UINTN *BufferOutSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINTN PendingBufferSize;
+ UINT8 *TempBuffer;
+ INTN Ret;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ PendingBufferSize = 0;
+ TempBuffer = NULL;
+ Ret = 0;
+
+ if (TlsConn == NULL || \
+ TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
+ BufferOutSize == NULL || \
+ (BufferIn == NULL && BufferInSize != 0) || \
+ (BufferIn != NULL && BufferInSize == 0) || \
+ (BufferOut == NULL && *BufferOutSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ if (PendingBufferSize == 0 && BufferIn != NULL && BufferInSize != 0) {
+ Ret = BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
+ if (Ret != (INTN) BufferInSize) {
+ return EFI_ABORTED;
+ }
+
+ TempBuffer = (UINT8 *) OPENSSL_malloc (MAX_BUFFER_SIZE);
+
+ //
+ // ssl3_send_alert() will be called in ssl3_read_bytes() function.
+ // TempBuffer is invalid since it's a Alert message, so just ignore it.
+ //
+ SSL_read (TlsConn->Ssl, TempBuffer, MAX_BUFFER_SIZE);
+
+ OPENSSL_free (TempBuffer);
+
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ }
+
+ if (PendingBufferSize > *BufferOutSize) {
+ *BufferOutSize = PendingBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (PendingBufferSize > 0) {
+ *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32) PendingBufferSize);
+ } else {
+ *BufferOutSize = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Build the CloseNotify packet.
+
+ @param[in] Tls Pointer to the TLS object for state checking.
+ @param[in, out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseNotify (
+ IN VOID *Tls,
+ IN OUT UINT8 *Buffer,
+ IN OUT UINTN *BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINTN PendingBufferSize;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ PendingBufferSize = 0;
+
+ if (TlsConn == NULL || \
+ TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
+ BufferSize == NULL || \
+ (Buffer == NULL && *BufferSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ if (PendingBufferSize == 0) {
+ //
+ // ssl3_send_alert() and ssl3_dispatch_alert() function will be called.
+ //
+ SSL_shutdown (TlsConn->Ssl);
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ }
+
+ if (PendingBufferSize > *BufferSize) {
+ *BufferSize = PendingBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (PendingBufferSize > 0) {
+ *BufferSize = BIO_read (TlsConn->OutBio, Buffer, (UINT32) PendingBufferSize);
+ } else {
+ *BufferSize = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Attempts to read bytes from one TLS object and places the data in Buffer.
+
+ This function will attempt to read BufferSize bytes from the TLS object
+ and places the data in Buffer.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] Buffer Pointer to the buffer to store the data.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The amount of data successfully read from the TLS object.
+ @retval <=0 No data was successfully read.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficOut (
+ IN VOID *Tls,
+ IN OUT VOID *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->OutBio == 0) {
+ return -1;
+ }
+
+ //
+ // Read and return the amount of data from the BIO.
+ //
+ return BIO_read (TlsConn->OutBio, Buffer, (UINT32) BufferSize);
+}
+
+/**
+ Attempts to write data from the buffer to TLS object.
+
+ This function will attempt to write BufferSize bytes data from the Buffer
+ to the TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The amount of data successfully written to the TLS object.
+ @retval <=0 No data was successfully written.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficIn (
+ IN VOID *Tls,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->InBio == 0) {
+ return -1;
+ }
+
+ //
+ // Write and return the amount of data to the BIO.
+ //
+ return BIO_write (TlsConn->InBio, Buffer, (UINT32) BufferSize);
+}
+/**
+ Attempts to read bytes from the specified TLS connection into the buffer.
+
+ This function tries to read BufferSize bytes data from the specified TLS
+ connection into the Buffer.
+
+ @param[in] Tls Pointer to the TLS connection for data reading.
+ @param[in,out] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The read operation was successful, and return value is the
+ number of bytes actually read from the TLS connection.
+ @retval <=0 The read operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsRead (
+ IN VOID *Tls,
+ IN OUT VOID *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return -1;
+ }
+
+ //
+ // Read bytes from the specified TLS connection.
+ //
+ return SSL_read (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
+}
+
+/**
+ Attempts to write data to a TLS connection.
+
+ This function tries to write BufferSize bytes data from the Buffer into the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS connection for data writing.
+ @param[in] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The write operation was successful, and return value is the
+ number of bytes actually written to the TLS connection.
+ @retval <=0 The write operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsWrite (
+ IN VOID *Tls,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return -1;
+ }
+
+ //
+ // Write bytes to the specified TLS connection.
+ //
+ return SSL_write (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
+}
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 04/10] CryptoPkg: Add new TlsLib library
2016-12-14 7:34 ` [Patch 04/10] CryptoPkg: Add new TlsLib library Jiaxin Wu
@ 2016-12-16 2:10 ` Ye, Ting
2016-12-16 2:51 ` Wu, Jiaxin
0 siblings, 1 reply; 37+ messages in thread
From: Ye, Ting @ 2016-12-16 2:10 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Long, Qin, Fu, Siyuan, Zhang, Lubo, Thomas Palmer
Hi Jiaxin,
Some comments included as following:
1. In TlsGetHostPublicCert, line 1892:
The status is set to EFI_NOT_FOUND but not returned. Does it make sense to update *DataSize in that case?
2. TlsDoHandshake uses EFI_PROTOCOL_ERROR but not record in function header.
3. TlsGetCurrentCompressionId uses EFI_UNSUPPROTED but not record in function header.
4. Typo in TlsHandeAlert, should be TlsHandleAlert? Please also update the function description.
Others look good to me.
Reviewed-by: Ye Ting <ting.ye@intel.com>
Thanks,
Ting
-----Original Message-----
From: Wu, Jiaxin
Sent: Wednesday, December 14, 2016 3:34 PM
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Long, Qin <qin.long@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 04/10] CryptoPkg: Add new TlsLib library
This patch is used to add new TlsLib library, which is wrapped
over OpenSSL. The implementation provides TLS library functions
for EFI TLS protocol and EFI TLS Configuration Protocol.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
CryptoPkg/CryptoPkg.dec | 4 +
CryptoPkg/CryptoPkg.dsc | 1 +
CryptoPkg/Include/Library/TlsLib.h | 785 +++++++++++++++++++++
CryptoPkg/Library/TlsLib/InternalTlsLib.h | 35 +
CryptoPkg/Library/TlsLib/TlsConfig.c | 1055 +++++++++++++++++++++++++++++
CryptoPkg/Library/TlsLib/TlsInit.c | 291 ++++++++
CryptoPkg/Library/TlsLib/TlsLib.inf | 49 ++
CryptoPkg/Library/TlsLib/TlsLib.uni | 19 +
CryptoPkg/Library/TlsLib/TlsProcess.c | 461 +++++++++++++
9 files changed, 2700 insertions(+)
create mode 100644 CryptoPkg/Include/Library/TlsLib.h
create mode 100644 CryptoPkg/Library/TlsLib/InternalTlsLib.h
create mode 100644 CryptoPkg/Library/TlsLib/TlsConfig.c
create mode 100644 CryptoPkg/Library/TlsLib/TlsInit.c
create mode 100644 CryptoPkg/Library/TlsLib/TlsLib.inf
create mode 100644 CryptoPkg/Library/TlsLib/TlsLib.uni
create mode 100644 CryptoPkg/Library/TlsLib/TlsProcess.c
diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec
index 80579b7..eee26cb 100644
--- a/CryptoPkg/CryptoPkg.dec
+++ b/CryptoPkg/CryptoPkg.dec
@@ -29,10 +29,14 @@
[LibraryClasses]
## @libraryclass Provides basic library functions for cryptographic primitives.
##
BaseCryptLib|Include/Library/BaseCryptLib.h
+ ## @libraryclass Provides TLS library functions for EFI TLS protocol.
+ ##
+ TlsLib|Include/Library/TlsLib.h
+
[Protocols]
## Include/Protocol/RuntimeCrypt.h
gEfiRuntimeCryptProtocolGuid = { 0xe1475e0c, 0x1746, 0x4802, {0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 }}
[UserExtensions.TianoCore."ExtraFiles"]
diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
index 3c3e444..468e60b 100644
--- a/CryptoPkg/CryptoPkg.dsc
+++ b/CryptoPkg/CryptoPkg.dsc
@@ -121,10 +121,11 @@
###################################################################################################
[Components]
CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
+ CryptoPkg/Library/TlsLib/TlsLib.inf
CryptoPkg/Application/Cryptest/Cryptest.inf
CryptoPkg/CryptRuntimeDxe/CryptRuntimeDxe.inf
diff --git a/CryptoPkg/Include/Library/TlsLib.h b/CryptoPkg/Include/Library/TlsLib.h
new file mode 100644
index 0000000..38b861e
--- /dev/null
+++ b/CryptoPkg/Include/Library/TlsLib.h
@@ -0,0 +1,785 @@
+/** @file
+ Defines TLS Library APIs.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_LIB_H__
+#define __TLS_LIB_H__
+
+/**
+ Initializes the OpenSSL library.
+
+ This function registers ciphers and digests used directly and indirectly
+ by SSL/TLS, and initializes the readable error messages.
+ This function must be called before any other action takes places.
+
+**/
+VOID
+EFIAPI
+TlsInitialize (
+ VOID
+ );
+
+/**
+ Free an allocated SSL_CTX object.
+
+ @param[in] TlsCtx Pointer to the SSL_CTX object to be released.
+
+**/
+VOID
+EFIAPI
+TlsCtxFree (
+ IN VOID *TlsCtx
+ );
+
+/**
+ Creates a new SSL_CTX object as framework to establish TLS/SSL enabled
+ connections.
+
+ @param[in] MajorVer Major Version of TLS/SSL Protocol.
+ @param[in] MinorVer Minor Version of TLS/SSL Protocol.
+
+ @return Pointer to an allocated SSL_CTX object.
+ If the creation failed, TlsCtxNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsCtxNew (
+ IN UINT8 MajorVer,
+ IN UINT8 MinorVer
+ );
+
+/**
+ Free an allocated TLS object.
+
+ This function removes the TLS object pointed to by Tls and frees up the
+ allocated memory. If Tls is NULL, nothing is done.
+
+ @param[in] Tls Pointer to the TLS object to be freed.
+
+**/
+VOID
+EFIAPI
+TlsFree (
+ IN VOID *Tls
+ );
+
+/**
+ Create a new TLS object for a connection.
+
+ This function creates a new TLS object for a connection. The new object
+ inherits the setting of the underlying context TlsCtx: connection method,
+ options, verification setting.
+
+ @param[in] TlsCtx Pointer to the SSL_CTX object.
+
+ @return Pointer to an allocated SSL object.
+ If the creation failed, TlsNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsNew (
+ IN VOID *TlsCtx
+ );
+
+/**
+ Checks if the TLS handshake was done.
+
+ This function will check if the specified TLS handshake was done.
+
+ @param[in] Tls Pointer to the TLS object for handshake state checking.
+
+ @retval TRUE The TLS handshake was done.
+ @retval FALSE The TLS handshake was not done.
+
+**/
+BOOLEAN
+EFIAPI
+TlsInHandshake (
+ IN VOID *Tls
+ );
+
+/**
+ Perform a TLS/SSL handshake.
+
+ This function will perform a TLS/SSL handshake.
+
+ @param[in] Tls Pointer to the TLS object for handshake operation.
+ @param[in] BufferIn Pointer to the most recently received TLS Handshake packet.
+ @param[in] BufferInSize Packet size in bytes for the most recently received TLS
+ Handshake packet.
+ @param[out] BufferOut Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferIn is NULL but BufferInSize is NOT 0.
+ BufferInSize is 0 but BufferIn is NOT NULL.
+ BufferOutSize is NULL.
+ BufferOut is NULL if *BufferOutSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsDoHandshake (
+ IN VOID *Tls,
+ IN UINT8 *BufferIn, OPTIONAL
+ IN UINTN BufferInSize, OPTIONAL
+ OUT UINT8 *BufferOut, OPTIONAL
+ IN OUT UINTN *BufferOutSize
+ );
+
+/**
+ Hande Alert message recorded in BufferIn. If BufferIn is NULL and BufferInSize is zero,
+ TLS session has errors and the response packet needs to be Alert message based on error type.
+
+ @param[in] Tls Pointer to the TLS object for state checking.
+ @param[in] BufferIn Pointer to the most recently received TLS Alert packet.
+ @param[in] BufferInSize Packet size in bytes for the most recently received TLS
+ Alert packet.
+ @param[out] BufferOut Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferIn is NULL but BufferInSize is NOT 0.
+ BufferInSize is 0 but BufferIn is NOT NULL.
+ BufferOutSize is NULL.
+ BufferOut is NULL if *BufferOutSize is not zero.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsHandeAlert (
+ IN VOID *Tls,
+ IN UINT8 *BufferIn, OPTIONAL
+ IN UINTN BufferInSize, OPTIONAL
+ OUT UINT8 *BufferOut, OPTIONAL
+ IN OUT UINTN *BufferOutSize
+ );
+
+/**
+ Build the CloseNotify packet.
+
+ @param[in] Tls Pointer to the TLS object for state checking.
+ @param[in, out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseNotify (
+ IN VOID *Tls,
+ IN OUT UINT8 *Buffer,
+ IN OUT UINTN *BufferSize
+ );
+
+/**
+ Attempts to read bytes from one TLS object and places the data in Buffer.
+
+ This function will attempt to read BufferSize bytes from the TLS object
+ and places the data in Buffer.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] Buffer Pointer to the buffer to store the data.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The amount of data successfully read from the TLS object.
+ @retval <=0 No data was successfully read.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficOut (
+ IN VOID *Tls,
+ IN OUT VOID *Buffer,
+ IN UINTN BufferSize
+ );
+
+/**
+ Attempts to write data from the buffer to TLS object.
+
+ This function will attempt to write BufferSize bytes data from the Buffer
+ to the TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The amount of data successfully written to the TLS object.
+ @retval <=0 No data was successfully written.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficIn (
+ IN VOID *Tls,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ );
+
+/**
+ Attempts to read bytes from the specified TLS connection into the buffer.
+
+ This function tries to read BufferSize bytes data from the specified TLS
+ connection into the Buffer.
+
+ @param[in] Tls Pointer to the TLS connection for data reading.
+ @param[in,out] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The read operation was successful, and return value is the
+ number of bytes actually read from the TLS connection.
+ @retval <=0 The read operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsRead (
+ IN VOID *Tls,
+ IN OUT VOID *Buffer,
+ IN UINTN BufferSize
+ );
+
+/**
+ Attempts to write data to a TLS connection.
+
+ This function tries to write BufferSize bytes data from the Buffer into the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS connection for data writing.
+ @param[in] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The write operation was successful, and return value is the
+ number of bytes actually written to the TLS connection.
+ @retval <=0 The write operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsWrite (
+ IN VOID *Tls,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ );
+
+/**
+ Set a new TLS/SSL method for a particular TLS object.
+
+ This function sets a new TLS/SSL method for a particular TLS object.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] MajorVer Major Version of TLS/SSL Protocol.
+ @param[in] MinorVer Minor Version of TLS/SSL Protocol.
+
+ @retval EFI_SUCCESS The TLS/SSL method was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS/SSL method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetVersion (
+ IN VOID *Tls,
+ IN UINT8 MajorVer,
+ IN UINT8 MinorVer
+ );
+
+/**
+ Set TLS object to work in client or server mode.
+
+ This function prepares a TLS object to work in client or server mode.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] IsServer Work in server mode.
+
+ @retval EFI_SUCCESS The TLS/SSL work mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS/SSL work mode.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetConnectionEnd (
+ IN VOID *Tls,
+ IN BOOLEAN IsServer
+ );
+
+/**
+ Set the ciphers list to be used by the TLS object.
+
+ This function sets the ciphers for use by a specified TLS object.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] CipherId Pointer to a string that contains one or more
+ ciphers separated by a colon.
+ @param[in] CipherNum The number of cipher in the list.
+
+ @retval EFI_SUCCESS The ciphers list was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS cipher in the list.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCipherList (
+ IN VOID *Tls,
+ IN UINT16 *CipherId,
+ IN UINTN CipherNum
+ );
+
+/**
+ Set the compression method for TLS/SSL operations.
+
+ This function handles TLS/SSL integrated compression methods.
+
+ @param[in] CompMethod The compression method ID.
+
+ @retval EFI_SUCCESS The compression method for the communication was
+ set successfully.
+ @retval EFI_UNSUPPORTED Unsupported compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCompressionMethod (
+ IN UINT8 CompMethod
+ );
+
+/**
+ Set peer certificate verification mode for the TLS connection.
+
+ This function sets the verification mode flags for the TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] VerifyMode A set of logically or'ed verification mode flags.
+
+**/
+VOID
+EFIAPI
+TlsSetVerify (
+ IN VOID *Tls,
+ IN UINT32 VerifyMode
+ );
+
+/**
+ Sets a TLS/SSL session ID to be used during TLS/SSL connect.
+
+ This function sets a session ID to be used when the TLS/SSL connection is
+ to be established.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] SessionId Session ID data used for session resumption.
+ @param[in] SessionIdLen Length of Session ID in bytes.
+
+ @retval EFI_SUCCESS Session ID was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED No available session for ID setting.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionId (
+ IN VOID *Tls,
+ IN UINT8 *SessionId,
+ IN UINT16 SessionIdLen
+ );
+
+/**
+ Adds the CA to the cert store when requesting Server or Client authentication.
+
+ This function adds the CA certificate to the list of CAs when requesting
+ Server or Client authentication for the chosen TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a DER-encoded binary
+ X.509 certificate or PEM-encoded X.509 certificate.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
+ @retval EFI_ABORTED Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCaCertificate (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Loads the local public certificate into the specified TLS object.
+
+ This function loads the X.509 certificate into the specified TLS object
+ for TLS negotiation.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a DER-encoded binary
+ X.509 certificate or PEM-encoded X.509 certificate.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
+ @retval EFI_ABORTED Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPublicCert (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Adds the local private key to the specified TLS object.
+
+ This function adds the local private key (PEM-encoded RSA or PKCS#8 private
+ key) into the specified TLS object for TLS negotiation.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a PEM-encoded RSA
+ or PKCS#8 private key.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_ABORTED Invalid private key data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPrivateKey (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Adds the CA-supplied certificate revocation list for certificate validation.
+
+ This function adds the CA-supplied certificate revocation list data for
+ certificate validity checking.
+
+ @param[in] Data Pointer to the data buffer of a DER-encoded CRL data.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_ABORTED Invalid CRL data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCertRevocationList (
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Gets the protocol version used by the specified TLS connection.
+
+ This function returns the protocol version used by the specified TLS
+ connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The protocol version of the specified TLS connection.
+
+**/
+UINT16
+EFIAPI
+TlsGetVersion (
+ IN VOID *Tls
+ );
+
+/**
+ Gets the connection end of the specified TLS connection.
+
+ This function returns the connection end (as client or as server) used by
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The connection end used by the specified TLS connection.
+
+**/
+UINT8
+EFIAPI
+TlsGetConnectionEnd (
+ IN VOID *Tls
+ );
+
+/**
+ Gets the cipher suite used by the specified TLS connection.
+
+ This function returns current cipher suite used by the specified
+ TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] CipherId The cipher suite used by the TLS object.
+
+ @retval EFI_SUCCESS The cipher suite was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported cipher suite.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCipher (
+ IN VOID *Tls,
+ IN OUT UINT16 *CipherId
+ );
+
+/**
+ Gets the compression methods used by the specified TLS connection.
+
+ This function returns current integrated compression methods used by
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] CompressionId The current compression method used by
+ the TLS object.
+
+ @retval EFI_SUCCESS The compression method was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_ABORTED Invalid Compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCompressionId (
+ IN VOID *Tls,
+ IN OUT UINT8 *CompressionId
+ );
+
+/**
+ Gets the verification mode currently set in the TLS connection.
+
+ This function returns the peer verification mode currently set in the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The verification mode set in the specified TLS connection.
+
+**/
+UINT32
+EFIAPI
+TlsGetVerify (
+ IN VOID *Tls
+ );
+
+/**
+ Gets the session ID used by the specified TLS connection.
+
+ This function returns the TLS/SSL session ID currently used by the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] SessionId Buffer to contain the returned session ID.
+ @param[in,out] SessionIdLen The length of Session ID in bytes.
+
+ @retval EFI_SUCCESS The Session ID was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionId (
+ IN VOID *Tls,
+ IN OUT UINT8 *SessionId,
+ IN OUT UINT16 *SessionIdLen
+ );
+
+/**
+ Gets the client random data used in the specified TLS connection.
+
+ This function returns the TLS/SSL client random data currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] ClientRandom Buffer to contain the returned client
+ random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetClientRandom (
+ IN VOID *Tls,
+ IN OUT UINT8 *ClientRandom
+ );
+
+/**
+ Gets the server random data used in the specified TLS connection.
+
+ This function returns the TLS/SSL server random data currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] ServerRandom Buffer to contain the returned server
+ random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetServerRandom (
+ IN VOID *Tls,
+ IN OUT UINT8 *ServerRandom
+ );
+
+/**
+ Gets the master key data used in the specified TLS connection.
+
+ This function returns the TLS/SSL master key material currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] KeyMaterial Buffer to contain the returned key material.
+
+ @retval EFI_SUCCESS Key material was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetKeyMaterial (
+ IN VOID *Tls,
+ IN OUT UINT8 *KeyMaterial
+ );
+
+/**
+ Gets the CA Certificate from the cert store.
+
+ This function returns the CA certificate for the chosen
+ TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the CA
+ certificate data sent to the client.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCaCertificate (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Gets the local public Certificate set in the specified TLS object.
+
+ This function returns the local public certificate which was currently set
+ in the specified TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the local
+ public certificate.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_NOT_FOUND The certificate is not found.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPublicCert (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Gets the local private key set in the specified TLS object.
+
+ This function returns the local private key data which was currently set
+ in the specified TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the local
+ private key data.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPrivateKey (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Gets the CA-supplied certificate revocation list data set in the specified
+ TLS object.
+
+ This function returns the CA-supplied certificate revocation list data which
+ was currently set in the specified TLS object.
+
+ @param[out] Data Pointer to the data buffer to receive the CRL data.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCertRevocationList (
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ );
+
+#endif // __TLS_LIB_H__
diff --git a/CryptoPkg/Library/TlsLib/InternalTlsLib.h b/CryptoPkg/Library/TlsLib/InternalTlsLib.h
new file mode 100644
index 0000000..2438de9
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/InternalTlsLib.h
@@ -0,0 +1,35 @@
+/** @file
+ Internal include file for TlsLib.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include <Library/BaseCryptLib.h>
+#include <openssl/ssl.h>
+#include <openssl/bio.h>
+#include <openssl/err.h>
+
+typedef struct {
+ //
+ // Main SSL Connection which is created by a server or a client
+ // per established connection.
+ //
+ SSL *Ssl;
+ //
+ // Memory BIO for the TLS/SSL Reading operations.
+ //
+ BIO *InBio;
+ //
+ // Memory BIO for the TLS/SSL Writing operations.
+ //
+ BIO *OutBio;
+} TLS_CONNECTION;
+
diff --git a/CryptoPkg/Library/TlsLib/TlsConfig.c b/CryptoPkg/Library/TlsLib/TlsConfig.c
new file mode 100644
index 0000000..31220b3
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsConfig.c
@@ -0,0 +1,1055 @@
+/** @file
+ SSL/TLS Configuration Library Wrapper Implementation over OpenSSL.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalTlsLib.h"
+
+typedef struct {
+ //
+ // IANA/IETF defined Cipher Suite ID
+ //
+ UINT16 IanaCipher;
+ //
+ // OpenSSL-used Cipher Suite String
+ //
+ CONST CHAR8 *OpensslCipher;
+} TLS_CIPHER_PAIR;
+
+//
+// The mapping table between IANA/IETF Cipher Suite definitions and
+// OpenSSL-used Cipher Suite name.
+//
+STATIC CONST TLS_CIPHER_PAIR TlsCipherMappingTable[] = {
+ { 0x0001, "NULL-MD5" }, /// TLS_RSA_WITH_NULL_MD5
+ { 0x0002, "NULL-SHA" }, /// TLS_RSA_WITH_NULL_SHA
+ { 0x0004, "RC4-MD5" }, /// TLS_RSA_WITH_RC4_128_MD5
+ { 0x0005, "RC4-SHA" }, /// TLS_RSA_WITH_RC4_128_SHA
+ { 0x000A, "DES-CBC3-SHA" }, /// TLS_RSA_WITH_3DES_EDE_CBC_SHA, mandatory TLS 1.1
+ { 0x0016, "DHE-RSA-DES-CBC3-SHA" }, /// TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ { 0x002F, "AES128-SHA" }, /// TLS_RSA_WITH_AES_128_CBC_SHA, mandatory TLS 1.2
+ { 0x0030, "DH-DSS-AES128-SHA" }, /// TLS_DH_DSS_WITH_AES_128_CBC_SHA
+ { 0x0031, "DH-RSA-AES128-SHA" }, /// TLS_DH_RSA_WITH_AES_128_CBC_SHA
+ { 0x0033, "DHE-RSA-AES128-SHA" }, /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ { 0x0035, "AES256-SHA" }, /// TLS_RSA_WITH_AES_256_CBC_SHA
+ { 0x0036, "DH-DSS-AES256-SHA" }, /// TLS_DH_DSS_WITH_AES_256_CBC_SHA
+ { 0x0037, "DH-RSA-AES256-SHA" }, /// TLS_DH_RSA_WITH_AES_256_CBC_SHA
+ { 0x0039, "DHE-RSA-AES256-SHA" }, /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ { 0x003B, "NULL-SHA256" }, /// TLS_RSA_WITH_NULL_SHA256
+ { 0x003C, "AES128-SHA256" }, /// TLS_RSA_WITH_AES_128_CBC_SHA256
+ { 0x003D, "AES256-SHA256" }, /// TLS_RSA_WITH_AES_256_CBC_SHA256
+ { 0x003E, "DH-DSS-AES128-SHA256" }, /// TLS_DH_DSS_WITH_AES_128_CBC_SHA256
+ { 0x003F, "DH-RSA-AES128-SHA256" }, /// TLS_DH_RSA_WITH_AES_128_CBC_SHA256
+ { 0x0067, "DHE-RSA-AES128-SHA256" }, /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ { 0x0068, "DH-DSS-AES256-SHA256" }, /// TLS_DH_DSS_WITH_AES_256_CBC_SHA256
+ { 0x0069, "DH-RSA-AES256-SHA256" }, /// TLS_DH_RSA_WITH_AES_256_CBC_SHA256
+ { 0x006B, "DHE-RSA-AES256-SHA256" } /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+};
+
+/**
+ Gets the OpenSSL cipher suite string for the supplied IANA TLS cipher suite.
+
+ @param[in] CipherId The supplied IANA TLS cipher suite ID.
+
+ @return The corresponding OpenSSL cipher suite string if found,
+ NULL otherwise.
+
+**/
+STATIC
+CONST CHAR8 *
+TlsGetCipherString (
+ IN UINT16 CipherId
+ )
+{
+ CONST TLS_CIPHER_PAIR *CipherEntry;
+ UINTN TableSize;
+ UINTN Index;
+
+ CipherEntry = TlsCipherMappingTable;
+ TableSize = sizeof (TlsCipherMappingTable) / sizeof (TLS_CIPHER_PAIR);
+
+ //
+ // Search Cipher Mapping Table for IANA-OpenSSL Cipher Translation
+ //
+ for (Index = 0; Index < TableSize; Index++, CipherEntry++) {
+ //
+ // Translate IANA cipher suite name to OpenSSL name.
+ //
+ if (CipherEntry->IanaCipher == CipherId) {
+ return CipherEntry->OpensslCipher;
+ }
+ }
+
+ //
+ // No Cipher Mapping found, return NULL.
+ //
+ return NULL;
+}
+
+/**
+ Set a new TLS/SSL method for a particular TLS object.
+
+ This function sets a new TLS/SSL method for a particular TLS object.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] MajorVer Major Version of TLS/SSL Protocol.
+ @param[in] MinorVer Minor Version of TLS/SSL Protocol.
+
+ @retval EFI_SUCCESS The TLS/SSL method was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS/SSL method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetVersion (
+ IN VOID *Tls,
+ IN UINT8 MajorVer,
+ IN UINT8 MinorVer
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINT16 ProtoVersion;
+
+ TlsConn = (TLS_CONNECTION *)Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ProtoVersion = (MajorVer << 8) | MinorVer;
+
+ switch (ProtoVersion) {
+ case TLS1_VERSION:
+ //
+ // TLS 1.0
+ //
+ SSL_set_ssl_method (TlsConn->Ssl, TLSv1_method ());
+ break;
+ case TLS1_1_VERSION:
+ //
+ // TLS 1.1
+ //
+ SSL_set_ssl_method (TlsConn->Ssl, TLSv1_1_method ());
+ break;
+ case TLS1_2_VERSION:
+ //
+ // TLS 1.2
+ //
+ SSL_set_ssl_method (TlsConn->Ssl, TLSv1_2_method ());
+ break;
+ default:
+ //
+ // Unsupported Protocol Version
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;;
+}
+
+/**
+ Set TLS object to work in client or server mode.
+
+ This function prepares a TLS object to work in client or server mode.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] IsServer Work in server mode.
+
+ @retval EFI_SUCCESS The TLS/SSL work mode was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS/SSL work mode.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetConnectionEnd (
+ IN VOID *Tls,
+ IN BOOLEAN IsServer
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!IsServer) {
+ //
+ // Set TLS to work in Client mode.
+ //
+ SSL_set_connect_state (TlsConn->Ssl);
+ } else {
+ //
+ // Set TLS to work in Server mode.
+ // It is unsupported for UEFI version currently.
+ //
+ //SSL_set_accept_state (TlsConn->Ssl);
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set the ciphers list to be used by the TLS object.
+
+ This function sets the ciphers for use by a specified TLS object.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] CipherId Pointer to a UINT16 cipher Id.
+ @param[in] CipherNum The number of cipher in the list.
+
+ @retval EFI_SUCCESS The ciphers list was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported TLS cipher in the list.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCipherList (
+ IN VOID *Tls,
+ IN UINT16 *CipherId,
+ IN UINTN CipherNum
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINTN Index;
+ CONST CHAR8 *MappingName;
+ CHAR8 CipherString[500];
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MappingName = NULL;
+
+ memset (CipherString, 0, sizeof (CipherString));
+
+ for (Index = 0; Index < CipherNum; Index++) {
+ //
+ // Handling OpenSSL / RFC Cipher name mapping.
+ //
+ MappingName = TlsGetCipherString (*(CipherId + Index));
+ if (MappingName == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Index != 0) {
+ //
+ // The ciphers were separated by a colon.
+ //
+ AsciiStrCatS (CipherString, sizeof (CipherString), ":");
+ }
+
+ AsciiStrCatS (CipherString, sizeof (CipherString), MappingName);
+ }
+
+ AsciiStrCatS (CipherString, sizeof (CipherString), ":@STRENGTH");
+
+ //
+ // Sets the ciphers for use by the Tls object.
+ //
+ if (SSL_set_cipher_list (TlsConn->Ssl, CipherString) <= 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set the compression method for TLS/SSL operations.
+
+ This function handles TLS/SSL integrated compression methods.
+
+ @param[in] CompMethod The compression method ID.
+
+ @retval EFI_SUCCESS The compression method for the communication was
+ set successfully.
+ @retval EFI_UNSUPPORTED Unsupported compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCompressionMethod (
+ IN UINT8 CompMethod
+ )
+{
+ COMP_METHOD *Cm;
+ INTN Ret;
+
+ Cm = NULL;
+ Ret = 0;
+
+ if (CompMethod == 0) {
+ //
+ // TLS defines one standard compression method, CompressionMethod.null (0),
+ // which specifies that data exchanged via the record protocol will not be compressed.
+ // So, return EFI_SUCCESS directly (RFC 3749).
+ //
+ return EFI_SUCCESS;
+ } else if (CompMethod == 1) {
+ Cm = COMP_zlib();
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Adds the compression method to the list of available
+ // compression methods.
+ //
+ Ret = SSL_COMP_add_compression_method (CompMethod, Cm);
+ if (Ret != 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Set peer certificate verification mode for the TLS connection.
+
+ This function sets the verification mode flags for the TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] VerifyMode A set of logically or'ed verification mode flags.
+
+**/
+VOID
+EFIAPI
+TlsSetVerify (
+ IN VOID *Tls,
+ IN UINT32 VerifyMode
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return;
+ }
+
+ //
+ // Set peer certificate verification parameters with NULL callback.
+ //
+ SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL);
+}
+
+/**
+ Sets a TLS/SSL session ID to be used during TLS/SSL connect.
+
+ This function sets a session ID to be used when the TLS/SSL connection is
+ to be established.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] SessionId Session ID data used for session resumption.
+ @param[in] SessionIdLen Length of Session ID in bytes.
+
+ @retval EFI_SUCCESS Session ID was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED No available session for ID setting.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionId (
+ IN VOID *Tls,
+ IN UINT8 *SessionId,
+ IN UINT16 SessionIdLen
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ SSL_SESSION *Session;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Session = NULL;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Session = SSL_get_session (TlsConn->Ssl);
+ if (Session == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Session->session_id_length = SessionIdLen;
+ CopyMem (Session->session_id, SessionId, Session->session_id_length);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Adds the CA to the cert store when requesting Server or Client authentication.
+
+ This function adds the CA certificate to the list of CAs when requesting
+ Server or Client authentication for the chosen TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a DER-encoded binary
+ X.509 certificate or PEM-encoded X.509 certificate.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
+ @retval EFI_ABORTED Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCaCertificate (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ BIO *BioCert;
+ X509 *Cert;
+ X509_STORE *X509Store;
+ EFI_STATUS Status;
+ TLS_CONNECTION *TlsConn;
+ SSL_CTX *SslCtx;
+ INTN Ret;
+ unsigned long ErrorCode;
+
+ BioCert = NULL;
+ Cert = NULL;
+ X509Store = NULL;
+ Status = EFI_SUCCESS;
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Ret = 0;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
+ // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
+ //
+ Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
+ if (Cert == NULL) {
+ //
+ // Certificate is from PEM encoding.
+ //
+ BioCert = BIO_new (BIO_s_mem ());
+ if (BioCert == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
+ if (Cert == NULL) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+ }
+
+ SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);
+ X509Store = SSL_CTX_get_cert_store (SslCtx);
+ if (X509Store == NULL) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ //
+ // Add certificate to X509 store
+ //
+ Ret = X509_STORE_add_cert (X509Store, Cert);
+ if (Ret != 1) {
+ ErrorCode = ERR_peek_last_error ();
+ //
+ // Ignore "already in table" errors
+ //
+ if (!(ERR_GET_FUNC (ErrorCode) == X509_F_X509_STORE_ADD_CERT &&
+ ERR_GET_REASON (ErrorCode) == X509_R_CERT_ALREADY_IN_HASH_TABLE)) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+ }
+
+ON_EXIT:
+ if (BioCert != NULL) {
+ BIO_free (BioCert);
+ }
+
+ if (Cert != NULL) {
+ X509_free (Cert);
+ }
+
+ return Status;
+}
+
+/**
+ Loads the local public certificate into the specified TLS object.
+
+ This function loads the X.509 certificate into the specified TLS object
+ for TLS negotiation.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a DER-encoded binary
+ X.509 certificate or PEM-encoded X.509 certificate.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_OUT_OF_RESOURCES Required resources could not be allocated.
+ @retval EFI_ABORTED Invalid X.509 certificate.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPublicCert (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ BIO *BioCert;
+ X509 *Cert;
+ EFI_STATUS Status;
+ TLS_CONNECTION *TlsConn;
+
+ BioCert = NULL;
+ Cert = NULL;
+ Status = EFI_SUCCESS;
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
+ // Determine whether certificate is from DER encoding, if so, translate it to X509 structure.
+ //
+ Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
+ if (Cert == NULL) {
+ //
+ // Certificate is from PEM encoding.
+ //
+ BioCert = BIO_new (BIO_s_mem ());
+ if (BioCert == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
+ if (Cert == NULL) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+ }
+
+ if (SSL_use_certificate (TlsConn->Ssl, Cert) != 1) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+ if (BioCert != NULL) {
+ BIO_free (BioCert);
+ }
+
+ if (Cert != NULL) {
+ X509_free (Cert);
+ }
+
+ return Status;
+}
+
+/**
+ Adds the local private key to the specified TLS object.
+
+ This function adds the local private key (PEM-encoded RSA or PKCS#8 private
+ key) into the specified TLS object for TLS negotiation.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Data Pointer to the data buffer of a PEM-encoded RSA
+ or PKCS#8 private key.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_ABORTED Invalid private key data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPrivateKey (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Adds the CA-supplied certificate revocation list for certificate validation.
+
+ This function adds the CA-supplied certificate revocation list data for
+ certificate validity checking.
+
+ @param[in] Data Pointer to the data buffer of a DER-encoded CRL data.
+ @param[in] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_ABORTED Invalid CRL data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetCertRevocationList (
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Gets the protocol version used by the specified TLS connection.
+
+ This function returns the protocol version used by the specified TLS
+ connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The protocol version of the specified TLS connection.
+
+**/
+UINT16
+EFIAPI
+TlsGetVersion (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ ASSERT (TlsConn != NULL);
+
+ return (UINT16)(SSL_version (TlsConn->Ssl));
+}
+
+/**
+ Gets the connection end of the specified TLS connection.
+
+ This function returns the connection end (as client or as server) used by
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The connection end used by the specified TLS connection.
+
+**/
+UINT8
+EFIAPI
+TlsGetConnectionEnd (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ ASSERT (TlsConn != NULL);
+
+ return (UINT8)SSL_is_server (TlsConn->Ssl);
+}
+
+/**
+ Gets the cipher suite used by the specified TLS connection.
+
+ This function returns current cipher suite used by the specified
+ TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] CipherId The cipher suite used by the TLS object.
+
+ @retval EFI_SUCCESS The cipher suite was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Unsupported cipher suite.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCipher (
+ IN VOID *Tls,
+ IN OUT UINT16 *CipherId
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ CONST SSL_CIPHER *Cipher;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Cipher = NULL;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Cipher = SSL_get_current_cipher (TlsConn->Ssl);
+ if (Cipher == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *CipherId = (SSL_CIPHER_get_id (Cipher)) & 0xFFFF;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the compression methods used by the specified TLS connection.
+
+ This function returns current integrated compression methods used by
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] CompressionId The current compression method used by
+ the TLS object.
+
+ @retval EFI_SUCCESS The compression method was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_ABORTED Invalid Compression method.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCurrentCompressionId (
+ IN VOID *Tls,
+ IN OUT UINT8 *CompressionId
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Gets the verification mode currently set in the TLS connection.
+
+ This function returns the peer verification mode currently set in the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+
+ @return The verification mode set in the specified TLS connection.
+
+**/
+UINT32
+EFIAPI
+TlsGetVerify (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ ASSERT (TlsConn != NULL);
+
+ return SSL_get_verify_mode (TlsConn->Ssl);
+}
+
+/**
+ Gets the session ID used by the specified TLS connection.
+
+ This function returns the TLS/SSL session ID currently used by the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] SessionId Buffer to contain the returned session ID.
+ @param[in,out] SessionIdLen The length of Session ID in bytes.
+
+ @retval EFI_SUCCESS The Session ID was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionId (
+ IN VOID *Tls,
+ IN OUT UINT8 *SessionId,
+ IN OUT UINT16 *SessionIdLen
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ SSL_SESSION *Session;
+ CONST UINT8 *SslSessionId;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Session = NULL;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL || SessionIdLen == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Session = SSL_get_session (TlsConn->Ssl);
+ if (Session == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SslSessionId = SSL_SESSION_get_id (Session, (unsigned int *)SessionIdLen);
+ CopyMem (SessionId, SslSessionId, *SessionIdLen);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the client random data used in the specified TLS connection.
+
+ This function returns the TLS/SSL client random data currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] ClientRandom Buffer to contain the returned client
+ random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetClientRandom (
+ IN VOID *Tls,
+ IN OUT UINT8 *ClientRandom
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || ClientRandom == NULL) {
+ return;
+ }
+
+ CopyMem (ClientRandom, TlsConn->Ssl->s3->client_random, SSL3_RANDOM_SIZE);
+}
+
+/**
+ Gets the server random data used in the specified TLS connection.
+
+ This function returns the TLS/SSL server random data currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] ServerRandom Buffer to contain the returned server
+ random data (32 bytes).
+
+**/
+VOID
+EFIAPI
+TlsGetServerRandom (
+ IN VOID *Tls,
+ IN OUT UINT8 *ServerRandom
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || ServerRandom == NULL) {
+ return;
+ }
+
+ CopyMem (ServerRandom, TlsConn->Ssl->s3->server_random, SSL3_RANDOM_SIZE);
+}
+
+/**
+ Gets the master key data used in the specified TLS connection.
+
+ This function returns the TLS/SSL master key material currently used in
+ the specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] KeyMaterial Buffer to contain the returned key material.
+
+ @retval EFI_SUCCESS Key material was returned successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetKeyMaterial (
+ IN VOID *Tls,
+ IN OUT UINT8 *KeyMaterial
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ SSL_SESSION *Session;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ Session = NULL;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || KeyMaterial == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Session = SSL_get_session (TlsConn->Ssl);
+
+ if (Session == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CopyMem (KeyMaterial, Session->master_key, Session->master_key_length);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Gets the CA Certificate from the cert store.
+
+ This function returns the CA certificate for the chosen
+ TLS connection.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the CA
+ certificate data sent to the client.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCaCertificate (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Gets the local public Certificate set in the specified TLS object.
+
+ This function returns the local public certificate which was currently set
+ in the specified TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the local
+ public certificate.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_NOT_FOUND The certificate is not found.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPublicCert (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ )
+{
+ X509 *Cert;
+ EFI_STATUS Status;
+ TLS_CONNECTION *TlsConn;
+
+ Cert = NULL;
+ Status = EFI_SUCCESS;
+ TlsConn = (TLS_CONNECTION *) Tls;
+
+ if (TlsConn == NULL || TlsConn->Ssl == NULL || DataSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Cert = SSL_get_certificate(TlsConn->Ssl);
+ if (Cert == NULL) {
+ Status = EFI_NOT_FOUND;
+ }
+
+ //
+ // Only DER encoding is supported currently.
+ //
+ if (*DataSize < (UINTN) i2d_X509 (Cert, NULL)) {
+ *DataSize = (UINTN) i2d_X509 (Cert, NULL);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *DataSize = (UINTN) i2d_X509 (Cert, (unsigned char **) &Data);
+
+ return Status;
+}
+
+/**
+ Gets the local private key set in the specified TLS object.
+
+ This function returns the local private key data which was currently set
+ in the specified TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[out] Data Pointer to the data buffer to receive the local
+ private key data.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetHostPrivateKey (
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Gets the CA-supplied certificate revocation list data set in the specified
+ TLS object.
+
+ This function returns the CA-supplied certificate revocation list data which
+ was currently set in the specified TLS object.
+
+ @param[out] Data Pointer to the data buffer to receive the CRL data.
+ @param[in,out] DataSize The size of data buffer in bytes.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetCertRevocationList (
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
+ )
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/CryptoPkg/Library/TlsLib/TlsInit.c b/CryptoPkg/Library/TlsLib/TlsInit.c
new file mode 100644
index 0000000..6b1fd93
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsInit.c
@@ -0,0 +1,291 @@
+/** @file
+ SSL/TLS Initialization Library Wrapper Implementation over OpenSSL.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalTlsLib.h"
+
+/**
+ Initializes the OpenSSL library.
+
+ This function registers ciphers and digests used directly and indirectly
+ by SSL/TLS, and initializes the readable error messages.
+ This function must be called before any other action takes places.
+
+**/
+VOID
+EFIAPI
+TlsInitialize (
+ VOID
+ )
+{
+ //
+ // Performs initialization of crypto and ssl library, and loads required
+ // algorithms.
+ //
+ SSL_library_init ();
+
+ //
+ // Loads error strings from both crypto and ssl library.
+ //
+ SSL_load_error_strings ();
+
+ /// OpenSSL_add_all_algorithms();
+
+ //
+ // Initialize the pseudorandom number generator.
+ //
+ RandomSeed (NULL, 0);
+}
+
+/**
+ Free an allocated SSL_CTX object.
+
+ @param[in] TlsCtx Pointer to the SSL_CTX object to be released.
+
+**/
+VOID
+EFIAPI
+TlsCtxFree (
+ IN VOID *TlsCtx
+ )
+{
+ if (TlsCtx == NULL) {
+ return;
+ }
+
+ if (TlsCtx != NULL) {
+ SSL_CTX_free ((SSL_CTX *) (TlsCtx));
+ }
+}
+
+/**
+ Creates a new SSL_CTX object as framework to establish TLS/SSL enabled
+ connections.
+
+ @param[in] MajorVer Major Version of TLS/SSL Protocol.
+ @param[in] MinorVer Minor Version of TLS/SSL Protocol.
+
+ @return Pointer to an allocated SSL_CTX object.
+ If the creation failed, TlsCtxNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsCtxNew (
+ IN UINT8 MajorVer,
+ IN UINT8 MinorVer
+ )
+{
+ SSL_CTX *TlsCtx;
+ UINT16 ProtoVersion;
+
+ ProtoVersion = (MajorVer << 8) | MinorVer;
+
+ TlsCtx = SSL_CTX_new (SSLv23_client_method ());
+ if (TlsCtx == NULL) {
+ return NULL;
+ }
+
+ //
+ // Ensure SSLv3 is disabled
+ //
+ SSL_CTX_set_options (TlsCtx, SSL_OP_NO_SSLv3);
+
+ //
+ // Treat as minimum accepted versions. Client can use higher
+ // TLS version if server supports it
+ //
+ switch (ProtoVersion) {
+ case TLS1_VERSION:
+ //
+ // TLS 1.0
+ //
+ break;
+ case TLS1_1_VERSION:
+ //
+ // TLS 1.1
+ //
+ SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1);
+ break;
+ case TLS1_2_VERSION:
+ //
+ // TLS 1.2
+ //
+ SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1);
+ SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1_1);
+ break;
+ default:
+ //
+ // Unsupported TLS/SSL Protocol Version.
+ //
+ break;
+ }
+
+ return (VOID *) TlsCtx;
+}
+
+/**
+ Free an allocated TLS object.
+
+ This function removes the TLS object pointed to by Tls and frees up the
+ allocated memory. If Tls is NULL, nothing is done.
+
+ @param[in] Tls Pointer to the TLS object to be freed.
+
+**/
+VOID
+EFIAPI
+TlsFree (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL) {
+ return;
+ }
+
+ //
+ // Free the internal TLS and BIO objects.
+ //
+ if (TlsConn->Ssl != NULL) {
+ SSL_free (TlsConn->Ssl);
+ }
+
+ if (TlsConn->InBio != NULL) {
+ BIO_free (TlsConn->InBio);
+ }
+
+ if (TlsConn->OutBio != NULL) {
+ BIO_free (TlsConn->OutBio);
+ }
+
+ OPENSSL_free (Tls);
+}
+
+/**
+ Create a new TLS object for a connection.
+
+ This function creates a new TLS object for a connection. The new object
+ inherits the setting of the underlying context TlsCtx: connection method,
+ options, verification setting.
+
+ @param[in] TlsCtx Pointer to the SSL_CTX object.
+
+ @return Pointer to an allocated SSL object.
+ If the creation failed, TlsNew() returns NULL.
+
+**/
+VOID *
+EFIAPI
+TlsNew (
+ IN VOID *TlsCtx
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ SSL_CTX *SslCtx;
+ X509_STORE *X509Store;
+
+ TlsConn = NULL;
+
+ //
+ // Allocate one new TLS_CONNECTION object
+ //
+ TlsConn = (TLS_CONNECTION *) OPENSSL_malloc (sizeof (TLS_CONNECTION));
+ if (TlsConn == NULL) {
+ return NULL;
+ }
+
+ TlsConn->Ssl = NULL;
+
+ //
+ // Create a new SSL Object
+ //
+ TlsConn->Ssl = SSL_new ((SSL_CTX *) TlsCtx);
+ if (TlsConn->Ssl == NULL) {
+ TlsFree ((VOID *) TlsConn);
+ return NULL;
+ }
+
+ //
+ // Initialize the created SSL Object
+ //
+ SSL_set_info_callback (TlsConn->Ssl, NULL);
+
+ TlsConn->InBio = NULL;
+
+ //
+ // Set up Reading BIO for TLS connection
+ //
+ TlsConn->InBio = BIO_new (BIO_s_mem ());
+ if (TlsConn->InBio == NULL) {
+ TlsFree ((VOID *) TlsConn);
+ return NULL;
+ }
+
+ //
+ // Sets the behaviour of memory BIO when it is empty. It will set the
+ // read retry flag.
+ //
+ BIO_set_mem_eof_return (TlsConn->InBio, -1);
+
+ TlsConn->OutBio = NULL;
+
+ //
+ // Set up Writing BIO for TLS connection
+ //
+ TlsConn->OutBio = BIO_new (BIO_s_mem ());
+ if (TlsConn->OutBio == NULL) {
+ TlsFree ((VOID *) TlsConn);
+ return NULL;
+ }
+
+ //
+ // Sets the behaviour of memory BIO when it is empty. It will set the
+ // write retry flag.
+ //
+ BIO_set_mem_eof_return (TlsConn->OutBio, -1);
+
+ ASSERT (TlsConn->Ssl != NULL && TlsConn->InBio != NULL && TlsConn->OutBio != NULL);
+
+ //
+ // Connects the InBio and OutBio for the read and write operations.
+ //
+ SSL_set_bio (TlsConn->Ssl, TlsConn->InBio, TlsConn->OutBio);
+
+ //
+ // Create new X509 store if needed
+ //
+ SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);
+ X509Store = SSL_CTX_get_cert_store (SslCtx);
+ if (X509Store == NULL) {
+ X509Store = X509_STORE_new ();
+ if (X509Store == NULL) {
+ TlsFree ((VOID *) TlsConn);
+ return NULL;
+ }
+ SSL_CTX_set1_verify_cert_store (SslCtx, X509Store);
+ X509_STORE_free (X509Store);
+ }
+
+ //
+ // Set X509_STORE flags used in certificate validation
+ //
+ X509_STORE_set_flags (
+ X509Store,
+ X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
+ );
+ return (VOID *) TlsConn;
+}
diff --git a/CryptoPkg/Library/TlsLib/TlsLib.inf b/CryptoPkg/Library/TlsLib/TlsLib.inf
new file mode 100644
index 0000000..2122b3b
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsLib.inf
@@ -0,0 +1,49 @@
+## @file
+# SSL/TLS Wrapper Library Instance based on OpenSSL.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TlsLib
+ MODULE_UNI_FILE = TlsLib.uni
+ FILE_GUID = CC729DC5-4E21-0B36-1A00-3A8E1B86A155
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = TlsLib|DXE_DRIVER DXE_CORE UEFI_APPLICATION UEFI_DRIVER
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF ARM AARCH64
+#
+
+[Sources]
+ InternalTlsLib.h
+ TlsInit.c
+ TlsConfig.c
+ TlsProcess.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ CryptoPkg/CryptoPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiRuntimeServicesTableLib
+ DebugLib
+ OpensslLib
+ IntrinsicLib
+ PrintLib
diff --git a/CryptoPkg/Library/TlsLib/TlsLib.uni b/CryptoPkg/Library/TlsLib/TlsLib.uni
new file mode 100644
index 0000000..9b79287
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsLib.uni
@@ -0,0 +1,19 @@
+// /** @file
+// SSL/TLS Wrapper Library Instance based on OpenSSL.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "SSL/TLS Wrapper Library Instance"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module provides SSL/TLS Wrapper Library Instance."
\ No newline at end of file
diff --git a/CryptoPkg/Library/TlsLib/TlsProcess.c b/CryptoPkg/Library/TlsLib/TlsProcess.c
new file mode 100644
index 0000000..52b55d7
--- /dev/null
+++ b/CryptoPkg/Library/TlsLib/TlsProcess.c
@@ -0,0 +1,461 @@
+/** @file
+ SSL/TLS Process Library Wrapper Implementation over OpenSSL.
+ The process includes the TLS handshake and packet I/O.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "InternalTlsLib.h"
+
+#define MAX_BUFFER_SIZE 32768
+
+/**
+ Checks if the TLS handshake was done.
+
+ This function will check if the specified TLS handshake was done.
+
+ @param[in] Tls Pointer to the TLS object for handshake state checking.
+
+ @retval TRUE The TLS handshake was done.
+ @retval FALSE The TLS handshake was not done.
+
+**/
+BOOLEAN
+EFIAPI
+TlsInHandshake (
+ IN VOID *Tls
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return FALSE;
+ }
+
+ //
+ // Return the status which indicates if the TLS handshake was done.
+ //
+ return !SSL_is_init_finished (TlsConn->Ssl);
+}
+
+/**
+ Perform a TLS/SSL handshake.
+
+ This function will perform a TLS/SSL handshake.
+
+ @param[in] Tls Pointer to the TLS object for handshake operation.
+ @param[in] BufferIn Pointer to the most recently received TLS Handshake packet.
+ @param[in] BufferInSize Packet size in bytes for the most recently received TLS
+ Handshake packet.
+ @param[out] BufferOut Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferIn is NULL but BufferInSize is NOT 0.
+ BufferInSize is 0 but BufferIn is NOT NULL.
+ BufferOutSize is NULL.
+ BufferOut is NULL if *BufferOutSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsDoHandshake (
+ IN VOID *Tls,
+ IN UINT8 *BufferIn, OPTIONAL
+ IN UINTN BufferInSize, OPTIONAL
+ OUT UINT8 *BufferOut, OPTIONAL
+ IN OUT UINTN *BufferOutSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINTN PendingBufferSize;
+ INTN Ret;
+ unsigned long ErrorCode;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ PendingBufferSize = 0;
+ Ret = 1;
+
+ if (TlsConn == NULL || \
+ TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
+ BufferOutSize == NULL || \
+ (BufferIn == NULL && BufferInSize != 0) || \
+ (BufferIn != NULL && BufferInSize == 0) || \
+ (BufferOut == NULL && *BufferOutSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(BufferIn == NULL && BufferInSize == 0) {
+ //
+ // If RequestBuffer is NULL and RequestSize is 0, and TLS session
+ // status is EfiTlsSessionNotStarted, the TLS session will be initiated
+ // and the response packet needs to be ClientHello.
+ //
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ if (PendingBufferSize == 0) {
+ SSL_set_connect_state (TlsConn->Ssl);
+ Ret = SSL_do_handshake (TlsConn->Ssl);
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ }
+ } else {
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ if (PendingBufferSize == 0) {
+ BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
+ Ret = SSL_do_handshake (TlsConn->Ssl);
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ }
+ }
+
+ if (Ret < 1) {
+ Ret = SSL_get_error (TlsConn->Ssl, (int) Ret);
+ if (Ret == SSL_ERROR_SSL ||
+ Ret == SSL_ERROR_SYSCALL ||
+ Ret == SSL_ERROR_ZERO_RETURN) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a SSL_HANDSHAKE_ERROR State=0x%x SSL_ERROR_%a\n",
+ __FUNCTION__,
+ SSL_get_state (TlsConn->Ssl),
+ Ret == SSL_ERROR_SSL ? "SSL" : Ret == SSL_ERROR_SYSCALL ? "SYSCALL" : "ZERO_RETURN"
+ ));
+ DEBUG_CODE_BEGIN ();
+ while (TRUE) {
+ ErrorCode = ERR_get_error ();
+ if (ErrorCode == 0) {
+ break;
+ }
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a ERROR 0x%x=L%x:F%x:R%x\n",
+ __FUNCTION__,
+ ErrorCode,
+ ERR_GET_LIB (ErrorCode),
+ ERR_GET_FUNC (ErrorCode),
+ ERR_GET_REASON (ErrorCode)
+ ));
+ }
+ DEBUG_CODE_END ();
+ return EFI_PROTOCOL_ERROR;
+ }
+ }
+
+ if (PendingBufferSize > *BufferOutSize) {
+ *BufferOutSize = PendingBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (PendingBufferSize > 0) {
+ *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32) PendingBufferSize);
+ } else {
+ *BufferOutSize = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Hande Alert message recorded in BufferIn. If BufferIn is NULL and BufferInSize is zero,
+ TLS session has errors and the response packet needs to be Alert message based on error type.
+
+ @param[in] Tls Pointer to the TLS object for state checking.
+ @param[in] BufferIn Pointer to the most recently received TLS Alert packet.
+ @param[in] BufferInSize Packet size in bytes for the most recently received TLS
+ Alert packet.
+ @param[out] BufferOut Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferIn is NULL but BufferInSize is NOT 0.
+ BufferInSize is 0 but BufferIn is NOT NULL.
+ BufferOutSize is NULL.
+ BufferOut is NULL if *BufferOutSize is not zero.
+ @retval EFI_ABORTED An error occurred.
+ @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsHandeAlert (
+ IN VOID *Tls,
+ IN UINT8 *BufferIn, OPTIONAL
+ IN UINTN BufferInSize, OPTIONAL
+ OUT UINT8 *BufferOut, OPTIONAL
+ IN OUT UINTN *BufferOutSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINTN PendingBufferSize;
+ UINT8 *TempBuffer;
+ INTN Ret;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ PendingBufferSize = 0;
+ TempBuffer = NULL;
+ Ret = 0;
+
+ if (TlsConn == NULL || \
+ TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
+ BufferOutSize == NULL || \
+ (BufferIn == NULL && BufferInSize != 0) || \
+ (BufferIn != NULL && BufferInSize == 0) || \
+ (BufferOut == NULL && *BufferOutSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ if (PendingBufferSize == 0 && BufferIn != NULL && BufferInSize != 0) {
+ Ret = BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
+ if (Ret != (INTN) BufferInSize) {
+ return EFI_ABORTED;
+ }
+
+ TempBuffer = (UINT8 *) OPENSSL_malloc (MAX_BUFFER_SIZE);
+
+ //
+ // ssl3_send_alert() will be called in ssl3_read_bytes() function.
+ // TempBuffer is invalid since it's a Alert message, so just ignore it.
+ //
+ SSL_read (TlsConn->Ssl, TempBuffer, MAX_BUFFER_SIZE);
+
+ OPENSSL_free (TempBuffer);
+
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ }
+
+ if (PendingBufferSize > *BufferOutSize) {
+ *BufferOutSize = PendingBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (PendingBufferSize > 0) {
+ *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32) PendingBufferSize);
+ } else {
+ *BufferOutSize = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Build the CloseNotify packet.
+
+ @param[in] Tls Pointer to the TLS object for state checking.
+ @param[in, out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ Tls is NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseNotify (
+ IN VOID *Tls,
+ IN OUT UINT8 *Buffer,
+ IN OUT UINTN *BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINTN PendingBufferSize;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ PendingBufferSize = 0;
+
+ if (TlsConn == NULL || \
+ TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio == NULL || \
+ BufferSize == NULL || \
+ (Buffer == NULL && *BufferSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ if (PendingBufferSize == 0) {
+ //
+ // ssl3_send_alert() and ssl3_dispatch_alert() function will be called.
+ //
+ SSL_shutdown (TlsConn->Ssl);
+ PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
+ }
+
+ if (PendingBufferSize > *BufferSize) {
+ *BufferSize = PendingBufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (PendingBufferSize > 0) {
+ *BufferSize = BIO_read (TlsConn->OutBio, Buffer, (UINT32) PendingBufferSize);
+ } else {
+ *BufferSize = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Attempts to read bytes from one TLS object and places the data in Buffer.
+
+ This function will attempt to read BufferSize bytes from the TLS object
+ and places the data in Buffer.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in,out] Buffer Pointer to the buffer to store the data.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The amount of data successfully read from the TLS object.
+ @retval <=0 No data was successfully read.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficOut (
+ IN VOID *Tls,
+ IN OUT VOID *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->OutBio == 0) {
+ return -1;
+ }
+
+ //
+ // Read and return the amount of data from the BIO.
+ //
+ return BIO_read (TlsConn->OutBio, Buffer, (UINT32) BufferSize);
+}
+
+/**
+ Attempts to write data from the buffer to TLS object.
+
+ This function will attempt to write BufferSize bytes data from the Buffer
+ to the TLS object.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The amount of data successfully written to the TLS object.
+ @retval <=0 No data was successfully written.
+
+**/
+INTN
+EFIAPI
+TlsCtrlTrafficIn (
+ IN VOID *Tls,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->InBio == 0) {
+ return -1;
+ }
+
+ //
+ // Write and return the amount of data to the BIO.
+ //
+ return BIO_write (TlsConn->InBio, Buffer, (UINT32) BufferSize);
+}
+/**
+ Attempts to read bytes from the specified TLS connection into the buffer.
+
+ This function tries to read BufferSize bytes data from the specified TLS
+ connection into the Buffer.
+
+ @param[in] Tls Pointer to the TLS connection for data reading.
+ @param[in,out] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The read operation was successful, and return value is the
+ number of bytes actually read from the TLS connection.
+ @retval <=0 The read operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsRead (
+ IN VOID *Tls,
+ IN OUT VOID *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return -1;
+ }
+
+ //
+ // Read bytes from the specified TLS connection.
+ //
+ return SSL_read (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
+}
+
+/**
+ Attempts to write data to a TLS connection.
+
+ This function tries to write BufferSize bytes data from the Buffer into the
+ specified TLS connection.
+
+ @param[in] Tls Pointer to the TLS connection for data writing.
+ @param[in] Buffer Pointer to the data buffer.
+ @param[in] BufferSize The size of Buffer in bytes.
+
+ @retval >0 The write operation was successful, and return value is the
+ number of bytes actually written to the TLS connection.
+ @retval <=0 The write operation was not successful.
+
+**/
+INTN
+EFIAPI
+TlsWrite (
+ IN VOID *Tls,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *) Tls;
+ if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ return -1;
+ }
+
+ //
+ // Write bytes to the specified TLS connection.
+ //
+ return SSL_write (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
+}
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 04/10] CryptoPkg: Add new TlsLib library
2016-12-16 2:10 ` Ye, Ting
@ 2016-12-16 2:51 ` Wu, Jiaxin
0 siblings, 0 replies; 37+ messages in thread
From: Wu, Jiaxin @ 2016-12-16 2:51 UTC (permalink / raw)
To: Ye, Ting, edk2-devel@lists.01.org
Cc: Long, Qin, Fu, Siyuan, Zhang, Lubo, Thomas Palmer
> Some comments included as following:
>
> 1. In TlsGetHostPublicCert, line 1892:
> The status is set to EFI_NOT_FOUND but not returned. Does it make
> sense to update *DataSize in that case?
You are right, EFI_NOT_FOUND should be returned directly.
> 2. TlsDoHandshake uses EFI_PROTOCOL_ERROR but not record in function
> header.
> 3. TlsGetCurrentCompressionId uses EFI_UNSUPPROTED but not record in
> function header.
> 4. Typo in TlsHandeAlert, should be TlsHandleAlert? Please also update the
> function description.
It's the typo. Thanks for the correction.
>
> Others look good to me.
>
> Reviewed-by: Ye Ting <ting.ye@intel.com>
Thanks Ting, I will correct it before commit the patch.
>
> Thanks,
> Ting
>
>
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: Wednesday, December 14, 2016 3:34 PM
> To: edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Long, Qin <qin.long@intel.com>; Fu, Siyuan
> <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Thomas
> Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
> Subject: [Patch 04/10] CryptoPkg: Add new TlsLib library
>
> This patch is used to add new TlsLib library, which is wrapped
> over OpenSSL. The implementation provides TLS library functions
> for EFI TLS protocol and EFI TLS Configuration Protocol.
>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> CryptoPkg/CryptoPkg.dec | 4 +
> CryptoPkg/CryptoPkg.dsc | 1 +
> CryptoPkg/Include/Library/TlsLib.h | 785 +++++++++++++++++++++
> CryptoPkg/Library/TlsLib/InternalTlsLib.h | 35 +
> CryptoPkg/Library/TlsLib/TlsConfig.c | 1055
> +++++++++++++++++++++++++++++
> CryptoPkg/Library/TlsLib/TlsInit.c | 291 ++++++++
> CryptoPkg/Library/TlsLib/TlsLib.inf | 49 ++
> CryptoPkg/Library/TlsLib/TlsLib.uni | 19 +
> CryptoPkg/Library/TlsLib/TlsProcess.c | 461 +++++++++++++
> 9 files changed, 2700 insertions(+)
> create mode 100644 CryptoPkg/Include/Library/TlsLib.h
> create mode 100644 CryptoPkg/Library/TlsLib/InternalTlsLib.h
> create mode 100644 CryptoPkg/Library/TlsLib/TlsConfig.c
> create mode 100644 CryptoPkg/Library/TlsLib/TlsInit.c
> create mode 100644 CryptoPkg/Library/TlsLib/TlsLib.inf
> create mode 100644 CryptoPkg/Library/TlsLib/TlsLib.uni
> create mode 100644 CryptoPkg/Library/TlsLib/TlsProcess.c
>
> diff --git a/CryptoPkg/CryptoPkg.dec b/CryptoPkg/CryptoPkg.dec
> index 80579b7..eee26cb 100644
> --- a/CryptoPkg/CryptoPkg.dec
> +++ b/CryptoPkg/CryptoPkg.dec
> @@ -29,10 +29,14 @@
> [LibraryClasses]
> ## @libraryclass Provides basic library functions for cryptographic
> primitives.
> ##
> BaseCryptLib|Include/Library/BaseCryptLib.h
>
> + ## @libraryclass Provides TLS library functions for EFI TLS protocol.
> + ##
> + TlsLib|Include/Library/TlsLib.h
> +
> [Protocols]
> ## Include/Protocol/RuntimeCrypt.h
> gEfiRuntimeCryptProtocolGuid = { 0xe1475e0c, 0x1746, 0x4802, {0x86, 0x2e,
> 0x1, 0x1c, 0x2c, 0x2d, 0x9d, 0x86 }}
>
> [UserExtensions.TianoCore."ExtraFiles"]
> diff --git a/CryptoPkg/CryptoPkg.dsc b/CryptoPkg/CryptoPkg.dsc
> index 3c3e444..468e60b 100644
> --- a/CryptoPkg/CryptoPkg.dsc
> +++ b/CryptoPkg/CryptoPkg.dsc
> @@ -121,10 +121,11 @@
>
> ##########################################################
> #########################################
> [Components]
> CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
> CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> + CryptoPkg/Library/TlsLib/TlsLib.inf
>
> CryptoPkg/Application/Cryptest/Cryptest.inf
>
> CryptoPkg/CryptRuntimeDxe/CryptRuntimeDxe.inf
>
> diff --git a/CryptoPkg/Include/Library/TlsLib.h
> b/CryptoPkg/Include/Library/TlsLib.h
> new file mode 100644
> index 0000000..38b861e
> --- /dev/null
> +++ b/CryptoPkg/Include/Library/TlsLib.h
> @@ -0,0 +1,785 @@
> +/** @file
> + Defines TLS Library APIs.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __TLS_LIB_H__
> +#define __TLS_LIB_H__
> +
> +/**
> + Initializes the OpenSSL library.
> +
> + This function registers ciphers and digests used directly and indirectly
> + by SSL/TLS, and initializes the readable error messages.
> + This function must be called before any other action takes places.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsInitialize (
> + VOID
> + );
> +
> +/**
> + Free an allocated SSL_CTX object.
> +
> + @param[in] TlsCtx Pointer to the SSL_CTX object to be released.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsCtxFree (
> + IN VOID *TlsCtx
> + );
> +
> +/**
> + Creates a new SSL_CTX object as framework to establish TLS/SSL enabled
> + connections.
> +
> + @param[in] MajorVer Major Version of TLS/SSL Protocol.
> + @param[in] MinorVer Minor Version of TLS/SSL Protocol.
> +
> + @return Pointer to an allocated SSL_CTX object.
> + If the creation failed, TlsCtxNew() returns NULL.
> +
> +**/
> +VOID *
> +EFIAPI
> +TlsCtxNew (
> + IN UINT8 MajorVer,
> + IN UINT8 MinorVer
> + );
> +
> +/**
> + Free an allocated TLS object.
> +
> + This function removes the TLS object pointed to by Tls and frees up the
> + allocated memory. If Tls is NULL, nothing is done.
> +
> + @param[in] Tls Pointer to the TLS object to be freed.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsFree (
> + IN VOID *Tls
> + );
> +
> +/**
> + Create a new TLS object for a connection.
> +
> + This function creates a new TLS object for a connection. The new object
> + inherits the setting of the underlying context TlsCtx: connection method,
> + options, verification setting.
> +
> + @param[in] TlsCtx Pointer to the SSL_CTX object.
> +
> + @return Pointer to an allocated SSL object.
> + If the creation failed, TlsNew() returns NULL.
> +
> +**/
> +VOID *
> +EFIAPI
> +TlsNew (
> + IN VOID *TlsCtx
> + );
> +
> +/**
> + Checks if the TLS handshake was done.
> +
> + This function will check if the specified TLS handshake was done.
> +
> + @param[in] Tls Pointer to the TLS object for handshake state checking.
> +
> + @retval TRUE The TLS handshake was done.
> + @retval FALSE The TLS handshake was not done.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +TlsInHandshake (
> + IN VOID *Tls
> + );
> +
> +/**
> + Perform a TLS/SSL handshake.
> +
> + This function will perform a TLS/SSL handshake.
> +
> + @param[in] Tls Pointer to the TLS object for handshake operation.
> + @param[in] BufferIn Pointer to the most recently received TLS
> Handshake packet.
> + @param[in] BufferInSize Packet size in bytes for the most recently
> received TLS
> + Handshake packet.
> + @param[out] BufferOut Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On
> input, it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + Tls is NULL.
> + BufferIn is NULL but BufferInSize is NOT 0.
> + BufferInSize is 0 but BufferIn is NOT NULL.
> + BufferOutSize is NULL.
> + BufferOut is NULL if *BufferOutSize is not zero.
> + @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the
> response packet.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsDoHandshake (
> + IN VOID *Tls,
> + IN UINT8 *BufferIn, OPTIONAL
> + IN UINTN BufferInSize, OPTIONAL
> + OUT UINT8 *BufferOut, OPTIONAL
> + IN OUT UINTN *BufferOutSize
> + );
> +
> +/**
> + Hande Alert message recorded in BufferIn. If BufferIn is NULL and
> BufferInSize is zero,
> + TLS session has errors and the response packet needs to be Alert message
> based on error type.
> +
> + @param[in] Tls Pointer to the TLS object for state checking.
> + @param[in] BufferIn Pointer to the most recently received TLS Alert
> packet.
> + @param[in] BufferInSize Packet size in bytes for the most recently
> received TLS
> + Alert packet.
> + @param[out] BufferOut Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On
> input, it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + Tls is NULL.
> + BufferIn is NULL but BufferInSize is NOT 0.
> + BufferInSize is 0 but BufferIn is NOT NULL.
> + BufferOutSize is NULL.
> + BufferOut is NULL if *BufferOutSize is not zero.
> + @retval EFI_ABORTED An error occurred.
> + @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the
> response packet.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsHandeAlert (
> + IN VOID *Tls,
> + IN UINT8 *BufferIn, OPTIONAL
> + IN UINTN BufferInSize, OPTIONAL
> + OUT UINT8 *BufferOut, OPTIONAL
> + IN OUT UINTN *BufferOutSize
> + );
> +
> +/**
> + Build the CloseNotify packet.
> +
> + @param[in] Tls Pointer to the TLS object for state checking.
> + @param[in, out] Buffer Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferSize Pointer to the buffer size in bytes. On input,
> it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + Tls is NULL.
> + BufferSize is NULL.
> + Buffer is NULL if *BufferSize is not zero.
> + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the
> response packet.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCloseNotify (
> + IN VOID *Tls,
> + IN OUT UINT8 *Buffer,
> + IN OUT UINTN *BufferSize
> + );
> +
> +/**
> + Attempts to read bytes from one TLS object and places the data in Buffer.
> +
> + This function will attempt to read BufferSize bytes from the TLS object
> + and places the data in Buffer.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] Buffer Pointer to the buffer to store the data.
> + @param[in] BufferSize The size of Buffer in bytes.
> +
> + @retval >0 The amount of data successfully read from the TLS object.
> + @retval <=0 No data was successfully read.
> +
> +**/
> +INTN
> +EFIAPI
> +TlsCtrlTrafficOut (
> + IN VOID *Tls,
> + IN OUT VOID *Buffer,
> + IN UINTN BufferSize
> + );
> +
> +/**
> + Attempts to write data from the buffer to TLS object.
> +
> + This function will attempt to write BufferSize bytes data from the Buffer
> + to the TLS object.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] Buffer Pointer to the data buffer.
> + @param[in] BufferSize The size of Buffer in bytes.
> +
> + @retval >0 The amount of data successfully written to the TLS object.
> + @retval <=0 No data was successfully written.
> +
> +**/
> +INTN
> +EFIAPI
> +TlsCtrlTrafficIn (
> + IN VOID *Tls,
> + IN VOID *Buffer,
> + IN UINTN BufferSize
> + );
> +
> +/**
> + Attempts to read bytes from the specified TLS connection into the buffer.
> +
> + This function tries to read BufferSize bytes data from the specified TLS
> + connection into the Buffer.
> +
> + @param[in] Tls Pointer to the TLS connection for data reading.
> + @param[in,out] Buffer Pointer to the data buffer.
> + @param[in] BufferSize The size of Buffer in bytes.
> +
> + @retval >0 The read operation was successful, and return value is the
> + number of bytes actually read from the TLS connection.
> + @retval <=0 The read operation was not successful.
> +
> +**/
> +INTN
> +EFIAPI
> +TlsRead (
> + IN VOID *Tls,
> + IN OUT VOID *Buffer,
> + IN UINTN BufferSize
> + );
> +
> +/**
> + Attempts to write data to a TLS connection.
> +
> + This function tries to write BufferSize bytes data from the Buffer into the
> + specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS connection for data writing.
> + @param[in] Buffer Pointer to the data buffer.
> + @param[in] BufferSize The size of Buffer in bytes.
> +
> + @retval >0 The write operation was successful, and return value is the
> + number of bytes actually written to the TLS connection.
> + @retval <=0 The write operation was not successful.
> +
> +**/
> +INTN
> +EFIAPI
> +TlsWrite (
> + IN VOID *Tls,
> + IN VOID *Buffer,
> + IN UINTN BufferSize
> + );
> +
> +/**
> + Set a new TLS/SSL method for a particular TLS object.
> +
> + This function sets a new TLS/SSL method for a particular TLS object.
> +
> + @param[in] Tls Pointer to a TLS object.
> + @param[in] MajorVer Major Version of TLS/SSL Protocol.
> + @param[in] MinorVer Minor Version of TLS/SSL Protocol.
> +
> + @retval EFI_SUCCESS The TLS/SSL method was set successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Unsupported TLS/SSL method.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetVersion (
> + IN VOID *Tls,
> + IN UINT8 MajorVer,
> + IN UINT8 MinorVer
> + );
> +
> +/**
> + Set TLS object to work in client or server mode.
> +
> + This function prepares a TLS object to work in client or server mode.
> +
> + @param[in] Tls Pointer to a TLS object.
> + @param[in] IsServer Work in server mode.
> +
> + @retval EFI_SUCCESS The TLS/SSL work mode was set successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Unsupported TLS/SSL work mode.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetConnectionEnd (
> + IN VOID *Tls,
> + IN BOOLEAN IsServer
> + );
> +
> +/**
> + Set the ciphers list to be used by the TLS object.
> +
> + This function sets the ciphers for use by a specified TLS object.
> +
> + @param[in] Tls Pointer to a TLS object.
> + @param[in] CipherId Pointer to a string that contains one or more
> + ciphers separated by a colon.
> + @param[in] CipherNum The number of cipher in the list.
> +
> + @retval EFI_SUCCESS The ciphers list was set successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Unsupported TLS cipher in the list.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetCipherList (
> + IN VOID *Tls,
> + IN UINT16 *CipherId,
> + IN UINTN CipherNum
> + );
> +
> +/**
> + Set the compression method for TLS/SSL operations.
> +
> + This function handles TLS/SSL integrated compression methods.
> +
> + @param[in] CompMethod The compression method ID.
> +
> + @retval EFI_SUCCESS The compression method for the communication
> was
> + set successfully.
> + @retval EFI_UNSUPPORTED Unsupported compression method.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetCompressionMethod (
> + IN UINT8 CompMethod
> + );
> +
> +/**
> + Set peer certificate verification mode for the TLS connection.
> +
> + This function sets the verification mode flags for the TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] VerifyMode A set of logically or'ed verification mode flags.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsSetVerify (
> + IN VOID *Tls,
> + IN UINT32 VerifyMode
> + );
> +
> +/**
> + Sets a TLS/SSL session ID to be used during TLS/SSL connect.
> +
> + This function sets a session ID to be used when the TLS/SSL connection is
> + to be established.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] SessionId Session ID data used for session resumption.
> + @param[in] SessionIdLen Length of Session ID in bytes.
> +
> + @retval EFI_SUCCESS Session ID was set successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED No available session for ID setting.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetSessionId (
> + IN VOID *Tls,
> + IN UINT8 *SessionId,
> + IN UINT16 SessionIdLen
> + );
> +
> +/**
> + Adds the CA to the cert store when requesting Server or Client
> authentication.
> +
> + This function adds the CA certificate to the list of CAs when requesting
> + Server or Client authentication for the chosen TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] Data Pointer to the data buffer of a DER-encoded binary
> + X.509 certificate or PEM-encoded X.509 certificate.
> + @param[in] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_OUT_OF_RESOURCES Required resources could not be
> allocated.
> + @retval EFI_ABORTED Invalid X.509 certificate.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetCaCertificate (
> + IN VOID *Tls,
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Loads the local public certificate into the specified TLS object.
> +
> + This function loads the X.509 certificate into the specified TLS object
> + for TLS negotiation.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] Data Pointer to the data buffer of a DER-encoded binary
> + X.509 certificate or PEM-encoded X.509 certificate.
> + @param[in] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_OUT_OF_RESOURCES Required resources could not be
> allocated.
> + @retval EFI_ABORTED Invalid X.509 certificate.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetHostPublicCert (
> + IN VOID *Tls,
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Adds the local private key to the specified TLS object.
> +
> + This function adds the local private key (PEM-encoded RSA or PKCS#8
> private
> + key) into the specified TLS object for TLS negotiation.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] Data Pointer to the data buffer of a PEM-encoded RSA
> + or PKCS#8 private key.
> + @param[in] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_ABORTED Invalid private key data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetHostPrivateKey (
> + IN VOID *Tls,
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Adds the CA-supplied certificate revocation list for certificate validation.
> +
> + This function adds the CA-supplied certificate revocation list data for
> + certificate validity checking.
> +
> + @param[in] Data Pointer to the data buffer of a DER-encoded CRL data.
> + @param[in] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_ABORTED Invalid CRL data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetCertRevocationList (
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Gets the protocol version used by the specified TLS connection.
> +
> + This function returns the protocol version used by the specified TLS
> + connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> +
> + @return The protocol version of the specified TLS connection.
> +
> +**/
> +UINT16
> +EFIAPI
> +TlsGetVersion (
> + IN VOID *Tls
> + );
> +
> +/**
> + Gets the connection end of the specified TLS connection.
> +
> + This function returns the connection end (as client or as server) used by
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> +
> + @return The connection end used by the specified TLS connection.
> +
> +**/
> +UINT8
> +EFIAPI
> +TlsGetConnectionEnd (
> + IN VOID *Tls
> + );
> +
> +/**
> + Gets the cipher suite used by the specified TLS connection.
> +
> + This function returns current cipher suite used by the specified
> + TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] CipherId The cipher suite used by the TLS object.
> +
> + @retval EFI_SUCCESS The cipher suite was returned successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Unsupported cipher suite.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetCurrentCipher (
> + IN VOID *Tls,
> + IN OUT UINT16 *CipherId
> + );
> +
> +/**
> + Gets the compression methods used by the specified TLS connection.
> +
> + This function returns current integrated compression methods used by
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] CompressionId The current compression method used
> by
> + the TLS object.
> +
> + @retval EFI_SUCCESS The compression method was returned
> successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_ABORTED Invalid Compression method.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetCurrentCompressionId (
> + IN VOID *Tls,
> + IN OUT UINT8 *CompressionId
> + );
> +
> +/**
> + Gets the verification mode currently set in the TLS connection.
> +
> + This function returns the peer verification mode currently set in the
> + specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> +
> + @return The verification mode set in the specified TLS connection.
> +
> +**/
> +UINT32
> +EFIAPI
> +TlsGetVerify (
> + IN VOID *Tls
> + );
> +
> +/**
> + Gets the session ID used by the specified TLS connection.
> +
> + This function returns the TLS/SSL session ID currently used by the
> + specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] SessionId Buffer to contain the returned session ID.
> + @param[in,out] SessionIdLen The length of Session ID in bytes.
> +
> + @retval EFI_SUCCESS The Session ID was returned successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetSessionId (
> + IN VOID *Tls,
> + IN OUT UINT8 *SessionId,
> + IN OUT UINT16 *SessionIdLen
> + );
> +
> +/**
> + Gets the client random data used in the specified TLS connection.
> +
> + This function returns the TLS/SSL client random data currently used in
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] ClientRandom Buffer to contain the returned client
> + random data (32 bytes).
> +
> +**/
> +VOID
> +EFIAPI
> +TlsGetClientRandom (
> + IN VOID *Tls,
> + IN OUT UINT8 *ClientRandom
> + );
> +
> +/**
> + Gets the server random data used in the specified TLS connection.
> +
> + This function returns the TLS/SSL server random data currently used in
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] ServerRandom Buffer to contain the returned server
> + random data (32 bytes).
> +
> +**/
> +VOID
> +EFIAPI
> +TlsGetServerRandom (
> + IN VOID *Tls,
> + IN OUT UINT8 *ServerRandom
> + );
> +
> +/**
> + Gets the master key data used in the specified TLS connection.
> +
> + This function returns the TLS/SSL master key material currently used in
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] KeyMaterial Buffer to contain the returned key material.
> +
> + @retval EFI_SUCCESS Key material was returned successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetKeyMaterial (
> + IN VOID *Tls,
> + IN OUT UINT8 *KeyMaterial
> + );
> +
> +/**
> + Gets the CA Certificate from the cert store.
> +
> + This function returns the CA certificate for the chosen
> + TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[out] Data Pointer to the data buffer to receive the CA
> + certificate data sent to the client.
> + @param[in,out] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetCaCertificate (
> + IN VOID *Tls,
> + OUT VOID *Data,
> + IN OUT UINTN *DataSize
> + );
> +
> +/**
> + Gets the local public Certificate set in the specified TLS object.
> +
> + This function returns the local public certificate which was currently set
> + in the specified TLS object.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[out] Data Pointer to the data buffer to receive the local
> + public certificate.
> + @param[in,out] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_NOT_FOUND The certificate is not found.
> + @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetHostPublicCert (
> + IN VOID *Tls,
> + OUT VOID *Data,
> + IN OUT UINTN *DataSize
> + );
> +
> +/**
> + Gets the local private key set in the specified TLS object.
> +
> + This function returns the local private key data which was currently set
> + in the specified TLS object.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[out] Data Pointer to the data buffer to receive the local
> + private key data.
> + @param[in,out] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetHostPrivateKey (
> + IN VOID *Tls,
> + OUT VOID *Data,
> + IN OUT UINTN *DataSize
> + );
> +
> +/**
> + Gets the CA-supplied certificate revocation list data set in the specified
> + TLS object.
> +
> + This function returns the CA-supplied certificate revocation list data which
> + was currently set in the specified TLS object.
> +
> + @param[out] Data Pointer to the data buffer to receive the CRL data.
> + @param[in,out] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetCertRevocationList (
> + OUT VOID *Data,
> + IN OUT UINTN *DataSize
> + );
> +
> +#endif // __TLS_LIB_H__
> diff --git a/CryptoPkg/Library/TlsLib/InternalTlsLib.h
> b/CryptoPkg/Library/TlsLib/InternalTlsLib.h
> new file mode 100644
> index 0000000..2438de9
> --- /dev/null
> +++ b/CryptoPkg/Library/TlsLib/InternalTlsLib.h
> @@ -0,0 +1,35 @@
> +/** @file
> + Internal include file for TlsLib.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include <Library/BaseCryptLib.h>
> +#include <openssl/ssl.h>
> +#include <openssl/bio.h>
> +#include <openssl/err.h>
> +
> +typedef struct {
> + //
> + // Main SSL Connection which is created by a server or a client
> + // per established connection.
> + //
> + SSL *Ssl;
> + //
> + // Memory BIO for the TLS/SSL Reading operations.
> + //
> + BIO *InBio;
> + //
> + // Memory BIO for the TLS/SSL Writing operations.
> + //
> + BIO *OutBio;
> +} TLS_CONNECTION;
> +
> diff --git a/CryptoPkg/Library/TlsLib/TlsConfig.c
> b/CryptoPkg/Library/TlsLib/TlsConfig.c
> new file mode 100644
> index 0000000..31220b3
> --- /dev/null
> +++ b/CryptoPkg/Library/TlsLib/TlsConfig.c
> @@ -0,0 +1,1055 @@
> +/** @file
> + SSL/TLS Configuration Library Wrapper Implementation over OpenSSL.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "InternalTlsLib.h"
> +
> +typedef struct {
> + //
> + // IANA/IETF defined Cipher Suite ID
> + //
> + UINT16 IanaCipher;
> + //
> + // OpenSSL-used Cipher Suite String
> + //
> + CONST CHAR8 *OpensslCipher;
> +} TLS_CIPHER_PAIR;
> +
> +//
> +// The mapping table between IANA/IETF Cipher Suite definitions and
> +// OpenSSL-used Cipher Suite name.
> +//
> +STATIC CONST TLS_CIPHER_PAIR TlsCipherMappingTable[] = {
> + { 0x0001, "NULL-MD5" }, /// TLS_RSA_WITH_NULL_MD5
> + { 0x0002, "NULL-SHA" }, /// TLS_RSA_WITH_NULL_SHA
> + { 0x0004, "RC4-MD5" }, /// TLS_RSA_WITH_RC4_128_MD5
> + { 0x0005, "RC4-SHA" }, /// TLS_RSA_WITH_RC4_128_SHA
> + { 0x000A, "DES-CBC3-SHA" }, ///
> TLS_RSA_WITH_3DES_EDE_CBC_SHA, mandatory TLS 1.1
> + { 0x0016, "DHE-RSA-DES-CBC3-SHA" }, ///
> TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
> + { 0x002F, "AES128-SHA" }, /// TLS_RSA_WITH_AES_128_CBC_SHA,
> mandatory TLS 1.2
> + { 0x0030, "DH-DSS-AES128-SHA" }, ///
> TLS_DH_DSS_WITH_AES_128_CBC_SHA
> + { 0x0031, "DH-RSA-AES128-SHA" }, ///
> TLS_DH_RSA_WITH_AES_128_CBC_SHA
> + { 0x0033, "DHE-RSA-AES128-SHA" }, ///
> TLS_DHE_RSA_WITH_AES_128_CBC_SHA
> + { 0x0035, "AES256-SHA" }, /// TLS_RSA_WITH_AES_256_CBC_SHA
> + { 0x0036, "DH-DSS-AES256-SHA" }, ///
> TLS_DH_DSS_WITH_AES_256_CBC_SHA
> + { 0x0037, "DH-RSA-AES256-SHA" }, ///
> TLS_DH_RSA_WITH_AES_256_CBC_SHA
> + { 0x0039, "DHE-RSA-AES256-SHA" }, ///
> TLS_DHE_RSA_WITH_AES_256_CBC_SHA
> + { 0x003B, "NULL-SHA256" }, /// TLS_RSA_WITH_NULL_SHA256
> + { 0x003C, "AES128-SHA256" }, ///
> TLS_RSA_WITH_AES_128_CBC_SHA256
> + { 0x003D, "AES256-SHA256" }, ///
> TLS_RSA_WITH_AES_256_CBC_SHA256
> + { 0x003E, "DH-DSS-AES128-SHA256" }, ///
> TLS_DH_DSS_WITH_AES_128_CBC_SHA256
> + { 0x003F, "DH-RSA-AES128-SHA256" }, ///
> TLS_DH_RSA_WITH_AES_128_CBC_SHA256
> + { 0x0067, "DHE-RSA-AES128-SHA256" }, ///
> TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
> + { 0x0068, "DH-DSS-AES256-SHA256" }, ///
> TLS_DH_DSS_WITH_AES_256_CBC_SHA256
> + { 0x0069, "DH-RSA-AES256-SHA256" }, ///
> TLS_DH_RSA_WITH_AES_256_CBC_SHA256
> + { 0x006B, "DHE-RSA-AES256-SHA256" } ///
> TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
> +};
> +
> +/**
> + Gets the OpenSSL cipher suite string for the supplied IANA TLS cipher suite.
> +
> + @param[in] CipherId The supplied IANA TLS cipher suite ID.
> +
> + @return The corresponding OpenSSL cipher suite string if found,
> + NULL otherwise.
> +
> +**/
> +STATIC
> +CONST CHAR8 *
> +TlsGetCipherString (
> + IN UINT16 CipherId
> + )
> +{
> + CONST TLS_CIPHER_PAIR *CipherEntry;
> + UINTN TableSize;
> + UINTN Index;
> +
> + CipherEntry = TlsCipherMappingTable;
> + TableSize = sizeof (TlsCipherMappingTable) / sizeof (TLS_CIPHER_PAIR);
> +
> + //
> + // Search Cipher Mapping Table for IANA-OpenSSL Cipher Translation
> + //
> + for (Index = 0; Index < TableSize; Index++, CipherEntry++) {
> + //
> + // Translate IANA cipher suite name to OpenSSL name.
> + //
> + if (CipherEntry->IanaCipher == CipherId) {
> + return CipherEntry->OpensslCipher;
> + }
> + }
> +
> + //
> + // No Cipher Mapping found, return NULL.
> + //
> + return NULL;
> +}
> +
> +/**
> + Set a new TLS/SSL method for a particular TLS object.
> +
> + This function sets a new TLS/SSL method for a particular TLS object.
> +
> + @param[in] Tls Pointer to a TLS object.
> + @param[in] MajorVer Major Version of TLS/SSL Protocol.
> + @param[in] MinorVer Minor Version of TLS/SSL Protocol.
> +
> + @retval EFI_SUCCESS The TLS/SSL method was set successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Unsupported TLS/SSL method.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetVersion (
> + IN VOID *Tls,
> + IN UINT8 MajorVer,
> + IN UINT8 MinorVer
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + UINT16 ProtoVersion;
> +
> + TlsConn = (TLS_CONNECTION *)Tls;
> + if (TlsConn == NULL || TlsConn->Ssl == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + ProtoVersion = (MajorVer << 8) | MinorVer;
> +
> + switch (ProtoVersion) {
> + case TLS1_VERSION:
> + //
> + // TLS 1.0
> + //
> + SSL_set_ssl_method (TlsConn->Ssl, TLSv1_method ());
> + break;
> + case TLS1_1_VERSION:
> + //
> + // TLS 1.1
> + //
> + SSL_set_ssl_method (TlsConn->Ssl, TLSv1_1_method ());
> + break;
> + case TLS1_2_VERSION:
> + //
> + // TLS 1.2
> + //
> + SSL_set_ssl_method (TlsConn->Ssl, TLSv1_2_method ());
> + break;
> + default:
> + //
> + // Unsupported Protocol Version
> + //
> + return EFI_UNSUPPORTED;
> + }
> +
> + return EFI_SUCCESS;;
> +}
> +
> +/**
> + Set TLS object to work in client or server mode.
> +
> + This function prepares a TLS object to work in client or server mode.
> +
> + @param[in] Tls Pointer to a TLS object.
> + @param[in] IsServer Work in server mode.
> +
> + @retval EFI_SUCCESS The TLS/SSL work mode was set successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Unsupported TLS/SSL work mode.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetConnectionEnd (
> + IN VOID *Tls,
> + IN BOOLEAN IsServer
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + if (TlsConn == NULL || TlsConn->Ssl == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (!IsServer) {
> + //
> + // Set TLS to work in Client mode.
> + //
> + SSL_set_connect_state (TlsConn->Ssl);
> + } else {
> + //
> + // Set TLS to work in Server mode.
> + // It is unsupported for UEFI version currently.
> + //
> + //SSL_set_accept_state (TlsConn->Ssl);
> + return EFI_UNSUPPORTED;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Set the ciphers list to be used by the TLS object.
> +
> + This function sets the ciphers for use by a specified TLS object.
> +
> + @param[in] Tls Pointer to a TLS object.
> + @param[in] CipherId Pointer to a UINT16 cipher Id.
> + @param[in] CipherNum The number of cipher in the list.
> +
> + @retval EFI_SUCCESS The ciphers list was set successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Unsupported TLS cipher in the list.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetCipherList (
> + IN VOID *Tls,
> + IN UINT16 *CipherId,
> + IN UINTN CipherNum
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + UINTN Index;
> + CONST CHAR8 *MappingName;
> + CHAR8 CipherString[500];
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + MappingName = NULL;
> +
> + memset (CipherString, 0, sizeof (CipherString));
> +
> + for (Index = 0; Index < CipherNum; Index++) {
> + //
> + // Handling OpenSSL / RFC Cipher name mapping.
> + //
> + MappingName = TlsGetCipherString (*(CipherId + Index));
> + if (MappingName == NULL) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + if (Index != 0) {
> + //
> + // The ciphers were separated by a colon.
> + //
> + AsciiStrCatS (CipherString, sizeof (CipherString), ":");
> + }
> +
> + AsciiStrCatS (CipherString, sizeof (CipherString), MappingName);
> + }
> +
> + AsciiStrCatS (CipherString, sizeof (CipherString), ":@STRENGTH");
> +
> + //
> + // Sets the ciphers for use by the Tls object.
> + //
> + if (SSL_set_cipher_list (TlsConn->Ssl, CipherString) <= 0) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Set the compression method for TLS/SSL operations.
> +
> + This function handles TLS/SSL integrated compression methods.
> +
> + @param[in] CompMethod The compression method ID.
> +
> + @retval EFI_SUCCESS The compression method for the communication
> was
> + set successfully.
> + @retval EFI_UNSUPPORTED Unsupported compression method.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetCompressionMethod (
> + IN UINT8 CompMethod
> + )
> +{
> + COMP_METHOD *Cm;
> + INTN Ret;
> +
> + Cm = NULL;
> + Ret = 0;
> +
> + if (CompMethod == 0) {
> + //
> + // TLS defines one standard compression method,
> CompressionMethod.null (0),
> + // which specifies that data exchanged via the record protocol will not be
> compressed.
> + // So, return EFI_SUCCESS directly (RFC 3749).
> + //
> + return EFI_SUCCESS;
> + } else if (CompMethod == 1) {
> + Cm = COMP_zlib();
> + } else {
> + return EFI_UNSUPPORTED;
> + }
> +
> + //
> + // Adds the compression method to the list of available
> + // compression methods.
> + //
> + Ret = SSL_COMP_add_compression_method (CompMethod, Cm);
> + if (Ret != 0) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Set peer certificate verification mode for the TLS connection.
> +
> + This function sets the verification mode flags for the TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] VerifyMode A set of logically or'ed verification mode flags.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsSetVerify (
> + IN VOID *Tls,
> + IN UINT32 VerifyMode
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + if (TlsConn == NULL || TlsConn->Ssl == NULL) {
> + return;
> + }
> +
> + //
> + // Set peer certificate verification parameters with NULL callback.
> + //
> + SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL);
> +}
> +
> +/**
> + Sets a TLS/SSL session ID to be used during TLS/SSL connect.
> +
> + This function sets a session ID to be used when the TLS/SSL connection is
> + to be established.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] SessionId Session ID data used for session resumption.
> + @param[in] SessionIdLen Length of Session ID in bytes.
> +
> + @retval EFI_SUCCESS Session ID was set successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED No available session for ID setting.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetSessionId (
> + IN VOID *Tls,
> + IN UINT8 *SessionId,
> + IN UINT16 SessionIdLen
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + SSL_SESSION *Session;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + Session = NULL;
> +
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Session = SSL_get_session (TlsConn->Ssl);
> + if (Session == NULL) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + Session->session_id_length = SessionIdLen;
> + CopyMem (Session->session_id, SessionId, Session->session_id_length);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Adds the CA to the cert store when requesting Server or Client
> authentication.
> +
> + This function adds the CA certificate to the list of CAs when requesting
> + Server or Client authentication for the chosen TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] Data Pointer to the data buffer of a DER-encoded binary
> + X.509 certificate or PEM-encoded X.509 certificate.
> + @param[in] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_OUT_OF_RESOURCES Required resources could not be
> allocated.
> + @retval EFI_ABORTED Invalid X.509 certificate.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetCaCertificate (
> + IN VOID *Tls,
> + IN VOID *Data,
> + IN UINTN DataSize
> + )
> +{
> + BIO *BioCert;
> + X509 *Cert;
> + X509_STORE *X509Store;
> + EFI_STATUS Status;
> + TLS_CONNECTION *TlsConn;
> + SSL_CTX *SslCtx;
> + INTN Ret;
> + unsigned long ErrorCode;
> +
> + BioCert = NULL;
> + Cert = NULL;
> + X509Store = NULL;
> + Status = EFI_SUCCESS;
> + TlsConn = (TLS_CONNECTION *) Tls;
> + Ret = 0;
> +
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize
> == 0) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
> + // Determine whether certificate is from DER encoding, if so, translate it to
> X509 structure.
> + //
> + Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
> + if (Cert == NULL) {
> + //
> + // Certificate is from PEM encoding.
> + //
> + BioCert = BIO_new (BIO_s_mem ());
> + if (BioCert == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> +
> + Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
> + if (Cert == NULL) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> + }
> +
> + SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);
> + X509Store = SSL_CTX_get_cert_store (SslCtx);
> + if (X509Store == NULL) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Add certificate to X509 store
> + //
> + Ret = X509_STORE_add_cert (X509Store, Cert);
> + if (Ret != 1) {
> + ErrorCode = ERR_peek_last_error ();
> + //
> + // Ignore "already in table" errors
> + //
> + if (!(ERR_GET_FUNC (ErrorCode) == X509_F_X509_STORE_ADD_CERT &&
> + ERR_GET_REASON (ErrorCode) ==
> X509_R_CERT_ALREADY_IN_HASH_TABLE)) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> + }
> +
> +ON_EXIT:
> + if (BioCert != NULL) {
> + BIO_free (BioCert);
> + }
> +
> + if (Cert != NULL) {
> + X509_free (Cert);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Loads the local public certificate into the specified TLS object.
> +
> + This function loads the X.509 certificate into the specified TLS object
> + for TLS negotiation.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] Data Pointer to the data buffer of a DER-encoded binary
> + X.509 certificate or PEM-encoded X.509 certificate.
> + @param[in] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_OUT_OF_RESOURCES Required resources could not be
> allocated.
> + @retval EFI_ABORTED Invalid X.509 certificate.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetHostPublicCert (
> + IN VOID *Tls,
> + IN VOID *Data,
> + IN UINTN DataSize
> + )
> +{
> + BIO *BioCert;
> + X509 *Cert;
> + EFI_STATUS Status;
> + TLS_CONNECTION *TlsConn;
> +
> + BioCert = NULL;
> + Cert = NULL;
> + Status = EFI_SUCCESS;
> + TlsConn = (TLS_CONNECTION *) Tls;
> +
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize
> == 0) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // DER-encoded binary X.509 certificate or PEM-encoded X.509 certificate.
> + // Determine whether certificate is from DER encoding, if so, translate it to
> X509 structure.
> + //
> + Cert = d2i_X509 (NULL, (const unsigned char ** )&Data, (long) DataSize);
> + if (Cert == NULL) {
> + //
> + // Certificate is from PEM encoding.
> + //
> + BioCert = BIO_new (BIO_s_mem ());
> + if (BioCert == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> +
> + Cert = PEM_read_bio_X509 (BioCert, NULL, NULL, NULL);
> + if (Cert == NULL) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> + }
> +
> + if (SSL_use_certificate (TlsConn->Ssl, Cert) != 1) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> +
> +ON_EXIT:
> + if (BioCert != NULL) {
> + BIO_free (BioCert);
> + }
> +
> + if (Cert != NULL) {
> + X509_free (Cert);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Adds the local private key to the specified TLS object.
> +
> + This function adds the local private key (PEM-encoded RSA or PKCS#8
> private
> + key) into the specified TLS object for TLS negotiation.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] Data Pointer to the data buffer of a PEM-encoded RSA
> + or PKCS#8 private key.
> + @param[in] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_ABORTED Invalid private key data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetHostPrivateKey (
> + IN VOID *Tls,
> + IN VOID *Data,
> + IN UINTN DataSize
> + )
> +{
> + return EFI_UNSUPPORTED;
> +}
> +
> +/**
> + Adds the CA-supplied certificate revocation list for certificate validation.
> +
> + This function adds the CA-supplied certificate revocation list data for
> + certificate validity checking.
> +
> + @param[in] Data Pointer to the data buffer of a DER-encoded CRL data.
> + @param[in] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_ABORTED Invalid CRL data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetCertRevocationList (
> + IN VOID *Data,
> + IN UINTN DataSize
> + )
> +{
> + return EFI_UNSUPPORTED;
> +}
> +
> +/**
> + Gets the protocol version used by the specified TLS connection.
> +
> + This function returns the protocol version used by the specified TLS
> + connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> +
> + @return The protocol version of the specified TLS connection.
> +
> +**/
> +UINT16
> +EFIAPI
> +TlsGetVersion (
> + IN VOID *Tls
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> +
> + ASSERT (TlsConn != NULL);
> +
> + return (UINT16)(SSL_version (TlsConn->Ssl));
> +}
> +
> +/**
> + Gets the connection end of the specified TLS connection.
> +
> + This function returns the connection end (as client or as server) used by
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> +
> + @return The connection end used by the specified TLS connection.
> +
> +**/
> +UINT8
> +EFIAPI
> +TlsGetConnectionEnd (
> + IN VOID *Tls
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> +
> + ASSERT (TlsConn != NULL);
> +
> + return (UINT8)SSL_is_server (TlsConn->Ssl);
> +}
> +
> +/**
> + Gets the cipher suite used by the specified TLS connection.
> +
> + This function returns current cipher suite used by the specified
> + TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] CipherId The cipher suite used by the TLS object.
> +
> + @retval EFI_SUCCESS The cipher suite was returned successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Unsupported cipher suite.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetCurrentCipher (
> + IN VOID *Tls,
> + IN OUT UINT16 *CipherId
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + CONST SSL_CIPHER *Cipher;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + Cipher = NULL;
> +
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Cipher = SSL_get_current_cipher (TlsConn->Ssl);
> + if (Cipher == NULL) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + *CipherId = (SSL_CIPHER_get_id (Cipher)) & 0xFFFF;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Gets the compression methods used by the specified TLS connection.
> +
> + This function returns current integrated compression methods used by
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] CompressionId The current compression method used
> by
> + the TLS object.
> +
> + @retval EFI_SUCCESS The compression method was returned
> successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_ABORTED Invalid Compression method.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetCurrentCompressionId (
> + IN VOID *Tls,
> + IN OUT UINT8 *CompressionId
> + )
> +{
> + return EFI_UNSUPPORTED;
> +}
> +
> +/**
> + Gets the verification mode currently set in the TLS connection.
> +
> + This function returns the peer verification mode currently set in the
> + specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> +
> + @return The verification mode set in the specified TLS connection.
> +
> +**/
> +UINT32
> +EFIAPI
> +TlsGetVerify (
> + IN VOID *Tls
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> +
> + ASSERT (TlsConn != NULL);
> +
> + return SSL_get_verify_mode (TlsConn->Ssl);
> +}
> +
> +/**
> + Gets the session ID used by the specified TLS connection.
> +
> + This function returns the TLS/SSL session ID currently used by the
> + specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] SessionId Buffer to contain the returned session ID.
> + @param[in,out] SessionIdLen The length of Session ID in bytes.
> +
> + @retval EFI_SUCCESS The Session ID was returned successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetSessionId (
> + IN VOID *Tls,
> + IN OUT UINT8 *SessionId,
> + IN OUT UINT16 *SessionIdLen
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + SSL_SESSION *Session;
> + CONST UINT8 *SslSessionId;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + Session = NULL;
> +
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL ||
> SessionIdLen == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Session = SSL_get_session (TlsConn->Ssl);
> + if (Session == NULL) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + SslSessionId = SSL_SESSION_get_id (Session, (unsigned int
> *)SessionIdLen);
> + CopyMem (SessionId, SslSessionId, *SessionIdLen);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Gets the client random data used in the specified TLS connection.
> +
> + This function returns the TLS/SSL client random data currently used in
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] ClientRandom Buffer to contain the returned client
> + random data (32 bytes).
> +
> +**/
> +VOID
> +EFIAPI
> +TlsGetClientRandom (
> + IN VOID *Tls,
> + IN OUT UINT8 *ClientRandom
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> +
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || ClientRandom == NULL) {
> + return;
> + }
> +
> + CopyMem (ClientRandom, TlsConn->Ssl->s3->client_random,
> SSL3_RANDOM_SIZE);
> +}
> +
> +/**
> + Gets the server random data used in the specified TLS connection.
> +
> + This function returns the TLS/SSL server random data currently used in
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] ServerRandom Buffer to contain the returned server
> + random data (32 bytes).
> +
> +**/
> +VOID
> +EFIAPI
> +TlsGetServerRandom (
> + IN VOID *Tls,
> + IN OUT UINT8 *ServerRandom
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> +
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || ServerRandom == NULL) {
> + return;
> + }
> +
> + CopyMem (ServerRandom, TlsConn->Ssl->s3->server_random,
> SSL3_RANDOM_SIZE);
> +}
> +
> +/**
> + Gets the master key data used in the specified TLS connection.
> +
> + This function returns the TLS/SSL master key material currently used in
> + the specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] KeyMaterial Buffer to contain the returned key material.
> +
> + @retval EFI_SUCCESS Key material was returned successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED Invalid TLS/SSL session.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetKeyMaterial (
> + IN VOID *Tls,
> + IN OUT UINT8 *KeyMaterial
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + SSL_SESSION *Session;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + Session = NULL;
> +
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || KeyMaterial == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Session = SSL_get_session (TlsConn->Ssl);
> +
> + if (Session == NULL) {
> + return EFI_UNSUPPORTED;
> + }
> +
> + CopyMem (KeyMaterial, Session->master_key, Session-
> >master_key_length);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Gets the CA Certificate from the cert store.
> +
> + This function returns the CA certificate for the chosen
> + TLS connection.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[out] Data Pointer to the data buffer to receive the CA
> + certificate data sent to the client.
> + @param[in,out] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetCaCertificate (
> + IN VOID *Tls,
> + OUT VOID *Data,
> + IN OUT UINTN *DataSize
> + )
> +{
> + return EFI_UNSUPPORTED;
> +}
> +
> +/**
> + Gets the local public Certificate set in the specified TLS object.
> +
> + This function returns the local public certificate which was currently set
> + in the specified TLS object.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[out] Data Pointer to the data buffer to receive the local
> + public certificate.
> + @param[in,out] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_NOT_FOUND The certificate is not found.
> + @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetHostPublicCert (
> + IN VOID *Tls,
> + OUT VOID *Data,
> + IN OUT UINTN *DataSize
> + )
> +{
> + X509 *Cert;
> + EFI_STATUS Status;
> + TLS_CONNECTION *TlsConn;
> +
> + Cert = NULL;
> + Status = EFI_SUCCESS;
> + TlsConn = (TLS_CONNECTION *) Tls;
> +
> + if (TlsConn == NULL || TlsConn->Ssl == NULL || DataSize == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Cert = SSL_get_certificate(TlsConn->Ssl);
> + if (Cert == NULL) {
> + Status = EFI_NOT_FOUND;
> + }
> +
> + //
> + // Only DER encoding is supported currently.
> + //
> + if (*DataSize < (UINTN) i2d_X509 (Cert, NULL)) {
> + *DataSize = (UINTN) i2d_X509 (Cert, NULL);
> + return EFI_BUFFER_TOO_SMALL;
> + }
> +
> + *DataSize = (UINTN) i2d_X509 (Cert, (unsigned char **) &Data);
> +
> + return Status;
> +}
> +
> +/**
> + Gets the local private key set in the specified TLS object.
> +
> + This function returns the local private key data which was currently set
> + in the specified TLS object.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[out] Data Pointer to the data buffer to receive the local
> + private key data.
> + @param[in,out] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetHostPrivateKey (
> + IN VOID *Tls,
> + OUT VOID *Data,
> + IN OUT UINTN *DataSize
> + )
> +{
> + return EFI_UNSUPPORTED;
> +}
> +
> +/**
> + Gets the CA-supplied certificate revocation list data set in the specified
> + TLS object.
> +
> + This function returns the CA-supplied certificate revocation list data which
> + was currently set in the specified TLS object.
> +
> + @param[out] Data Pointer to the data buffer to receive the CRL data.
> + @param[in,out] DataSize The size of data buffer in bytes.
> +
> + @retval EFI_SUCCESS The operation succeeded.
> + @retval EFI_UNSUPPORTED This function is not supported.
> + @retval EFI_BUFFER_TOO_SMALL The Data is too small to hold the data.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetCertRevocationList (
> + OUT VOID *Data,
> + IN OUT UINTN *DataSize
> + )
> +{
> + return EFI_UNSUPPORTED;
> +}
> diff --git a/CryptoPkg/Library/TlsLib/TlsInit.c
> b/CryptoPkg/Library/TlsLib/TlsInit.c
> new file mode 100644
> index 0000000..6b1fd93
> --- /dev/null
> +++ b/CryptoPkg/Library/TlsLib/TlsInit.c
> @@ -0,0 +1,291 @@
> +/** @file
> + SSL/TLS Initialization Library Wrapper Implementation over OpenSSL.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "InternalTlsLib.h"
> +
> +/**
> + Initializes the OpenSSL library.
> +
> + This function registers ciphers and digests used directly and indirectly
> + by SSL/TLS, and initializes the readable error messages.
> + This function must be called before any other action takes places.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsInitialize (
> + VOID
> + )
> +{
> + //
> + // Performs initialization of crypto and ssl library, and loads required
> + // algorithms.
> + //
> + SSL_library_init ();
> +
> + //
> + // Loads error strings from both crypto and ssl library.
> + //
> + SSL_load_error_strings ();
> +
> + /// OpenSSL_add_all_algorithms();
> +
> + //
> + // Initialize the pseudorandom number generator.
> + //
> + RandomSeed (NULL, 0);
> +}
> +
> +/**
> + Free an allocated SSL_CTX object.
> +
> + @param[in] TlsCtx Pointer to the SSL_CTX object to be released.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsCtxFree (
> + IN VOID *TlsCtx
> + )
> +{
> + if (TlsCtx == NULL) {
> + return;
> + }
> +
> + if (TlsCtx != NULL) {
> + SSL_CTX_free ((SSL_CTX *) (TlsCtx));
> + }
> +}
> +
> +/**
> + Creates a new SSL_CTX object as framework to establish TLS/SSL enabled
> + connections.
> +
> + @param[in] MajorVer Major Version of TLS/SSL Protocol.
> + @param[in] MinorVer Minor Version of TLS/SSL Protocol.
> +
> + @return Pointer to an allocated SSL_CTX object.
> + If the creation failed, TlsCtxNew() returns NULL.
> +
> +**/
> +VOID *
> +EFIAPI
> +TlsCtxNew (
> + IN UINT8 MajorVer,
> + IN UINT8 MinorVer
> + )
> +{
> + SSL_CTX *TlsCtx;
> + UINT16 ProtoVersion;
> +
> + ProtoVersion = (MajorVer << 8) | MinorVer;
> +
> + TlsCtx = SSL_CTX_new (SSLv23_client_method ());
> + if (TlsCtx == NULL) {
> + return NULL;
> + }
> +
> + //
> + // Ensure SSLv3 is disabled
> + //
> + SSL_CTX_set_options (TlsCtx, SSL_OP_NO_SSLv3);
> +
> + //
> + // Treat as minimum accepted versions. Client can use higher
> + // TLS version if server supports it
> + //
> + switch (ProtoVersion) {
> + case TLS1_VERSION:
> + //
> + // TLS 1.0
> + //
> + break;
> + case TLS1_1_VERSION:
> + //
> + // TLS 1.1
> + //
> + SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1);
> + break;
> + case TLS1_2_VERSION:
> + //
> + // TLS 1.2
> + //
> + SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1);
> + SSL_CTX_set_options (TlsCtx, SSL_OP_NO_TLSv1_1);
> + break;
> + default:
> + //
> + // Unsupported TLS/SSL Protocol Version.
> + //
> + break;
> + }
> +
> + return (VOID *) TlsCtx;
> +}
> +
> +/**
> + Free an allocated TLS object.
> +
> + This function removes the TLS object pointed to by Tls and frees up the
> + allocated memory. If Tls is NULL, nothing is done.
> +
> + @param[in] Tls Pointer to the TLS object to be freed.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsFree (
> + IN VOID *Tls
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + if (TlsConn == NULL) {
> + return;
> + }
> +
> + //
> + // Free the internal TLS and BIO objects.
> + //
> + if (TlsConn->Ssl != NULL) {
> + SSL_free (TlsConn->Ssl);
> + }
> +
> + if (TlsConn->InBio != NULL) {
> + BIO_free (TlsConn->InBio);
> + }
> +
> + if (TlsConn->OutBio != NULL) {
> + BIO_free (TlsConn->OutBio);
> + }
> +
> + OPENSSL_free (Tls);
> +}
> +
> +/**
> + Create a new TLS object for a connection.
> +
> + This function creates a new TLS object for a connection. The new object
> + inherits the setting of the underlying context TlsCtx: connection method,
> + options, verification setting.
> +
> + @param[in] TlsCtx Pointer to the SSL_CTX object.
> +
> + @return Pointer to an allocated SSL object.
> + If the creation failed, TlsNew() returns NULL.
> +
> +**/
> +VOID *
> +EFIAPI
> +TlsNew (
> + IN VOID *TlsCtx
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + SSL_CTX *SslCtx;
> + X509_STORE *X509Store;
> +
> + TlsConn = NULL;
> +
> + //
> + // Allocate one new TLS_CONNECTION object
> + //
> + TlsConn = (TLS_CONNECTION *) OPENSSL_malloc (sizeof
> (TLS_CONNECTION));
> + if (TlsConn == NULL) {
> + return NULL;
> + }
> +
> + TlsConn->Ssl = NULL;
> +
> + //
> + // Create a new SSL Object
> + //
> + TlsConn->Ssl = SSL_new ((SSL_CTX *) TlsCtx);
> + if (TlsConn->Ssl == NULL) {
> + TlsFree ((VOID *) TlsConn);
> + return NULL;
> + }
> +
> + //
> + // Initialize the created SSL Object
> + //
> + SSL_set_info_callback (TlsConn->Ssl, NULL);
> +
> + TlsConn->InBio = NULL;
> +
> + //
> + // Set up Reading BIO for TLS connection
> + //
> + TlsConn->InBio = BIO_new (BIO_s_mem ());
> + if (TlsConn->InBio == NULL) {
> + TlsFree ((VOID *) TlsConn);
> + return NULL;
> + }
> +
> + //
> + // Sets the behaviour of memory BIO when it is empty. It will set the
> + // read retry flag.
> + //
> + BIO_set_mem_eof_return (TlsConn->InBio, -1);
> +
> + TlsConn->OutBio = NULL;
> +
> + //
> + // Set up Writing BIO for TLS connection
> + //
> + TlsConn->OutBio = BIO_new (BIO_s_mem ());
> + if (TlsConn->OutBio == NULL) {
> + TlsFree ((VOID *) TlsConn);
> + return NULL;
> + }
> +
> + //
> + // Sets the behaviour of memory BIO when it is empty. It will set the
> + // write retry flag.
> + //
> + BIO_set_mem_eof_return (TlsConn->OutBio, -1);
> +
> + ASSERT (TlsConn->Ssl != NULL && TlsConn->InBio != NULL && TlsConn-
> >OutBio != NULL);
> +
> + //
> + // Connects the InBio and OutBio for the read and write operations.
> + //
> + SSL_set_bio (TlsConn->Ssl, TlsConn->InBio, TlsConn->OutBio);
> +
> + //
> + // Create new X509 store if needed
> + //
> + SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);
> + X509Store = SSL_CTX_get_cert_store (SslCtx);
> + if (X509Store == NULL) {
> + X509Store = X509_STORE_new ();
> + if (X509Store == NULL) {
> + TlsFree ((VOID *) TlsConn);
> + return NULL;
> + }
> + SSL_CTX_set1_verify_cert_store (SslCtx, X509Store);
> + X509_STORE_free (X509Store);
> + }
> +
> + //
> + // Set X509_STORE flags used in certificate validation
> + //
> + X509_STORE_set_flags (
> + X509Store,
> + X509_V_FLAG_PARTIAL_CHAIN | X509_V_FLAG_NO_CHECK_TIME
> + );
> + return (VOID *) TlsConn;
> +}
> diff --git a/CryptoPkg/Library/TlsLib/TlsLib.inf
> b/CryptoPkg/Library/TlsLib/TlsLib.inf
> new file mode 100644
> index 0000000..2122b3b
> --- /dev/null
> +++ b/CryptoPkg/Library/TlsLib/TlsLib.inf
> @@ -0,0 +1,49 @@
> +## @file
> +# SSL/TLS Wrapper Library Instance based on OpenSSL.
> +#
> +# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +# (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions of the
> BSD License
> +# which accompanies this distribution. The full text of the license may be
> found at
> +# http://opensource.org/licenses/bsd-license.php
> +#
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = TlsLib
> + MODULE_UNI_FILE = TlsLib.uni
> + FILE_GUID = CC729DC5-4E21-0B36-1A00-3A8E1B86A155
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = TlsLib|DXE_DRIVER DXE_CORE
> UEFI_APPLICATION UEFI_DRIVER
> +
> +#
> +# The following information is for reference only and not required by the
> build tools.
> +#
> +# VALID_ARCHITECTURES = IA32 X64 IPF ARM AARCH64
> +#
> +
> +[Sources]
> + InternalTlsLib.h
> + TlsInit.c
> + TlsConfig.c
> + TlsProcess.c
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + CryptoPkg/CryptoPkg.dec
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + MemoryAllocationLib
> + UefiRuntimeServicesTableLib
> + DebugLib
> + OpensslLib
> + IntrinsicLib
> + PrintLib
> diff --git a/CryptoPkg/Library/TlsLib/TlsLib.uni
> b/CryptoPkg/Library/TlsLib/TlsLib.uni
> new file mode 100644
> index 0000000..9b79287
> --- /dev/null
> +++ b/CryptoPkg/Library/TlsLib/TlsLib.uni
> @@ -0,0 +1,19 @@
> +// /** @file
> +// SSL/TLS Wrapper Library Instance based on OpenSSL.
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// This program and the accompanying materials
> +// are licensed and made available under the terms and conditions of the
> BSD License
> +// which accompanies this distribution. The full text of the license may be
> found at
> +// http://opensource.org/licenses/bsd-license.php
> +//
> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "SSL/TLS Wrapper
> Library Instance"
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "This module
> provides SSL/TLS Wrapper Library Instance."
> \ No newline at end of file
> diff --git a/CryptoPkg/Library/TlsLib/TlsProcess.c
> b/CryptoPkg/Library/TlsLib/TlsProcess.c
> new file mode 100644
> index 0000000..52b55d7
> --- /dev/null
> +++ b/CryptoPkg/Library/TlsLib/TlsProcess.c
> @@ -0,0 +1,461 @@
> +/** @file
> + SSL/TLS Process Library Wrapper Implementation over OpenSSL.
> + The process includes the TLS handshake and packet I/O.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "InternalTlsLib.h"
> +
> +#define MAX_BUFFER_SIZE 32768
> +
> +/**
> + Checks if the TLS handshake was done.
> +
> + This function will check if the specified TLS handshake was done.
> +
> + @param[in] Tls Pointer to the TLS object for handshake state checking.
> +
> + @retval TRUE The TLS handshake was done.
> + @retval FALSE The TLS handshake was not done.
> +
> +**/
> +BOOLEAN
> +EFIAPI
> +TlsInHandshake (
> + IN VOID *Tls
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + if (TlsConn == NULL || TlsConn->Ssl == NULL) {
> + return FALSE;
> + }
> +
> + //
> + // Return the status which indicates if the TLS handshake was done.
> + //
> + return !SSL_is_init_finished (TlsConn->Ssl);
> +}
> +
> +/**
> + Perform a TLS/SSL handshake.
> +
> + This function will perform a TLS/SSL handshake.
> +
> + @param[in] Tls Pointer to the TLS object for handshake operation.
> + @param[in] BufferIn Pointer to the most recently received TLS
> Handshake packet.
> + @param[in] BufferInSize Packet size in bytes for the most recently
> received TLS
> + Handshake packet.
> + @param[out] BufferOut Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On
> input, it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + Tls is NULL.
> + BufferIn is NULL but BufferInSize is NOT 0.
> + BufferInSize is 0 but BufferIn is NOT NULL.
> + BufferOutSize is NULL.
> + BufferOut is NULL if *BufferOutSize is not zero.
> + @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the
> response packet.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsDoHandshake (
> + IN VOID *Tls,
> + IN UINT8 *BufferIn, OPTIONAL
> + IN UINTN BufferInSize, OPTIONAL
> + OUT UINT8 *BufferOut, OPTIONAL
> + IN OUT UINTN *BufferOutSize
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + UINTN PendingBufferSize;
> + INTN Ret;
> + unsigned long ErrorCode;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + PendingBufferSize = 0;
> + Ret = 1;
> +
> + if (TlsConn == NULL || \
> + TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio ==
> NULL || \
> + BufferOutSize == NULL || \
> + (BufferIn == NULL && BufferInSize != 0) || \
> + (BufferIn != NULL && BufferInSize == 0) || \
> + (BufferOut == NULL && *BufferOutSize != 0)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if(BufferIn == NULL && BufferInSize == 0) {
> + //
> + // If RequestBuffer is NULL and RequestSize is 0, and TLS session
> + // status is EfiTlsSessionNotStarted, the TLS session will be initiated
> + // and the response packet needs to be ClientHello.
> + //
> + PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
> + if (PendingBufferSize == 0) {
> + SSL_set_connect_state (TlsConn->Ssl);
> + Ret = SSL_do_handshake (TlsConn->Ssl);
> + PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
> + }
> + } else {
> + PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
> + if (PendingBufferSize == 0) {
> + BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
> + Ret = SSL_do_handshake (TlsConn->Ssl);
> + PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
> + }
> + }
> +
> + if (Ret < 1) {
> + Ret = SSL_get_error (TlsConn->Ssl, (int) Ret);
> + if (Ret == SSL_ERROR_SSL ||
> + Ret == SSL_ERROR_SYSCALL ||
> + Ret == SSL_ERROR_ZERO_RETURN) {
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a SSL_HANDSHAKE_ERROR State=0x%x SSL_ERROR_%a\n",
> + __FUNCTION__,
> + SSL_get_state (TlsConn->Ssl),
> + Ret == SSL_ERROR_SSL ? "SSL" : Ret == SSL_ERROR_SYSCALL ?
> "SYSCALL" : "ZERO_RETURN"
> + ));
> + DEBUG_CODE_BEGIN ();
> + while (TRUE) {
> + ErrorCode = ERR_get_error ();
> + if (ErrorCode == 0) {
> + break;
> + }
> + DEBUG ((
> + DEBUG_ERROR,
> + "%a ERROR 0x%x=L%x:F%x:R%x\n",
> + __FUNCTION__,
> + ErrorCode,
> + ERR_GET_LIB (ErrorCode),
> + ERR_GET_FUNC (ErrorCode),
> + ERR_GET_REASON (ErrorCode)
> + ));
> + }
> + DEBUG_CODE_END ();
> + return EFI_PROTOCOL_ERROR;
> + }
> + }
> +
> + if (PendingBufferSize > *BufferOutSize) {
> + *BufferOutSize = PendingBufferSize;
> + return EFI_BUFFER_TOO_SMALL;
> + }
> +
> + if (PendingBufferSize > 0) {
> + *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32)
> PendingBufferSize);
> + } else {
> + *BufferOutSize = 0;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Hande Alert message recorded in BufferIn. If BufferIn is NULL and
> BufferInSize is zero,
> + TLS session has errors and the response packet needs to be Alert message
> based on error type.
> +
> + @param[in] Tls Pointer to the TLS object for state checking.
> + @param[in] BufferIn Pointer to the most recently received TLS Alert
> packet.
> + @param[in] BufferInSize Packet size in bytes for the most recently
> received TLS
> + Alert packet.
> + @param[out] BufferOut Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferOutSize Pointer to the buffer size in bytes. On
> input, it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + Tls is NULL.
> + BufferIn is NULL but BufferInSize is NOT 0.
> + BufferInSize is 0 but BufferIn is NOT NULL.
> + BufferOutSize is NULL.
> + BufferOut is NULL if *BufferOutSize is not zero.
> + @retval EFI_ABORTED An error occurred.
> + @retval EFI_BUFFER_TOO_SMALL BufferOutSize is too small to hold the
> response packet.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsHandeAlert (
> + IN VOID *Tls,
> + IN UINT8 *BufferIn, OPTIONAL
> + IN UINTN BufferInSize, OPTIONAL
> + OUT UINT8 *BufferOut, OPTIONAL
> + IN OUT UINTN *BufferOutSize
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + UINTN PendingBufferSize;
> + UINT8 *TempBuffer;
> + INTN Ret;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + PendingBufferSize = 0;
> + TempBuffer = NULL;
> + Ret = 0;
> +
> + if (TlsConn == NULL || \
> + TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio ==
> NULL || \
> + BufferOutSize == NULL || \
> + (BufferIn == NULL && BufferInSize != 0) || \
> + (BufferIn != NULL && BufferInSize == 0) || \
> + (BufferOut == NULL && *BufferOutSize != 0)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
> + if (PendingBufferSize == 0 && BufferIn != NULL && BufferInSize != 0) {
> + Ret = BIO_write (TlsConn->InBio, BufferIn, (UINT32) BufferInSize);
> + if (Ret != (INTN) BufferInSize) {
> + return EFI_ABORTED;
> + }
> +
> + TempBuffer = (UINT8 *) OPENSSL_malloc (MAX_BUFFER_SIZE);
> +
> + //
> + // ssl3_send_alert() will be called in ssl3_read_bytes() function.
> + // TempBuffer is invalid since it's a Alert message, so just ignore it.
> + //
> + SSL_read (TlsConn->Ssl, TempBuffer, MAX_BUFFER_SIZE);
> +
> + OPENSSL_free (TempBuffer);
> +
> + PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
> + }
> +
> + if (PendingBufferSize > *BufferOutSize) {
> + *BufferOutSize = PendingBufferSize;
> + return EFI_BUFFER_TOO_SMALL;
> + }
> +
> + if (PendingBufferSize > 0) {
> + *BufferOutSize = BIO_read (TlsConn->OutBio, BufferOut, (UINT32)
> PendingBufferSize);
> + } else {
> + *BufferOutSize = 0;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Build the CloseNotify packet.
> +
> + @param[in] Tls Pointer to the TLS object for state checking.
> + @param[in, out] Buffer Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferSize Pointer to the buffer size in bytes. On input,
> it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + Tls is NULL.
> + BufferSize is NULL.
> + Buffer is NULL if *BufferSize is not zero.
> + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the
> response packet.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCloseNotify (
> + IN VOID *Tls,
> + IN OUT UINT8 *Buffer,
> + IN OUT UINTN *BufferSize
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> + UINTN PendingBufferSize;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + PendingBufferSize = 0;
> +
> + if (TlsConn == NULL || \
> + TlsConn->Ssl == NULL || TlsConn->InBio == NULL || TlsConn->OutBio ==
> NULL || \
> + BufferSize == NULL || \
> + (Buffer == NULL && *BufferSize != 0)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
> + if (PendingBufferSize == 0) {
> + //
> + // ssl3_send_alert() and ssl3_dispatch_alert() function will be called.
> + //
> + SSL_shutdown (TlsConn->Ssl);
> + PendingBufferSize = (UINTN) BIO_ctrl_pending (TlsConn->OutBio);
> + }
> +
> + if (PendingBufferSize > *BufferSize) {
> + *BufferSize = PendingBufferSize;
> + return EFI_BUFFER_TOO_SMALL;
> + }
> +
> + if (PendingBufferSize > 0) {
> + *BufferSize = BIO_read (TlsConn->OutBio, Buffer, (UINT32)
> PendingBufferSize);
> + } else {
> + *BufferSize = 0;
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Attempts to read bytes from one TLS object and places the data in Buffer.
> +
> + This function will attempt to read BufferSize bytes from the TLS object
> + and places the data in Buffer.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in,out] Buffer Pointer to the buffer to store the data.
> + @param[in] BufferSize The size of Buffer in bytes.
> +
> + @retval >0 The amount of data successfully read from the TLS object.
> + @retval <=0 No data was successfully read.
> +
> +**/
> +INTN
> +EFIAPI
> +TlsCtrlTrafficOut (
> + IN VOID *Tls,
> + IN OUT VOID *Buffer,
> + IN UINTN BufferSize
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + if (TlsConn == NULL || TlsConn->OutBio == 0) {
> + return -1;
> + }
> +
> + //
> + // Read and return the amount of data from the BIO.
> + //
> + return BIO_read (TlsConn->OutBio, Buffer, (UINT32) BufferSize);
> +}
> +
> +/**
> + Attempts to write data from the buffer to TLS object.
> +
> + This function will attempt to write BufferSize bytes data from the Buffer
> + to the TLS object.
> +
> + @param[in] Tls Pointer to the TLS object.
> + @param[in] Buffer Pointer to the data buffer.
> + @param[in] BufferSize The size of Buffer in bytes.
> +
> + @retval >0 The amount of data successfully written to the TLS object.
> + @retval <=0 No data was successfully written.
> +
> +**/
> +INTN
> +EFIAPI
> +TlsCtrlTrafficIn (
> + IN VOID *Tls,
> + IN VOID *Buffer,
> + IN UINTN BufferSize
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + if (TlsConn == NULL || TlsConn->InBio == 0) {
> + return -1;
> + }
> +
> + //
> + // Write and return the amount of data to the BIO.
> + //
> + return BIO_write (TlsConn->InBio, Buffer, (UINT32) BufferSize);
> +}
> +/**
> + Attempts to read bytes from the specified TLS connection into the buffer.
> +
> + This function tries to read BufferSize bytes data from the specified TLS
> + connection into the Buffer.
> +
> + @param[in] Tls Pointer to the TLS connection for data reading.
> + @param[in,out] Buffer Pointer to the data buffer.
> + @param[in] BufferSize The size of Buffer in bytes.
> +
> + @retval >0 The read operation was successful, and return value is the
> + number of bytes actually read from the TLS connection.
> + @retval <=0 The read operation was not successful.
> +
> +**/
> +INTN
> +EFIAPI
> +TlsRead (
> + IN VOID *Tls,
> + IN OUT VOID *Buffer,
> + IN UINTN BufferSize
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + if (TlsConn == NULL || TlsConn->Ssl == NULL) {
> + return -1;
> + }
> +
> + //
> + // Read bytes from the specified TLS connection.
> + //
> + return SSL_read (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
> +}
> +
> +/**
> + Attempts to write data to a TLS connection.
> +
> + This function tries to write BufferSize bytes data from the Buffer into the
> + specified TLS connection.
> +
> + @param[in] Tls Pointer to the TLS connection for data writing.
> + @param[in] Buffer Pointer to the data buffer.
> + @param[in] BufferSize The size of Buffer in bytes.
> +
> + @retval >0 The write operation was successful, and return value is the
> + number of bytes actually written to the TLS connection.
> + @retval <=0 The write operation was not successful.
> +
> +**/
> +INTN
> +EFIAPI
> +TlsWrite (
> + IN VOID *Tls,
> + IN VOID *Buffer,
> + IN UINTN BufferSize
> + )
> +{
> + TLS_CONNECTION *TlsConn;
> +
> + TlsConn = (TLS_CONNECTION *) Tls;
> + if (TlsConn == NULL || TlsConn->Ssl == NULL) {
> + return -1;
> + }
> +
> + //
> + // Write bytes to the specified TLS connection.
> + //
> + return SSL_write (TlsConn->Ssl, Buffer, (UINT32) BufferSize);
> +}
> --
> 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
` (3 preceding siblings ...)
2016-12-14 7:34 ` [Patch 04/10] CryptoPkg: Add new TlsLib library Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-14 8:41 ` Fu, Siyuan
2016-12-14 7:34 ` [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration Jiaxin Wu
` (4 subsequent siblings)
9 siblings, 1 reply; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Ye Ting, Fu Siyuan, Zhang Lubo, Long Qin, Thomas Palmer,
Wu Jiaxin
This patch is the implementation of EFI TLS Service Binding
Protocol, EFI TLS Protocol and EFI TLS Configuration Protocol
Interfaces.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/TlsDxe/TlsConfigProtocol.c | 152 ++++++++
NetworkPkg/TlsDxe/TlsDriver.c | 498 +++++++++++++++++++++++++++
NetworkPkg/TlsDxe/TlsDriver.h | 237 +++++++++++++
NetworkPkg/TlsDxe/TlsDxe.inf | 65 ++++
NetworkPkg/TlsDxe/TlsDxe.uni | 25 ++
| 18 +
NetworkPkg/TlsDxe/TlsImpl.c | 270 +++++++++++++++
NetworkPkg/TlsDxe/TlsImpl.h | 315 +++++++++++++++++
NetworkPkg/TlsDxe/TlsProtocol.c | 632 ++++++++++++++++++++++++++++++++++
9 files changed, 2212 insertions(+)
create mode 100644 NetworkPkg/TlsDxe/TlsConfigProtocol.c
create mode 100644 NetworkPkg/TlsDxe/TlsDriver.c
create mode 100644 NetworkPkg/TlsDxe/TlsDriver.h
create mode 100644 NetworkPkg/TlsDxe/TlsDxe.inf
create mode 100644 NetworkPkg/TlsDxe/TlsDxe.uni
create mode 100644 NetworkPkg/TlsDxe/TlsDxeExtra.uni
create mode 100644 NetworkPkg/TlsDxe/TlsImpl.c
create mode 100644 NetworkPkg/TlsDxe/TlsImpl.h
create mode 100644 NetworkPkg/TlsDxe/TlsProtocol.c
diff --git a/NetworkPkg/TlsDxe/TlsConfigProtocol.c b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
new file mode 100644
index 0000000..2ec79c9
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
@@ -0,0 +1,152 @@
+/** @file
+ Implementation of EFI TLS Configuration Protocol Interfaces.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsImpl.h"
+
+EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol = {
+ TlsConfigurationSetData,
+ TlsConfigurationGetData
+};
+
+/**
+ Set TLS configuration data.
+
+ The SetData() function sets TLS configuration to non-volatile storage or volatile
+ storage.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in] Data Pointer to configuration data.
+ @param[in] DataSize Total size of configuration data.
+
+ @retval EFI_SUCCESS The TLS configuration data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationSetData (
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL || Data == NULL || DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
+
+ switch (DataType) {
+ case EfiTlsConfigDataTypeCACertificate:
+ Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeHostPublicCert:
+ Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeHostPrivateKey:
+ Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeCertRevocationList:
+ Status = TlsSetCertRevocationList (Data, DataSize);
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Get TLS configuration data.
+
+ The GetData() function gets TLS configuration.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in, out] Data Pointer to configuration data.
+ @param[in, out] DataSize Total size of configuration data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS configuration data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS configuration data is not found.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationGetData (
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
+
+ switch (DataType) {
+ case EfiTlsConfigDataTypeCACertificate:
+ Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeHostPublicCert:
+ Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeHostPrivateKey:
+ Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeCertRevocationList:
+ Status = TlsGetCertRevocationList (Data, DataSize);
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.c
new file mode 100644
index 0000000..0a75c39
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDriver.c
@@ -0,0 +1,498 @@
+/** @file
+ The Driver Binding and Service Binding Protocol for TlsDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsImpl.h"
+
+EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
+ TlsServiceBindingCreateChild,
+ TlsServiceBindingDestroyChild
+};
+
+/**
+ Release all the resources used by the TLS instance.
+
+ @param[in] Instance The TLS instance data.
+
+**/
+VOID
+TlsCleanInstance (
+ IN TLS_INSTANCE *Instance
+ )
+{
+ if (Instance != NULL) {
+ if (Instance->TlsConn != NULL) {
+ TlsFree (Instance->TlsConn);
+ }
+
+ FreePool (Instance);
+ }
+}
+
+/**
+ Create the TLS instance and initialize it.
+
+ @param[in] Service The pointer to the TLS service.
+ @param[out] Instance The pointer to the TLS instance.
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+ @retval EFI_SUCCESS The TLS instance is created.
+
+**/
+EFI_STATUS
+TlsCreateInstance (
+ IN TLS_SERVICE *Service,
+ OUT TLS_INSTANCE **Instance
+ )
+{
+ TLS_INSTANCE *TlsInstance;
+
+ *Instance = NULL;
+
+ TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
+ if (TlsInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
+ InitializeListHead (&TlsInstance->Link);
+ TlsInstance->InDestroy = FALSE;
+ TlsInstance->Service = Service;
+
+ CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
+ CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig));
+
+ TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
+
+ *Instance = TlsInstance;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Release all the resources used by the TLS service binding instance.
+
+ @param[in] Service The TLS service data.
+
+**/
+VOID
+TlsCleanService (
+ IN TLS_SERVICE *Service
+ )
+{
+ if (Service != NULL) {
+ if (Service->TlsCtx != NULL) {
+ TlsCtxFree (Service->TlsCtx);
+ }
+
+ FreePool (Service);
+ }
+}
+
+/**
+ Create then initialize a TLS service.
+
+ @param[in] Image ImageHandle of the TLS driver
+ @param[out] Service The service for TLS driver
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service.
+ @retval EFI_SUCCESS The service is created for the driver.
+
+**/
+EFI_STATUS
+TlsCreateService (
+ IN EFI_HANDLE Image,
+ OUT TLS_SERVICE **Service
+ )
+{
+ EFI_STATUS Status;
+ TLS_SERVICE *TlsService;
+
+ Status = EFI_SUCCESS;
+ *Service = NULL;
+
+ ASSERT (Service != NULL);
+
+ //
+ // Allocate a TLS Service Data
+ //
+ TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
+ if (TlsService == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize TLS Service Data
+ //
+ TlsService->Signature = TLS_SERVICE_SIGNATURE;
+ CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding));
+ TlsService->TlsChildrenNum = 0;
+ InitializeListHead (&TlsService->TlsChildrenList);
+ TlsService->ImageHandle = Image;
+
+ *Service = TlsService;
+
+ return Status;
+}
+
+/**
+ Unloads an image.
+
+ @param[in] ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleNum;
+ EFI_HANDLE *HandleBuffer;
+ UINT32 Index;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ TLS_SERVICE *TlsService;
+
+ HandleBuffer = NULL;
+ ServiceBinding = NULL;
+ TlsService = NULL;
+
+ //
+ // Locate all the handles with Tls service binding protocol.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiTlsServiceBindingProtocolGuid,
+ NULL,
+ &HandleNum,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < HandleNum; Index++) {
+ //
+ // Firstly, find ServiceBinding interface
+ //
+ Status = gBS->OpenProtocol (
+ HandleBuffer[Index],
+ &gEfiTlsServiceBindingProtocolGuid,
+ (VOID **) &ServiceBinding,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
+
+ //
+ // Then, uninstall ServiceBinding interface
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ HandleBuffer[Index],
+ &gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TlsCleanService (TlsService);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ TLS_SERVICE *TlsService;
+
+ //
+ // Create TLS Service
+ //
+ Status = TlsCreateService (ImageHandle, &TlsService);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (TlsService != NULL);
+
+ //
+ // Initializes the OpenSSL library.
+ //
+ TlsInitialize ();
+
+ //
+ // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
+ // connections. TLS 1.0 is used as the default version.
+ //
+ TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR);
+ if (TlsService->TlsCtx == NULL) {
+ FreePool (TlsService);
+ return EFI_ABORTED;
+ }
+
+ //
+ // Install the TlsServiceBinding Protocol onto Handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &TlsService->Handle,
+ &gEfiTlsServiceBindingProtocolGuid,
+ &TlsService->ServiceBinding,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_CLEAN_SERVICE;
+ }
+
+ return Status;
+
+ON_CLEAN_SERVICE:
+ TlsCleanService (TlsService);
+
+ return Status;
+}
+
+/**
+ Creates a child handle and installs a protocol.
+
+ The CreateChild() function installs a protocol on ChildHandle.
+ If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+ If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
+ then a new handle is created. If it is a pointer to an existing UEFI handle,
+ then the protocol is added to the existing UEFI handle.
+
+ @retval EFI_SUCCES The protocol was added to ChildHandle.
+ @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
+ the child.
+ @retval other The child handle was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingCreateChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE *ChildHandle
+ )
+{
+ TLS_SERVICE *TlsService;
+ TLS_INSTANCE *TlsInstance;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ if ((This == NULL) || (ChildHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TlsService = TLS_SERVICE_FROM_THIS (This);
+
+ Status = TlsCreateInstance (TlsService, &TlsInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (TlsInstance != NULL);
+
+ //
+ // Create a new TLS connection object.
+ //
+ TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
+ if (TlsInstance->TlsConn == NULL) {
+ Status = EFI_ABORTED;
+ goto ON_ERROR;
+ }
+
+ //
+ // Set default ConnectionEnd to EfiTlsClient
+ //
+ Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
+ // Install TLS protocol and configuration protocol onto ChildHandle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ ChildHandle,
+ &gEfiTlsProtocolGuid,
+ &TlsInstance->Tls,
+ &gEfiTlsConfigurationProtocolGuid,
+ &TlsInstance->TlsConfig,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ TlsInstance->ChildHandle = *ChildHandle;
+
+ //
+ // Add it to the TLS service's child list.
+ //
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
+ TlsService->TlsChildrenNum++;
+
+ gBS->RestoreTPL (OldTpl);
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+ TlsCleanInstance (TlsInstance);
+ return Status;
+}
+
+/**
+ Destroys a child handle with a protocol installed on it.
+
+ The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+ that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+ last protocol on ChildHandle, then ChildHandle is destroyed.
+
+ @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param ChildHandle Handle of the child to destroy.
+
+ @retval EFI_SUCCES The protocol was removed from ChildHandle.
+ @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.
+ @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
+ because its services are being used.
+ @retval other The child handle was not destroyed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingDestroyChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ChildHandle
+ )
+{
+ TLS_SERVICE *TlsService;
+ TLS_INSTANCE *TlsInstance;
+
+ EFI_TLS_PROTOCOL *Tls;
+ EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ if ((This == NULL) || (ChildHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TlsService = TLS_SERVICE_FROM_THIS (This);
+
+ //
+ // Find TLS protocol interface installed in ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTlsProtocolGuid,
+ (VOID **) &Tls,
+ TlsService->ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Find TLS configuration protocol interface installed in ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTlsConfigurationProtocolGuid,
+ (VOID **) &TlsConfig,
+ TlsService->ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TlsInstance = TLS_INSTANCE_FROM_PROTOCOL_THIS (Tls);
+
+ if (TlsInstance->Service != TlsService) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TlsInstance->InDestroy) {
+ return EFI_SUCCESS;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ TlsInstance->InDestroy = TRUE;
+
+ //
+ // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle.
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandle,
+ &gEfiTlsProtocolGuid,
+ Tls,
+ &gEfiTlsConfigurationProtocolGuid,
+ TlsConfig,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ RemoveEntryList (&TlsInstance->Link);
+ TlsService->TlsChildrenNum--;
+
+ gBS->RestoreTPL (OldTpl);
+
+ TlsCleanInstance (TlsInstance);
+
+ return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/TlsDxe/TlsDriver.h b/NetworkPkg/TlsDxe/TlsDriver.h
new file mode 100644
index 0000000..c3c30a8
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDriver.h
@@ -0,0 +1,237 @@
+/** @file
+ Header file of the Driver Binding and Service Binding Protocol for TlsDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_TLS_DRIVER_H__
+#define __EFI_TLS_DRIVER_H__
+
+#include <Uefi.h>
+
+//
+// Driver Protocols
+//
+#include <Protocol/ServiceBinding.h>
+
+//
+// Driver Version
+//
+#define TLS_VERSION 0x00000000
+
+#define TLS_SERVICE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'S')
+
+#define TLS_INSTANCE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'I')
+
+///
+/// TLS Service Data
+///
+typedef struct _TLS_SERVICE TLS_SERVICE;
+
+///
+/// TLS Instance Data
+///
+typedef struct _TLS_INSTANCE TLS_INSTANCE;
+
+
+struct _TLS_SERVICE {
+ UINT32 Signature;
+ EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
+
+ UINT16 TlsChildrenNum;
+ LIST_ENTRY TlsChildrenList;
+
+ //
+ // Handle to install TlsServiceBinding protocol.
+ //
+ EFI_HANDLE Handle;
+ EFI_HANDLE ImageHandle;
+
+ //
+ // Main SSL Context object which is created by a server or client once per program
+ // life-time and which holds mainly default values for the SSL object which are later
+ // created for the connections.
+ //
+ VOID *TlsCtx;
+};
+
+struct _TLS_INSTANCE {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+
+ BOOLEAN InDestroy;
+
+ TLS_SERVICE *Service;
+ EFI_HANDLE ChildHandle;
+
+ EFI_TLS_PROTOCOL Tls;
+ EFI_TLS_CONFIGURATION_PROTOCOL TlsConfig;
+
+ EFI_TLS_SESSION_STATE TlsSessionState;
+
+ //
+ // Main SSL Connection which is created by a server or a client
+ // per established connection.
+ //
+ VOID *TlsConn;
+};
+
+
+#define TLS_SERVICE_FROM_THIS(a) \
+ CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE)
+
+#define TLS_INSTANCE_FROM_PROTOCOL_THIS(a) \
+ CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE)
+
+#define TLS_INSTANCE_FROM_CONFIGURATION_THIS(a) \
+ CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE)
+
+
+/**
+ Release all the resources used by the TLS instance.
+
+ @param[in] Instance The TLS instance data.
+
+**/
+VOID
+TlsCleanInstance (
+ IN TLS_INSTANCE *Instance
+ );
+
+/**
+ Create the TLS instance and initialize it.
+
+ @param[in] Service The pointer to the TLS service.
+ @param[out] Instance The pointer to the TLS instance.
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+ @retval EFI_SUCCESS The TLS instance is created.
+
+**/
+EFI_STATUS
+TlsCreateInstance (
+ IN TLS_SERVICE *Service,
+ OUT TLS_INSTANCE **Instance
+ );
+
+/**
+ Release all the resources used by the TLS service binding instance.
+
+ @param[in] Service The TLS service data.
+
+**/
+VOID
+TlsCleanService (
+ IN TLS_SERVICE *Service
+ );
+
+/**
+ Create then initialize a TLS service.
+
+ @param[in] Image ImageHandle of the TLS driver
+ @param[out] Service The service for TLS driver
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service.
+ @retval EFI_SUCCESS The service is created for the driver.
+
+**/
+EFI_STATUS
+TlsCreateService (
+ IN EFI_HANDLE Image,
+ OUT TLS_SERVICE **Service
+ );
+
+/**
+ Unloads an image.
+
+ @param[in] ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsUnload (
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Creates a child handle and installs a protocol.
+
+ The CreateChild() function installs a protocol on ChildHandle.
+ If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+ If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
+ then a new handle is created. If it is a pointer to an existing UEFI handle,
+ then the protocol is added to the existing UEFI handle.
+
+ @retval EFI_SUCCES The protocol was added to ChildHandle.
+ @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
+ the child.
+ @retval other The child handle was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingCreateChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE *ChildHandle
+ );
+
+/**
+ Destroys a child handle with a protocol installed on it.
+
+ The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+ that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+ last protocol on ChildHandle, then ChildHandle is destroyed.
+
+ @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param ChildHandle Handle of the child to destroy.
+
+ @retval EFI_SUCCES The protocol was removed from ChildHandle.
+ @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.
+ @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
+ because its services are being used.
+ @retval other The child handle was not destroyed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingDestroyChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ChildHandle
+ );
+
+#endif
diff --git a/NetworkPkg/TlsDxe/TlsDxe.inf b/NetworkPkg/TlsDxe/TlsDxe.inf
new file mode 100644
index 0000000..dba3257
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxe.inf
@@ -0,0 +1,65 @@
+## @file
+# This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
+# EFI TLS Configuration Protocol.
+#
+# This module produces EFI TLS (Transport Layer Security) Protocol and EFI TLS
+# Service Binding Protocol, to provide TLS services.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TlsDxe
+ FILE_GUID = 3aceb0c0-3c72-11e4-9a56-74d435052646
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = TlsDriverEntryPoint
+ UNLOAD_IMAGE = TlsUnload
+ MODULE_UNI_FILE = TlsDxe.uni
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ CryptoPkg/CryptoPkg.dec
+
+[Sources]
+ TlsDriver.h
+ TlsDriver.c
+ TlsProtocol.c
+ TlsConfigProtocol.c
+ TlsImpl.h
+ TlsImpl.c
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ BaseLib
+ UefiLib
+ DebugLib
+ NetLib
+ BaseCryptLib
+ TlsLib
+
+[Protocols]
+ gEfiTlsServiceBindingProtocolGuid ## PRODUCES
+ gEfiTlsProtocolGuid ## PRODUCES
+ gEfiTlsConfigurationProtocolGuid ## PRODUCES
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ TlsDxeExtra.uni
diff --git a/NetworkPkg/TlsDxe/TlsDxe.uni b/NetworkPkg/TlsDxe/TlsDxe.uni
new file mode 100644
index 0000000..98c41ca
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxe.uni
@@ -0,0 +1,25 @@
+// /** @file
+// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
+// EFI TLS Configuration Protocol.
+//
+// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS
+// Service Binding Protocol, and EFI TLS Configuration Protocol to provide TLS
+// services.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "UEFI TLS service"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS Configuration Protocol to provide EFI TLS services."
+
--git a/NetworkPkg/TlsDxe/TlsDxeExtra.uni b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
new file mode 100644
index 0000000..a38582a
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// TlsDxe Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php.
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"EFI TLS DXE Driver"
diff --git a/NetworkPkg/TlsDxe/TlsImpl.c b/NetworkPkg/TlsDxe/TlsImpl.c
new file mode 100644
index 0000000..5fb1e78
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsImpl.c
@@ -0,0 +1,270 @@
+/** @file
+ The Miscellaneous Routines for TlsDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsImpl.h"
+
+/**
+ Encrypt the message listed in fragment.
+
+ @param[in] TlsInstance The pointer to the TLS instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment.
+ On input these fragments contain the TLS header and
+ plain text TLS payload;
+ On output these fragments contain the TLS header and
+ cipher text TLS payload.
+ @param[in] FragmentCount Number of fragment.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other errors as indicated.
+**/
+EFI_STATUS
+TlsEcryptPacket (
+ IN TLS_INSTANCE *TlsInstance,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount
+ )
+{
+ UINTN Index;
+ UINT32 BytesCopied;
+ UINT32 BufferInSize;
+ UINT8 *BufferIn;
+ UINT8 *BufferInPtr;
+ TLS_RECORD_HEADER *RecordHeaderIn;
+ UINT16 ThisPlainMessageSize;
+ TLS_RECORD_HEADER *TempRecordHeader;
+ UINT16 ThisMessageSize;
+ UINT32 BufferOutSize;
+ UINT8 *BufferOut;
+ INTN Ret;
+
+ BytesCopied = 0;
+ BufferInSize = 0;
+ BufferIn = NULL;
+ BufferInPtr = NULL;
+ RecordHeaderIn = NULL;
+ TempRecordHeader = NULL;
+ BufferOutSize = 0;
+ BufferOut = NULL;
+ Ret = 0;
+
+ //
+ // Calculate the size according to the fragment table.
+ //
+ for (Index = 0; Index < *FragmentCount; Index++) {
+ BufferInSize += (*FragmentTable)[Index].FragmentLength;
+ }
+
+ //
+ // Allocate buffer for processing data.
+ //
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Copy all TLS plain record header and payload into ProcessBuffer.
+ //
+ for (Index = 0; Index < *FragmentCount; Index++) {
+ CopyMem (
+ (BufferIn + BytesCopied),
+ (*FragmentTable)[Index].FragmentBuffer,
+ (*FragmentTable)[Index].FragmentLength
+ );
+ BytesCopied += (*FragmentTable)[Index].FragmentLength;
+ }
+
+ BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Parsing buffer.
+ //
+ BufferInPtr = BufferIn;
+ TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
+ while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
+ RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
+ ASSERT (RecordHeaderIn->ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA);
+ ThisPlainMessageSize = RecordHeaderIn->Length;
+
+ TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), ThisPlainMessageSize);
+
+ Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), MAX_BUFFER_SIZE);
+
+ if (Ret > 0) {
+ ThisMessageSize = (UINT16) Ret;
+ } else {
+ ThisMessageSize = 0;
+ }
+
+ BufferOutSize += ThisMessageSize;
+
+ BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize;
+ TempRecordHeader += ThisMessageSize;
+ }
+
+ FreePool (BufferIn);
+
+ //
+ // The caller will take responsible to handle the original fragment table.
+ //
+ *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
+ if (*FragmentTable == NULL) {
+ FreePool (BufferOut);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ (*FragmentTable)[0].FragmentBuffer = BufferOut;
+ (*FragmentTable)[0].FragmentLength = BufferOutSize;
+ *FragmentCount = 1;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Decrypt the message listed in fragment.
+
+ @param[in] TlsInstance The pointer to the TLS instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment.
+ On input these fragments contain the TLS header and
+ cipher text TLS payload;
+ On output these fragments contain the TLS header and
+ plain text TLS payload.
+ @param[in] FragmentCount Number of fragment.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other errors as indicated.
+**/
+EFI_STATUS
+TlsDecryptPacket (
+ IN TLS_INSTANCE *TlsInstance,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount
+ )
+{
+ UINTN Index;
+ UINT32 BytesCopied;
+ UINT8 *BufferIn;
+ UINT32 BufferInSize;
+ UINT8 *BufferInPtr;
+ TLS_RECORD_HEADER *RecordHeaderIn;
+ UINT16 ThisCipherMessageSize;
+ TLS_RECORD_HEADER *TempRecordHeader;
+ UINT16 ThisPlainMessageSize;
+ UINT8 *BufferOut;
+ UINT32 BufferOutSize;
+ INTN Ret;
+
+ BytesCopied = 0;
+ BufferIn = NULL;
+ BufferInSize = 0;
+ BufferInPtr = NULL;
+ RecordHeaderIn = NULL;
+ TempRecordHeader = NULL;
+ BufferOut = NULL;
+ BufferOutSize = 0;
+ Ret = 0;
+
+ //
+ // Calculate the size according to the fragment table.
+ //
+ for (Index = 0; Index < *FragmentCount; Index++) {
+ BufferInSize += (*FragmentTable)[Index].FragmentLength;
+ }
+
+ //
+ // Allocate buffer for processing data
+ //
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Copy all TLS plain record header and payload to ProcessBuffer
+ //
+ for (Index = 0; Index < *FragmentCount; Index++) {
+ CopyMem (
+ (BufferIn + BytesCopied),
+ (*FragmentTable)[Index].FragmentBuffer,
+ (*FragmentTable)[Index].FragmentLength
+ );
+ BytesCopied += (*FragmentTable)[Index].FragmentLength;
+ }
+
+ BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Parsing buffer. Received packet may have multiply TLS record message.
+ //
+ BufferInPtr = BufferIn;
+ TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
+ while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
+ RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
+ ASSERT (RecordHeaderIn->ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA);
+ ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);
+
+ Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn), RECORD_HEADER_LEN + ThisCipherMessageSize);
+ if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) {
+ FreePool (BufferIn);
+ TlsInstance->TlsSessionState = EfiTlsSessionError;
+ return EFI_ABORTED;
+ }
+
+ Ret = 0;
+ Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1), MAX_BUFFER_SIZE);
+
+ if (Ret > 0) {
+ ThisPlainMessageSize = (UINT16) Ret;
+ } else {
+ ThisPlainMessageSize = 0;
+ }
+
+ CopyMem (TempRecordHeader, RecordHeaderIn, RECORD_HEADER_LEN);
+ TempRecordHeader->Length = ThisPlainMessageSize;
+ BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize;
+
+ BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize;
+ TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize;
+ }
+
+ FreePool (BufferIn);
+
+ //
+ // The caller will take responsible to handle the original fragment table
+ //
+ *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
+ if (*FragmentTable == NULL) {
+ FreePool (BufferOut);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ (*FragmentTable)[0].FragmentBuffer = BufferOut;
+ (*FragmentTable)[0].FragmentLength = BufferOutSize;
+ *FragmentCount = 1;
+
+ return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/TlsDxe/TlsImpl.h b/NetworkPkg/TlsDxe/TlsImpl.h
new file mode 100644
index 0000000..b0615cb
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsImpl.h
@@ -0,0 +1,315 @@
+/** @file
+ Header file of Miscellaneous Routines for TlsDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_TLS_IMPL_H__
+#define __EFI_TLS_IMPL_H__
+
+//
+// Libraries
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/NetLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/TlsLib.h>
+
+//
+// Consumed Protocols
+//
+#include <Protocol/Tls.h>
+#include <Protocol/TlsConfig.h>
+
+#include <IndustryStandard/Tls1.h>
+
+#include "TlsDriver.h"
+
+//
+// Protocol instances
+//
+extern EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding;
+extern EFI_TLS_PROTOCOL mTlsProtocol;
+extern EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol;
+
+#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) + Length(2)
+
+#define MAX_BUFFER_SIZE 32768
+
+/**
+ Encrypt the message listed in fragment.
+
+ @param[in] TlsInstance The pointer to the TLS instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment.
+ On input these fragments contain the TLS header and
+ plain text TLS payload;
+ On output these fragments contain the TLS header and
+ cipher text TLS payload.
+ @param[in] FragmentCount Number of fragment.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other errors as indicated.
+**/
+EFI_STATUS
+TlsEcryptPacket (
+ IN TLS_INSTANCE *TlsInstance,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount
+ );
+
+/**
+ Decrypt the message listed in fragment.
+
+ @param[in] TlsInstance The pointer to the TLS instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment.
+ On input these fragments contain the TLS header and
+ cipher text TLS payload;
+ On output these fragments contain the TLS header and
+ plain text TLS payload.
+ @param[in] FragmentCount Number of fragment.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other errors as indicated.
+**/
+EFI_STATUS
+TlsDecryptPacket (
+ IN TLS_INSTANCE *TlsInstance,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount
+ );
+
+/**
+ Set TLS session data.
+
+ The SetSessionData() function set data for a new TLS session. All session data should
+ be set before BuildResponsePacket() invoked.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in] Data Pointer to session data.
+ @param[in] DataSize Total size of session data.
+
+ @retval EFI_SUCCESS The TLS session data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_ACCESS_DENIED If the DataType is one of below:
+ EfiTlsClientRandom
+ EfiTlsServerRandom
+ EfiTlsKeyMaterial
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionStateNotStarted.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionData (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Get TLS session data.
+
+ The GetSessionData() function return the TLS session information.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in, out] Data Pointer to session data.
+ @param[in, out] DataSize Total size of session data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS session data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS session data is not found.
+ @retval EFI_NOT_READY The DataType is not ready in current session state.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionData (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Build response packet according to TLS state machine. This function is only valid for
+ alert, handshake and change_cipher_spec content type.
+
+ The BuildResponsePacket() function builds TLS response packet in response to the TLS
+ request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
+ RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
+ will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
+ session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
+ session has errors and the response packet needs to be Alert message based on error
+ type.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL
+ means TLS need initiate the TLS session and response
+ packet need to be ClientHello.
+ @param[in] RequestSize Packet size in bytes for the most recently received TLS
+ packet. 0 is only valid when RequestBuffer is NULL.
+ @param[out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ RequestBuffer is NULL but RequestSize is NOT 0.
+ RequestSize is 0 but RequestBuffer is NOT NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+ @retval EFI_NOT_READY Current TLS session state is NOT ready to build
+ ResponsePacket.
+ @retval EFI_ABORTED Something wrong build response packet.
+**/
+EFI_STATUS
+EFIAPI
+TlsBuildResponsePacket (
+ IN EFI_TLS_PROTOCOL *This,
+ IN UINT8 *RequestBuffer, OPTIONAL
+ IN UINTN RequestSize, OPTIONAL
+ OUT UINT8 *Buffer, OPTIONAL
+ IN OUT UINTN *BufferSize
+ );
+
+/**
+ Decrypt or encrypt TLS packet during session. This function is only valid after
+ session connected and for application_data content type.
+
+ The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take
+ responsible to handle the original FragmentTable while
+ it may be reallocated in TLS driver. If CryptMode is
+ EfiTlsEncrypt, on input these fragments contain the TLS
+ header and plain text TLS APP payload; on output these
+ fragments contain the TLS header and cipher text TLS
+ APP payload. If CryptMode is EfiTlsDecrypt, on input
+ these fragments contain the TLS header and cipher text
+ TLS APP payload; on output these fragments contain the
+ TLS header and plain text TLS APP payload.
+ @param[in] FragmentCount Number of fragment.
+ @param[in] CryptMode Crypt mode.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ FragmentTable is NULL.
+ FragmentCount is NULL.
+ CryptoMode is invalid.
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionDataTransferring.
+ @retval EFI_ABORTED Something wrong decryption the message. TLS session
+ status will become EfiTlsSessionError. The caller need
+ call BuildResponsePacket() to generate Error Alert
+ message and send it out.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation.
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessPacket (
+ IN EFI_TLS_PROTOCOL *This,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount,
+ IN EFI_TLS_CRYPT_MODE CryptMode
+ );
+
+/**
+ Set TLS configuration data.
+
+ The SetData() function sets TLS configuration to non-volatile storage or volatile
+ storage.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in] Data Pointer to configuration data.
+ @param[in] DataSize Total size of configuration data.
+
+ @retval EFI_SUCCESS The TLS configuration data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationSetData (
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Get TLS configuration data.
+
+ The GetData() function gets TLS configuration.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in, out] Data Pointer to configuration data.
+ @param[in, out] DataSize Total size of configuration data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS configuration data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS configuration data is not found.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationGetData (
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ );
+
+#endif
diff --git a/NetworkPkg/TlsDxe/TlsProtocol.c b/NetworkPkg/TlsDxe/TlsProtocol.c
new file mode 100644
index 0000000..bc617e1
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsProtocol.c
@@ -0,0 +1,632 @@
+/** @file
+ Implementation of EFI TLS Protocol Interfaces.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsImpl.h"
+
+EFI_TLS_PROTOCOL mTlsProtocol = {
+ TlsSetSessionData,
+ TlsGetSessionData,
+ TlsBuildResponsePacket,
+ TlsProcessPacket
+};
+
+/**
+ Set TLS session data.
+
+ The SetSessionData() function set data for a new TLS session. All session data should
+ be set before BuildResponsePacket() invoked.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in] Data Pointer to session data.
+ @param[in] DataSize Total size of session data.
+
+ @retval EFI_SUCCESS The TLS session data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_ACCESS_DENIED If the DataType is one of below:
+ EfiTlsClientRandom
+ EfiTlsServerRandom
+ EfiTlsKeyMaterial
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionStateNotStarted.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionData (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+ UINT16 *CipherId;
+ UINTN Index;
+
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+ CipherId = NULL;
+
+ if (This == NULL || Data == NULL || DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+ if (DataType != EfiTlsSessionState && Instance->TlsSessionState != EfiTlsSessionNotStarted){
+ Status = EFI_NOT_READY;
+ goto ON_EXIT;
+ }
+
+ switch (DataType) {
+ //
+ // Session Configuration
+ //
+ case EfiTlsVersion:
+ if (DataSize != sizeof (EFI_TLS_VERSION)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)->Major, ((EFI_TLS_VERSION *) Data)->Minor);
+ break;
+ case EfiTlsConnectionEnd:
+ if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data));
+ break;
+ case EfiTlsCipherList:
+ CipherId = AllocatePool (DataSize);
+ if (CipherId == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {
+ *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));
+ }
+
+ Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER));
+
+ FreePool (CipherId);
+ break;
+ case EfiTlsCompressionMethod:
+ //
+ // TLS seems only define one CompressionMethod.null, which specifies that data exchanged via the
+ // record protocol will not be compressed.
+ // More information from OpenSSL: http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compression_method.html
+ // The TLS RFC does however not specify compression methods or their corresponding identifiers,
+ // so there is currently no compatible way to integrate compression with unknown peers.
+ // It is therefore currently not recommended to integrate compression into applications.
+ // Applications for non-public use may agree on certain compression methods.
+ // Using different compression methods with the same identifier will lead to connection failure.
+ //
+ for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); Index++) {
+ Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index));
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ break;
+ case EfiTlsExtensionData:
+ Status = EFI_UNSUPPORTED;
+ goto ON_EXIT;
+ case EfiTlsVerifyMethod:
+ if (DataSize != sizeof (EFI_TLS_VERIFY)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data));
+ break;
+ case EfiTlsSessionID:
+ if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Status = TlsSetSessionId (
+ Instance->TlsConn,
+ ((EFI_TLS_SESSION_ID *) Data)->Data,
+ ((EFI_TLS_SESSION_ID *) Data)->Length
+ );
+ break;
+ case EfiTlsSessionState:
+ if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data;
+ break;
+ //
+ // Session information
+ //
+ case EfiTlsClientRandom:
+ Status = EFI_ACCESS_DENIED;
+ break;
+ case EfiTlsServerRandom:
+ Status = EFI_ACCESS_DENIED;
+ break;
+ case EfiTlsKeyMaterial:
+ Status = EFI_ACCESS_DENIED;
+ break;
+ //
+ // Unsupported type.
+ //
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Get TLS session data.
+
+ The GetSessionData() function return the TLS session information.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in, out] Data Pointer to session data.
+ @param[in, out] DataSize Total size of session data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS session data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS session data is not found.
+ @retval EFI_NOT_READY The DataType is not ready in current session state.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionData (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+ if (Instance->TlsSessionState == EfiTlsSessionNotStarted &&
+ (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom ||
+ DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) {
+ Status = EFI_NOT_READY;
+ goto ON_EXIT;
+ }
+
+ switch (DataType) {
+ case EfiTlsVersion:
+ if (*DataSize < sizeof (EFI_TLS_VERSION)) {
+ *DataSize = sizeof (EFI_TLS_VERSION);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_VERSION);
+ *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn));
+ break;
+ case EfiTlsConnectionEnd:
+ if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {
+ *DataSize = sizeof (EFI_TLS_CONNECTION_END);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_CONNECTION_END);
+ *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn);
+ break;
+ case EfiTlsCipherList:
+ //
+ // Get the current session cipher suite.
+ //
+ if (*DataSize < sizeof (EFI_TLS_CIPHER)) {
+ *DataSize = sizeof (EFI_TLS_CIPHER);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof(EFI_TLS_CIPHER);
+ Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data);
+ *((UINT16 *) Data) = HTONS (*((UINT16 *) Data));
+ break;
+ case EfiTlsCompressionMethod:
+ //
+ // Get the current session compression method.
+ //
+ if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {
+ *DataSize = sizeof (EFI_TLS_COMPRESSION);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_COMPRESSION);
+ Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *) Data);
+ break;
+ case EfiTlsExtensionData:
+ Status = EFI_UNSUPPORTED;
+ goto ON_EXIT;
+ case EfiTlsVerifyMethod:
+ if (*DataSize < sizeof (EFI_TLS_VERIFY)) {
+ *DataSize = sizeof (EFI_TLS_VERIFY);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_VERIFY);
+ *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn);
+ break;
+ case EfiTlsSessionID:
+ if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {
+ *DataSize = sizeof (EFI_TLS_SESSION_ID);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_SESSION_ID);
+ Status = TlsGetSessionId (
+ Instance->TlsConn,
+ ((EFI_TLS_SESSION_ID *) Data)->Data,
+ &(((EFI_TLS_SESSION_ID *) Data)->Length)
+ );
+ break;
+ case EfiTlsSessionState:
+ if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {
+ *DataSize = sizeof (EFI_TLS_SESSION_STATE);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_SESSION_STATE);
+ CopyMem (Data, &Instance->TlsSessionState, *DataSize);
+ break;
+ case EfiTlsClientRandom:
+ if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
+ *DataSize = sizeof (EFI_TLS_RANDOM);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_RANDOM);
+ TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data);
+ break;
+ case EfiTlsServerRandom:
+ if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
+ *DataSize = sizeof (EFI_TLS_RANDOM);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_RANDOM);
+ TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data);
+ break;
+ case EfiTlsKeyMaterial:
+ if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {
+ *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
+ Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data);
+ break;
+ //
+ // Unsupported type.
+ //
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Build response packet according to TLS state machine. This function is only valid for
+ alert, handshake and change_cipher_spec content type.
+
+ The BuildResponsePacket() function builds TLS response packet in response to the TLS
+ request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
+ RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
+ will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
+ session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
+ session has errors and the response packet needs to be Alert message based on error
+ type.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL
+ means TLS need initiate the TLS session and response
+ packet need to be ClientHello.
+ @param[in] RequestSize Packet size in bytes for the most recently received TLS
+ packet. 0 is only valid when RequestBuffer is NULL.
+ @param[out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ RequestBuffer is NULL but RequestSize is NOT 0.
+ RequestSize is 0 but RequestBuffer is NOT NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+ @retval EFI_NOT_READY Current TLS session state is NOT ready to build
+ ResponsePacket.
+ @retval EFI_ABORTED Something wrong build response packet.
+**/
+EFI_STATUS
+EFIAPI
+TlsBuildResponsePacket (
+ IN EFI_TLS_PROTOCOL *This,
+ IN UINT8 *RequestBuffer, OPTIONAL
+ IN UINTN RequestSize, OPTIONAL
+ OUT UINT8 *Buffer, OPTIONAL
+ IN OUT UINTN *BufferSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if ((This == NULL) || (BufferSize == NULL) ||
+ (RequestBuffer == NULL && RequestSize != 0) ||
+ (RequestBuffer != NULL && RequestSize == 0) ||
+ (Buffer == NULL && *BufferSize !=0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+ if(RequestBuffer == NULL && RequestSize == 0) {
+ switch (Instance->TlsSessionState) {
+ case EfiTlsSessionNotStarted:
+ //
+ // ClientHello.
+ //
+ Status = TlsDoHandshake (
+ Instance->TlsConn,
+ NULL,
+ 0,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // *BufferSize should not be zero when ClientHello.
+ //
+ if (*BufferSize == 0) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ Instance->TlsSessionState = EfiTlsSessionHandShaking;
+
+ break;
+ case EfiTlsSessionClosing:
+ //
+ // TLS session will be closed and response packet needs to be CloseNotify.
+ //
+ Status = TlsCloseNotify (
+ Instance->TlsConn,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // *BufferSize should not be zero when build CloseNotify message.
+ //
+ if (*BufferSize == 0) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ break;
+ case EfiTlsSessionError:
+ //
+ // TLS session has errors and the response packet needs to be Alert
+ // message based on error type.
+ //
+ Status = TlsHandeAlert (
+ Instance->TlsConn,
+ NULL,
+ 0,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ break;
+ default:
+ //
+ // Current TLS session state is NOT ready to build ResponsePacket.
+ //
+ Status = EFI_NOT_READY;
+ }
+ } else {
+ //
+ // 1. Received packet may have multiply TLS record messages.
+ // 2. One TLS record message may have multiply handshake protocol.
+ // 3. Some errors may be happened in handshake.
+ // TlsDoHandshake() can handle all of those cases.
+ //
+ if (TlsInHandshake (Instance->TlsConn)) {
+ Status = TlsDoHandshake (
+ Instance->TlsConn,
+ RequestBuffer,
+ RequestSize,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ if (!TlsInHandshake (Instance->TlsConn)) {
+ Instance->TlsSessionState = EfiTlsSessionDataTransferring;
+ }
+ } else {
+ //
+ // Must be alert message, Decrypt it and build the ResponsePacket.
+ //
+ ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType == TLS_CONTENT_TYPE_ALERT);
+
+ Status = TlsHandeAlert (
+ Instance->TlsConn,
+ RequestBuffer,
+ RequestSize,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ Instance->TlsSessionState = EfiTlsSessionError;
+ }
+
+ goto ON_EXIT;
+ }
+ }
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Decrypt or encrypt TLS packet during session. This function is only valid after
+ session connected and for application_data content type.
+
+ The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take
+ responsible to handle the original FragmentTable while
+ it may be reallocated in TLS driver. If CryptMode is
+ EfiTlsEncrypt, on input these fragments contain the TLS
+ header and plain text TLS APP payload; on output these
+ fragments contain the TLS header and cipher text TLS
+ APP payload. If CryptMode is EfiTlsDecrypt, on input
+ these fragments contain the TLS header and cipher text
+ TLS APP payload; on output these fragments contain the
+ TLS header and plain text TLS APP payload.
+ @param[in] FragmentCount Number of fragment.
+ @param[in] CryptMode Crypt mode.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ FragmentTable is NULL.
+ FragmentCount is NULL.
+ CryptoMode is invalid.
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionDataTransferring.
+ @retval EFI_ABORTED Something wrong decryption the message. TLS session
+ status will become EfiTlsSessionError. The caller need
+ call BuildResponsePacket() to generate Error Alert
+ message and send it out.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation.
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessPacket (
+ IN EFI_TLS_PROTOCOL *This,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount,
+ IN EFI_TLS_CRYPT_MODE CryptMode
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+ if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
+ Status = EFI_NOT_READY;
+ goto ON_EXIT;
+ }
+
+ //
+ // Packet sent or received may have multiply TLS record message(Application data type).
+ // So,on input these fragments contain the TLS header and TLS APP payload;
+ // on output these fragments also contain the TLS header and TLS APP payload.
+ //
+ switch (CryptMode) {
+ case EfiTlsEncrypt:
+ Status = TlsEcryptPacket (Instance, FragmentTable, FragmentCount);
+ break;
+ case EfiTlsDecrypt:
+ Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
2016-12-14 7:34 ` [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL Jiaxin Wu
@ 2016-12-14 8:41 ` Fu, Siyuan
2016-12-15 7:24 ` Wu, Jiaxin
0 siblings, 1 reply; 37+ messages in thread
From: Fu, Siyuan @ 2016-12-14 8:41 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Ye, Ting, Zhang, Lubo, Long, Qin, Thomas Palmer
Hi, Jiaxin
Some comments as below:
In TlsImpl.c
Should the ASSERT in line 104 be an error handling? I mean is the input buffer coming from external input, and have we checked ContentType within it?
Seems the TempRecordHeader pointer will be modified in the while loop, shouldn't the 3rd parameter be the reminding buffer size of the output buffer?
Should we return error if the TlsCtrlTrafficOut return a failure?
Similar questions for the decrypt packet function.
Best Regards,
Siyuan
-----Original Message-----
From: Wu, Jiaxin
Sent: 2016年12月14日 15:34
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
This patch is the implementation of EFI TLS Service Binding
Protocol, EFI TLS Protocol and EFI TLS Configuration Protocol
Interfaces.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/TlsDxe/TlsConfigProtocol.c | 152 ++++++++
NetworkPkg/TlsDxe/TlsDriver.c | 498 +++++++++++++++++++++++++++
NetworkPkg/TlsDxe/TlsDriver.h | 237 +++++++++++++
NetworkPkg/TlsDxe/TlsDxe.inf | 65 ++++
NetworkPkg/TlsDxe/TlsDxe.uni | 25 ++
| 18 +
NetworkPkg/TlsDxe/TlsImpl.c | 270 +++++++++++++++
NetworkPkg/TlsDxe/TlsImpl.h | 315 +++++++++++++++++
NetworkPkg/TlsDxe/TlsProtocol.c | 632 ++++++++++++++++++++++++++++++++++
9 files changed, 2212 insertions(+)
create mode 100644 NetworkPkg/TlsDxe/TlsConfigProtocol.c
create mode 100644 NetworkPkg/TlsDxe/TlsDriver.c
create mode 100644 NetworkPkg/TlsDxe/TlsDriver.h
create mode 100644 NetworkPkg/TlsDxe/TlsDxe.inf
create mode 100644 NetworkPkg/TlsDxe/TlsDxe.uni
create mode 100644 NetworkPkg/TlsDxe/TlsDxeExtra.uni
create mode 100644 NetworkPkg/TlsDxe/TlsImpl.c
create mode 100644 NetworkPkg/TlsDxe/TlsImpl.h
create mode 100644 NetworkPkg/TlsDxe/TlsProtocol.c
diff --git a/NetworkPkg/TlsDxe/TlsConfigProtocol.c b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
new file mode 100644
index 0000000..2ec79c9
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
@@ -0,0 +1,152 @@
+/** @file
+ Implementation of EFI TLS Configuration Protocol Interfaces.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsImpl.h"
+
+EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol = {
+ TlsConfigurationSetData,
+ TlsConfigurationGetData
+};
+
+/**
+ Set TLS configuration data.
+
+ The SetData() function sets TLS configuration to non-volatile storage or volatile
+ storage.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in] Data Pointer to configuration data.
+ @param[in] DataSize Total size of configuration data.
+
+ @retval EFI_SUCCESS The TLS configuration data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationSetData (
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL || Data == NULL || DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
+
+ switch (DataType) {
+ case EfiTlsConfigDataTypeCACertificate:
+ Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeHostPublicCert:
+ Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeHostPrivateKey:
+ Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeCertRevocationList:
+ Status = TlsSetCertRevocationList (Data, DataSize);
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Get TLS configuration data.
+
+ The GetData() function gets TLS configuration.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in, out] Data Pointer to configuration data.
+ @param[in, out] DataSize Total size of configuration data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS configuration data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS configuration data is not found.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationGetData (
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
+
+ switch (DataType) {
+ case EfiTlsConfigDataTypeCACertificate:
+ Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeHostPublicCert:
+ Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeHostPrivateKey:
+ Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize);
+ break;
+ case EfiTlsConfigDataTypeCertRevocationList:
+ Status = TlsGetCertRevocationList (Data, DataSize);
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.c
new file mode 100644
index 0000000..0a75c39
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDriver.c
@@ -0,0 +1,498 @@
+/** @file
+ The Driver Binding and Service Binding Protocol for TlsDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsImpl.h"
+
+EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
+ TlsServiceBindingCreateChild,
+ TlsServiceBindingDestroyChild
+};
+
+/**
+ Release all the resources used by the TLS instance.
+
+ @param[in] Instance The TLS instance data.
+
+**/
+VOID
+TlsCleanInstance (
+ IN TLS_INSTANCE *Instance
+ )
+{
+ if (Instance != NULL) {
+ if (Instance->TlsConn != NULL) {
+ TlsFree (Instance->TlsConn);
+ }
+
+ FreePool (Instance);
+ }
+}
+
+/**
+ Create the TLS instance and initialize it.
+
+ @param[in] Service The pointer to the TLS service.
+ @param[out] Instance The pointer to the TLS instance.
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+ @retval EFI_SUCCESS The TLS instance is created.
+
+**/
+EFI_STATUS
+TlsCreateInstance (
+ IN TLS_SERVICE *Service,
+ OUT TLS_INSTANCE **Instance
+ )
+{
+ TLS_INSTANCE *TlsInstance;
+
+ *Instance = NULL;
+
+ TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
+ if (TlsInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
+ InitializeListHead (&TlsInstance->Link);
+ TlsInstance->InDestroy = FALSE;
+ TlsInstance->Service = Service;
+
+ CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
+ CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof (TlsInstance->TlsConfig));
+
+ TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
+
+ *Instance = TlsInstance;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Release all the resources used by the TLS service binding instance.
+
+ @param[in] Service The TLS service data.
+
+**/
+VOID
+TlsCleanService (
+ IN TLS_SERVICE *Service
+ )
+{
+ if (Service != NULL) {
+ if (Service->TlsCtx != NULL) {
+ TlsCtxFree (Service->TlsCtx);
+ }
+
+ FreePool (Service);
+ }
+}
+
+/**
+ Create then initialize a TLS service.
+
+ @param[in] Image ImageHandle of the TLS driver
+ @param[out] Service The service for TLS driver
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service.
+ @retval EFI_SUCCESS The service is created for the driver.
+
+**/
+EFI_STATUS
+TlsCreateService (
+ IN EFI_HANDLE Image,
+ OUT TLS_SERVICE **Service
+ )
+{
+ EFI_STATUS Status;
+ TLS_SERVICE *TlsService;
+
+ Status = EFI_SUCCESS;
+ *Service = NULL;
+
+ ASSERT (Service != NULL);
+
+ //
+ // Allocate a TLS Service Data
+ //
+ TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
+ if (TlsService == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize TLS Service Data
+ //
+ TlsService->Signature = TLS_SERVICE_SIGNATURE;
+ CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof (TlsService->ServiceBinding));
+ TlsService->TlsChildrenNum = 0;
+ InitializeListHead (&TlsService->TlsChildrenList);
+ TlsService->ImageHandle = Image;
+
+ *Service = TlsService;
+
+ return Status;
+}
+
+/**
+ Unloads an image.
+
+ @param[in] ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleNum;
+ EFI_HANDLE *HandleBuffer;
+ UINT32 Index;
+ EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
+ TLS_SERVICE *TlsService;
+
+ HandleBuffer = NULL;
+ ServiceBinding = NULL;
+ TlsService = NULL;
+
+ //
+ // Locate all the handles with Tls service binding protocol.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiTlsServiceBindingProtocolGuid,
+ NULL,
+ &HandleNum,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < HandleNum; Index++) {
+ //
+ // Firstly, find ServiceBinding interface
+ //
+ Status = gBS->OpenProtocol (
+ HandleBuffer[Index],
+ &gEfiTlsServiceBindingProtocolGuid,
+ (VOID **) &ServiceBinding,
+ ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
+
+ //
+ // Then, uninstall ServiceBinding interface
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ HandleBuffer[Index],
+ &gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TlsCleanService (TlsService);
+ }
+
+ if (HandleBuffer != NULL) {
+ FreePool (HandleBuffer);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ TLS_SERVICE *TlsService;
+
+ //
+ // Create TLS Service
+ //
+ Status = TlsCreateService (ImageHandle, &TlsService);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (TlsService != NULL);
+
+ //
+ // Initializes the OpenSSL library.
+ //
+ TlsInitialize ();
+
+ //
+ // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
+ // connections. TLS 1.0 is used as the default version.
+ //
+ TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR, TLS10_PROTOCOL_VERSION_MINOR);
+ if (TlsService->TlsCtx == NULL) {
+ FreePool (TlsService);
+ return EFI_ABORTED;
+ }
+
+ //
+ // Install the TlsServiceBinding Protocol onto Handle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &TlsService->Handle,
+ &gEfiTlsServiceBindingProtocolGuid,
+ &TlsService->ServiceBinding,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_CLEAN_SERVICE;
+ }
+
+ return Status;
+
+ON_CLEAN_SERVICE:
+ TlsCleanService (TlsService);
+
+ return Status;
+}
+
+/**
+ Creates a child handle and installs a protocol.
+
+ The CreateChild() function installs a protocol on ChildHandle.
+ If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+ If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
+ then a new handle is created. If it is a pointer to an existing UEFI handle,
+ then the protocol is added to the existing UEFI handle.
+
+ @retval EFI_SUCCES The protocol was added to ChildHandle.
+ @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
+ the child.
+ @retval other The child handle was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingCreateChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE *ChildHandle
+ )
+{
+ TLS_SERVICE *TlsService;
+ TLS_INSTANCE *TlsInstance;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ if ((This == NULL) || (ChildHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TlsService = TLS_SERVICE_FROM_THIS (This);
+
+ Status = TlsCreateInstance (TlsService, &TlsInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (TlsInstance != NULL);
+
+ //
+ // Create a new TLS connection object.
+ //
+ TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
+ if (TlsInstance->TlsConn == NULL) {
+ Status = EFI_ABORTED;
+ goto ON_ERROR;
+ }
+
+ //
+ // Set default ConnectionEnd to EfiTlsClient
+ //
+ Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
+ // Install TLS protocol and configuration protocol onto ChildHandle
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ ChildHandle,
+ &gEfiTlsProtocolGuid,
+ &TlsInstance->Tls,
+ &gEfiTlsConfigurationProtocolGuid,
+ &TlsInstance->TlsConfig,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ TlsInstance->ChildHandle = *ChildHandle;
+
+ //
+ // Add it to the TLS service's child list.
+ //
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
+ TlsService->TlsChildrenNum++;
+
+ gBS->RestoreTPL (OldTpl);
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+ TlsCleanInstance (TlsInstance);
+ return Status;
+}
+
+/**
+ Destroys a child handle with a protocol installed on it.
+
+ The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+ that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+ last protocol on ChildHandle, then ChildHandle is destroyed.
+
+ @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param ChildHandle Handle of the child to destroy.
+
+ @retval EFI_SUCCES The protocol was removed from ChildHandle.
+ @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.
+ @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
+ because its services are being used.
+ @retval other The child handle was not destroyed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingDestroyChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ChildHandle
+ )
+{
+ TLS_SERVICE *TlsService;
+ TLS_INSTANCE *TlsInstance;
+
+ EFI_TLS_PROTOCOL *Tls;
+ EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ if ((This == NULL) || (ChildHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TlsService = TLS_SERVICE_FROM_THIS (This);
+
+ //
+ // Find TLS protocol interface installed in ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTlsProtocolGuid,
+ (VOID **) &Tls,
+ TlsService->ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Find TLS configuration protocol interface installed in ChildHandle
+ //
+ Status = gBS->OpenProtocol (
+ ChildHandle,
+ &gEfiTlsConfigurationProtocolGuid,
+ (VOID **) &TlsConfig,
+ TlsService->ImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ TlsInstance = TLS_INSTANCE_FROM_PROTOCOL_THIS (Tls);
+
+ if (TlsInstance->Service != TlsService) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (TlsInstance->InDestroy) {
+ return EFI_SUCCESS;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ TlsInstance->InDestroy = TRUE;
+
+ //
+ // Uninstall the TLS protocol and TLS Configuration Protocol interface installed in ChildHandle.
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandle,
+ &gEfiTlsProtocolGuid,
+ Tls,
+ &gEfiTlsConfigurationProtocolGuid,
+ TlsConfig,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ RemoveEntryList (&TlsInstance->Link);
+ TlsService->TlsChildrenNum--;
+
+ gBS->RestoreTPL (OldTpl);
+
+ TlsCleanInstance (TlsInstance);
+
+ return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/TlsDxe/TlsDriver.h b/NetworkPkg/TlsDxe/TlsDriver.h
new file mode 100644
index 0000000..c3c30a8
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDriver.h
@@ -0,0 +1,237 @@
+/** @file
+ Header file of the Driver Binding and Service Binding Protocol for TlsDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_TLS_DRIVER_H__
+#define __EFI_TLS_DRIVER_H__
+
+#include <Uefi.h>
+
+//
+// Driver Protocols
+//
+#include <Protocol/ServiceBinding.h>
+
+//
+// Driver Version
+//
+#define TLS_VERSION 0x00000000
+
+#define TLS_SERVICE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'S')
+
+#define TLS_INSTANCE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'I')
+
+///
+/// TLS Service Data
+///
+typedef struct _TLS_SERVICE TLS_SERVICE;
+
+///
+/// TLS Instance Data
+///
+typedef struct _TLS_INSTANCE TLS_INSTANCE;
+
+
+struct _TLS_SERVICE {
+ UINT32 Signature;
+ EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
+
+ UINT16 TlsChildrenNum;
+ LIST_ENTRY TlsChildrenList;
+
+ //
+ // Handle to install TlsServiceBinding protocol.
+ //
+ EFI_HANDLE Handle;
+ EFI_HANDLE ImageHandle;
+
+ //
+ // Main SSL Context object which is created by a server or client once per program
+ // life-time and which holds mainly default values for the SSL object which are later
+ // created for the connections.
+ //
+ VOID *TlsCtx;
+};
+
+struct _TLS_INSTANCE {
+ UINT32 Signature;
+ LIST_ENTRY Link;
+
+ BOOLEAN InDestroy;
+
+ TLS_SERVICE *Service;
+ EFI_HANDLE ChildHandle;
+
+ EFI_TLS_PROTOCOL Tls;
+ EFI_TLS_CONFIGURATION_PROTOCOL TlsConfig;
+
+ EFI_TLS_SESSION_STATE TlsSessionState;
+
+ //
+ // Main SSL Connection which is created by a server or a client
+ // per established connection.
+ //
+ VOID *TlsConn;
+};
+
+
+#define TLS_SERVICE_FROM_THIS(a) \
+ CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE)
+
+#define TLS_INSTANCE_FROM_PROTOCOL_THIS(a) \
+ CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE)
+
+#define TLS_INSTANCE_FROM_CONFIGURATION_THIS(a) \
+ CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE)
+
+
+/**
+ Release all the resources used by the TLS instance.
+
+ @param[in] Instance The TLS instance data.
+
+**/
+VOID
+TlsCleanInstance (
+ IN TLS_INSTANCE *Instance
+ );
+
+/**
+ Create the TLS instance and initialize it.
+
+ @param[in] Service The pointer to the TLS service.
+ @param[out] Instance The pointer to the TLS instance.
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
+ @retval EFI_SUCCESS The TLS instance is created.
+
+**/
+EFI_STATUS
+TlsCreateInstance (
+ IN TLS_SERVICE *Service,
+ OUT TLS_INSTANCE **Instance
+ );
+
+/**
+ Release all the resources used by the TLS service binding instance.
+
+ @param[in] Service The TLS service data.
+
+**/
+VOID
+TlsCleanService (
+ IN TLS_SERVICE *Service
+ );
+
+/**
+ Create then initialize a TLS service.
+
+ @param[in] Image ImageHandle of the TLS driver
+ @param[out] Service The service for TLS driver
+
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create the service.
+ @retval EFI_SUCCESS The service is created for the driver.
+
+**/
+EFI_STATUS
+TlsCreateService (
+ IN EFI_HANDLE Image,
+ OUT TLS_SERVICE **Service
+ );
+
+/**
+ Unloads an image.
+
+ @param[in] ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsUnload (
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ Creates a child handle and installs a protocol.
+
+ The CreateChild() function installs a protocol on ChildHandle.
+ If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.
+ If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.
+
+ @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param[in] ChildHandle Pointer to the handle of the child to create. If it is NULL,
+ then a new handle is created. If it is a pointer to an existing UEFI handle,
+ then the protocol is added to the existing UEFI handle.
+
+ @retval EFI_SUCCES The protocol was added to ChildHandle.
+ @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
+ @retval EFI_OUT_OF_RESOURCES There are not enough resources available to create
+ the child.
+ @retval other The child handle was not created.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingCreateChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE *ChildHandle
+ );
+
+/**
+ Destroys a child handle with a protocol installed on it.
+
+ The DestroyChild() function does the opposite of CreateChild(). It removes a protocol
+ that was installed by CreateChild() from ChildHandle. If the removed protocol is the
+ last protocol on ChildHandle, then ChildHandle is destroyed.
+
+ @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.
+ @param ChildHandle Handle of the child to destroy.
+
+ @retval EFI_SUCCES The protocol was removed from ChildHandle.
+ @retval EFI_UNSUPPORTED ChildHandle does not support the protocol that is being removed.
+ @retval EFI_INVALID_PARAMETER Child handle is NULL.
+ @retval EFI_ACCESS_DENIED The protocol could not be removed from the ChildHandle
+ because its services are being used.
+ @retval other The child handle was not destroyed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsServiceBindingDestroyChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ChildHandle
+ );
+
+#endif
diff --git a/NetworkPkg/TlsDxe/TlsDxe.inf b/NetworkPkg/TlsDxe/TlsDxe.inf
new file mode 100644
index 0000000..dba3257
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxe.inf
@@ -0,0 +1,65 @@
+## @file
+# This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
+# EFI TLS Configuration Protocol.
+#
+# This module produces EFI TLS (Transport Layer Security) Protocol and EFI TLS
+# Service Binding Protocol, to provide TLS services.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TlsDxe
+ FILE_GUID = 3aceb0c0-3c72-11e4-9a56-74d435052646
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = TlsDriverEntryPoint
+ UNLOAD_IMAGE = TlsUnload
+ MODULE_UNI_FILE = TlsDxe.uni
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ CryptoPkg/CryptoPkg.dec
+
+[Sources]
+ TlsDriver.h
+ TlsDriver.c
+ TlsProtocol.c
+ TlsConfigProtocol.c
+ TlsImpl.h
+ TlsImpl.c
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ BaseLib
+ UefiLib
+ DebugLib
+ NetLib
+ BaseCryptLib
+ TlsLib
+
+[Protocols]
+ gEfiTlsServiceBindingProtocolGuid ## PRODUCES
+ gEfiTlsProtocolGuid ## PRODUCES
+ gEfiTlsConfigurationProtocolGuid ## PRODUCES
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ TlsDxeExtra.uni
diff --git a/NetworkPkg/TlsDxe/TlsDxe.uni b/NetworkPkg/TlsDxe/TlsDxe.uni
new file mode 100644
index 0000000..98c41ca
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxe.uni
@@ -0,0 +1,25 @@
+// /** @file
+// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and
+// EFI TLS Configuration Protocol.
+//
+// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS
+// Service Binding Protocol, and EFI TLS Configuration Protocol to provide TLS
+// services.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "UEFI TLS service"
+
+#string STR_MODULE_DESCRIPTION #language en-US "This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS Configuration Protocol to provide EFI TLS services."
+
--git a/NetworkPkg/TlsDxe/TlsDxeExtra.uni b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
new file mode 100644
index 0000000..a38582a
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
@@ -0,0 +1,18 @@
+// /** @file
+// TlsDxe Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php.
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"EFI TLS DXE Driver"
diff --git a/NetworkPkg/TlsDxe/TlsImpl.c b/NetworkPkg/TlsDxe/TlsImpl.c
new file mode 100644
index 0000000..5fb1e78
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsImpl.c
@@ -0,0 +1,270 @@
+/** @file
+ The Miscellaneous Routines for TlsDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsImpl.h"
+
+/**
+ Encrypt the message listed in fragment.
+
+ @param[in] TlsInstance The pointer to the TLS instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment.
+ On input these fragments contain the TLS header and
+ plain text TLS payload;
+ On output these fragments contain the TLS header and
+ cipher text TLS payload.
+ @param[in] FragmentCount Number of fragment.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other errors as indicated.
+**/
+EFI_STATUS
+TlsEcryptPacket (
+ IN TLS_INSTANCE *TlsInstance,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount
+ )
+{
+ UINTN Index;
+ UINT32 BytesCopied;
+ UINT32 BufferInSize;
+ UINT8 *BufferIn;
+ UINT8 *BufferInPtr;
+ TLS_RECORD_HEADER *RecordHeaderIn;
+ UINT16 ThisPlainMessageSize;
+ TLS_RECORD_HEADER *TempRecordHeader;
+ UINT16 ThisMessageSize;
+ UINT32 BufferOutSize;
+ UINT8 *BufferOut;
+ INTN Ret;
+
+ BytesCopied = 0;
+ BufferInSize = 0;
+ BufferIn = NULL;
+ BufferInPtr = NULL;
+ RecordHeaderIn = NULL;
+ TempRecordHeader = NULL;
+ BufferOutSize = 0;
+ BufferOut = NULL;
+ Ret = 0;
+
+ //
+ // Calculate the size according to the fragment table.
+ //
+ for (Index = 0; Index < *FragmentCount; Index++) {
+ BufferInSize += (*FragmentTable)[Index].FragmentLength;
+ }
+
+ //
+ // Allocate buffer for processing data.
+ //
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Copy all TLS plain record header and payload into ProcessBuffer.
+ //
+ for (Index = 0; Index < *FragmentCount; Index++) {
+ CopyMem (
+ (BufferIn + BytesCopied),
+ (*FragmentTable)[Index].FragmentBuffer,
+ (*FragmentTable)[Index].FragmentLength
+ );
+ BytesCopied += (*FragmentTable)[Index].FragmentLength;
+ }
+
+ BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Parsing buffer.
+ //
+ BufferInPtr = BufferIn;
+ TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
+ while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
+ RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
+ ASSERT (RecordHeaderIn->ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA);
+ ThisPlainMessageSize = RecordHeaderIn->Length;
+
+ TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1), ThisPlainMessageSize);
+
+ Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8 *)(TempRecordHeader), MAX_BUFFER_SIZE);
+
+ if (Ret > 0) {
+ ThisMessageSize = (UINT16) Ret;
+ } else {
+ ThisMessageSize = 0;
+ }
+
+ BufferOutSize += ThisMessageSize;
+
+ BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize;
+ TempRecordHeader += ThisMessageSize;
+ }
+
+ FreePool (BufferIn);
+
+ //
+ // The caller will take responsible to handle the original fragment table.
+ //
+ *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
+ if (*FragmentTable == NULL) {
+ FreePool (BufferOut);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ (*FragmentTable)[0].FragmentBuffer = BufferOut;
+ (*FragmentTable)[0].FragmentLength = BufferOutSize;
+ *FragmentCount = 1;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Decrypt the message listed in fragment.
+
+ @param[in] TlsInstance The pointer to the TLS instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment.
+ On input these fragments contain the TLS header and
+ cipher text TLS payload;
+ On output these fragments contain the TLS header and
+ plain text TLS payload.
+ @param[in] FragmentCount Number of fragment.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other errors as indicated.
+**/
+EFI_STATUS
+TlsDecryptPacket (
+ IN TLS_INSTANCE *TlsInstance,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount
+ )
+{
+ UINTN Index;
+ UINT32 BytesCopied;
+ UINT8 *BufferIn;
+ UINT32 BufferInSize;
+ UINT8 *BufferInPtr;
+ TLS_RECORD_HEADER *RecordHeaderIn;
+ UINT16 ThisCipherMessageSize;
+ TLS_RECORD_HEADER *TempRecordHeader;
+ UINT16 ThisPlainMessageSize;
+ UINT8 *BufferOut;
+ UINT32 BufferOutSize;
+ INTN Ret;
+
+ BytesCopied = 0;
+ BufferIn = NULL;
+ BufferInSize = 0;
+ BufferInPtr = NULL;
+ RecordHeaderIn = NULL;
+ TempRecordHeader = NULL;
+ BufferOut = NULL;
+ BufferOutSize = 0;
+ Ret = 0;
+
+ //
+ // Calculate the size according to the fragment table.
+ //
+ for (Index = 0; Index < *FragmentCount; Index++) {
+ BufferInSize += (*FragmentTable)[Index].FragmentLength;
+ }
+
+ //
+ // Allocate buffer for processing data
+ //
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Copy all TLS plain record header and payload to ProcessBuffer
+ //
+ for (Index = 0; Index < *FragmentCount; Index++) {
+ CopyMem (
+ (BufferIn + BytesCopied),
+ (*FragmentTable)[Index].FragmentBuffer,
+ (*FragmentTable)[Index].FragmentLength
+ );
+ BytesCopied += (*FragmentTable)[Index].FragmentLength;
+ }
+
+ BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Parsing buffer. Received packet may have multiply TLS record message.
+ //
+ BufferInPtr = BufferIn;
+ TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
+ while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
+ RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
+ ASSERT (RecordHeaderIn->ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA);
+ ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);
+
+ Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn), RECORD_HEADER_LEN + ThisCipherMessageSize);
+ if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) {
+ FreePool (BufferIn);
+ TlsInstance->TlsSessionState = EfiTlsSessionError;
+ return EFI_ABORTED;
+ }
+
+ Ret = 0;
+ Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1), MAX_BUFFER_SIZE);
+
+ if (Ret > 0) {
+ ThisPlainMessageSize = (UINT16) Ret;
+ } else {
+ ThisPlainMessageSize = 0;
+ }
+
+ CopyMem (TempRecordHeader, RecordHeaderIn, RECORD_HEADER_LEN);
+ TempRecordHeader->Length = ThisPlainMessageSize;
+ BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize;
+
+ BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize;
+ TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize;
+ }
+
+ FreePool (BufferIn);
+
+ //
+ // The caller will take responsible to handle the original fragment table
+ //
+ *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
+ if (*FragmentTable == NULL) {
+ FreePool (BufferOut);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ (*FragmentTable)[0].FragmentBuffer = BufferOut;
+ (*FragmentTable)[0].FragmentLength = BufferOutSize;
+ *FragmentCount = 1;
+
+ return EFI_SUCCESS;
+}
diff --git a/NetworkPkg/TlsDxe/TlsImpl.h b/NetworkPkg/TlsDxe/TlsImpl.h
new file mode 100644
index 0000000..b0615cb
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsImpl.h
@@ -0,0 +1,315 @@
+/** @file
+ Header file of Miscellaneous Routines for TlsDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_TLS_IMPL_H__
+#define __EFI_TLS_IMPL_H__
+
+//
+// Libraries
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/NetLib.h>
+#include <Library/BaseCryptLib.h>
+#include <Library/TlsLib.h>
+
+//
+// Consumed Protocols
+//
+#include <Protocol/Tls.h>
+#include <Protocol/TlsConfig.h>
+
+#include <IndustryStandard/Tls1.h>
+
+#include "TlsDriver.h"
+
+//
+// Protocol instances
+//
+extern EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding;
+extern EFI_TLS_PROTOCOL mTlsProtocol;
+extern EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol;
+
+#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) + Length(2)
+
+#define MAX_BUFFER_SIZE 32768
+
+/**
+ Encrypt the message listed in fragment.
+
+ @param[in] TlsInstance The pointer to the TLS instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment.
+ On input these fragments contain the TLS header and
+ plain text TLS payload;
+ On output these fragments contain the TLS header and
+ cipher text TLS payload.
+ @param[in] FragmentCount Number of fragment.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other errors as indicated.
+**/
+EFI_STATUS
+TlsEcryptPacket (
+ IN TLS_INSTANCE *TlsInstance,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount
+ );
+
+/**
+ Decrypt the message listed in fragment.
+
+ @param[in] TlsInstance The pointer to the TLS instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment.
+ On input these fragments contain the TLS header and
+ cipher text TLS payload;
+ On output these fragments contain the TLS header and
+ plain text TLS payload.
+ @param[in] FragmentCount Number of fragment.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other errors as indicated.
+**/
+EFI_STATUS
+TlsDecryptPacket (
+ IN TLS_INSTANCE *TlsInstance,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount
+ );
+
+/**
+ Set TLS session data.
+
+ The SetSessionData() function set data for a new TLS session. All session data should
+ be set before BuildResponsePacket() invoked.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in] Data Pointer to session data.
+ @param[in] DataSize Total size of session data.
+
+ @retval EFI_SUCCESS The TLS session data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_ACCESS_DENIED If the DataType is one of below:
+ EfiTlsClientRandom
+ EfiTlsServerRandom
+ EfiTlsKeyMaterial
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionStateNotStarted.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionData (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Get TLS session data.
+
+ The GetSessionData() function return the TLS session information.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in, out] Data Pointer to session data.
+ @param[in, out] DataSize Total size of session data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS session data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS session data is not found.
+ @retval EFI_NOT_READY The DataType is not ready in current session state.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionData (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ );
+
+/**
+ Build response packet according to TLS state machine. This function is only valid for
+ alert, handshake and change_cipher_spec content type.
+
+ The BuildResponsePacket() function builds TLS response packet in response to the TLS
+ request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
+ RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
+ will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
+ session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
+ session has errors and the response packet needs to be Alert message based on error
+ type.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL
+ means TLS need initiate the TLS session and response
+ packet need to be ClientHello.
+ @param[in] RequestSize Packet size in bytes for the most recently received TLS
+ packet. 0 is only valid when RequestBuffer is NULL.
+ @param[out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ RequestBuffer is NULL but RequestSize is NOT 0.
+ RequestSize is 0 but RequestBuffer is NOT NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+ @retval EFI_NOT_READY Current TLS session state is NOT ready to build
+ ResponsePacket.
+ @retval EFI_ABORTED Something wrong build response packet.
+**/
+EFI_STATUS
+EFIAPI
+TlsBuildResponsePacket (
+ IN EFI_TLS_PROTOCOL *This,
+ IN UINT8 *RequestBuffer, OPTIONAL
+ IN UINTN RequestSize, OPTIONAL
+ OUT UINT8 *Buffer, OPTIONAL
+ IN OUT UINTN *BufferSize
+ );
+
+/**
+ Decrypt or encrypt TLS packet during session. This function is only valid after
+ session connected and for application_data content type.
+
+ The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take
+ responsible to handle the original FragmentTable while
+ it may be reallocated in TLS driver. If CryptMode is
+ EfiTlsEncrypt, on input these fragments contain the TLS
+ header and plain text TLS APP payload; on output these
+ fragments contain the TLS header and cipher text TLS
+ APP payload. If CryptMode is EfiTlsDecrypt, on input
+ these fragments contain the TLS header and cipher text
+ TLS APP payload; on output these fragments contain the
+ TLS header and plain text TLS APP payload.
+ @param[in] FragmentCount Number of fragment.
+ @param[in] CryptMode Crypt mode.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ FragmentTable is NULL.
+ FragmentCount is NULL.
+ CryptoMode is invalid.
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionDataTransferring.
+ @retval EFI_ABORTED Something wrong decryption the message. TLS session
+ status will become EfiTlsSessionError. The caller need
+ call BuildResponsePacket() to generate Error Alert
+ message and send it out.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation.
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessPacket (
+ IN EFI_TLS_PROTOCOL *This,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount,
+ IN EFI_TLS_CRYPT_MODE CryptMode
+ );
+
+/**
+ Set TLS configuration data.
+
+ The SetData() function sets TLS configuration to non-volatile storage or volatile
+ storage.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in] Data Pointer to configuration data.
+ @param[in] DataSize Total size of configuration data.
+
+ @retval EFI_SUCCESS The TLS configuration data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationSetData (
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Get TLS configuration data.
+
+ The GetData() function gets TLS configuration.
+
+ @param[in] This Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+ @param[in] DataType Configuration data type.
+ @param[in, out] Data Pointer to configuration data.
+ @param[in, out] DataSize Total size of configuration data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS configuration data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS configuration data is not found.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigurationGetData (
+ IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
+ IN EFI_TLS_CONFIG_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ );
+
+#endif
diff --git a/NetworkPkg/TlsDxe/TlsProtocol.c b/NetworkPkg/TlsDxe/TlsProtocol.c
new file mode 100644
index 0000000..bc617e1
--- /dev/null
+++ b/NetworkPkg/TlsDxe/TlsProtocol.c
@@ -0,0 +1,632 @@
+/** @file
+ Implementation of EFI TLS Protocol Interfaces.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsImpl.h"
+
+EFI_TLS_PROTOCOL mTlsProtocol = {
+ TlsSetSessionData,
+ TlsGetSessionData,
+ TlsBuildResponsePacket,
+ TlsProcessPacket
+};
+
+/**
+ Set TLS session data.
+
+ The SetSessionData() function set data for a new TLS session. All session data should
+ be set before BuildResponsePacket() invoked.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in] Data Pointer to session data.
+ @param[in] DataSize Total size of session data.
+
+ @retval EFI_SUCCESS The TLS session data is set successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ Data is NULL.
+ DataSize is 0.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_ACCESS_DENIED If the DataType is one of below:
+ EfiTlsClientRandom
+ EfiTlsServerRandom
+ EfiTlsKeyMaterial
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionStateNotStarted.
+ @retval EFI_OUT_OF_RESOURCES Required system resources could not be allocated.
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSessionData (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+ UINT16 *CipherId;
+ UINTN Index;
+
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+ CipherId = NULL;
+
+ if (This == NULL || Data == NULL || DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+ if (DataType != EfiTlsSessionState && Instance->TlsSessionState != EfiTlsSessionNotStarted){
+ Status = EFI_NOT_READY;
+ goto ON_EXIT;
+ }
+
+ switch (DataType) {
+ //
+ // Session Configuration
+ //
+ case EfiTlsVersion:
+ if (DataSize != sizeof (EFI_TLS_VERSION)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)->Major, ((EFI_TLS_VERSION *) Data)->Minor);
+ break;
+ case EfiTlsConnectionEnd:
+ if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Status = TlsSetConnectionEnd (Instance->TlsConn, *((EFI_TLS_CONNECTION_END *) Data));
+ break;
+ case EfiTlsCipherList:
+ CipherId = AllocatePool (DataSize);
+ if (CipherId == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {
+ *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));
+ }
+
+ Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof (EFI_TLS_CIPHER));
+
+ FreePool (CipherId);
+ break;
+ case EfiTlsCompressionMethod:
+ //
+ // TLS seems only define one CompressionMethod.null, which specifies that data exchanged via the
+ // record protocol will not be compressed.
+ // More information from OpenSSL: http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compression_method.html
+ // The TLS RFC does however not specify compression methods or their corresponding identifiers,
+ // so there is currently no compatible way to integrate compression with unknown peers.
+ // It is therefore currently not recommended to integrate compression into applications.
+ // Applications for non-public use may agree on certain compression methods.
+ // Using different compression methods with the same identifier will lead to connection failure.
+ //
+ for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION); Index++) {
+ Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index));
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ break;
+ case EfiTlsExtensionData:
+ Status = EFI_UNSUPPORTED;
+ goto ON_EXIT;
+ case EfiTlsVerifyMethod:
+ if (DataSize != sizeof (EFI_TLS_VERIFY)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data));
+ break;
+ case EfiTlsSessionID:
+ if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Status = TlsSetSessionId (
+ Instance->TlsConn,
+ ((EFI_TLS_SESSION_ID *) Data)->Data,
+ ((EFI_TLS_SESSION_ID *) Data)->Length
+ );
+ break;
+ case EfiTlsSessionState:
+ if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data;
+ break;
+ //
+ // Session information
+ //
+ case EfiTlsClientRandom:
+ Status = EFI_ACCESS_DENIED;
+ break;
+ case EfiTlsServerRandom:
+ Status = EFI_ACCESS_DENIED;
+ break;
+ case EfiTlsKeyMaterial:
+ Status = EFI_ACCESS_DENIED;
+ break;
+ //
+ // Unsupported type.
+ //
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Get TLS session data.
+
+ The GetSessionData() function return the TLS session information.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] DataType TLS session data type.
+ @param[in, out] Data Pointer to session data.
+ @param[in, out] DataSize Total size of session data. On input, it means
+ the size of Data buffer. On output, it means the size
+ of copied Data buffer if EFI_SUCCESS, and means the
+ size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
+
+ @retval EFI_SUCCESS The TLS session data is got successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ DataSize is NULL.
+ Data is NULL if *DataSize is not zero.
+ @retval EFI_UNSUPPORTED The DataType is unsupported.
+ @retval EFI_NOT_FOUND The TLS session data is not found.
+ @retval EFI_NOT_READY The DataType is not ready in current session state.
+ @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
+**/
+EFI_STATUS
+EFIAPI
+TlsGetSessionData (
+ IN EFI_TLS_PROTOCOL *This,
+ IN EFI_TLS_SESSION_DATA_TYPE DataType,
+ IN OUT VOID *Data, OPTIONAL
+ IN OUT UINTN *DataSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+ if (Instance->TlsSessionState == EfiTlsSessionNotStarted &&
+ (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom ||
+ DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) {
+ Status = EFI_NOT_READY;
+ goto ON_EXIT;
+ }
+
+ switch (DataType) {
+ case EfiTlsVersion:
+ if (*DataSize < sizeof (EFI_TLS_VERSION)) {
+ *DataSize = sizeof (EFI_TLS_VERSION);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_VERSION);
+ *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn));
+ break;
+ case EfiTlsConnectionEnd:
+ if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {
+ *DataSize = sizeof (EFI_TLS_CONNECTION_END);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_CONNECTION_END);
+ *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn);
+ break;
+ case EfiTlsCipherList:
+ //
+ // Get the current session cipher suite.
+ //
+ if (*DataSize < sizeof (EFI_TLS_CIPHER)) {
+ *DataSize = sizeof (EFI_TLS_CIPHER);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof(EFI_TLS_CIPHER);
+ Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data);
+ *((UINT16 *) Data) = HTONS (*((UINT16 *) Data));
+ break;
+ case EfiTlsCompressionMethod:
+ //
+ // Get the current session compression method.
+ //
+ if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {
+ *DataSize = sizeof (EFI_TLS_COMPRESSION);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_COMPRESSION);
+ Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *) Data);
+ break;
+ case EfiTlsExtensionData:
+ Status = EFI_UNSUPPORTED;
+ goto ON_EXIT;
+ case EfiTlsVerifyMethod:
+ if (*DataSize < sizeof (EFI_TLS_VERIFY)) {
+ *DataSize = sizeof (EFI_TLS_VERIFY);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_VERIFY);
+ *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn);
+ break;
+ case EfiTlsSessionID:
+ if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {
+ *DataSize = sizeof (EFI_TLS_SESSION_ID);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_SESSION_ID);
+ Status = TlsGetSessionId (
+ Instance->TlsConn,
+ ((EFI_TLS_SESSION_ID *) Data)->Data,
+ &(((EFI_TLS_SESSION_ID *) Data)->Length)
+ );
+ break;
+ case EfiTlsSessionState:
+ if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {
+ *DataSize = sizeof (EFI_TLS_SESSION_STATE);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_SESSION_STATE);
+ CopyMem (Data, &Instance->TlsSessionState, *DataSize);
+ break;
+ case EfiTlsClientRandom:
+ if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
+ *DataSize = sizeof (EFI_TLS_RANDOM);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_RANDOM);
+ TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data);
+ break;
+ case EfiTlsServerRandom:
+ if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
+ *DataSize = sizeof (EFI_TLS_RANDOM);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_RANDOM);
+ TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data);
+ break;
+ case EfiTlsKeyMaterial:
+ if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {
+ *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto ON_EXIT;
+ }
+ *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
+ Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data);
+ break;
+ //
+ // Unsupported type.
+ //
+ default:
+ Status = EFI_UNSUPPORTED;
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Build response packet according to TLS state machine. This function is only valid for
+ alert, handshake and change_cipher_spec content type.
+
+ The BuildResponsePacket() function builds TLS response packet in response to the TLS
+ request packet specified by RequestBuffer and RequestSize. If RequestBuffer is NULL and
+ RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS session
+ will be initiated and the response packet needs to be ClientHello. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing, the TLS
+ session will be closed and response packet needs to be CloseNotify. If RequestBuffer is
+ NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the TLS
+ session has errors and the response packet needs to be Alert message based on error
+ type.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in] RequestBuffer Pointer to the most recently received TLS packet. NULL
+ means TLS need initiate the TLS session and response
+ packet need to be ClientHello.
+ @param[in] RequestSize Packet size in bytes for the most recently received TLS
+ packet. 0 is only valid when RequestBuffer is NULL.
+ @param[out] Buffer Pointer to the buffer to hold the built packet.
+ @param[in, out] BufferSize Pointer to the buffer size in bytes. On input, it is
+ the buffer size provided by the caller. On output, it
+ is the buffer size in fact needed to contain the
+ packet.
+
+ @retval EFI_SUCCESS The required TLS packet is built successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ RequestBuffer is NULL but RequestSize is NOT 0.
+ RequestSize is 0 but RequestBuffer is NOT NULL.
+ BufferSize is NULL.
+ Buffer is NULL if *BufferSize is not zero.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the response packet.
+ @retval EFI_NOT_READY Current TLS session state is NOT ready to build
+ ResponsePacket.
+ @retval EFI_ABORTED Something wrong build response packet.
+**/
+EFI_STATUS
+EFIAPI
+TlsBuildResponsePacket (
+ IN EFI_TLS_PROTOCOL *This,
+ IN UINT8 *RequestBuffer, OPTIONAL
+ IN UINTN RequestSize, OPTIONAL
+ OUT UINT8 *Buffer, OPTIONAL
+ IN OUT UINTN *BufferSize
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if ((This == NULL) || (BufferSize == NULL) ||
+ (RequestBuffer == NULL && RequestSize != 0) ||
+ (RequestBuffer != NULL && RequestSize == 0) ||
+ (Buffer == NULL && *BufferSize !=0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+ if(RequestBuffer == NULL && RequestSize == 0) {
+ switch (Instance->TlsSessionState) {
+ case EfiTlsSessionNotStarted:
+ //
+ // ClientHello.
+ //
+ Status = TlsDoHandshake (
+ Instance->TlsConn,
+ NULL,
+ 0,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // *BufferSize should not be zero when ClientHello.
+ //
+ if (*BufferSize == 0) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ Instance->TlsSessionState = EfiTlsSessionHandShaking;
+
+ break;
+ case EfiTlsSessionClosing:
+ //
+ // TLS session will be closed and response packet needs to be CloseNotify.
+ //
+ Status = TlsCloseNotify (
+ Instance->TlsConn,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // *BufferSize should not be zero when build CloseNotify message.
+ //
+ if (*BufferSize == 0) {
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
+ }
+
+ break;
+ case EfiTlsSessionError:
+ //
+ // TLS session has errors and the response packet needs to be Alert
+ // message based on error type.
+ //
+ Status = TlsHandeAlert (
+ Instance->TlsConn,
+ NULL,
+ 0,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ break;
+ default:
+ //
+ // Current TLS session state is NOT ready to build ResponsePacket.
+ //
+ Status = EFI_NOT_READY;
+ }
+ } else {
+ //
+ // 1. Received packet may have multiply TLS record messages.
+ // 2. One TLS record message may have multiply handshake protocol.
+ // 3. Some errors may be happened in handshake.
+ // TlsDoHandshake() can handle all of those cases.
+ //
+ if (TlsInHandshake (Instance->TlsConn)) {
+ Status = TlsDoHandshake (
+ Instance->TlsConn,
+ RequestBuffer,
+ RequestSize,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ if (!TlsInHandshake (Instance->TlsConn)) {
+ Instance->TlsSessionState = EfiTlsSessionDataTransferring;
+ }
+ } else {
+ //
+ // Must be alert message, Decrypt it and build the ResponsePacket.
+ //
+ ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType == TLS_CONTENT_TYPE_ALERT);
+
+ Status = TlsHandeAlert (
+ Instance->TlsConn,
+ RequestBuffer,
+ RequestSize,
+ Buffer,
+ BufferSize
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ Instance->TlsSessionState = EfiTlsSessionError;
+ }
+
+ goto ON_EXIT;
+ }
+ }
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
+
+/**
+ Decrypt or encrypt TLS packet during session. This function is only valid after
+ session connected and for application_data content type.
+
+ The ProcessPacket () function process each inbound or outbound TLS APP packet.
+
+ @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[in, out] FragmentTable Pointer to a list of fragment. The caller will take
+ responsible to handle the original FragmentTable while
+ it may be reallocated in TLS driver. If CryptMode is
+ EfiTlsEncrypt, on input these fragments contain the TLS
+ header and plain text TLS APP payload; on output these
+ fragments contain the TLS header and cipher text TLS
+ APP payload. If CryptMode is EfiTlsDecrypt, on input
+ these fragments contain the TLS header and cipher text
+ TLS APP payload; on output these fragments contain the
+ TLS header and plain text TLS APP payload.
+ @param[in] FragmentCount Number of fragment.
+ @param[in] CryptMode Crypt mode.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ This is NULL.
+ FragmentTable is NULL.
+ FragmentCount is NULL.
+ CryptoMode is invalid.
+ @retval EFI_NOT_READY Current TLS session state is NOT
+ EfiTlsSessionDataTransferring.
+ @retval EFI_ABORTED Something wrong decryption the message. TLS session
+ status will become EfiTlsSessionError. The caller need
+ call BuildResponsePacket() to generate Error Alert
+ message and send it out.
+ @retval EFI_OUT_OF_RESOURCES No enough resource to finish the operation.
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessPacket (
+ IN EFI_TLS_PROTOCOL *This,
+ IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
+ IN UINT32 *FragmentCount,
+ IN EFI_TLS_CRYPT_MODE CryptMode
+ )
+{
+ EFI_STATUS Status;
+ TLS_INSTANCE *Instance;
+
+ EFI_TPL OldTpl;
+
+ Status = EFI_SUCCESS;
+
+ if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
+
+ if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
+ Status = EFI_NOT_READY;
+ goto ON_EXIT;
+ }
+
+ //
+ // Packet sent or received may have multiply TLS record message(Application data type).
+ // So,on input these fragments contain the TLS header and TLS APP payload;
+ // on output these fragments also contain the TLS header and TLS APP payload.
+ //
+ switch (CryptMode) {
+ case EfiTlsEncrypt:
+ Status = TlsEcryptPacket (Instance, FragmentTable, FragmentCount);
+ break;
+ case EfiTlsDecrypt:
+ Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+ return Status;
+}
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
2016-12-14 8:41 ` Fu, Siyuan
@ 2016-12-15 7:24 ` Wu, Jiaxin
0 siblings, 0 replies; 37+ messages in thread
From: Wu, Jiaxin @ 2016-12-15 7:24 UTC (permalink / raw)
To: Fu, Siyuan, edk2-devel@lists.01.org
Cc: Ye, Ting, Zhang, Lubo, Long, Qin, Thomas Palmer
Thanks Siyuan, I have refined the TlsEcryptPacket/TlsDecryptPacket function according your feedback.
[PATCH v2 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL
Thanks,
Jiaxin
> -----Original Message-----
> From: Fu, Siyuan
> Sent: Wednesday, December 14, 2016 4:41 PM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>;
> Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation
> over OpenSSL
>
> Hi, Jiaxin
>
> Some comments as below:
>
> In TlsImpl.c
>
> Should the ASSERT in line 104 be an error handling? I mean is the input buffer
> coming from external input, and have we checked ContentType within it?
>
> Seems the TempRecordHeader pointer will be modified in the while loop,
> shouldn't the 3rd parameter be the reminding buffer size of the output
> buffer?
>
> Should we return error if the TlsCtrlTrafficOut return a failure?
>
> Similar questions for the decrypt packet function.
>
>
> Best Regards,
> Siyuan
>
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: 2016年12月14日 15:34
> To: edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang,
> Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas
> Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
> Subject: [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation
> over OpenSSL
>
> This patch is the implementation of EFI TLS Service Binding
> Protocol, EFI TLS Protocol and EFI TLS Configuration Protocol
> Interfaces.
>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> NetworkPkg/TlsDxe/TlsConfigProtocol.c | 152 ++++++++
> NetworkPkg/TlsDxe/TlsDriver.c | 498
> +++++++++++++++++++++++++++
> NetworkPkg/TlsDxe/TlsDriver.h | 237 +++++++++++++
> NetworkPkg/TlsDxe/TlsDxe.inf | 65 ++++
> NetworkPkg/TlsDxe/TlsDxe.uni | 25 ++
> NetworkPkg/TlsDxe/TlsDxeExtra.uni | 18 +
> NetworkPkg/TlsDxe/TlsImpl.c | 270 +++++++++++++++
> NetworkPkg/TlsDxe/TlsImpl.h | 315 +++++++++++++++++
> NetworkPkg/TlsDxe/TlsProtocol.c | 632
> ++++++++++++++++++++++++++++++++++
> 9 files changed, 2212 insertions(+)
> create mode 100644 NetworkPkg/TlsDxe/TlsConfigProtocol.c
> create mode 100644 NetworkPkg/TlsDxe/TlsDriver.c
> create mode 100644 NetworkPkg/TlsDxe/TlsDriver.h
> create mode 100644 NetworkPkg/TlsDxe/TlsDxe.inf
> create mode 100644 NetworkPkg/TlsDxe/TlsDxe.uni
> create mode 100644 NetworkPkg/TlsDxe/TlsDxeExtra.uni
> create mode 100644 NetworkPkg/TlsDxe/TlsImpl.c
> create mode 100644 NetworkPkg/TlsDxe/TlsImpl.h
> create mode 100644 NetworkPkg/TlsDxe/TlsProtocol.c
>
> diff --git a/NetworkPkg/TlsDxe/TlsConfigProtocol.c
> b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
> new file mode 100644
> index 0000000..2ec79c9
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsConfigProtocol.c
> @@ -0,0 +1,152 @@
> +/** @file
> + Implementation of EFI TLS Configuration Protocol Interfaces.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsImpl.h"
> +
> +EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol = {
> + TlsConfigurationSetData,
> + TlsConfigurationGetData
> +};
> +
> +/**
> + Set TLS configuration data.
> +
> + The SetData() function sets TLS configuration to non-volatile storage or
> volatile
> + storage.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in] Data Pointer to configuration data.
> + @param[in] DataSize Total size of configuration data.
> +
> + @retval EFI_SUCCESS The TLS configuration data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationSetData (
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if (This == NULL || Data == NULL || DataSize == 0) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
> +
> + switch (DataType) {
> + case EfiTlsConfigDataTypeCACertificate:
> + Status = TlsSetCaCertificate (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeHostPublicCert:
> + Status = TlsSetHostPublicCert (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeHostPrivateKey:
> + Status = TlsSetHostPrivateKey (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeCertRevocationList:
> + Status = TlsSetCertRevocationList (Data, DataSize);
> + break;
> + default:
> + Status = EFI_UNSUPPORTED;
> + }
> +
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> +
> +/**
> + Get TLS configuration data.
> +
> + The GetData() function gets TLS configuration.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in, out] Data Pointer to configuration data.
> + @param[in, out] DataSize Total size of configuration data. On input, it
> means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS configuration data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS configuration data is not found.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationGetData (
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> +
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0))
> {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_CONFIGURATION_THIS (This);
> +
> + switch (DataType) {
> + case EfiTlsConfigDataTypeCACertificate:
> + Status = TlsGetCaCertificate (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeHostPublicCert:
> + Status = TlsGetHostPublicCert (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeHostPrivateKey:
> + Status = TlsGetHostPrivateKey (Instance->TlsConn, Data, DataSize);
> + break;
> + case EfiTlsConfigDataTypeCertRevocationList:
> + Status = TlsGetCertRevocationList (Data, DataSize);
> + break;
> + default:
> + Status = EFI_UNSUPPORTED;
> + }
> +
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> diff --git a/NetworkPkg/TlsDxe/TlsDriver.c b/NetworkPkg/TlsDxe/TlsDriver.c
> new file mode 100644
> index 0000000..0a75c39
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDriver.c
> @@ -0,0 +1,498 @@
> +/** @file
> + The Driver Binding and Service Binding Protocol for TlsDxe driver.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsImpl.h"
> +
> +EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding = {
> + TlsServiceBindingCreateChild,
> + TlsServiceBindingDestroyChild
> +};
> +
> +/**
> + Release all the resources used by the TLS instance.
> +
> + @param[in] Instance The TLS instance data.
> +
> +**/
> +VOID
> +TlsCleanInstance (
> + IN TLS_INSTANCE *Instance
> + )
> +{
> + if (Instance != NULL) {
> + if (Instance->TlsConn != NULL) {
> + TlsFree (Instance->TlsConn);
> + }
> +
> + FreePool (Instance);
> + }
> +}
> +
> +/**
> + Create the TLS instance and initialize it.
> +
> + @param[in] Service The pointer to the TLS service.
> + @param[out] Instance The pointer to the TLS instance.
> +
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
> + @retval EFI_SUCCESS The TLS instance is created.
> +
> +**/
> +EFI_STATUS
> +TlsCreateInstance (
> + IN TLS_SERVICE *Service,
> + OUT TLS_INSTANCE **Instance
> + )
> +{
> + TLS_INSTANCE *TlsInstance;
> +
> + *Instance = NULL;
> +
> + TlsInstance = AllocateZeroPool (sizeof (TLS_INSTANCE));
> + if (TlsInstance == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + TlsInstance->Signature = TLS_INSTANCE_SIGNATURE;
> + InitializeListHead (&TlsInstance->Link);
> + TlsInstance->InDestroy = FALSE;
> + TlsInstance->Service = Service;
> +
> + CopyMem (&TlsInstance->Tls, &mTlsProtocol, sizeof (TlsInstance->Tls));
> + CopyMem (&TlsInstance->TlsConfig, &mTlsConfigurationProtocol, sizeof
> (TlsInstance->TlsConfig));
> +
> + TlsInstance->TlsSessionState = EfiTlsSessionNotStarted;
> +
> + *Instance = TlsInstance;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Release all the resources used by the TLS service binding instance.
> +
> + @param[in] Service The TLS service data.
> +
> +**/
> +VOID
> +TlsCleanService (
> + IN TLS_SERVICE *Service
> + )
> +{
> + if (Service != NULL) {
> + if (Service->TlsCtx != NULL) {
> + TlsCtxFree (Service->TlsCtx);
> + }
> +
> + FreePool (Service);
> + }
> +}
> +
> +/**
> + Create then initialize a TLS service.
> +
> + @param[in] Image ImageHandle of the TLS driver
> + @param[out] Service The service for TLS driver
> +
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create
> the service.
> + @retval EFI_SUCCESS The service is created for the driver.
> +
> +**/
> +EFI_STATUS
> +TlsCreateService (
> + IN EFI_HANDLE Image,
> + OUT TLS_SERVICE **Service
> + )
> +{
> + EFI_STATUS Status;
> + TLS_SERVICE *TlsService;
> +
> + Status = EFI_SUCCESS;
> + *Service = NULL;
> +
> + ASSERT (Service != NULL);
> +
> + //
> + // Allocate a TLS Service Data
> + //
> + TlsService = AllocateZeroPool (sizeof (TLS_SERVICE));
> + if (TlsService == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Initialize TLS Service Data
> + //
> + TlsService->Signature = TLS_SERVICE_SIGNATURE;
> + CopyMem (&TlsService->ServiceBinding, &mTlsServiceBinding, sizeof
> (TlsService->ServiceBinding));
> + TlsService->TlsChildrenNum = 0;
> + InitializeListHead (&TlsService->TlsChildrenList);
> + TlsService->ImageHandle = Image;
> +
> + *Service = TlsService;
> +
> + return Status;
> +}
> +
> +/**
> + Unloads an image.
> +
> + @param[in] ImageHandle Handle that identifies the image to be
> unloaded.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsUnload (
> + IN EFI_HANDLE ImageHandle
> + )
> +{
> + EFI_STATUS Status;
> + UINTN HandleNum;
> + EFI_HANDLE *HandleBuffer;
> + UINT32 Index;
> + EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
> + TLS_SERVICE *TlsService;
> +
> + HandleBuffer = NULL;
> + ServiceBinding = NULL;
> + TlsService = NULL;
> +
> + //
> + // Locate all the handles with Tls service binding protocol.
> + //
> + Status = gBS->LocateHandleBuffer (
> + ByProtocol,
> + &gEfiTlsServiceBindingProtocolGuid,
> + NULL,
> + &HandleNum,
> + &HandleBuffer
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + for (Index = 0; Index < HandleNum; Index++) {
> + //
> + // Firstly, find ServiceBinding interface
> + //
> + Status = gBS->OpenProtocol (
> + HandleBuffer[Index],
> + &gEfiTlsServiceBindingProtocolGuid,
> + (VOID **) &ServiceBinding,
> + ImageHandle,
> + NULL,
> + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + TlsService = TLS_SERVICE_FROM_THIS (ServiceBinding);
> +
> + //
> + // Then, uninstall ServiceBinding interface
> + //
> + Status = gBS->UninstallMultipleProtocolInterfaces (
> + HandleBuffer[Index],
> + &gEfiTlsServiceBindingProtocolGuid, ServiceBinding,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + TlsCleanService (TlsService);
> + }
> +
> + if (HandleBuffer != NULL) {
> + FreePool (HandleBuffer);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This is the declaration of an EFI image entry point. This entry point is
> + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> + both device drivers and bus drivers.
> +
> + @param ImageHandle The firmware allocated handle for the UEFI
> image.
> + @param SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Others An unexpected error occurred.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsDriverEntryPoint (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> +
> + TLS_SERVICE *TlsService;
> +
> + //
> + // Create TLS Service
> + //
> + Status = TlsCreateService (ImageHandle, &TlsService);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + ASSERT (TlsService != NULL);
> +
> + //
> + // Initializes the OpenSSL library.
> + //
> + TlsInitialize ();
> +
> + //
> + // Create a new SSL_CTX object as framework to establish TLS/SSL enabled
> + // connections. TLS 1.0 is used as the default version.
> + //
> + TlsService->TlsCtx = TlsCtxNew (TLS10_PROTOCOL_VERSION_MAJOR,
> TLS10_PROTOCOL_VERSION_MINOR);
> + if (TlsService->TlsCtx == NULL) {
> + FreePool (TlsService);
> + return EFI_ABORTED;
> + }
> +
> + //
> + // Install the TlsServiceBinding Protocol onto Handle
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &TlsService->Handle,
> + &gEfiTlsServiceBindingProtocolGuid,
> + &TlsService->ServiceBinding,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_CLEAN_SERVICE;
> + }
> +
> + return Status;
> +
> +ON_CLEAN_SERVICE:
> + TlsCleanService (TlsService);
> +
> + return Status;
> +}
> +
> +/**
> + Creates a child handle and installs a protocol.
> +
> + The CreateChild() function installs a protocol on ChildHandle.
> + If ChildHandle is a pointer to NULL, then a new handle is created and
> returned in ChildHandle.
> + If ChildHandle is not a pointer to NULL, then the protocol installs on the
> existing ChildHandle.
> +
> + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> + @param[in] ChildHandle Pointer to the handle of the child to create. If it is
> NULL,
> + then a new handle is created. If it is a pointer to an existing
> UEFI handle,
> + then the protocol is added to the existing UEFI handle.
> +
> + @retval EFI_SUCCES The protocol was added to ChildHandle.
> + @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources
> available to create
> + the child.
> + @retval other The child handle was not created.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingCreateChild (
> + IN EFI_SERVICE_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE *ChildHandle
> + )
> +{
> + TLS_SERVICE *TlsService;
> + TLS_INSTANCE *TlsInstance;
> + EFI_STATUS Status;
> + EFI_TPL OldTpl;
> +
> + if ((This == NULL) || (ChildHandle == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + TlsService = TLS_SERVICE_FROM_THIS (This);
> +
> + Status = TlsCreateInstance (TlsService, &TlsInstance);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + ASSERT (TlsInstance != NULL);
> +
> + //
> + // Create a new TLS connection object.
> + //
> + TlsInstance->TlsConn = TlsNew (TlsService->TlsCtx);
> + if (TlsInstance->TlsConn == NULL) {
> + Status = EFI_ABORTED;
> + goto ON_ERROR;
> + }
> +
> + //
> + // Set default ConnectionEnd to EfiTlsClient
> + //
> + Status = TlsSetConnectionEnd (TlsInstance->TlsConn, EfiTlsClient);
> + if (EFI_ERROR (Status)) {
> + goto ON_ERROR;
> + }
> +
> + //
> + // Install TLS protocol and configuration protocol onto ChildHandle
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + ChildHandle,
> + &gEfiTlsProtocolGuid,
> + &TlsInstance->Tls,
> + &gEfiTlsConfigurationProtocolGuid,
> + &TlsInstance->TlsConfig,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_ERROR;
> + }
> +
> + TlsInstance->ChildHandle = *ChildHandle;
> +
> + //
> + // Add it to the TLS service's child list.
> + //
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + InsertTailList (&TlsService->TlsChildrenList, &TlsInstance->Link);
> + TlsService->TlsChildrenNum++;
> +
> + gBS->RestoreTPL (OldTpl);
> +
> + return EFI_SUCCESS;
> +
> +ON_ERROR:
> + TlsCleanInstance (TlsInstance);
> + return Status;
> +}
> +
> +/**
> + Destroys a child handle with a protocol installed on it.
> +
> + The DestroyChild() function does the opposite of CreateChild(). It removes
> a protocol
> + that was installed by CreateChild() from ChildHandle. If the removed
> protocol is the
> + last protocol on ChildHandle, then ChildHandle is destroyed.
> +
> + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> + @param ChildHandle Handle of the child to destroy.
> +
> + @retval EFI_SUCCES The protocol was removed from ChildHandle.
> + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol
> that is being removed.
> + @retval EFI_INVALID_PARAMETER Child handle is NULL.
> + @retval EFI_ACCESS_DENIED The protocol could not be removed from
> the ChildHandle
> + because its services are being used.
> + @retval other The child handle was not destroyed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingDestroyChild (
> + IN EFI_SERVICE_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE ChildHandle
> + )
> +{
> + TLS_SERVICE *TlsService;
> + TLS_INSTANCE *TlsInstance;
> +
> + EFI_TLS_PROTOCOL *Tls;
> + EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfig;
> + EFI_STATUS Status;
> + EFI_TPL OldTpl;
> +
> + if ((This == NULL) || (ChildHandle == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + TlsService = TLS_SERVICE_FROM_THIS (This);
> +
> + //
> + // Find TLS protocol interface installed in ChildHandle
> + //
> + Status = gBS->OpenProtocol (
> + ChildHandle,
> + &gEfiTlsProtocolGuid,
> + (VOID **) &Tls,
> + TlsService->ImageHandle,
> + NULL,
> + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Find TLS configuration protocol interface installed in ChildHandle
> + //
> + Status = gBS->OpenProtocol (
> + ChildHandle,
> + &gEfiTlsConfigurationProtocolGuid,
> + (VOID **) &TlsConfig,
> + TlsService->ImageHandle,
> + NULL,
> + EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + TlsInstance = TLS_INSTANCE_FROM_PROTOCOL_THIS (Tls);
> +
> + if (TlsInstance->Service != TlsService) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (TlsInstance->InDestroy) {
> + return EFI_SUCCESS;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + TlsInstance->InDestroy = TRUE;
> +
> + //
> + // Uninstall the TLS protocol and TLS Configuration Protocol interface
> installed in ChildHandle.
> + //
> + Status = gBS->UninstallMultipleProtocolInterfaces (
> + ChildHandle,
> + &gEfiTlsProtocolGuid,
> + Tls,
> + &gEfiTlsConfigurationProtocolGuid,
> + TlsConfig,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + RemoveEntryList (&TlsInstance->Link);
> + TlsService->TlsChildrenNum--;
> +
> + gBS->RestoreTPL (OldTpl);
> +
> + TlsCleanInstance (TlsInstance);
> +
> + return EFI_SUCCESS;
> +}
> diff --git a/NetworkPkg/TlsDxe/TlsDriver.h b/NetworkPkg/TlsDxe/TlsDriver.h
> new file mode 100644
> index 0000000..c3c30a8
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDriver.h
> @@ -0,0 +1,237 @@
> +/** @file
> + Header file of the Driver Binding and Service Binding Protocol for TlsDxe
> driver.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __EFI_TLS_DRIVER_H__
> +#define __EFI_TLS_DRIVER_H__
> +
> +#include <Uefi.h>
> +
> +//
> +// Driver Protocols
> +//
> +#include <Protocol/ServiceBinding.h>
> +
> +//
> +// Driver Version
> +//
> +#define TLS_VERSION 0x00000000
> +
> +#define TLS_SERVICE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'S')
> +
> +#define TLS_INSTANCE_SIGNATURE SIGNATURE_32 ('T', 'L', 'S', 'I')
> +
> +///
> +/// TLS Service Data
> +///
> +typedef struct _TLS_SERVICE TLS_SERVICE;
> +
> +///
> +/// TLS Instance Data
> +///
> +typedef struct _TLS_INSTANCE TLS_INSTANCE;
> +
> +
> +struct _TLS_SERVICE {
> + UINT32 Signature;
> + EFI_SERVICE_BINDING_PROTOCOL ServiceBinding;
> +
> + UINT16 TlsChildrenNum;
> + LIST_ENTRY TlsChildrenList;
> +
> + //
> + // Handle to install TlsServiceBinding protocol.
> + //
> + EFI_HANDLE Handle;
> + EFI_HANDLE ImageHandle;
> +
> + //
> + // Main SSL Context object which is created by a server or client once per
> program
> + // life-time and which holds mainly default values for the SSL object which
> are later
> + // created for the connections.
> + //
> + VOID *TlsCtx;
> +};
> +
> +struct _TLS_INSTANCE {
> + UINT32 Signature;
> + LIST_ENTRY Link;
> +
> + BOOLEAN InDestroy;
> +
> + TLS_SERVICE *Service;
> + EFI_HANDLE ChildHandle;
> +
> + EFI_TLS_PROTOCOL Tls;
> + EFI_TLS_CONFIGURATION_PROTOCOL TlsConfig;
> +
> + EFI_TLS_SESSION_STATE TlsSessionState;
> +
> + //
> + // Main SSL Connection which is created by a server or a client
> + // per established connection.
> + //
> + VOID *TlsConn;
> +};
> +
> +
> +#define TLS_SERVICE_FROM_THIS(a) \
> + CR (a, TLS_SERVICE, ServiceBinding, TLS_SERVICE_SIGNATURE)
> +
> +#define TLS_INSTANCE_FROM_PROTOCOL_THIS(a) \
> + CR (a, TLS_INSTANCE, Tls, TLS_INSTANCE_SIGNATURE)
> +
> +#define TLS_INSTANCE_FROM_CONFIGURATION_THIS(a) \
> + CR (a, TLS_INSTANCE, TlsConfig, TLS_INSTANCE_SIGNATURE)
> +
> +
> +/**
> + Release all the resources used by the TLS instance.
> +
> + @param[in] Instance The TLS instance data.
> +
> +**/
> +VOID
> +TlsCleanInstance (
> + IN TLS_INSTANCE *Instance
> + );
> +
> +/**
> + Create the TLS instance and initialize it.
> +
> + @param[in] Service The pointer to the TLS service.
> + @param[out] Instance The pointer to the TLS instance.
> +
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
> + @retval EFI_SUCCESS The TLS instance is created.
> +
> +**/
> +EFI_STATUS
> +TlsCreateInstance (
> + IN TLS_SERVICE *Service,
> + OUT TLS_INSTANCE **Instance
> + );
> +
> +/**
> + Release all the resources used by the TLS service binding instance.
> +
> + @param[in] Service The TLS service data.
> +
> +**/
> +VOID
> +TlsCleanService (
> + IN TLS_SERVICE *Service
> + );
> +
> +/**
> + Create then initialize a TLS service.
> +
> + @param[in] Image ImageHandle of the TLS driver
> + @param[out] Service The service for TLS driver
> +
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate resource to create
> the service.
> + @retval EFI_SUCCESS The service is created for the driver.
> +
> +**/
> +EFI_STATUS
> +TlsCreateService (
> + IN EFI_HANDLE Image,
> + OUT TLS_SERVICE **Service
> + );
> +
> +/**
> + Unloads an image.
> +
> + @param[in] ImageHandle Handle that identifies the image to be
> unloaded.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsUnload (
> + IN EFI_HANDLE ImageHandle
> + );
> +
> +/**
> + This is the declaration of an EFI image entry point. This entry point is
> + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> + both device drivers and bus drivers.
> +
> + @param ImageHandle The firmware allocated handle for the UEFI
> image.
> + @param SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Others An unexpected error occurred.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsDriverEntryPoint (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + );
> +
> +/**
> + Creates a child handle and installs a protocol.
> +
> + The CreateChild() function installs a protocol on ChildHandle.
> + If ChildHandle is a pointer to NULL, then a new handle is created and
> returned in ChildHandle.
> + If ChildHandle is not a pointer to NULL, then the protocol installs on the
> existing ChildHandle.
> +
> + @param[in] This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> + @param[in] ChildHandle Pointer to the handle of the child to create. If it is
> NULL,
> + then a new handle is created. If it is a pointer to an existing
> UEFI handle,
> + then the protocol is added to the existing UEFI handle.
> +
> + @retval EFI_SUCCES The protocol was added to ChildHandle.
> + @retval EFI_INVALID_PARAMETER ChildHandle is NULL.
> + @retval EFI_OUT_OF_RESOURCES There are not enough resources
> available to create
> + the child.
> + @retval other The child handle was not created.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingCreateChild (
> + IN EFI_SERVICE_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE *ChildHandle
> + );
> +
> +/**
> + Destroys a child handle with a protocol installed on it.
> +
> + The DestroyChild() function does the opposite of CreateChild(). It removes
> a protocol
> + that was installed by CreateChild() from ChildHandle. If the removed
> protocol is the
> + last protocol on ChildHandle, then ChildHandle is destroyed.
> +
> + @param This Pointer to the EFI_SERVICE_BINDING_PROTOCOL
> instance.
> + @param ChildHandle Handle of the child to destroy.
> +
> + @retval EFI_SUCCES The protocol was removed from ChildHandle.
> + @retval EFI_UNSUPPORTED ChildHandle does not support the protocol
> that is being removed.
> + @retval EFI_INVALID_PARAMETER Child handle is NULL.
> + @retval EFI_ACCESS_DENIED The protocol could not be removed from
> the ChildHandle
> + because its services are being used.
> + @retval other The child handle was not destroyed.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsServiceBindingDestroyChild (
> + IN EFI_SERVICE_BINDING_PROTOCOL *This,
> + IN EFI_HANDLE ChildHandle
> + );
> +
> +#endif
> diff --git a/NetworkPkg/TlsDxe/TlsDxe.inf b/NetworkPkg/TlsDxe/TlsDxe.inf
> new file mode 100644
> index 0000000..dba3257
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDxe.inf
> @@ -0,0 +1,65 @@
> +## @file
> +# This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol
> and
> +# EFI TLS Configuration Protocol.
> +#
> +# This module produces EFI TLS (Transport Layer Security) Protocol and EFI
> TLS
> +# Service Binding Protocol, to provide TLS services.
> +#
> +# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +#
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions of the
> BSD License
> +# which accompanies this distribution. The full text of the license may be
> found at
> +# http://opensource.org/licenses/bsd-license.php.
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +#
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = TlsDxe
> + FILE_GUID = 3aceb0c0-3c72-11e4-9a56-74d435052646
> + MODULE_TYPE = UEFI_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = TlsDriverEntryPoint
> + UNLOAD_IMAGE = TlsUnload
> + MODULE_UNI_FILE = TlsDxe.uni
> +
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + CryptoPkg/CryptoPkg.dec
> +
> +[Sources]
> + TlsDriver.h
> + TlsDriver.c
> + TlsProtocol.c
> + TlsConfigProtocol.c
> + TlsImpl.h
> + TlsImpl.c
> +
> +[LibraryClasses]
> + UefiDriverEntryPoint
> + UefiBootServicesTableLib
> + MemoryAllocationLib
> + BaseMemoryLib
> + BaseLib
> + UefiLib
> + DebugLib
> + NetLib
> + BaseCryptLib
> + TlsLib
> +
> +[Protocols]
> + gEfiTlsServiceBindingProtocolGuid ## PRODUCES
> + gEfiTlsProtocolGuid ## PRODUCES
> + gEfiTlsConfigurationProtocolGuid ## PRODUCES
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + TlsDxeExtra.uni
> diff --git a/NetworkPkg/TlsDxe/TlsDxe.uni b/NetworkPkg/TlsDxe/TlsDxe.uni
> new file mode 100644
> index 0000000..98c41ca
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDxe.uni
> @@ -0,0 +1,25 @@
> +// /** @file
> +// This module produces EFI TLS Protocol, EFI TLS Service Binding Protocol
> and
> +// EFI TLS Configuration Protocol.
> +//
> +// This module produces EFI TLS (Transport Layer Security) Protocol, EFI TLS
> +// Service Binding Protocol, and EFI TLS Configuration Protocol to provide
> TLS
> +// services.
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// This program and the accompanying materials
> +// are licensed and made available under the terms and conditions of the
> BSD License
> +// which accompanies this distribution. The full text of the license may be
> found at
> +// http://opensource.org/licenses/bsd-license.php
> +//
> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "UEFI TLS service"
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "This module
> produces EFI TLS Protocol, EFI TLS Service Binding Protocol and EFI TLS
> Configuration Protocol to provide EFI TLS services."
> +
> diff --git a/NetworkPkg/TlsDxe/TlsDxeExtra.uni
> b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
> new file mode 100644
> index 0000000..a38582a
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsDxeExtra.uni
> @@ -0,0 +1,18 @@
> +// /** @file
> +// TlsDxe Localized Strings and Content
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// This program and the accompanying materials
> +// are licensed and made available under the terms and conditions of the
> BSD License
> +// which accompanies this distribution. The full text of the license may be
> found at
> +// http://opensource.org/licenses/bsd-license.php.
> +//
> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"EFI TLS DXE Driver"
> diff --git a/NetworkPkg/TlsDxe/TlsImpl.c b/NetworkPkg/TlsDxe/TlsImpl.c
> new file mode 100644
> index 0000000..5fb1e78
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsImpl.c
> @@ -0,0 +1,270 @@
> +/** @file
> + The Miscellaneous Routines for TlsDxe driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsImpl.h"
> +
> +/**
> + Encrypt the message listed in fragment.
> +
> + @param[in] TlsInstance The pointer to the TLS instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment.
> + On input these fragments contain the TLS header and
> + plain text TLS payload;
> + On output these fragments contain the TLS header and
> + cipher text TLS payload.
> + @param[in] FragmentCount Number of fragment.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsEcryptPacket (
> + IN TLS_INSTANCE *TlsInstance,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount
> + )
> +{
> + UINTN Index;
> + UINT32 BytesCopied;
> + UINT32 BufferInSize;
> + UINT8 *BufferIn;
> + UINT8 *BufferInPtr;
> + TLS_RECORD_HEADER *RecordHeaderIn;
> + UINT16 ThisPlainMessageSize;
> + TLS_RECORD_HEADER *TempRecordHeader;
> + UINT16 ThisMessageSize;
> + UINT32 BufferOutSize;
> + UINT8 *BufferOut;
> + INTN Ret;
> +
> + BytesCopied = 0;
> + BufferInSize = 0;
> + BufferIn = NULL;
> + BufferInPtr = NULL;
> + RecordHeaderIn = NULL;
> + TempRecordHeader = NULL;
> + BufferOutSize = 0;
> + BufferOut = NULL;
> + Ret = 0;
> +
> + //
> + // Calculate the size according to the fragment table.
> + //
> + for (Index = 0; Index < *FragmentCount; Index++) {
> + BufferInSize += (*FragmentTable)[Index].FragmentLength;
> + }
> +
> + //
> + // Allocate buffer for processing data.
> + //
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Copy all TLS plain record header and payload into ProcessBuffer.
> + //
> + for (Index = 0; Index < *FragmentCount; Index++) {
> + CopyMem (
> + (BufferIn + BytesCopied),
> + (*FragmentTable)[Index].FragmentBuffer,
> + (*FragmentTable)[Index].FragmentLength
> + );
> + BytesCopied += (*FragmentTable)[Index].FragmentLength;
> + }
> +
> + BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Parsing buffer.
> + //
> + BufferInPtr = BufferIn;
> + TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
> + while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
> + RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
> + ASSERT (RecordHeaderIn->ContentType ==
> TLS_CONTENT_TYPE_APPLICATION_DATA);
> + ThisPlainMessageSize = RecordHeaderIn->Length;
> +
> + TlsWrite (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn + 1),
> ThisPlainMessageSize);
> +
> + Ret = TlsCtrlTrafficOut (TlsInstance->TlsConn, (UINT8
> *)(TempRecordHeader), MAX_BUFFER_SIZE);
> +
> + if (Ret > 0) {
> + ThisMessageSize = (UINT16) Ret;
> + } else {
> + ThisMessageSize = 0;
> + }
> +
> + BufferOutSize += ThisMessageSize;
> +
> + BufferInPtr += RECORD_HEADER_LEN + ThisPlainMessageSize;
> + TempRecordHeader += ThisMessageSize;
> + }
> +
> + FreePool (BufferIn);
> +
> + //
> + // The caller will take responsible to handle the original fragment table.
> + //
> + *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
> + if (*FragmentTable == NULL) {
> + FreePool (BufferOut);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + (*FragmentTable)[0].FragmentBuffer = BufferOut;
> + (*FragmentTable)[0].FragmentLength = BufferOutSize;
> + *FragmentCount = 1;
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Decrypt the message listed in fragment.
> +
> + @param[in] TlsInstance The pointer to the TLS instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment.
> + On input these fragments contain the TLS header and
> + cipher text TLS payload;
> + On output these fragments contain the TLS header and
> + plain text TLS payload.
> + @param[in] FragmentCount Number of fragment.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsDecryptPacket (
> + IN TLS_INSTANCE *TlsInstance,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount
> + )
> +{
> + UINTN Index;
> + UINT32 BytesCopied;
> + UINT8 *BufferIn;
> + UINT32 BufferInSize;
> + UINT8 *BufferInPtr;
> + TLS_RECORD_HEADER *RecordHeaderIn;
> + UINT16 ThisCipherMessageSize;
> + TLS_RECORD_HEADER *TempRecordHeader;
> + UINT16 ThisPlainMessageSize;
> + UINT8 *BufferOut;
> + UINT32 BufferOutSize;
> + INTN Ret;
> +
> + BytesCopied = 0;
> + BufferIn = NULL;
> + BufferInSize = 0;
> + BufferInPtr = NULL;
> + RecordHeaderIn = NULL;
> + TempRecordHeader = NULL;
> + BufferOut = NULL;
> + BufferOutSize = 0;
> + Ret = 0;
> +
> + //
> + // Calculate the size according to the fragment table.
> + //
> + for (Index = 0; Index < *FragmentCount; Index++) {
> + BufferInSize += (*FragmentTable)[Index].FragmentLength;
> + }
> +
> + //
> + // Allocate buffer for processing data
> + //
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Copy all TLS plain record header and payload to ProcessBuffer
> + //
> + for (Index = 0; Index < *FragmentCount; Index++) {
> + CopyMem (
> + (BufferIn + BytesCopied),
> + (*FragmentTable)[Index].FragmentBuffer,
> + (*FragmentTable)[Index].FragmentLength
> + );
> + BytesCopied += (*FragmentTable)[Index].FragmentLength;
> + }
> +
> + BufferOut = AllocateZeroPool (MAX_BUFFER_SIZE);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Parsing buffer. Received packet may have multiply TLS record message.
> + //
> + BufferInPtr = BufferIn;
> + TempRecordHeader = (TLS_RECORD_HEADER *) BufferOut;
> + while ((UINTN) BufferInPtr < (UINTN) BufferIn + BufferInSize) {
> + RecordHeaderIn = (TLS_RECORD_HEADER *) BufferInPtr;
> + ASSERT (RecordHeaderIn->ContentType ==
> TLS_CONTENT_TYPE_APPLICATION_DATA);
> + ThisCipherMessageSize = NTOHS (RecordHeaderIn->Length);
> +
> + Ret = TlsCtrlTrafficIn (TlsInstance->TlsConn, (UINT8 *) (RecordHeaderIn),
> RECORD_HEADER_LEN + ThisCipherMessageSize);
> + if (Ret != RECORD_HEADER_LEN + ThisCipherMessageSize) {
> + FreePool (BufferIn);
> + TlsInstance->TlsSessionState = EfiTlsSessionError;
> + return EFI_ABORTED;
> + }
> +
> + Ret = 0;
> + Ret = TlsRead (TlsInstance->TlsConn, (UINT8 *) (TempRecordHeader + 1),
> MAX_BUFFER_SIZE);
> +
> + if (Ret > 0) {
> + ThisPlainMessageSize = (UINT16) Ret;
> + } else {
> + ThisPlainMessageSize = 0;
> + }
> +
> + CopyMem (TempRecordHeader, RecordHeaderIn,
> RECORD_HEADER_LEN);
> + TempRecordHeader->Length = ThisPlainMessageSize;
> + BufferOutSize += RECORD_HEADER_LEN + ThisPlainMessageSize;
> +
> + BufferInPtr += RECORD_HEADER_LEN + ThisCipherMessageSize;
> + TempRecordHeader += RECORD_HEADER_LEN + ThisPlainMessageSize;
> + }
> +
> + FreePool (BufferIn);
> +
> + //
> + // The caller will take responsible to handle the original fragment table
> + //
> + *FragmentTable = AllocateZeroPool (sizeof (EFI_TLS_FRAGMENT_DATA));
> + if (*FragmentTable == NULL) {
> + FreePool (BufferOut);
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + (*FragmentTable)[0].FragmentBuffer = BufferOut;
> + (*FragmentTable)[0].FragmentLength = BufferOutSize;
> + *FragmentCount = 1;
> +
> + return EFI_SUCCESS;
> +}
> diff --git a/NetworkPkg/TlsDxe/TlsImpl.h b/NetworkPkg/TlsDxe/TlsImpl.h
> new file mode 100644
> index 0000000..b0615cb
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsImpl.h
> @@ -0,0 +1,315 @@
> +/** @file
> + Header file of Miscellaneous Routines for TlsDxe driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __EFI_TLS_IMPL_H__
> +#define __EFI_TLS_IMPL_H__
> +
> +//
> +// Libraries
> +//
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/NetLib.h>
> +#include <Library/BaseCryptLib.h>
> +#include <Library/TlsLib.h>
> +
> +//
> +// Consumed Protocols
> +//
> +#include <Protocol/Tls.h>
> +#include <Protocol/TlsConfig.h>
> +
> +#include <IndustryStandard/Tls1.h>
> +
> +#include "TlsDriver.h"
> +
> +//
> +// Protocol instances
> +//
> +extern EFI_SERVICE_BINDING_PROTOCOL mTlsServiceBinding;
> +extern EFI_TLS_PROTOCOL mTlsProtocol;
> +extern EFI_TLS_CONFIGURATION_PROTOCOL mTlsConfigurationProtocol;
> +
> +#define RECORD_HEADER_LEN 5 /// ContentType(1) + Version(2) +
> Length(2)
> +
> +#define MAX_BUFFER_SIZE 32768
> +
> +/**
> + Encrypt the message listed in fragment.
> +
> + @param[in] TlsInstance The pointer to the TLS instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment.
> + On input these fragments contain the TLS header and
> + plain text TLS payload;
> + On output these fragments contain the TLS header and
> + cipher text TLS payload.
> + @param[in] FragmentCount Number of fragment.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsEcryptPacket (
> + IN TLS_INSTANCE *TlsInstance,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount
> + );
> +
> +/**
> + Decrypt the message listed in fragment.
> +
> + @param[in] TlsInstance The pointer to the TLS instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment.
> + On input these fragments contain the TLS header and
> + cipher text TLS payload;
> + On output these fragments contain the TLS header and
> + plain text TLS payload.
> + @param[in] FragmentCount Number of fragment.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other errors as indicated.
> +**/
> +EFI_STATUS
> +TlsDecryptPacket (
> + IN TLS_INSTANCE *TlsInstance,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount
> + );
> +
> +/**
> + Set TLS session data.
> +
> + The SetSessionData() function set data for a new TLS session. All session
> data should
> + be set before BuildResponsePacket() invoked.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in] Data Pointer to session data.
> + @param[in] DataSize Total size of session data.
> +
> + @retval EFI_SUCCESS The TLS session data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_ACCESS_DENIED If the DataType is one of below:
> + EfiTlsClientRandom
> + EfiTlsServerRandom
> + EfiTlsKeyMaterial
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionStateNotStarted.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetSessionData (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Get TLS session data.
> +
> + The GetSessionData() function return the TLS session information.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in, out] Data Pointer to session data.
> + @param[in, out] DataSize Total size of session data. On input, it means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS session data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS session data is not found.
> + @retval EFI_NOT_READY The DataType is not ready in current session
> state.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetSessionData (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + );
> +
> +/**
> + Build response packet according to TLS state machine. This function is only
> valid for
> + alert, handshake and change_cipher_spec content type.
> +
> + The BuildResponsePacket() function builds TLS response packet in
> response to the TLS
> + request packet specified by RequestBuffer and RequestSize. If
> RequestBuffer is NULL and
> + RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS
> session
> + will be initiated and the response packet needs to be ClientHello. If
> RequestBuffer is
> + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing,
> the TLS
> + session will be closed and response packet needs to be CloseNotify. If
> RequestBuffer is
> + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the
> TLS
> + session has errors and the response packet needs to be Alert message
> based on error
> + type.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] RequestBuffer Pointer to the most recently received TLS
> packet. NULL
> + means TLS need initiate the TLS session and response
> + packet need to be ClientHello.
> + @param[in] RequestSize Packet size in bytes for the most recently
> received TLS
> + packet. 0 is only valid when RequestBuffer is NULL.
> + @param[out] Buffer Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferSize Pointer to the buffer size in bytes. On input,
> it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + RequestBuffer is NULL but RequestSize is NOT 0.
> + RequestSize is 0 but RequestBuffer is NOT NULL.
> + BufferSize is NULL.
> + Buffer is NULL if *BufferSize is not zero.
> + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the
> response packet.
> + @retval EFI_NOT_READY Current TLS session state is NOT ready to
> build
> + ResponsePacket.
> + @retval EFI_ABORTED Something wrong build response packet.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsBuildResponsePacket (
> + IN EFI_TLS_PROTOCOL *This,
> + IN UINT8 *RequestBuffer, OPTIONAL
> + IN UINTN RequestSize, OPTIONAL
> + OUT UINT8 *Buffer, OPTIONAL
> + IN OUT UINTN *BufferSize
> + );
> +
> +/**
> + Decrypt or encrypt TLS packet during session. This function is only valid
> after
> + session connected and for application_data content type.
> +
> + The ProcessPacket () function process each inbound or outbound TLS APP
> packet.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment. The caller
> will take
> + responsible to handle the original FragmentTable while
> + it may be reallocated in TLS driver. If CryptMode is
> + EfiTlsEncrypt, on input these fragments contain the TLS
> + header and plain text TLS APP payload; on output these
> + fragments contain the TLS header and cipher text TLS
> + APP payload. If CryptMode is EfiTlsDecrypt, on input
> + these fragments contain the TLS header and cipher text
> + TLS APP payload; on output these fragments contain the
> + TLS header and plain text TLS APP payload.
> + @param[in] FragmentCount Number of fragment.
> + @param[in] CryptMode Crypt mode.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + FragmentTable is NULL.
> + FragmentCount is NULL.
> + CryptoMode is invalid.
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionDataTransferring.
> + @retval EFI_ABORTED Something wrong decryption the message.
> TLS session
> + status will become EfiTlsSessionError. The caller need
> + call BuildResponsePacket() to generate Error Alert
> + message and send it out.
> + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the
> operation.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessPacket (
> + IN EFI_TLS_PROTOCOL *This,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount,
> + IN EFI_TLS_CRYPT_MODE CryptMode
> + );
> +
> +/**
> + Set TLS configuration data.
> +
> + The SetData() function sets TLS configuration to non-volatile storage or
> volatile
> + storage.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in] Data Pointer to configuration data.
> + @param[in] DataSize Total size of configuration data.
> +
> + @retval EFI_SUCCESS The TLS configuration data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationSetData (
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + );
> +
> +/**
> + Get TLS configuration data.
> +
> + The GetData() function gets TLS configuration.
> +
> + @param[in] This Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> + @param[in] DataType Configuration data type.
> + @param[in, out] Data Pointer to configuration data.
> + @param[in, out] DataSize Total size of configuration data. On input, it
> means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS configuration data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS configuration data is not found.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigurationGetData (
> + IN EFI_TLS_CONFIGURATION_PROTOCOL *This,
> + IN EFI_TLS_CONFIG_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + );
> +
> +#endif
> diff --git a/NetworkPkg/TlsDxe/TlsProtocol.c
> b/NetworkPkg/TlsDxe/TlsProtocol.c
> new file mode 100644
> index 0000000..bc617e1
> --- /dev/null
> +++ b/NetworkPkg/TlsDxe/TlsProtocol.c
> @@ -0,0 +1,632 @@
> +/** @file
> + Implementation of EFI TLS Protocol Interfaces.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsImpl.h"
> +
> +EFI_TLS_PROTOCOL mTlsProtocol = {
> + TlsSetSessionData,
> + TlsGetSessionData,
> + TlsBuildResponsePacket,
> + TlsProcessPacket
> +};
> +
> +/**
> + Set TLS session data.
> +
> + The SetSessionData() function set data for a new TLS session. All session
> data should
> + be set before BuildResponsePacket() invoked.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in] Data Pointer to session data.
> + @param[in] DataSize Total size of session data.
> +
> + @retval EFI_SUCCESS The TLS session data is set successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + Data is NULL.
> + DataSize is 0.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_ACCESS_DENIED If the DataType is one of below:
> + EfiTlsClientRandom
> + EfiTlsServerRandom
> + EfiTlsKeyMaterial
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionStateNotStarted.
> + @retval EFI_OUT_OF_RESOURCES Required system resources could not
> be allocated.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsSetSessionData (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN VOID *Data,
> + IN UINTN DataSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> + UINT16 *CipherId;
> + UINTN Index;
> +
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> + CipherId = NULL;
> +
> + if (This == NULL || Data == NULL || DataSize == 0) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> + if (DataType != EfiTlsSessionState && Instance->TlsSessionState !=
> EfiTlsSessionNotStarted){
> + Status = EFI_NOT_READY;
> + goto ON_EXIT;
> + }
> +
> + switch (DataType) {
> + //
> + // Session Configuration
> + //
> + case EfiTlsVersion:
> + if (DataSize != sizeof (EFI_TLS_VERSION)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + Status = TlsSetVersion (Instance->TlsConn, ((EFI_TLS_VERSION *) Data)-
> >Major, ((EFI_TLS_VERSION *) Data)->Minor);
> + break;
> + case EfiTlsConnectionEnd:
> + if (DataSize != sizeof (EFI_TLS_CONNECTION_END)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + Status = TlsSetConnectionEnd (Instance->TlsConn,
> *((EFI_TLS_CONNECTION_END *) Data));
> + break;
> + case EfiTlsCipherList:
> + CipherId = AllocatePool (DataSize);
> + if (CipherId == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + for (Index = 0; Index < DataSize / sizeof (EFI_TLS_CIPHER); Index++) {
> + *(CipherId +Index) = HTONS (*(((UINT16 *) Data) + Index));
> + }
> +
> + Status = TlsSetCipherList (Instance->TlsConn, CipherId, DataSize / sizeof
> (EFI_TLS_CIPHER));
> +
> + FreePool (CipherId);
> + break;
> + case EfiTlsCompressionMethod:
> + //
> + // TLS seems only define one CompressionMethod.null, which specifies
> that data exchanged via the
> + // record protocol will not be compressed.
> + // More information from OpenSSL:
> http://www.openssl.org/docs/manmaster/ssl/SSL_COMP_add_compressio
> n_method.html
> + // The TLS RFC does however not specify compression methods or their
> corresponding identifiers,
> + // so there is currently no compatible way to integrate compression with
> unknown peers.
> + // It is therefore currently not recommended to integrate compression
> into applications.
> + // Applications for non-public use may agree on certain compression
> methods.
> + // Using different compression methods with the same identifier will lead
> to connection failure.
> + //
> + for (Index = 0; Index < DataSize / sizeof (EFI_TLS_COMPRESSION);
> Index++) {
> + Status = TlsSetCompressionMethod (*((UINT8 *) Data + Index));
> + if (EFI_ERROR (Status)) {
> + break;
> + }
> + }
> +
> + break;
> + case EfiTlsExtensionData:
> + Status = EFI_UNSUPPORTED;
> + goto ON_EXIT;
> + case EfiTlsVerifyMethod:
> + if (DataSize != sizeof (EFI_TLS_VERIFY)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + TlsSetVerify (Instance->TlsConn, *((UINT32 *) Data));
> + break;
> + case EfiTlsSessionID:
> + if (DataSize != sizeof (EFI_TLS_SESSION_ID)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + Status = TlsSetSessionId (
> + Instance->TlsConn,
> + ((EFI_TLS_SESSION_ID *) Data)->Data,
> + ((EFI_TLS_SESSION_ID *) Data)->Length
> + );
> + break;
> + case EfiTlsSessionState:
> + if (DataSize != sizeof (EFI_TLS_SESSION_STATE)) {
> + Status = EFI_INVALID_PARAMETER;
> + goto ON_EXIT;
> + }
> +
> + Instance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) Data;
> + break;
> + //
> + // Session information
> + //
> + case EfiTlsClientRandom:
> + Status = EFI_ACCESS_DENIED;
> + break;
> + case EfiTlsServerRandom:
> + Status = EFI_ACCESS_DENIED;
> + break;
> + case EfiTlsKeyMaterial:
> + Status = EFI_ACCESS_DENIED;
> + break;
> + //
> + // Unsupported type.
> + //
> + default:
> + Status = EFI_UNSUPPORTED;
> + }
> +
> +ON_EXIT:
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> +
> +/**
> + Get TLS session data.
> +
> + The GetSessionData() function return the TLS session information.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] DataType TLS session data type.
> + @param[in, out] Data Pointer to session data.
> + @param[in, out] DataSize Total size of session data. On input, it means
> + the size of Data buffer. On output, it means the size
> + of copied Data buffer if EFI_SUCCESS, and means the
> + size of desired Data buffer if EFI_BUFFER_TOO_SMALL.
> +
> + @retval EFI_SUCCESS The TLS session data is got successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + DataSize is NULL.
> + Data is NULL if *DataSize is not zero.
> + @retval EFI_UNSUPPORTED The DataType is unsupported.
> + @retval EFI_NOT_FOUND The TLS session data is not found.
> + @retval EFI_NOT_READY The DataType is not ready in current session
> state.
> + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to hold the data.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsGetSessionData (
> + IN EFI_TLS_PROTOCOL *This,
> + IN EFI_TLS_SESSION_DATA_TYPE DataType,
> + IN OUT VOID *Data, OPTIONAL
> + IN OUT UINTN *DataSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> +
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if (This == NULL || DataSize == NULL || (Data == NULL && *DataSize != 0))
> {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> + if (Instance->TlsSessionState == EfiTlsSessionNotStarted &&
> + (DataType == EfiTlsSessionID || DataType == EfiTlsClientRandom ||
> + DataType == EfiTlsServerRandom || DataType == EfiTlsKeyMaterial)) {
> + Status = EFI_NOT_READY;
> + goto ON_EXIT;
> + }
> +
> + switch (DataType) {
> + case EfiTlsVersion:
> + if (*DataSize < sizeof (EFI_TLS_VERSION)) {
> + *DataSize = sizeof (EFI_TLS_VERSION);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_VERSION);
> + *((UINT16 *) Data) = HTONS (TlsGetVersion (Instance->TlsConn));
> + break;
> + case EfiTlsConnectionEnd:
> + if (*DataSize < sizeof (EFI_TLS_CONNECTION_END)) {
> + *DataSize = sizeof (EFI_TLS_CONNECTION_END);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_CONNECTION_END);
> + *((UINT8 *) Data) = TlsGetConnectionEnd (Instance->TlsConn);
> + break;
> + case EfiTlsCipherList:
> + //
> + // Get the current session cipher suite.
> + //
> + if (*DataSize < sizeof (EFI_TLS_CIPHER)) {
> + *DataSize = sizeof (EFI_TLS_CIPHER);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof(EFI_TLS_CIPHER);
> + Status = TlsGetCurrentCipher (Instance->TlsConn, (UINT16 *) Data);
> + *((UINT16 *) Data) = HTONS (*((UINT16 *) Data));
> + break;
> + case EfiTlsCompressionMethod:
> + //
> + // Get the current session compression method.
> + //
> + if (*DataSize < sizeof (EFI_TLS_COMPRESSION)) {
> + *DataSize = sizeof (EFI_TLS_COMPRESSION);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_COMPRESSION);
> + Status = TlsGetCurrentCompressionId (Instance->TlsConn, (UINT8 *)
> Data);
> + break;
> + case EfiTlsExtensionData:
> + Status = EFI_UNSUPPORTED;
> + goto ON_EXIT;
> + case EfiTlsVerifyMethod:
> + if (*DataSize < sizeof (EFI_TLS_VERIFY)) {
> + *DataSize = sizeof (EFI_TLS_VERIFY);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_VERIFY);
> + *((UINT32 *) Data) = TlsGetVerify (Instance->TlsConn);
> + break;
> + case EfiTlsSessionID:
> + if (*DataSize < sizeof (EFI_TLS_SESSION_ID)) {
> + *DataSize = sizeof (EFI_TLS_SESSION_ID);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_SESSION_ID);
> + Status = TlsGetSessionId (
> + Instance->TlsConn,
> + ((EFI_TLS_SESSION_ID *) Data)->Data,
> + &(((EFI_TLS_SESSION_ID *) Data)->Length)
> + );
> + break;
> + case EfiTlsSessionState:
> + if (*DataSize < sizeof (EFI_TLS_SESSION_STATE)) {
> + *DataSize = sizeof (EFI_TLS_SESSION_STATE);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_SESSION_STATE);
> + CopyMem (Data, &Instance->TlsSessionState, *DataSize);
> + break;
> + case EfiTlsClientRandom:
> + if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
> + *DataSize = sizeof (EFI_TLS_RANDOM);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_RANDOM);
> + TlsGetClientRandom (Instance->TlsConn, (UINT8 *) Data);
> + break;
> + case EfiTlsServerRandom:
> + if (*DataSize < sizeof (EFI_TLS_RANDOM)) {
> + *DataSize = sizeof (EFI_TLS_RANDOM);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_RANDOM);
> + TlsGetServerRandom (Instance->TlsConn, (UINT8 *) Data);
> + break;
> + case EfiTlsKeyMaterial:
> + if (*DataSize < sizeof (EFI_TLS_MASTER_SECRET)) {
> + *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
> + Status = EFI_BUFFER_TOO_SMALL;
> + goto ON_EXIT;
> + }
> + *DataSize = sizeof (EFI_TLS_MASTER_SECRET);
> + Status = TlsGetKeyMaterial (Instance->TlsConn, (UINT8 *) Data);
> + break;
> + //
> + // Unsupported type.
> + //
> + default:
> + Status = EFI_UNSUPPORTED;
> + }
> +
> +ON_EXIT:
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> +
> +/**
> + Build response packet according to TLS state machine. This function is only
> valid for
> + alert, handshake and change_cipher_spec content type.
> +
> + The BuildResponsePacket() function builds TLS response packet in
> response to the TLS
> + request packet specified by RequestBuffer and RequestSize. If
> RequestBuffer is NULL and
> + RequestSize is 0, and TLS session status is EfiTlsSessionNotStarted, the TLS
> session
> + will be initiated and the response packet needs to be ClientHello. If
> RequestBuffer is
> + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionClosing,
> the TLS
> + session will be closed and response packet needs to be CloseNotify. If
> RequestBuffer is
> + NULL and RequestSize is 0, and TLS session status is EfiTlsSessionError, the
> TLS
> + session has errors and the response packet needs to be Alert message
> based on error
> + type.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in] RequestBuffer Pointer to the most recently received TLS
> packet. NULL
> + means TLS need initiate the TLS session and response
> + packet need to be ClientHello.
> + @param[in] RequestSize Packet size in bytes for the most recently
> received TLS
> + packet. 0 is only valid when RequestBuffer is NULL.
> + @param[out] Buffer Pointer to the buffer to hold the built packet.
> + @param[in, out] BufferSize Pointer to the buffer size in bytes. On input,
> it is
> + the buffer size provided by the caller. On output, it
> + is the buffer size in fact needed to contain the
> + packet.
> +
> + @retval EFI_SUCCESS The required TLS packet is built successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + RequestBuffer is NULL but RequestSize is NOT 0.
> + RequestSize is 0 but RequestBuffer is NOT NULL.
> + BufferSize is NULL.
> + Buffer is NULL if *BufferSize is not zero.
> + @retval EFI_BUFFER_TOO_SMALL BufferSize is too small to hold the
> response packet.
> + @retval EFI_NOT_READY Current TLS session state is NOT ready to
> build
> + ResponsePacket.
> + @retval EFI_ABORTED Something wrong build response packet.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsBuildResponsePacket (
> + IN EFI_TLS_PROTOCOL *This,
> + IN UINT8 *RequestBuffer, OPTIONAL
> + IN UINTN RequestSize, OPTIONAL
> + OUT UINT8 *Buffer, OPTIONAL
> + IN OUT UINTN *BufferSize
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if ((This == NULL) || (BufferSize == NULL) ||
> + (RequestBuffer == NULL && RequestSize != 0) ||
> + (RequestBuffer != NULL && RequestSize == 0) ||
> + (Buffer == NULL && *BufferSize !=0)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> + if(RequestBuffer == NULL && RequestSize == 0) {
> + switch (Instance->TlsSessionState) {
> + case EfiTlsSessionNotStarted:
> + //
> + // ClientHello.
> + //
> + Status = TlsDoHandshake (
> + Instance->TlsConn,
> + NULL,
> + 0,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + //
> + // *BufferSize should not be zero when ClientHello.
> + //
> + if (*BufferSize == 0) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> +
> + Instance->TlsSessionState = EfiTlsSessionHandShaking;
> +
> + break;
> + case EfiTlsSessionClosing:
> + //
> + // TLS session will be closed and response packet needs to be
> CloseNotify.
> + //
> + Status = TlsCloseNotify (
> + Instance->TlsConn,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + //
> + // *BufferSize should not be zero when build CloseNotify message.
> + //
> + if (*BufferSize == 0) {
> + Status = EFI_ABORTED;
> + goto ON_EXIT;
> + }
> +
> + break;
> + case EfiTlsSessionError:
> + //
> + // TLS session has errors and the response packet needs to be Alert
> + // message based on error type.
> + //
> + Status = TlsHandeAlert (
> + Instance->TlsConn,
> + NULL,
> + 0,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + break;
> + default:
> + //
> + // Current TLS session state is NOT ready to build ResponsePacket.
> + //
> + Status = EFI_NOT_READY;
> + }
> + } else {
> + //
> + // 1. Received packet may have multiply TLS record messages.
> + // 2. One TLS record message may have multiply handshake protocol.
> + // 3. Some errors may be happened in handshake.
> + // TlsDoHandshake() can handle all of those cases.
> + //
> + if (TlsInHandshake (Instance->TlsConn)) {
> + Status = TlsDoHandshake (
> + Instance->TlsConn,
> + RequestBuffer,
> + RequestSize,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + if (!TlsInHandshake (Instance->TlsConn)) {
> + Instance->TlsSessionState = EfiTlsSessionDataTransferring;
> + }
> + } else {
> + //
> + // Must be alert message, Decrypt it and build the ResponsePacket.
> + //
> + ASSERT (((TLS_RECORD_HEADER *) RequestBuffer)->ContentType ==
> TLS_CONTENT_TYPE_ALERT);
> +
> + Status = TlsHandeAlert (
> + Instance->TlsConn,
> + RequestBuffer,
> + RequestSize,
> + Buffer,
> + BufferSize
> + );
> + if (EFI_ERROR (Status)) {
> + if (Status != EFI_BUFFER_TOO_SMALL) {
> + Instance->TlsSessionState = EfiTlsSessionError;
> + }
> +
> + goto ON_EXIT;
> + }
> + }
> + }
> +
> +ON_EXIT:
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> +
> +/**
> + Decrypt or encrypt TLS packet during session. This function is only valid
> after
> + session connected and for application_data content type.
> +
> + The ProcessPacket () function process each inbound or outbound TLS APP
> packet.
> +
> + @param[in] This Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[in, out] FragmentTable Pointer to a list of fragment. The caller
> will take
> + responsible to handle the original FragmentTable while
> + it may be reallocated in TLS driver. If CryptMode is
> + EfiTlsEncrypt, on input these fragments contain the TLS
> + header and plain text TLS APP payload; on output these
> + fragments contain the TLS header and cipher text TLS
> + APP payload. If CryptMode is EfiTlsDecrypt, on input
> + these fragments contain the TLS header and cipher text
> + TLS APP payload; on output these fragments contain the
> + TLS header and plain text TLS APP payload.
> + @param[in] FragmentCount Number of fragment.
> + @param[in] CryptMode Crypt mode.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval EFI_INVALID_PARAMETER One or more of the following
> conditions is TRUE:
> + This is NULL.
> + FragmentTable is NULL.
> + FragmentCount is NULL.
> + CryptoMode is invalid.
> + @retval EFI_NOT_READY Current TLS session state is NOT
> + EfiTlsSessionDataTransferring.
> + @retval EFI_ABORTED Something wrong decryption the message.
> TLS session
> + status will become EfiTlsSessionError. The caller need
> + call BuildResponsePacket() to generate Error Alert
> + message and send it out.
> + @retval EFI_OUT_OF_RESOURCES No enough resource to finish the
> operation.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessPacket (
> + IN EFI_TLS_PROTOCOL *This,
> + IN OUT EFI_TLS_FRAGMENT_DATA **FragmentTable,
> + IN UINT32 *FragmentCount,
> + IN EFI_TLS_CRYPT_MODE CryptMode
> + )
> +{
> + EFI_STATUS Status;
> + TLS_INSTANCE *Instance;
> +
> + EFI_TPL OldTpl;
> +
> + Status = EFI_SUCCESS;
> +
> + if (This == NULL || FragmentTable == NULL || FragmentCount == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
> +
> + Instance = TLS_INSTANCE_FROM_PROTOCOL_THIS (This);
> +
> + if (Instance->TlsSessionState != EfiTlsSessionDataTransferring) {
> + Status = EFI_NOT_READY;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Packet sent or received may have multiply TLS record
> message(Application data type).
> + // So,on input these fragments contain the TLS header and TLS APP
> payload;
> + // on output these fragments also contain the TLS header and TLS APP
> payload.
> + //
> + switch (CryptMode) {
> + case EfiTlsEncrypt:
> + Status = TlsEcryptPacket (Instance, FragmentTable, FragmentCount);
> + break;
> + case EfiTlsDecrypt:
> + Status = TlsDecryptPacket (Instance, FragmentTable, FragmentCount);
> + break;
> + default:
> + return EFI_INVALID_PARAMETER;
> + }
> +
> +ON_EXIT:
> + gBS->RestoreTPL (OldTpl);
> + return Status;
> +}
> --
> 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
` (4 preceding siblings ...)
2016-12-14 7:34 ` [Patch 05/10] NetworkPkg/TlsDxe: TlsDxe driver implementation over OpenSSL Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-15 2:22 ` Fu, Siyuan
2016-12-14 7:34 ` [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6 Jiaxin Wu
` (3 subsequent siblings)
9 siblings, 1 reply; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Ye Ting, Fu Siyuan, Zhang Lubo, Long Qin, Thomas Palmer,
Wu Jiaxin
This patch provides the UI to support TLS auth configuration.
* EFI_SIGNATURE_LIST format is used for 'TlsCaCertificate'
variable. So, TLS supports multiple certificate configuration.
* The variable attribute is BS with NV, which only target at
preventing runtime phase attack.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/Include/Guid/TlsAuthConfigHii.h | 25 +
NetworkPkg/Include/Guid/TlsAuthentication.h | 29 +
NetworkPkg/NetworkPkg.dec | 7 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c | 135 ++
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf | 73 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni | 21 +
| 19 +
.../TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni | 39 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c | 1841 ++++++++++++++++++++
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h | 282 +++
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h | 49 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr | 152 ++
12 files changed, 2672 insertions(+)
create mode 100644 NetworkPkg/Include/Guid/TlsAuthConfigHii.h
create mode 100644 NetworkPkg/Include/Guid/TlsAuthentication.h
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
diff --git a/NetworkPkg/Include/Guid/TlsAuthConfigHii.h b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
new file mode 100644
index 0000000..9d21426
--- /dev/null
+++ b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
@@ -0,0 +1,25 @@
+/** @file
+ GUIDs used as HII FormSet and HII Package list GUID in TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_HII_GUID_H__
+#define __TLS_AUTH_CONFIG_HII_GUID_H__
+
+#define TLS_AUTH_CONFIG_GUID \
+ { \
+ 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf } \
+ }
+
+extern EFI_GUID gTlsAuthConfigGuid;
+
+#endif
diff --git a/NetworkPkg/Include/Guid/TlsAuthentication.h b/NetworkPkg/Include/Guid/TlsAuthentication.h
new file mode 100644
index 0000000..2e800dc
--- /dev/null
+++ b/NetworkPkg/Include/Guid/TlsAuthentication.h
@@ -0,0 +1,29 @@
+/** @file
+ This file defines TlsCaCertificate variable.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTHENTICATION_H__
+#define __TLS_AUTHENTICATION_H__
+
+// Private variable for CA Certificate configuration
+//
+#define EFI_TLS_CA_CERTIFICATE_GUID \
+ { \
+ 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae } \
+ }
+
+#define EFI_TLS_CA_CERTIFICATE_VARIABLE L"TlsCaCertificate"
+
+extern EFI_GUID gEfiTlsCaCertificateGuid;
+
+#endif
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
index 268188a..24d45f4 100644
--- a/NetworkPkg/NetworkPkg.dec
+++ b/NetworkPkg/NetworkPkg.dec
@@ -38,10 +38,17 @@
gIScsiConfigGuid = { 0x4b47d616, 0xa8d6, 0x4552, { 0x9d, 0x44, 0xcc, 0xad, 0x2e, 0xf, 0x4c, 0xf9}}
# Include/Guid/HttpBootConfigHii.h
gHttpBootConfigGuid = { 0x4d20583a, 0x7765, 0x4e7a, { 0x8a, 0x67, 0xdc, 0xde, 0x74, 0xee, 0x3e, 0xc5 }}
+ # Include/Guid/TlsAuthConfigHii.h
+ gTlsAuthConfigGuid = { 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf }}
+
+ # Include/Guid/TlsAuthentication.h
+ gEfiTlsCaCertificateGuid = { 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae }}
+
+
[PcdsFeatureFlag]
## Indicates if the IPsec IKEv2 Certificate Authentication feature is enabled or not.<BR><BR>
# TRUE - Certificate Authentication feature is enabled.<BR>
# FALSE - Does not support Certificate Authentication.<BR>
# @Prompt Enable IPsec IKEv2 Certificate Authentication.
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
new file mode 100644
index 0000000..647bc2f
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
@@ -0,0 +1,135 @@
+/** @file
+ The DriverEntryPoint for TlsAuthConfigDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsAuthConfigImpl.h"
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigDxeUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData;
+
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiCallerIdGuid,
+ (VOID **) &PrivateData
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (PrivateData->Signature == TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE);
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiCallerIdGuid,
+ PrivateData,
+ NULL
+ );
+
+ TlsAuthConfigFormUnload (PrivateData);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigDxeDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData;
+
+ PrivateData = NULL;
+
+ //
+ // If already started, return.
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiCallerIdGuid,
+ NULL,
+ ImageHandle,
+ ImageHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ //
+ // Initialize the private data structure.
+ //
+ PrivateData = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_PRIVATE_DATA));
+ if (PrivateData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the HII configuration form.
+ //
+ Status = TlsAuthConfigFormInit (PrivateData);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
+ // Install private GUID.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiCallerIdGuid,
+ PrivateData,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+ TlsAuthConfigFormUnload (PrivateData);
+ FreePool (PrivateData);
+
+ return Status;
+}
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
new file mode 100644
index 0000000..19f095e
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
@@ -0,0 +1,73 @@
+## @file
+# Provides the capability to configure Tls Authentication in a setup browser
+# By this module, user may change the content of TlsCaCertificate.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TlsAuthConfigDxe
+ MODULE_UNI_FILE = TlsAuthConfigDxe.uni
+ FILE_GUID = 7ca1024f-eb17-11e5-9dba-28d2447c4829
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = TlsAuthConfigDxeDriverEntryPoint
+ UNLOAD_IMAGE = TlsAuthConfigDxeUnload
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
+
+[Sources]
+ TlsAuthConfigImpl.c
+ TlsAuthConfigImpl.h
+ TlsAuthConfigNvData.h
+ TlsAuthConfigDxe.c
+ TlsAuthConfigDxeStrings.uni
+ TlsAuthConfigVfr.vfr
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+ DebugLib
+ HiiLib
+ DevicePathLib
+ UefiHiiServicesLib
+ FileExplorerLib
+ PrintLib
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES
+ gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
+
+[Guids]
+ gTlsAuthConfigGuid ## PRODUCES ## GUID
+ gEfiCertX509Guid ## CONSUMES ## GUID # Indicate the cert type
+ gEfiIfrTianoGuid ## CONSUMES ## HII
+ gEfiTlsCaCertificateGuid ## PRODUCES ## GUID
+
+[Depex]
+ gEfiHiiConfigRoutingProtocolGuid AND
+ gEfiHiiDatabaseProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ TlsAuthConfigDxeExtra.uni
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
new file mode 100644
index 0000000..f99a14f
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
@@ -0,0 +1,21 @@
+// /** @file
+// Provides the capability to configure Tls Authentication in a setup browser
+//
+// By this module, user may change the content of TlsCaCertificate.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the capability to configure Tls Authentication in a setup browser"
+
+#string STR_MODULE_DESCRIPTION #language en-US "By this module, user may change the content of TlsCaCertificate."
+
--git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
new file mode 100644
index 0000000..ee4c49f
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
@@ -0,0 +1,19 @@
+// /** @file
+// TlsAuthConfigDxe Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"TLS Auth Config DXE"
+
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
new file mode 100644
index 0000000..a8f7e43
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
@@ -0,0 +1,39 @@
+/** @file
+ String definitions for Tls Authentication Configuration form.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#langdef en-US "English"
+
+#string STR_TLS_AUTH_CONFIG_TITLE #language en-US "Tls Auth Configuration"
+#string STR_TLS_AUTH_CONFIG_HELP #language en-US "Press <Enter> to select Tls Auth Configuration."
+
+#string STR_TLS_AUTH_CONFIG_SERVER_CA #language en-US "Server CA Configuration"
+#string STR_TLS_AUTH_CONFIG_SERVER_CA_HELP #language en-US "Press <Enter> to configure Server CA."
+#string STR_TLS_AUTH_CONFIG_CLIENT_CERT #language en-US "Client Cert Configuration"
+#string STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP #language en-US "Client cert configuration is unsupported currently."
+
+#string STR_TLS_AUTH_CONFIG_ENROLL_CERT #language en-US "Enroll Cert"
+#string STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP #language en-US "Press <Enter> to enroll cert."
+#string STR_TLS_AUTH_CONFIG_DELETE_CERT #language en-US "Delete Cert"
+#string STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP #language en-US "Press <Enter> to delete cert."
+
+#string STR_TLS_AUTH_CONFIG_ADD_CERT_FILE #language en-US "Enroll Cert Using File"
+
+#string STR_TLS_AUTH_CONFIG_CERT_GUID #language en-US "Cert GUID"
+#string STR_TLS_AUTH_CONFIG_CERT_GUID_HELP #language en-US "Input digit character in 11111111-2222-3333-4444-1234567890ab format."
+#string STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT #language en-US "Commit Changes and Exit"
+#string STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT #language en-US "Discard Changes and Exit"
+
+#string STR_CERT_TYPE_PCKS_GUID #language en-US "GUID for CERT"
+
+#string STR_NULL #language en-US ""
\ No newline at end of file
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
new file mode 100644
index 0000000..1132cac
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
@@ -0,0 +1,1841 @@
+/** @file
+ The Miscellaneous Routines for TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsAuthConfigImpl.h"
+
+VOID *mStartOpCodeHandle = NULL;
+VOID *mEndOpCodeHandle = NULL;
+EFI_IFR_GUID_LABEL *mStartLabel = NULL;
+EFI_IFR_GUID_LABEL *mEndLabel = NULL;
+
+
+CHAR16 mTlsAuthConfigStorageName[] = L"TLS_AUTH_CONFIG_IFR_NVDATA";
+
+TLS_AUTH_CONFIG_PRIVATE_DATA *mTlsAuthPrivateData = NULL;
+
+HII_VENDOR_DEVICE_PATH mTlsAuthConfigHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ TLS_AUTH_CONFIG_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH),
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+//
+// Possible DER-encoded certificate file suffixes, end with NULL pointer.
+//
+CHAR16* mDerPemEncodedSuffix[] = {
+ L".cer",
+ L".der",
+ L".crt",
+ L".pem",
+ NULL
+};
+
+/**
+ This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix.
+
+ @param[in] FileSuffix The suffix of the input certificate file
+
+ @retval TRUE It's a DER/PEM-encoded certificate.
+ @retval FALSE It's NOT a DER/PEM-encoded certificate.
+
+**/
+BOOLEAN
+IsDerPemEncodeCertificate (
+ IN CONST CHAR16 *FileSuffix
+)
+{
+ UINTN Index;
+ for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) {
+ if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ Worker function that prints an EFI_GUID into specified Buffer.
+
+ @param[in] Guid Pointer to GUID to print.
+ @param[in] Buffer Buffer to print Guid into.
+ @param[in] BufferSize Size of Buffer.
+
+ @retval Number of characters printed.
+
+**/
+UINTN
+GuidToString (
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ UINTN Size;
+
+ Size = UnicodeSPrint (
+ Buffer,
+ BufferSize,
+ L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (UINTN)Guid->Data1,
+ (UINTN)Guid->Data2,
+ (UINTN)Guid->Data3,
+ (UINTN)Guid->Data4[0],
+ (UINTN)Guid->Data4[1],
+ (UINTN)Guid->Data4[2],
+ (UINTN)Guid->Data4[3],
+ (UINTN)Guid->Data4[4],
+ (UINTN)Guid->Data4[5],
+ (UINTN)Guid->Data4[6],
+ (UINTN)Guid->Data4[7]
+ );
+
+ //
+ // SPrint will null terminate the string. The -1 skips the null
+ //
+ return Size - 1;
+}
+
+/**
+ Convert a String to Guid Value.
+
+ @param[in] Str Specifies the String to be converted.
+ @param[in] StrLen Number of Unicode Characters of String (exclusive \0)
+ @param[out] Guid Return the result Guid value.
+
+ @retval EFI_SUCCESS The operation is finished successfully.
+ @retval EFI_NOT_FOUND Invalid string.
+
+**/
+EFI_STATUS
+StringToGuid (
+ IN CHAR16 *Str,
+ IN UINTN StrLen,
+ OUT EFI_GUID *Guid
+ )
+{
+ CHAR16 *PtrBuffer;
+ CHAR16 *PtrPosition;
+ UINT16 *Buffer;
+ UINTN Data;
+ UINTN Index;
+ UINT16 Digits[3];
+
+ Buffer = (CHAR16 *) AllocateZeroPool (sizeof (CHAR16) * (StrLen + 1));
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StrCpyS (Buffer, (StrLen + 1), Str);
+
+ //
+ // Data1
+ //
+ PtrBuffer = Buffer;
+ PtrPosition = PtrBuffer;
+ while (*PtrBuffer != L'\0') {
+ if (*PtrBuffer == L'-') {
+ break;
+ }
+ PtrBuffer++;
+ }
+ if (*PtrBuffer == L'\0') {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+
+ *PtrBuffer = L'\0';
+ Data = StrHexToUintn (PtrPosition);
+ Guid->Data1 = (UINT32)Data;
+
+ //
+ // Data2
+ //
+ PtrBuffer++;
+ PtrPosition = PtrBuffer;
+ while (*PtrBuffer != L'\0') {
+ if (*PtrBuffer == L'-') {
+ break;
+ }
+ PtrBuffer++;
+ }
+ if (*PtrBuffer == L'\0') {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ *PtrBuffer = L'\0';
+ Data = StrHexToUintn (PtrPosition);
+ Guid->Data2 = (UINT16)Data;
+
+ //
+ // Data3
+ //
+ PtrBuffer++;
+ PtrPosition = PtrBuffer;
+ while (*PtrBuffer != L'\0') {
+ if (*PtrBuffer == L'-') {
+ break;
+ }
+ PtrBuffer++;
+ }
+ if (*PtrBuffer == L'\0') {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ *PtrBuffer = L'\0';
+ Data = StrHexToUintn (PtrPosition);
+ Guid->Data3 = (UINT16)Data;
+
+ //
+ // Data4[0..1]
+ //
+ for ( Index = 0 ; Index < 2 ; Index++) {
+ PtrBuffer++;
+ if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ Digits[0] = *PtrBuffer;
+ PtrBuffer++;
+ Digits[1] = *PtrBuffer;
+ Digits[2] = L'\0';
+ Data = StrHexToUintn (Digits);
+ Guid->Data4[Index] = (UINT8)Data;
+ }
+
+ //
+ // skip the '-'
+ //
+ PtrBuffer++;
+ if ((*PtrBuffer != L'-' ) || ( *PtrBuffer == L'\0')) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Data4[2..7]
+ //
+ for ( ; Index < 8; Index++) {
+ PtrBuffer++;
+ if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ Digits[0] = *PtrBuffer;
+ PtrBuffer++;
+ Digits[1] = *PtrBuffer;
+ Digits[2] = L'\0';
+ Data = StrHexToUintn (Digits);
+ Guid->Data4[Index] = (UINT8)Data;
+ }
+
+ FreePool (Buffer);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ List all cert in specified database by GUID in the page
+ for user to select and delete as needed.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the vendor's signature database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+
+**/
+EFI_STATUS
+UpdateDeletePage (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINTN CertCount;
+ UINTN GuidIndex;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ UINTN DataSize;
+ UINT8 *Data;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINT32 ItemDataSize;
+ CHAR16 *GuidStr;
+ EFI_STRING_ID GuidID;
+ EFI_STRING_ID Help;
+
+ Data = NULL;
+ CertList = NULL;
+ Cert = NULL;
+ GuidStr = NULL;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+
+ //
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LabelNumber;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ //
+ // Read Variable.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ goto ON_EXIT;
+ }
+
+ Data = (UINT8 *) AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ GuidStr = AllocateZeroPool (100);
+ if (GuidStr == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Enumerate all data.
+ //
+ ItemDataSize = (UINT32) DataSize;
+ CertList = (EFI_SIGNATURE_LIST *) Data;
+ GuidIndex = 0;
+
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
+ Help = STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID);
+ } else {
+ //
+ // The signature type is not supported in current implementation.
+ //
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ continue;
+ }
+
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList
+ + sizeof (EFI_SIGNATURE_LIST)
+ + CertList->SignatureHeaderSize
+ + Index * CertList->SignatureSize);
+ //
+ // Display GUID and help
+ //
+ GuidToString (&Cert->SignatureOwner, GuidStr, 100);
+ GuidID = HiiSetString (Private->RegisteredHandle, 0, GuidStr, NULL);
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle,
+ (EFI_QUESTION_ID) (QuestionIdBase + GuidIndex++),
+ 0,
+ 0,
+ GuidID,
+ Help,
+ EFI_IFR_FLAG_CALLBACK,
+ 0,
+ NULL
+ );
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ON_EXIT:
+ HiiUpdateForm (
+ Private->RegisteredHandle,
+ &gTlsAuthConfigGuid,
+ FormId,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ if (StartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ }
+
+ if (EndOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+ }
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ if (GuidStr != NULL) {
+ FreePool (GuidStr);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Delete one entry from cert database.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the cert list.
+ @param[in] DeleteIndex Cert index to delete.
+
+ @retval EFI_SUCCESS Delete siganture successfully.
+ @retval EFI_NOT_FOUND Can't find the signature item,
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+**/
+EFI_STATUS
+DeleteCert (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase,
+ IN UINTN DeleteIndex
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ UINT8 *Data;
+ UINT8 *OldData;
+ UINT32 Attr;
+ UINT32 Index;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_LIST *NewCertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINTN CertCount;
+ UINT32 Offset;
+ BOOLEAN IsItemFound;
+ UINT32 ItemDataSize;
+ UINTN GuidIndex;
+
+ Data = NULL;
+ OldData = NULL;
+ CertList = NULL;
+ Cert = NULL;
+ Attr = 0;
+
+ //
+ // Get original signature list data.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL);
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ goto ON_EXIT;
+ }
+
+ OldData = (UINT8 *) AllocateZeroPool (DataSize);
+ if (OldData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData);
+ if (EFI_ERROR(Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Allocate space for new variable.
+ //
+ Data = (UINT8*) AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Enumerate all data and erasing the target item.
+ //
+ IsItemFound = FALSE;
+ ItemDataSize = (UINT32) DataSize;
+ CertList = (EFI_SIGNATURE_LIST *) OldData;
+ Offset = 0;
+ GuidIndex = 0;
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
+ //
+ // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
+ //
+ CopyMem (Data + Offset, CertList, (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
+ NewCertList = (EFI_SIGNATURE_LIST*) (Data + Offset);
+ Offset += (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ if (GuidIndex == DeleteIndex) {
+ //
+ // Find it! Skip it!
+ //
+ NewCertList->SignatureListSize -= CertList->SignatureSize;
+ IsItemFound = TRUE;
+ } else {
+ //
+ // This item doesn't match. Copy it to the Data buffer.
+ //
+ CopyMem (Data + Offset, (UINT8*)(Cert), CertList->SignatureSize);
+ Offset += CertList->SignatureSize;
+ }
+ GuidIndex++;
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+ }
+ } else {
+ //
+ // This List doesn't match. Just copy it to the Data buffer.
+ //
+ CopyMem (Data + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
+ Offset += CertList->SignatureListSize;
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ if (!IsItemFound) {
+ //
+ // Doesn't find the signature Item!
+ //
+ Status = EFI_NOT_FOUND;
+ goto ON_EXIT;
+ }
+
+ //
+ // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
+ //
+ ItemDataSize = Offset;
+ CertList = (EFI_SIGNATURE_LIST *) Data;
+ Offset = 0;
+ ZeroMem (OldData, ItemDataSize);
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount));
+ if (CertCount != 0) {
+ CopyMem (OldData + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
+ Offset += CertList->SignatureListSize;
+ }
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ DataSize = Offset;
+
+ Status = gRT->SetVariable(
+ VariableName,
+ VendorGuid,
+ Attr,
+ DataSize,
+ OldData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+ if (Data != NULL) {
+ FreePool(Data);
+ }
+
+ if (OldData != NULL) {
+ FreePool(OldData);
+ }
+
+ return UpdateDeletePage (
+ Private,
+ VariableName,
+ VendorGuid,
+ LabelNumber,
+ FormId,
+ QuestionIdBase
+ );
+}
+
+
+/**
+ Close an open file handle.
+
+ @param[in] FileHandle The file handle to close.
+
+**/
+VOID
+CloseFile (
+ IN EFI_FILE_HANDLE FileHandle
+ )
+{
+ if (FileHandle != NULL) {
+ FileHandle->Close (FileHandle);
+ }
+}
+
+/**
+ Read file content into BufferPtr, the size of the allocate buffer
+ is *FileSize plus AddtionAllocateSize.
+
+ @param[in] FileHandle The file to be read.
+ @param[in, out] BufferPtr Pointers to the pointer of allocated buffer.
+ @param[out] FileSize Size of input file
+ @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated.
+ In case the buffer need to contain others besides the file content.
+
+ @retval EFI_SUCCESS The file was read into the buffer.
+ @retval EFI_INVALID_PARAMETER A parameter was invalid.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval others Unexpected error.
+
+**/
+EFI_STATUS
+ReadFileContent (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN OUT VOID **BufferPtr,
+ OUT UINTN *FileSize,
+ IN UINTN AddtionAllocateSize
+ )
+
+{
+ UINTN BufferSize;
+ UINT64 SourceFileSize;
+ VOID *Buffer;
+ EFI_STATUS Status;
+
+ if ((FileHandle == NULL) || (FileSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Buffer = NULL;
+
+ //
+ // Get the file size
+ //
+ Status = FileHandle->SetPosition (FileHandle, (UINT64) -1);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = FileHandle->GetPosition (FileHandle, &SourceFileSize);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = FileHandle->SetPosition (FileHandle, 0);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize;
+ Buffer = AllocateZeroPool(BufferSize);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BufferSize = (UINTN) SourceFileSize;
+ *FileSize = BufferSize;
+
+ Status = FileHandle->Read (FileHandle, &BufferSize, Buffer);
+ if (EFI_ERROR (Status) || BufferSize != *FileSize) {
+ FreePool (Buffer);
+ Buffer = NULL;
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ *BufferPtr = Buffer;
+ return Status;
+}
+
+/**
+ This function will open a file or directory referenced by DevicePath.
+
+ This function opens a file with the open mode according to the file path. The
+ Attributes is valid only for EFI_FILE_MODE_CREATE.
+
+ @param[in, out] FilePath On input, the device path to the file.
+ On output, the remaining device path.
+ @param[out] FileHandle Pointer to the file handle.
+ @param[in] OpenMode The mode to open the file with.
+ @param[in] Attributes The file's file attributes.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+ @retval EFI_UNSUPPORTED Could not open the file path.
+ @retval EFI_NOT_FOUND The specified file could not be found on the
+ device or the file system could not be found on
+ the device.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
+ medium is no longer supported.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.
+ @retval EFI_ACCESS_DENIED The file was opened read only.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the
+ file.
+ @retval EFI_VOLUME_FULL The volume is full.
+**/
+EFI_STATUS
+EFIAPI
+OpenFileByDevicePath (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
+ OUT EFI_FILE_HANDLE *FileHandle,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;
+ EFI_FILE_PROTOCOL *Handle1;
+ EFI_FILE_PROTOCOL *Handle2;
+ EFI_HANDLE DeviceHandle;
+
+ if ((FilePath == NULL || FileHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->LocateDevicePath (
+ &gEfiSimpleFileSystemProtocolGuid,
+ FilePath,
+ &DeviceHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol(
+ DeviceHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID**)&EfiSimpleFileSystemProtocol,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1);
+ if (EFI_ERROR (Status)) {
+ FileHandle = NULL;
+ return Status;
+ }
+
+ //
+ // go down directories one node at a time.
+ //
+ while (!IsDevicePathEnd (*FilePath)) {
+ //
+ // For file system access each node should be a file path component
+ //
+ if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
+ ) {
+ FileHandle = NULL;
+ return (EFI_INVALID_PARAMETER);
+ }
+ //
+ // Open this file path node
+ //
+ Handle2 = Handle1;
+ Handle1 = NULL;
+
+ //
+ // Try to test opening an existing file
+ //
+ Status = Handle2->Open (
+ Handle2,
+ &Handle1,
+ ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
+ OpenMode &~EFI_FILE_MODE_CREATE,
+ 0
+ );
+
+ //
+ // see if the error was that it needs to be created
+ //
+ if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
+ Status = Handle2->Open (
+ Handle2,
+ &Handle1,
+ ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
+ OpenMode,
+ Attributes
+ );
+ }
+ //
+ // Close the last node
+ //
+ Handle2->Close (Handle2);
+
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ //
+ // Get the next node
+ //
+ *FilePath = NextDevicePathNode (*FilePath);
+ }
+
+ //
+ // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
+ //
+ *FileHandle = (VOID*)Handle1;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function converts an input device structure to a Unicode string.
+
+ @param[in] DevPath A pointer to the device path structure.
+
+ @return A new allocated Unicode string that represents the device path.
+
+**/
+CHAR16 *
+EFIAPI
+DevicePathToStr (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ )
+{
+ return ConvertDevicePathToText (
+ DevPath,
+ FALSE,
+ TRUE
+ );
+}
+
+
+/**
+ Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
+ The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL
+ means not enough memory resource.
+
+ @param DevicePath Device path.
+
+ @retval NULL Not enough memory resourece for AllocateCopyPool.
+ @retval Other A new allocated string that represents the file name.
+
+**/
+CHAR16 *
+ExtractFileNameFromDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CHAR16 *String;
+ CHAR16 *MatchString;
+ CHAR16 *LastMatch;
+ CHAR16 *FileName;
+ UINTN Length;
+
+ ASSERT(DevicePath != NULL);
+
+ String = DevicePathToStr(DevicePath);
+ MatchString = String;
+ LastMatch = String;
+ FileName = NULL;
+
+ while(MatchString != NULL){
+ LastMatch = MatchString + 1;
+ MatchString = StrStr(LastMatch,L"\\");
+ }
+
+ Length = StrLen(LastMatch);
+ FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);
+ if (FileName != NULL) {
+ *(FileName + Length) = 0;
+ }
+
+ FreePool(String);
+
+ return FileName;
+}
+
+/**
+ Enroll a new X509 certificate into Variable.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of CA database.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollX509toVariable (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+ UINTN X509DataSize;
+ VOID *X509Data;
+ EFI_SIGNATURE_LIST *CACert;
+ EFI_SIGNATURE_DATA *CACertData;
+ VOID *Data;
+ UINTN DataSize;
+ UINTN SigDataSize;
+ UINT32 Attr;
+
+ X509DataSize = 0;
+ SigDataSize = 0;
+ DataSize = 0;
+ X509Data = NULL;
+ CACert = NULL;
+ CACertData = NULL;
+ Data = NULL;
+
+ Status = ReadFileContent (
+ Private->FileContext->FHandle,
+ &X509Data,
+ &X509DataSize,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ ASSERT (X509Data != NULL);
+
+ SigDataSize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+
+ Data = AllocateZeroPool (SigDataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ CACert = (EFI_SIGNATURE_LIST*) Data;
+ CACert->SignatureListSize = (UINT32) SigDataSize;
+ CACert->SignatureHeaderSize = 0;
+ CACert->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid);
+
+ CACertData = (EFI_SIGNATURE_DATA*) ((UINT8* ) CACert + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&CACertData->SignatureOwner, Private->CertGuid);
+ CopyMem ((UINT8* ) (CACertData->SignatureData), X509Data, X509DataSize);
+
+ //
+ // Check if signature database entry has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR;
+
+ Status = gRT->GetVariable(
+ VariableName,
+ &gEfiTlsCaCertificateGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiTlsCaCertificateGuid,
+ Attr,
+ SigDataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ CloseFile (Private->FileContext->FHandle);
+ if (Private->FileContext->FileName != NULL) {
+ FreePool(Private->FileContext->FileName);
+ Private->FileContext->FileName = NULL;
+ }
+
+ Private->FileContext->FHandle = NULL;
+
+ if (Private->CertGuid != NULL) {
+ FreePool (Private->CertGuid);
+ Private->CertGuid = NULL;
+ }
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ if (X509Data != NULL) {
+ FreePool (X509Data);
+ }
+
+ return Status;
+}
+
+/**
+ Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of signature database.
+
+ @retval EFI_SUCCESS New Cert enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED The Cert file is unsupported type.
+ @retval others Fail to enroll Cert data.
+
+**/
+EFI_STATUS
+EnrollCertDatabase (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ UINT16* FilePostFix;
+ UINTN NameLength;
+
+ if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->CertGuid == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Parse the file's postfix.
+ //
+ NameLength = StrLen (Private->FileContext->FileName);
+ if (NameLength <= 4) {
+ return EFI_INVALID_PARAMETER;
+ }
+ FilePostFix = Private->FileContext->FileName + NameLength - 4;
+
+ if (IsDerPemEncodeCertificate (FilePostFix)) {
+ //
+ // Supports DER-encoded X509 certificate.
+ //
+ return EnrollX509toVariable (Private, VariableName);
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Refresh the global UpdateData structure.
+
+**/
+VOID
+RefreshUpdateData (
+ VOID
+ )
+{
+ //
+ // Free current updated date
+ //
+ if (mStartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mStartOpCodeHandle);
+ }
+
+ //
+ // Create new OpCode Handle
+ //
+ mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ mStartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+}
+
+/**
+ Clean up the dynamic opcode at label and form specified by both LabelId.
+
+ @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
+ @param[in] PrivateData Module private data.
+
+**/
+VOID
+CleanUpPage (
+ IN UINT16 LabelId,
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData
+ )
+{
+ RefreshUpdateData ();
+
+ //
+ // Remove all op-codes from dynamic page
+ //
+ mStartLabel->Number = LabelId;
+ HiiUpdateForm (
+ PrivateData->RegisteredHandle,
+ &gTlsAuthConfigGuid,
+ LabelId,
+ mStartOpCodeHandle, // Label LabelId
+ mEndOpCodeHandle // LABEL_END
+ );
+}
+
+/**
+ Update the form base on the selected file.
+
+ @param FilePath Point to the file path.
+ @param FormId The form need to display.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+
+**/
+BOOLEAN
+UpdatePage(
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN EFI_FORM_ID FormId
+ )
+{
+ CHAR16 *FileName;
+ EFI_STRING_ID StringToken;
+
+ FileName = NULL;
+
+ if (FilePath != NULL) {
+ FileName = ExtractFileNameFromDevicePath(FilePath);
+ }
+ if (FileName == NULL) {
+ //
+ // FileName = NULL has two case:
+ // 1. FilePath == NULL, not select file.
+ // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.
+ // In these two case, no need to update the form, and exit the caller function.
+ //
+ return TRUE;
+ }
+ StringToken = HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0, FileName, NULL);
+
+ mTlsAuthPrivateData->FileContext->FileName = FileName;
+
+ OpenFileByDevicePath (
+ &FilePath,
+ &mTlsAuthPrivateData->FileContext->FHandle,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ //
+ // Create Subtitle op-code for the display string of the option.
+ //
+ RefreshUpdateData ();
+ mStartLabel->Number = FormId;
+
+ HiiCreateSubTitleOpCode (
+ mStartOpCodeHandle,
+ StringToken,
+ 0,
+ 0,
+ 0
+ );
+
+ HiiUpdateForm (
+ mTlsAuthPrivateData->RegisteredHandle,
+ &gTlsAuthConfigGuid,
+ FormId,
+ mStartOpCodeHandle, /// Label FormId
+ mEndOpCodeHandle /// LABEL_END
+ );
+
+ return TRUE;
+}
+
+/**
+ Update the form base on the input file path info.
+
+ @param FilePath Point to the file path.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+**/
+BOOLEAN
+UpdateCAFromFile (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ )
+{
+ return UpdatePage(FilePath, TLS_AUTH_CONFIG_FORMID4_FORM);
+}
+
+/**
+ Unload the configuration form, this includes: delete all the configuration
+ entries, uninstall the form callback protocol, and free the resources used.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is unloaded.
+ @retval Others Failed to unload the form.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormUnload (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ )
+{
+ if (Private->DriverHandle != NULL) {
+ //
+ // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
+ //
+ gBS->UninstallMultipleProtocolInterfaces (
+ Private->DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mTlsAuthConfigHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &Private->ConfigAccess,
+ NULL
+ );
+ Private->DriverHandle = NULL;
+ }
+
+ if (Private->RegisteredHandle != NULL) {
+ //
+ // Remove HII package list
+ //
+ HiiRemovePackages (Private->RegisteredHandle);
+ Private->RegisteredHandle = NULL;
+ }
+
+ if (Private->CertGuid != NULL) {
+ FreePool (Private->CertGuid);
+ }
+
+ if (Private->FileContext != NULL) {
+ FreePool (Private->FileContext);
+ }
+
+ FreePool (Private);
+
+ if (mStartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mStartOpCodeHandle);
+ }
+
+ if (mEndOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mEndOpCodeHandle);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize the configuration form.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormInit (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE;
+
+ Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig;
+ Private->ConfigAccess.RouteConfig = TlsAuthConfigAccessRouteConfig;
+ Private->ConfigAccess.Callback = TlsAuthConfigAccessCallback;
+
+ //
+ // Install Device Path Protocol and Config Access protocol to driver handle.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mTlsAuthConfigHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &Private->ConfigAccess,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Publish our HII data.
+ //
+ Private->RegisteredHandle = HiiAddPackages (
+ &gTlsAuthConfigGuid,
+ Private->DriverHandle,
+ TlsAuthConfigDxeStrings,
+ TlsAuthConfigVfrBin,
+ NULL
+ );
+ if (Private->RegisteredHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ Private->FileContext = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT));
+ if (Private->FileContext == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Init OpCode Handle and Allocate space for creation of Buffer
+ //
+ mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (mStartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (mEndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ mStartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ mEndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ mEndLabel->Number = LABEL_END;
+
+ return EFI_SUCCESS;
+
+Error:
+ TlsAuthConfigFormUnload (Private);
+ return Status;
+}
+
+/**
+
+ This function allows the caller to request the current
+ configuration for one or more named elements. The resulting
+ string is in <ConfigAltResp> format. Any and all alternative
+ configuration strings shall also be appended to the end of the
+ current configuration string. If they are, they must appear
+ after the current configuration. They must contain the same
+ routing (GUID, NAME, PATH) as the current configuration string.
+ They must have an additional description indicating the type of
+ alternative configuration the string represents,
+ "ALTCFG=<StringToken>". That <StringToken> (when
+ converted from Hex UNICODE to binary) is a reference to a
+ string in the associated string pack.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Request A null-terminated Unicode string in
+ <ConfigRequest> format. Note that this
+ includes the routing information as well as
+ the configurable name / value pairs. It is
+ invalid for this string to be in
+ <MultiConfigRequest> format.
+ If a NULL is passed in for the Request field,
+ all of the settings being abstracted by this function
+ will be returned in the Results field. In addition,
+ if a ConfigHdr is passed in with no request elements,
+ all of the settings being abstracted for that particular
+ ConfigHdr reference will be returned in the Results Field.
+
+ @param Progress On return, points to a character in the
+ Request string. Points to the string's null
+ terminator if request was successful. Points
+ to the most recent "&" before the first
+ failing name / value pair (or the beginning
+ of the string if the failure is in the first
+ name / value pair) if the request was not
+ successful.
+
+ @param Results A null-terminated Unicode string in
+ <MultiConfigAltResp> format which has all values
+ filled in for the names in the Request string.
+ String to be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results string is filled with the
+ values corresponding to all requested
+ names.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_NOT_FOUND Routing data doesn't match any
+ known driver. Progress set to the
+ first character in the routing header.
+ Note: There is no requirement that the
+ driver validate the routing data. It
+ must skip the <ConfigHdr> in order to
+ process the names.
+
+ @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
+ to most recent "&" before the
+ error or the beginning of the
+ string.
+
+ @retval EFI_INVALID_PARAMETER Unknown name. Progress points
+ to the & before the name in
+ question.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ UINTN Size;
+ EFI_STRING ConfigRequest;
+ EFI_STRING ConfigRequestHdr;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
+ BOOLEAN AllocatedRequest;
+
+ if (Progress == NULL || Results == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AllocatedRequest = FALSE;
+ ConfigRequestHdr = NULL;
+ ConfigRequest = NULL;
+ Size = 0;
+
+ Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
+
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
+
+ *Progress = Request;
+
+ if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ ConfigRequest = Request;
+ if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+ //
+ // Request is set to NULL or OFFSET is NULL, construct full request string.
+ //
+ // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+ // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+ //
+ ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, Private->DriverHandle);
+ Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+ FreePool (ConfigRequestHdr);
+ ConfigRequestHdr = NULL;
+ }
+
+ Status = gHiiConfigRouting->BlockToConfig (
+ gHiiConfigRouting,
+ ConfigRequest,
+ (UINT8 *) &Private->TlsAuthConfigNvData,
+ BufferSize,
+ Results,
+ Progress
+ );
+
+ //
+ // Free the allocated config request string.
+ //
+ if (AllocatedRequest) {
+ FreePool (ConfigRequest);
+ }
+
+ //
+ // Set Progress string to the original request string.
+ //
+ if (Request == NULL) {
+ *Progress = NULL;
+ } else if (StrStr (Request, L"OFFSET") == NULL) {
+ *Progress = Request + StrLen (Request);
+ }
+
+ return Status;
+}
+
+/**
+
+ This function applies changes in a driver's configuration.
+ Input is a Configuration, which has the routing data for this
+ driver followed by name / value configuration pairs. The driver
+ must apply those pairs to its configurable storage. If the
+ driver's configuration is stored in a linear block of data
+ and the driver's name / value pairs are in <BlockConfig>
+ format, it may use the ConfigToBlock helper function (above) to
+ simplify the job.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Configuration A null-terminated Unicode string in
+ <ConfigString> format.
+
+ @param Progress A pointer to a string filled in with the
+ offset of the most recent '&' before the
+ first failing name / value pair (or the
+ beginn ing of the string if the failure
+ is in the first name / value pair) or
+ the terminating NULL if all was
+ successful.
+
+ @retval EFI_SUCCESS The results have been distributed or are
+ awaiting distribution.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
+ Results parameter would result
+ in this type of error.
+
+ @retval EFI_NOT_FOUND Target for the specified routing data
+ was not found
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
+
+ if (Progress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *Progress = Configuration;
+
+ if (Configuration == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check routing data in <ConfigHdr>.
+ // Note: there is no name for Name/Value storage, only GUID will be checked
+ //
+ if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
+
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
+
+ Status = gHiiConfigRouting->ConfigToBlock (
+ gHiiConfigRouting,
+ Configuration,
+ (UINT8 *) &Private->TlsAuthConfigNvData,
+ &BufferSize,
+ Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+/**
+
+ This function is called to provide results data to the driver.
+ This data consists of a unique key that is used to identify
+ which data is either being passed back or being asked for.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect. The format of the data tends to
+ vary based on the opcode that generated the callback.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original
+ exporting driver.
+ @param ActionRequest On return, points to the action requested by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
+ UINTN BufferSize;
+ TLS_AUTH_CONFIG_IFR_NVDATA *IfrNvData;
+ UINT16 LabelId;
+ EFI_DEVICE_PATH_PROTOCOL *File;
+
+ Status = EFI_SUCCESS;
+ File = NULL;
+
+ if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
+
+ mTlsAuthPrivateData = Private;
+
+ //
+ // Retrieve uncommitted data from Browser
+ //
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ IfrNvData = AllocateZeroPool (BufferSize);
+ if (IfrNvData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *) IfrNvData);
+
+ if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
+ (Action != EFI_BROWSER_ACTION_CHANGING)) {
+ Status = EFI_UNSUPPORTED;
+ goto EXIT;
+ }
+
+ if (Action == EFI_BROWSER_ACTION_CHANGING) {
+ switch (QuestionId) {
+ case KEY_TLS_AUTH_CONFIG_CLIENT_CERT:
+ case KEY_TLS_AUTH_CONFIG_SERVER_CA:
+ //
+ // Clear Cert GUID.
+ //
+ ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid));
+ if (Private->CertGuid == NULL) {
+ Private->CertGuid = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID));
+ if (Private->CertGuid == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) {
+ LabelId = TLS_AUTH_CONFIG_FORMID3_FORM;
+ } else if (QuestionId == KEY_TLS_AUTH_CONFIG_SERVER_CA) {
+ LabelId = TLS_AUTH_CONFIG_FORMID4_FORM;
+ }
+
+ //
+ // Refresh selected file.
+ //
+ CleanUpPage (LabelId, Private);
+ break;
+ case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE:
+ ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdateCAFromFile, &File);
+ break;
+
+ case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT:
+ Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE);
+ if (EFI_ERROR (Status)) {
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"ERROR: Enroll Cert Failure!",
+ NULL
+ );
+ }
+ break;
+
+ case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT:
+ if (Private->FileContext->FHandle != NULL) {
+ CloseFile (Private->FileContext->FHandle);
+ Private->FileContext->FHandle = NULL;
+ if (Private->FileContext->FileName!= NULL){
+ FreePool(Private->FileContext->FileName);
+ Private->FileContext->FileName = NULL;
+ }
+ }
+
+ if (Private->CertGuid!= NULL) {
+ FreePool (Private->CertGuid);
+ Private->CertGuid = NULL;
+ }
+ break;
+
+ case KEY_TLS_AUTH_CONFIG_DELETE_CERT:
+ UpdateDeletePage (
+ Private,
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ LABEL_CA_DELETE,
+ TLS_AUTH_CONFIG_FORMID5_FORM,
+ OPTION_DEL_CA_ESTION_ID
+ );
+ break;
+
+ default:
+ if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) &&
+ (QuestionId < (OPTION_DEL_CA_ESTION_ID + OPTION_CONFIG_RANGE))) {
+ DeleteCert (
+ Private,
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ LABEL_CA_DELETE,
+ TLS_AUTH_CONFIG_FORMID5_FORM,
+ OPTION_DEL_CA_ESTION_ID,
+ QuestionId - OPTION_DEL_CA_ESTION_ID
+ );
+ }
+ break;
+ }
+ } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
+ switch (QuestionId) {
+ case KEY_TLS_AUTH_CONFIG_CERT_GUID:
+ ASSERT (Private->CertGuid != NULL);
+ Status = StringToGuid (
+ IfrNvData->CertGuid,
+ StrLen (IfrNvData->CertGuid),
+ Private->CertGuid
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
+ break;
+ default:
+ break;
+ }
+ }
+
+EXIT:
+
+ if (!EFI_ERROR (Status)) {
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8*) IfrNvData, NULL);
+ }
+
+ FreePool (IfrNvData);
+
+ if (File != NULL){
+ FreePool(File);
+ File = NULL;
+ }
+
+ return EFI_SUCCESS;
+
+}
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
new file mode 100644
index 0000000..398f7b6
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
@@ -0,0 +1,282 @@
+/** @file
+ Header file of Miscellaneous Routines for TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_IMPL_H__
+#define __TLS_AUTH_CONFIG_IMPL_H__
+
+#include <Uefi.h>
+
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/SimpleFileSystem.h>
+
+//
+// Libraries
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Library/FileExplorerLib.h>
+#include <Library/PrintLib.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/ImageAuthentication.h>
+#include <Guid/TlsAuthentication.h>
+
+
+//
+// Include files with function prototypes
+//
+#include "TlsAuthConfigNvData.h"
+
+extern UINT8 TlsAuthConfigDxeStrings[];
+extern UINT8 TlsAuthConfigVfrBin[];
+
+#define TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('T', 'A', 'C', 'D')
+#define TLS_AUTH_CONFIG_PRIVATE_FROM_THIS(a) CR (a, TLS_AUTH_CONFIG_PRIVATE_DATA, ConfigAccess, TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE)
+
+#define TLS_AUTH_CONFIG_VAR_BASE_ATTR (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)
+
+typedef struct _TLS_AUTH_CONFIG_PRIVATE_DATA TLS_AUTH_CONFIG_PRIVATE_DATA;
+typedef struct _TLS_AUTH_CONFIG_FILE_CONTEXT TLS_AUTH_CONFIG_FILE_CONTEXT;
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+struct _TLS_AUTH_CONFIG_FILE_CONTEXT {
+ EFI_FILE_HANDLE FHandle;
+ UINT16 *FileName;
+};
+
+struct _TLS_AUTH_CONFIG_PRIVATE_DATA {
+ UINTN Signature;
+
+ EFI_HANDLE DriverHandle;
+ EFI_HII_HANDLE RegisteredHandle;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+ TLS_AUTH_CONFIG_IFR_NVDATA TlsAuthConfigNvData;
+
+ TLS_AUTH_CONFIG_FILE_CONTEXT *FileContext;
+
+ EFI_GUID *CertGuid;
+};
+
+/**
+ Unload the configuration form, this includes: delete all the configuration
+ entries, uninstall the form callback protocol, and free the resources used.
+ The form will only be unload completely when both IP4 and IP6 stack are stopped.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is unloaded.
+ @retval Others Failed to unload the form.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormUnload (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ );
+
+/**
+ Initialize the configuration form.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormInit (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ );
+
+/**
+
+ This function allows the caller to request the current
+ configuration for one or more named elements. The resulting
+ string is in <ConfigAltResp> format. Any and all alternative
+ configuration strings shall also be appended to the end of the
+ current configuration string. If they are, they must appear
+ after the current configuration. They must contain the same
+ routing (GUID, NAME, PATH) as the current configuration string.
+ They must have an additional description indicating the type of
+ alternative configuration the string represents,
+ "ALTCFG=<StringToken>". That <StringToken> (when
+ converted from Hex UNICODE to binary) is a reference to a
+ string in the associated string pack.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Request A null-terminated Unicode string in
+ <ConfigRequest> format. Note that this
+ includes the routing information as well as
+ the configurable name / value pairs. It is
+ invalid for this string to be in
+ <MultiConfigRequest> format.
+ If a NULL is passed in for the Request field,
+ all of the settings being abstracted by this function
+ will be returned in the Results field. In addition,
+ if a ConfigHdr is passed in with no request elements,
+ all of the settings being abstracted for that particular
+ ConfigHdr reference will be returned in the Results Field.
+
+ @param Progress On return, points to a character in the
+ Request string. Points to the string's null
+ terminator if request was successful. Points
+ to the most recent "&" before the first
+ failing name / value pair (or the beginning
+ of the string if the failure is in the first
+ name / value pair) if the request was not
+ successful.
+
+ @param Results A null-terminated Unicode string in
+ <MultiConfigAltResp> format which has all values
+ filled in for the names in the Request string.
+ String to be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results string is filled with the
+ values corresponding to all requested
+ names.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_NOT_FOUND Routing data doesn't match any
+ known driver. Progress set to the
+ first character in the routing header.
+ Note: There is no requirement that the
+ driver validate the routing data. It
+ must skip the <ConfigHdr> in order to
+ process the names.
+
+ @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
+ to most recent "&" before the
+ error or the beginning of the
+ string.
+
+ @retval EFI_INVALID_PARAMETER Unknown name. Progress points
+ to the & before the name in
+ question.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ );
+
+/**
+
+ This function applies changes in a driver's configuration.
+ Input is a Configuration, which has the routing data for this
+ driver followed by name / value configuration pairs. The driver
+ must apply those pairs to its configurable storage. If the
+ driver's configuration is stored in a linear block of data
+ and the driver's name / value pairs are in <BlockConfig>
+ format, it may use the ConfigToBlock helper function (above) to
+ simplify the job.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Configuration A null-terminated Unicode string in
+ <ConfigString> format.
+
+ @param Progress A pointer to a string filled in with the
+ offset of the most recent '&' before the
+ first failing name / value pair (or the
+ beginn ing of the string if the failure
+ is in the first name / value pair) or
+ the terminating NULL if all was
+ successful.
+
+ @retval EFI_SUCCESS The results have been distributed or are
+ awaiting distribution.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
+ Results parameter would result
+ in this type of error.
+
+ @retval EFI_NOT_FOUND Target for the specified routing data
+ was not found
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ );
+
+/**
+
+ This function is called to provide results data to the driver.
+ This data consists of a unique key that is used to identify
+ which data is either being passed back or being asked for.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect. The format of the data tends to
+ vary based on the opcode that generated the callback.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original
+ exporting driver.
+ @param ActionRequest On return, points to the action requested by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ );
+
+#endif
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
new file mode 100644
index 0000000..f453201
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
@@ -0,0 +1,49 @@
+/** @file
+ Header file for NV data structure definition.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_NV_DATA_H__
+#define __TLS_AUTH_CONFIG_NV_DATA_H__
+
+#include <Guid/TlsAuthConfigHii.h>
+
+#define TLS_AUTH_CONFIG_GUID_SIZE 36
+#define TLS_AUTH_CONFIG_GUID_STORAGE_SIZE 37
+
+#define TLS_AUTH_CONFIG_FORMID1_FORM 1
+#define TLS_AUTH_CONFIG_FORMID2_FORM 2
+#define TLS_AUTH_CONFIG_FORMID3_FORM 3
+#define TLS_AUTH_CONFIG_FORMID4_FORM 4
+#define TLS_AUTH_CONFIG_FORMID5_FORM 5
+
+
+#define KEY_TLS_AUTH_CONFIG_SERVER_CA 0x1000
+#define KEY_TLS_AUTH_CONFIG_CLIENT_CERT 0x1001
+#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT 0x1002
+#define KEY_TLS_AUTH_CONFIG_DELETE_CERT 0x1003
+#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE 0x1004
+#define KEY_TLS_AUTH_CONFIG_CERT_GUID 0x1005
+#define KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT 0x1006
+#define KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT 0x1007
+
+#define OPTION_DEL_CA_ESTION_ID 0x2000
+#define OPTION_CONFIG_RANGE 0x1000
+
+#define LABEL_CA_DELETE 0x1101
+#define LABEL_END 0xffff
+
+typedef struct {
+ CHAR16 CertGuid[TLS_AUTH_CONFIG_GUID_STORAGE_SIZE];
+} TLS_AUTH_CONFIG_IFR_NVDATA;
+
+#endif
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
new file mode 100644
index 0000000..fb130d9
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
@@ -0,0 +1,152 @@
+/** @file
+ VFR file used by TlsAuthConfigDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsAuthConfigNvData.h"
+
+formset
+ guid = TLS_AUTH_CONFIG_GUID,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_HELP),
+
+ varstore TLS_AUTH_CONFIG_IFR_NVDATA,
+ name = TLS_AUTH_CONFIG_IFR_NVDATA,
+ guid = TLS_AUTH_CONFIG_GUID;
+
+ //
+ // ##1 Form1: Main form for Tls Auth configration
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID1_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ //
+ // Display Server CA configration
+ //
+ goto TLS_AUTH_CONFIG_FORMID2_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_SERVER_CA;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ //
+ // Display Client cert configration
+ //
+ grayoutif TRUE; /// Current unsupported.
+ goto TLS_AUTH_CONFIG_FORMID3_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_CLIENT_CERT;
+ endif;
+ endform;
+
+ //
+ // ##2 Form2: CA configuration
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID2_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID4_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID5_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_DELETE_CERT;
+ endform;
+
+ //
+ // ##3 Form3 : Client cert configuration
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID3_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ //
+ // TODO...
+ //
+ endform;
+
+ //
+ // ##4 Form4: Enroll cert for CA
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID4_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID4_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ label TLS_AUTH_CONFIG_FORMID4_FORM;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ string varid = TLS_AUTH_CONFIG_IFR_NVDATA.CertGuid,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_CERT_GUID,
+ minsize = TLS_AUTH_CONFIG_GUID_SIZE,
+ maxsize = TLS_AUTH_CONFIG_GUID_SIZE,
+ endstring;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID1_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT;
+
+ goto TLS_AUTH_CONFIG_FORMID1_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT;
+
+ endform;
+
+ //
+ // ##5 Form5: Delete cert for CA
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID5_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT);
+
+ label LABEL_CA_DELETE;
+ label LABEL_END;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ endform;
+
+endformset;
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration
2016-12-14 7:34 ` [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration Jiaxin Wu
@ 2016-12-15 2:22 ` Fu, Siyuan
2016-12-22 2:52 ` Ye, Ting
0 siblings, 1 reply; 37+ messages in thread
From: Fu, Siyuan @ 2016-12-15 2:22 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Ye, Ting, Zhang, Lubo, Long, Qin, Thomas Palmer
Hi, Jiaxin
PrintLib support "%g" to print a GUID so you don't need to use "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" in GuidToString().
Beside of that, I do see a lot of drivers has similar internal function StringToGuid() or StrToGuid(), do we have a common library interface for this? if not I think it may worth to create one.
Other parts are good with me.
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
Best Regards
Siyuan
-----Original Message-----
From: Wu, Jiaxin
Sent: 2016年12月14日 15:34
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration
This patch provides the UI to support TLS auth configuration.
* EFI_SIGNATURE_LIST format is used for 'TlsCaCertificate'
variable. So, TLS supports multiple certificate configuration.
* The variable attribute is BS with NV, which only target at
preventing runtime phase attack.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/Include/Guid/TlsAuthConfigHii.h | 25 +
NetworkPkg/Include/Guid/TlsAuthentication.h | 29 +
NetworkPkg/NetworkPkg.dec | 7 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c | 135 ++
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf | 73 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni | 21 +
| 19 +
.../TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni | 39 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c | 1841 ++++++++++++++++++++
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h | 282 +++
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h | 49 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr | 152 ++
12 files changed, 2672 insertions(+)
create mode 100644 NetworkPkg/Include/Guid/TlsAuthConfigHii.h
create mode 100644 NetworkPkg/Include/Guid/TlsAuthentication.h
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
diff --git a/NetworkPkg/Include/Guid/TlsAuthConfigHii.h b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
new file mode 100644
index 0000000..9d21426
--- /dev/null
+++ b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
@@ -0,0 +1,25 @@
+/** @file
+ GUIDs used as HII FormSet and HII Package list GUID in TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_HII_GUID_H__
+#define __TLS_AUTH_CONFIG_HII_GUID_H__
+
+#define TLS_AUTH_CONFIG_GUID \
+ { \
+ 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf } \
+ }
+
+extern EFI_GUID gTlsAuthConfigGuid;
+
+#endif
diff --git a/NetworkPkg/Include/Guid/TlsAuthentication.h b/NetworkPkg/Include/Guid/TlsAuthentication.h
new file mode 100644
index 0000000..2e800dc
--- /dev/null
+++ b/NetworkPkg/Include/Guid/TlsAuthentication.h
@@ -0,0 +1,29 @@
+/** @file
+ This file defines TlsCaCertificate variable.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTHENTICATION_H__
+#define __TLS_AUTHENTICATION_H__
+
+// Private variable for CA Certificate configuration
+//
+#define EFI_TLS_CA_CERTIFICATE_GUID \
+ { \
+ 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae } \
+ }
+
+#define EFI_TLS_CA_CERTIFICATE_VARIABLE L"TlsCaCertificate"
+
+extern EFI_GUID gEfiTlsCaCertificateGuid;
+
+#endif
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
index 268188a..24d45f4 100644
--- a/NetworkPkg/NetworkPkg.dec
+++ b/NetworkPkg/NetworkPkg.dec
@@ -38,10 +38,17 @@
gIScsiConfigGuid = { 0x4b47d616, 0xa8d6, 0x4552, { 0x9d, 0x44, 0xcc, 0xad, 0x2e, 0xf, 0x4c, 0xf9}}
# Include/Guid/HttpBootConfigHii.h
gHttpBootConfigGuid = { 0x4d20583a, 0x7765, 0x4e7a, { 0x8a, 0x67, 0xdc, 0xde, 0x74, 0xee, 0x3e, 0xc5 }}
+ # Include/Guid/TlsAuthConfigHii.h
+ gTlsAuthConfigGuid = { 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf }}
+
+ # Include/Guid/TlsAuthentication.h
+ gEfiTlsCaCertificateGuid = { 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae }}
+
+
[PcdsFeatureFlag]
## Indicates if the IPsec IKEv2 Certificate Authentication feature is enabled or not.<BR><BR>
# TRUE - Certificate Authentication feature is enabled.<BR>
# FALSE - Does not support Certificate Authentication.<BR>
# @Prompt Enable IPsec IKEv2 Certificate Authentication.
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
new file mode 100644
index 0000000..647bc2f
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
@@ -0,0 +1,135 @@
+/** @file
+ The DriverEntryPoint for TlsAuthConfigDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsAuthConfigImpl.h"
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigDxeUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData;
+
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiCallerIdGuid,
+ (VOID **) &PrivateData
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (PrivateData->Signature == TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE);
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiCallerIdGuid,
+ PrivateData,
+ NULL
+ );
+
+ TlsAuthConfigFormUnload (PrivateData);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigDxeDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData;
+
+ PrivateData = NULL;
+
+ //
+ // If already started, return.
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiCallerIdGuid,
+ NULL,
+ ImageHandle,
+ ImageHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ //
+ // Initialize the private data structure.
+ //
+ PrivateData = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_PRIVATE_DATA));
+ if (PrivateData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the HII configuration form.
+ //
+ Status = TlsAuthConfigFormInit (PrivateData);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
+ // Install private GUID.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiCallerIdGuid,
+ PrivateData,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+ TlsAuthConfigFormUnload (PrivateData);
+ FreePool (PrivateData);
+
+ return Status;
+}
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
new file mode 100644
index 0000000..19f095e
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
@@ -0,0 +1,73 @@
+## @file
+# Provides the capability to configure Tls Authentication in a setup browser
+# By this module, user may change the content of TlsCaCertificate.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TlsAuthConfigDxe
+ MODULE_UNI_FILE = TlsAuthConfigDxe.uni
+ FILE_GUID = 7ca1024f-eb17-11e5-9dba-28d2447c4829
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = TlsAuthConfigDxeDriverEntryPoint
+ UNLOAD_IMAGE = TlsAuthConfigDxeUnload
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
+
+[Sources]
+ TlsAuthConfigImpl.c
+ TlsAuthConfigImpl.h
+ TlsAuthConfigNvData.h
+ TlsAuthConfigDxe.c
+ TlsAuthConfigDxeStrings.uni
+ TlsAuthConfigVfr.vfr
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+ DebugLib
+ HiiLib
+ DevicePathLib
+ UefiHiiServicesLib
+ FileExplorerLib
+ PrintLib
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES
+ gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
+
+[Guids]
+ gTlsAuthConfigGuid ## PRODUCES ## GUID
+ gEfiCertX509Guid ## CONSUMES ## GUID # Indicate the cert type
+ gEfiIfrTianoGuid ## CONSUMES ## HII
+ gEfiTlsCaCertificateGuid ## PRODUCES ## GUID
+
+[Depex]
+ gEfiHiiConfigRoutingProtocolGuid AND
+ gEfiHiiDatabaseProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ TlsAuthConfigDxeExtra.uni
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
new file mode 100644
index 0000000..f99a14f
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
@@ -0,0 +1,21 @@
+// /** @file
+// Provides the capability to configure Tls Authentication in a setup browser
+//
+// By this module, user may change the content of TlsCaCertificate.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the capability to configure Tls Authentication in a setup browser"
+
+#string STR_MODULE_DESCRIPTION #language en-US "By this module, user may change the content of TlsCaCertificate."
+
--git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
new file mode 100644
index 0000000..ee4c49f
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
@@ -0,0 +1,19 @@
+// /** @file
+// TlsAuthConfigDxe Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"TLS Auth Config DXE"
+
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
new file mode 100644
index 0000000..a8f7e43
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
@@ -0,0 +1,39 @@
+/** @file
+ String definitions for Tls Authentication Configuration form.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#langdef en-US "English"
+
+#string STR_TLS_AUTH_CONFIG_TITLE #language en-US "Tls Auth Configuration"
+#string STR_TLS_AUTH_CONFIG_HELP #language en-US "Press <Enter> to select Tls Auth Configuration."
+
+#string STR_TLS_AUTH_CONFIG_SERVER_CA #language en-US "Server CA Configuration"
+#string STR_TLS_AUTH_CONFIG_SERVER_CA_HELP #language en-US "Press <Enter> to configure Server CA."
+#string STR_TLS_AUTH_CONFIG_CLIENT_CERT #language en-US "Client Cert Configuration"
+#string STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP #language en-US "Client cert configuration is unsupported currently."
+
+#string STR_TLS_AUTH_CONFIG_ENROLL_CERT #language en-US "Enroll Cert"
+#string STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP #language en-US "Press <Enter> to enroll cert."
+#string STR_TLS_AUTH_CONFIG_DELETE_CERT #language en-US "Delete Cert"
+#string STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP #language en-US "Press <Enter> to delete cert."
+
+#string STR_TLS_AUTH_CONFIG_ADD_CERT_FILE #language en-US "Enroll Cert Using File"
+
+#string STR_TLS_AUTH_CONFIG_CERT_GUID #language en-US "Cert GUID"
+#string STR_TLS_AUTH_CONFIG_CERT_GUID_HELP #language en-US "Input digit character in 11111111-2222-3333-4444-1234567890ab format."
+#string STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT #language en-US "Commit Changes and Exit"
+#string STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT #language en-US "Discard Changes and Exit"
+
+#string STR_CERT_TYPE_PCKS_GUID #language en-US "GUID for CERT"
+
+#string STR_NULL #language en-US ""
\ No newline at end of file
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
new file mode 100644
index 0000000..1132cac
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
@@ -0,0 +1,1841 @@
+/** @file
+ The Miscellaneous Routines for TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsAuthConfigImpl.h"
+
+VOID *mStartOpCodeHandle = NULL;
+VOID *mEndOpCodeHandle = NULL;
+EFI_IFR_GUID_LABEL *mStartLabel = NULL;
+EFI_IFR_GUID_LABEL *mEndLabel = NULL;
+
+
+CHAR16 mTlsAuthConfigStorageName[] = L"TLS_AUTH_CONFIG_IFR_NVDATA";
+
+TLS_AUTH_CONFIG_PRIVATE_DATA *mTlsAuthPrivateData = NULL;
+
+HII_VENDOR_DEVICE_PATH mTlsAuthConfigHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ TLS_AUTH_CONFIG_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH),
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+//
+// Possible DER-encoded certificate file suffixes, end with NULL pointer.
+//
+CHAR16* mDerPemEncodedSuffix[] = {
+ L".cer",
+ L".der",
+ L".crt",
+ L".pem",
+ NULL
+};
+
+/**
+ This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix.
+
+ @param[in] FileSuffix The suffix of the input certificate file
+
+ @retval TRUE It's a DER/PEM-encoded certificate.
+ @retval FALSE It's NOT a DER/PEM-encoded certificate.
+
+**/
+BOOLEAN
+IsDerPemEncodeCertificate (
+ IN CONST CHAR16 *FileSuffix
+)
+{
+ UINTN Index;
+ for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) {
+ if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ Worker function that prints an EFI_GUID into specified Buffer.
+
+ @param[in] Guid Pointer to GUID to print.
+ @param[in] Buffer Buffer to print Guid into.
+ @param[in] BufferSize Size of Buffer.
+
+ @retval Number of characters printed.
+
+**/
+UINTN
+GuidToString (
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ UINTN Size;
+
+ Size = UnicodeSPrint (
+ Buffer,
+ BufferSize,
+ L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (UINTN)Guid->Data1,
+ (UINTN)Guid->Data2,
+ (UINTN)Guid->Data3,
+ (UINTN)Guid->Data4[0],
+ (UINTN)Guid->Data4[1],
+ (UINTN)Guid->Data4[2],
+ (UINTN)Guid->Data4[3],
+ (UINTN)Guid->Data4[4],
+ (UINTN)Guid->Data4[5],
+ (UINTN)Guid->Data4[6],
+ (UINTN)Guid->Data4[7]
+ );
+
+ //
+ // SPrint will null terminate the string. The -1 skips the null
+ //
+ return Size - 1;
+}
+
+/**
+ Convert a String to Guid Value.
+
+ @param[in] Str Specifies the String to be converted.
+ @param[in] StrLen Number of Unicode Characters of String (exclusive \0)
+ @param[out] Guid Return the result Guid value.
+
+ @retval EFI_SUCCESS The operation is finished successfully.
+ @retval EFI_NOT_FOUND Invalid string.
+
+**/
+EFI_STATUS
+StringToGuid (
+ IN CHAR16 *Str,
+ IN UINTN StrLen,
+ OUT EFI_GUID *Guid
+ )
+{
+ CHAR16 *PtrBuffer;
+ CHAR16 *PtrPosition;
+ UINT16 *Buffer;
+ UINTN Data;
+ UINTN Index;
+ UINT16 Digits[3];
+
+ Buffer = (CHAR16 *) AllocateZeroPool (sizeof (CHAR16) * (StrLen + 1));
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StrCpyS (Buffer, (StrLen + 1), Str);
+
+ //
+ // Data1
+ //
+ PtrBuffer = Buffer;
+ PtrPosition = PtrBuffer;
+ while (*PtrBuffer != L'\0') {
+ if (*PtrBuffer == L'-') {
+ break;
+ }
+ PtrBuffer++;
+ }
+ if (*PtrBuffer == L'\0') {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+
+ *PtrBuffer = L'\0';
+ Data = StrHexToUintn (PtrPosition);
+ Guid->Data1 = (UINT32)Data;
+
+ //
+ // Data2
+ //
+ PtrBuffer++;
+ PtrPosition = PtrBuffer;
+ while (*PtrBuffer != L'\0') {
+ if (*PtrBuffer == L'-') {
+ break;
+ }
+ PtrBuffer++;
+ }
+ if (*PtrBuffer == L'\0') {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ *PtrBuffer = L'\0';
+ Data = StrHexToUintn (PtrPosition);
+ Guid->Data2 = (UINT16)Data;
+
+ //
+ // Data3
+ //
+ PtrBuffer++;
+ PtrPosition = PtrBuffer;
+ while (*PtrBuffer != L'\0') {
+ if (*PtrBuffer == L'-') {
+ break;
+ }
+ PtrBuffer++;
+ }
+ if (*PtrBuffer == L'\0') {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ *PtrBuffer = L'\0';
+ Data = StrHexToUintn (PtrPosition);
+ Guid->Data3 = (UINT16)Data;
+
+ //
+ // Data4[0..1]
+ //
+ for ( Index = 0 ; Index < 2 ; Index++) {
+ PtrBuffer++;
+ if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ Digits[0] = *PtrBuffer;
+ PtrBuffer++;
+ Digits[1] = *PtrBuffer;
+ Digits[2] = L'\0';
+ Data = StrHexToUintn (Digits);
+ Guid->Data4[Index] = (UINT8)Data;
+ }
+
+ //
+ // skip the '-'
+ //
+ PtrBuffer++;
+ if ((*PtrBuffer != L'-' ) || ( *PtrBuffer == L'\0')) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Data4[2..7]
+ //
+ for ( ; Index < 8; Index++) {
+ PtrBuffer++;
+ if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ Digits[0] = *PtrBuffer;
+ PtrBuffer++;
+ Digits[1] = *PtrBuffer;
+ Digits[2] = L'\0';
+ Data = StrHexToUintn (Digits);
+ Guid->Data4[Index] = (UINT8)Data;
+ }
+
+ FreePool (Buffer);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ List all cert in specified database by GUID in the page
+ for user to select and delete as needed.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the vendor's signature database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+
+**/
+EFI_STATUS
+UpdateDeletePage (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINTN CertCount;
+ UINTN GuidIndex;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ UINTN DataSize;
+ UINT8 *Data;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINT32 ItemDataSize;
+ CHAR16 *GuidStr;
+ EFI_STRING_ID GuidID;
+ EFI_STRING_ID Help;
+
+ Data = NULL;
+ CertList = NULL;
+ Cert = NULL;
+ GuidStr = NULL;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+
+ //
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LabelNumber;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ //
+ // Read Variable.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ goto ON_EXIT;
+ }
+
+ Data = (UINT8 *) AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ GuidStr = AllocateZeroPool (100);
+ if (GuidStr == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Enumerate all data.
+ //
+ ItemDataSize = (UINT32) DataSize;
+ CertList = (EFI_SIGNATURE_LIST *) Data;
+ GuidIndex = 0;
+
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
+ Help = STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID);
+ } else {
+ //
+ // The signature type is not supported in current implementation.
+ //
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ continue;
+ }
+
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList
+ + sizeof (EFI_SIGNATURE_LIST)
+ + CertList->SignatureHeaderSize
+ + Index * CertList->SignatureSize);
+ //
+ // Display GUID and help
+ //
+ GuidToString (&Cert->SignatureOwner, GuidStr, 100);
+ GuidID = HiiSetString (Private->RegisteredHandle, 0, GuidStr, NULL);
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle,
+ (EFI_QUESTION_ID) (QuestionIdBase + GuidIndex++),
+ 0,
+ 0,
+ GuidID,
+ Help,
+ EFI_IFR_FLAG_CALLBACK,
+ 0,
+ NULL
+ );
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ON_EXIT:
+ HiiUpdateForm (
+ Private->RegisteredHandle,
+ &gTlsAuthConfigGuid,
+ FormId,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ if (StartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ }
+
+ if (EndOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+ }
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ if (GuidStr != NULL) {
+ FreePool (GuidStr);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Delete one entry from cert database.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the cert list.
+ @param[in] DeleteIndex Cert index to delete.
+
+ @retval EFI_SUCCESS Delete siganture successfully.
+ @retval EFI_NOT_FOUND Can't find the signature item,
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+**/
+EFI_STATUS
+DeleteCert (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase,
+ IN UINTN DeleteIndex
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ UINT8 *Data;
+ UINT8 *OldData;
+ UINT32 Attr;
+ UINT32 Index;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_LIST *NewCertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINTN CertCount;
+ UINT32 Offset;
+ BOOLEAN IsItemFound;
+ UINT32 ItemDataSize;
+ UINTN GuidIndex;
+
+ Data = NULL;
+ OldData = NULL;
+ CertList = NULL;
+ Cert = NULL;
+ Attr = 0;
+
+ //
+ // Get original signature list data.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL);
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ goto ON_EXIT;
+ }
+
+ OldData = (UINT8 *) AllocateZeroPool (DataSize);
+ if (OldData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData);
+ if (EFI_ERROR(Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Allocate space for new variable.
+ //
+ Data = (UINT8*) AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Enumerate all data and erasing the target item.
+ //
+ IsItemFound = FALSE;
+ ItemDataSize = (UINT32) DataSize;
+ CertList = (EFI_SIGNATURE_LIST *) OldData;
+ Offset = 0;
+ GuidIndex = 0;
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
+ //
+ // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
+ //
+ CopyMem (Data + Offset, CertList, (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
+ NewCertList = (EFI_SIGNATURE_LIST*) (Data + Offset);
+ Offset += (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ if (GuidIndex == DeleteIndex) {
+ //
+ // Find it! Skip it!
+ //
+ NewCertList->SignatureListSize -= CertList->SignatureSize;
+ IsItemFound = TRUE;
+ } else {
+ //
+ // This item doesn't match. Copy it to the Data buffer.
+ //
+ CopyMem (Data + Offset, (UINT8*)(Cert), CertList->SignatureSize);
+ Offset += CertList->SignatureSize;
+ }
+ GuidIndex++;
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+ }
+ } else {
+ //
+ // This List doesn't match. Just copy it to the Data buffer.
+ //
+ CopyMem (Data + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
+ Offset += CertList->SignatureListSize;
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ if (!IsItemFound) {
+ //
+ // Doesn't find the signature Item!
+ //
+ Status = EFI_NOT_FOUND;
+ goto ON_EXIT;
+ }
+
+ //
+ // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
+ //
+ ItemDataSize = Offset;
+ CertList = (EFI_SIGNATURE_LIST *) Data;
+ Offset = 0;
+ ZeroMem (OldData, ItemDataSize);
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount));
+ if (CertCount != 0) {
+ CopyMem (OldData + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
+ Offset += CertList->SignatureListSize;
+ }
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ DataSize = Offset;
+
+ Status = gRT->SetVariable(
+ VariableName,
+ VendorGuid,
+ Attr,
+ DataSize,
+ OldData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+ if (Data != NULL) {
+ FreePool(Data);
+ }
+
+ if (OldData != NULL) {
+ FreePool(OldData);
+ }
+
+ return UpdateDeletePage (
+ Private,
+ VariableName,
+ VendorGuid,
+ LabelNumber,
+ FormId,
+ QuestionIdBase
+ );
+}
+
+
+/**
+ Close an open file handle.
+
+ @param[in] FileHandle The file handle to close.
+
+**/
+VOID
+CloseFile (
+ IN EFI_FILE_HANDLE FileHandle
+ )
+{
+ if (FileHandle != NULL) {
+ FileHandle->Close (FileHandle);
+ }
+}
+
+/**
+ Read file content into BufferPtr, the size of the allocate buffer
+ is *FileSize plus AddtionAllocateSize.
+
+ @param[in] FileHandle The file to be read.
+ @param[in, out] BufferPtr Pointers to the pointer of allocated buffer.
+ @param[out] FileSize Size of input file
+ @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated.
+ In case the buffer need to contain others besides the file content.
+
+ @retval EFI_SUCCESS The file was read into the buffer.
+ @retval EFI_INVALID_PARAMETER A parameter was invalid.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval others Unexpected error.
+
+**/
+EFI_STATUS
+ReadFileContent (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN OUT VOID **BufferPtr,
+ OUT UINTN *FileSize,
+ IN UINTN AddtionAllocateSize
+ )
+
+{
+ UINTN BufferSize;
+ UINT64 SourceFileSize;
+ VOID *Buffer;
+ EFI_STATUS Status;
+
+ if ((FileHandle == NULL) || (FileSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Buffer = NULL;
+
+ //
+ // Get the file size
+ //
+ Status = FileHandle->SetPosition (FileHandle, (UINT64) -1);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = FileHandle->GetPosition (FileHandle, &SourceFileSize);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = FileHandle->SetPosition (FileHandle, 0);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize;
+ Buffer = AllocateZeroPool(BufferSize);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BufferSize = (UINTN) SourceFileSize;
+ *FileSize = BufferSize;
+
+ Status = FileHandle->Read (FileHandle, &BufferSize, Buffer);
+ if (EFI_ERROR (Status) || BufferSize != *FileSize) {
+ FreePool (Buffer);
+ Buffer = NULL;
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ *BufferPtr = Buffer;
+ return Status;
+}
+
+/**
+ This function will open a file or directory referenced by DevicePath.
+
+ This function opens a file with the open mode according to the file path. The
+ Attributes is valid only for EFI_FILE_MODE_CREATE.
+
+ @param[in, out] FilePath On input, the device path to the file.
+ On output, the remaining device path.
+ @param[out] FileHandle Pointer to the file handle.
+ @param[in] OpenMode The mode to open the file with.
+ @param[in] Attributes The file's file attributes.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+ @retval EFI_UNSUPPORTED Could not open the file path.
+ @retval EFI_NOT_FOUND The specified file could not be found on the
+ device or the file system could not be found on
+ the device.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
+ medium is no longer supported.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.
+ @retval EFI_ACCESS_DENIED The file was opened read only.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the
+ file.
+ @retval EFI_VOLUME_FULL The volume is full.
+**/
+EFI_STATUS
+EFIAPI
+OpenFileByDevicePath (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
+ OUT EFI_FILE_HANDLE *FileHandle,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;
+ EFI_FILE_PROTOCOL *Handle1;
+ EFI_FILE_PROTOCOL *Handle2;
+ EFI_HANDLE DeviceHandle;
+
+ if ((FilePath == NULL || FileHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->LocateDevicePath (
+ &gEfiSimpleFileSystemProtocolGuid,
+ FilePath,
+ &DeviceHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol(
+ DeviceHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID**)&EfiSimpleFileSystemProtocol,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1);
+ if (EFI_ERROR (Status)) {
+ FileHandle = NULL;
+ return Status;
+ }
+
+ //
+ // go down directories one node at a time.
+ //
+ while (!IsDevicePathEnd (*FilePath)) {
+ //
+ // For file system access each node should be a file path component
+ //
+ if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
+ ) {
+ FileHandle = NULL;
+ return (EFI_INVALID_PARAMETER);
+ }
+ //
+ // Open this file path node
+ //
+ Handle2 = Handle1;
+ Handle1 = NULL;
+
+ //
+ // Try to test opening an existing file
+ //
+ Status = Handle2->Open (
+ Handle2,
+ &Handle1,
+ ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
+ OpenMode &~EFI_FILE_MODE_CREATE,
+ 0
+ );
+
+ //
+ // see if the error was that it needs to be created
+ //
+ if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
+ Status = Handle2->Open (
+ Handle2,
+ &Handle1,
+ ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
+ OpenMode,
+ Attributes
+ );
+ }
+ //
+ // Close the last node
+ //
+ Handle2->Close (Handle2);
+
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ //
+ // Get the next node
+ //
+ *FilePath = NextDevicePathNode (*FilePath);
+ }
+
+ //
+ // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
+ //
+ *FileHandle = (VOID*)Handle1;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function converts an input device structure to a Unicode string.
+
+ @param[in] DevPath A pointer to the device path structure.
+
+ @return A new allocated Unicode string that represents the device path.
+
+**/
+CHAR16 *
+EFIAPI
+DevicePathToStr (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ )
+{
+ return ConvertDevicePathToText (
+ DevPath,
+ FALSE,
+ TRUE
+ );
+}
+
+
+/**
+ Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
+ The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL
+ means not enough memory resource.
+
+ @param DevicePath Device path.
+
+ @retval NULL Not enough memory resourece for AllocateCopyPool.
+ @retval Other A new allocated string that represents the file name.
+
+**/
+CHAR16 *
+ExtractFileNameFromDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CHAR16 *String;
+ CHAR16 *MatchString;
+ CHAR16 *LastMatch;
+ CHAR16 *FileName;
+ UINTN Length;
+
+ ASSERT(DevicePath != NULL);
+
+ String = DevicePathToStr(DevicePath);
+ MatchString = String;
+ LastMatch = String;
+ FileName = NULL;
+
+ while(MatchString != NULL){
+ LastMatch = MatchString + 1;
+ MatchString = StrStr(LastMatch,L"\\");
+ }
+
+ Length = StrLen(LastMatch);
+ FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);
+ if (FileName != NULL) {
+ *(FileName + Length) = 0;
+ }
+
+ FreePool(String);
+
+ return FileName;
+}
+
+/**
+ Enroll a new X509 certificate into Variable.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of CA database.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollX509toVariable (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+ UINTN X509DataSize;
+ VOID *X509Data;
+ EFI_SIGNATURE_LIST *CACert;
+ EFI_SIGNATURE_DATA *CACertData;
+ VOID *Data;
+ UINTN DataSize;
+ UINTN SigDataSize;
+ UINT32 Attr;
+
+ X509DataSize = 0;
+ SigDataSize = 0;
+ DataSize = 0;
+ X509Data = NULL;
+ CACert = NULL;
+ CACertData = NULL;
+ Data = NULL;
+
+ Status = ReadFileContent (
+ Private->FileContext->FHandle,
+ &X509Data,
+ &X509DataSize,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ ASSERT (X509Data != NULL);
+
+ SigDataSize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+
+ Data = AllocateZeroPool (SigDataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ CACert = (EFI_SIGNATURE_LIST*) Data;
+ CACert->SignatureListSize = (UINT32) SigDataSize;
+ CACert->SignatureHeaderSize = 0;
+ CACert->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid);
+
+ CACertData = (EFI_SIGNATURE_DATA*) ((UINT8* ) CACert + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&CACertData->SignatureOwner, Private->CertGuid);
+ CopyMem ((UINT8* ) (CACertData->SignatureData), X509Data, X509DataSize);
+
+ //
+ // Check if signature database entry has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR;
+
+ Status = gRT->GetVariable(
+ VariableName,
+ &gEfiTlsCaCertificateGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiTlsCaCertificateGuid,
+ Attr,
+ SigDataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ CloseFile (Private->FileContext->FHandle);
+ if (Private->FileContext->FileName != NULL) {
+ FreePool(Private->FileContext->FileName);
+ Private->FileContext->FileName = NULL;
+ }
+
+ Private->FileContext->FHandle = NULL;
+
+ if (Private->CertGuid != NULL) {
+ FreePool (Private->CertGuid);
+ Private->CertGuid = NULL;
+ }
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ if (X509Data != NULL) {
+ FreePool (X509Data);
+ }
+
+ return Status;
+}
+
+/**
+ Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of signature database.
+
+ @retval EFI_SUCCESS New Cert enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED The Cert file is unsupported type.
+ @retval others Fail to enroll Cert data.
+
+**/
+EFI_STATUS
+EnrollCertDatabase (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ UINT16* FilePostFix;
+ UINTN NameLength;
+
+ if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->CertGuid == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Parse the file's postfix.
+ //
+ NameLength = StrLen (Private->FileContext->FileName);
+ if (NameLength <= 4) {
+ return EFI_INVALID_PARAMETER;
+ }
+ FilePostFix = Private->FileContext->FileName + NameLength - 4;
+
+ if (IsDerPemEncodeCertificate (FilePostFix)) {
+ //
+ // Supports DER-encoded X509 certificate.
+ //
+ return EnrollX509toVariable (Private, VariableName);
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Refresh the global UpdateData structure.
+
+**/
+VOID
+RefreshUpdateData (
+ VOID
+ )
+{
+ //
+ // Free current updated date
+ //
+ if (mStartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mStartOpCodeHandle);
+ }
+
+ //
+ // Create new OpCode Handle
+ //
+ mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ mStartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+}
+
+/**
+ Clean up the dynamic opcode at label and form specified by both LabelId.
+
+ @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
+ @param[in] PrivateData Module private data.
+
+**/
+VOID
+CleanUpPage (
+ IN UINT16 LabelId,
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData
+ )
+{
+ RefreshUpdateData ();
+
+ //
+ // Remove all op-codes from dynamic page
+ //
+ mStartLabel->Number = LabelId;
+ HiiUpdateForm (
+ PrivateData->RegisteredHandle,
+ &gTlsAuthConfigGuid,
+ LabelId,
+ mStartOpCodeHandle, // Label LabelId
+ mEndOpCodeHandle // LABEL_END
+ );
+}
+
+/**
+ Update the form base on the selected file.
+
+ @param FilePath Point to the file path.
+ @param FormId The form need to display.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+
+**/
+BOOLEAN
+UpdatePage(
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN EFI_FORM_ID FormId
+ )
+{
+ CHAR16 *FileName;
+ EFI_STRING_ID StringToken;
+
+ FileName = NULL;
+
+ if (FilePath != NULL) {
+ FileName = ExtractFileNameFromDevicePath(FilePath);
+ }
+ if (FileName == NULL) {
+ //
+ // FileName = NULL has two case:
+ // 1. FilePath == NULL, not select file.
+ // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.
+ // In these two case, no need to update the form, and exit the caller function.
+ //
+ return TRUE;
+ }
+ StringToken = HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0, FileName, NULL);
+
+ mTlsAuthPrivateData->FileContext->FileName = FileName;
+
+ OpenFileByDevicePath (
+ &FilePath,
+ &mTlsAuthPrivateData->FileContext->FHandle,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ //
+ // Create Subtitle op-code for the display string of the option.
+ //
+ RefreshUpdateData ();
+ mStartLabel->Number = FormId;
+
+ HiiCreateSubTitleOpCode (
+ mStartOpCodeHandle,
+ StringToken,
+ 0,
+ 0,
+ 0
+ );
+
+ HiiUpdateForm (
+ mTlsAuthPrivateData->RegisteredHandle,
+ &gTlsAuthConfigGuid,
+ FormId,
+ mStartOpCodeHandle, /// Label FormId
+ mEndOpCodeHandle /// LABEL_END
+ );
+
+ return TRUE;
+}
+
+/**
+ Update the form base on the input file path info.
+
+ @param FilePath Point to the file path.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+**/
+BOOLEAN
+UpdateCAFromFile (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ )
+{
+ return UpdatePage(FilePath, TLS_AUTH_CONFIG_FORMID4_FORM);
+}
+
+/**
+ Unload the configuration form, this includes: delete all the configuration
+ entries, uninstall the form callback protocol, and free the resources used.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is unloaded.
+ @retval Others Failed to unload the form.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormUnload (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ )
+{
+ if (Private->DriverHandle != NULL) {
+ //
+ // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
+ //
+ gBS->UninstallMultipleProtocolInterfaces (
+ Private->DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mTlsAuthConfigHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &Private->ConfigAccess,
+ NULL
+ );
+ Private->DriverHandle = NULL;
+ }
+
+ if (Private->RegisteredHandle != NULL) {
+ //
+ // Remove HII package list
+ //
+ HiiRemovePackages (Private->RegisteredHandle);
+ Private->RegisteredHandle = NULL;
+ }
+
+ if (Private->CertGuid != NULL) {
+ FreePool (Private->CertGuid);
+ }
+
+ if (Private->FileContext != NULL) {
+ FreePool (Private->FileContext);
+ }
+
+ FreePool (Private);
+
+ if (mStartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mStartOpCodeHandle);
+ }
+
+ if (mEndOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mEndOpCodeHandle);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize the configuration form.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormInit (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE;
+
+ Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig;
+ Private->ConfigAccess.RouteConfig = TlsAuthConfigAccessRouteConfig;
+ Private->ConfigAccess.Callback = TlsAuthConfigAccessCallback;
+
+ //
+ // Install Device Path Protocol and Config Access protocol to driver handle.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mTlsAuthConfigHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &Private->ConfigAccess,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Publish our HII data.
+ //
+ Private->RegisteredHandle = HiiAddPackages (
+ &gTlsAuthConfigGuid,
+ Private->DriverHandle,
+ TlsAuthConfigDxeStrings,
+ TlsAuthConfigVfrBin,
+ NULL
+ );
+ if (Private->RegisteredHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ Private->FileContext = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT));
+ if (Private->FileContext == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Init OpCode Handle and Allocate space for creation of Buffer
+ //
+ mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (mStartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (mEndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ mStartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ mEndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ mEndLabel->Number = LABEL_END;
+
+ return EFI_SUCCESS;
+
+Error:
+ TlsAuthConfigFormUnload (Private);
+ return Status;
+}
+
+/**
+
+ This function allows the caller to request the current
+ configuration for one or more named elements. The resulting
+ string is in <ConfigAltResp> format. Any and all alternative
+ configuration strings shall also be appended to the end of the
+ current configuration string. If they are, they must appear
+ after the current configuration. They must contain the same
+ routing (GUID, NAME, PATH) as the current configuration string.
+ They must have an additional description indicating the type of
+ alternative configuration the string represents,
+ "ALTCFG=<StringToken>". That <StringToken> (when
+ converted from Hex UNICODE to binary) is a reference to a
+ string in the associated string pack.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Request A null-terminated Unicode string in
+ <ConfigRequest> format. Note that this
+ includes the routing information as well as
+ the configurable name / value pairs. It is
+ invalid for this string to be in
+ <MultiConfigRequest> format.
+ If a NULL is passed in for the Request field,
+ all of the settings being abstracted by this function
+ will be returned in the Results field. In addition,
+ if a ConfigHdr is passed in with no request elements,
+ all of the settings being abstracted for that particular
+ ConfigHdr reference will be returned in the Results Field.
+
+ @param Progress On return, points to a character in the
+ Request string. Points to the string's null
+ terminator if request was successful. Points
+ to the most recent "&" before the first
+ failing name / value pair (or the beginning
+ of the string if the failure is in the first
+ name / value pair) if the request was not
+ successful.
+
+ @param Results A null-terminated Unicode string in
+ <MultiConfigAltResp> format which has all values
+ filled in for the names in the Request string.
+ String to be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results string is filled with the
+ values corresponding to all requested
+ names.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_NOT_FOUND Routing data doesn't match any
+ known driver. Progress set to the
+ first character in the routing header.
+ Note: There is no requirement that the
+ driver validate the routing data. It
+ must skip the <ConfigHdr> in order to
+ process the names.
+
+ @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
+ to most recent "&" before the
+ error or the beginning of the
+ string.
+
+ @retval EFI_INVALID_PARAMETER Unknown name. Progress points
+ to the & before the name in
+ question.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ UINTN Size;
+ EFI_STRING ConfigRequest;
+ EFI_STRING ConfigRequestHdr;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
+ BOOLEAN AllocatedRequest;
+
+ if (Progress == NULL || Results == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AllocatedRequest = FALSE;
+ ConfigRequestHdr = NULL;
+ ConfigRequest = NULL;
+ Size = 0;
+
+ Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
+
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
+
+ *Progress = Request;
+
+ if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ ConfigRequest = Request;
+ if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+ //
+ // Request is set to NULL or OFFSET is NULL, construct full request string.
+ //
+ // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+ // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+ //
+ ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, Private->DriverHandle);
+ Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+ FreePool (ConfigRequestHdr);
+ ConfigRequestHdr = NULL;
+ }
+
+ Status = gHiiConfigRouting->BlockToConfig (
+ gHiiConfigRouting,
+ ConfigRequest,
+ (UINT8 *) &Private->TlsAuthConfigNvData,
+ BufferSize,
+ Results,
+ Progress
+ );
+
+ //
+ // Free the allocated config request string.
+ //
+ if (AllocatedRequest) {
+ FreePool (ConfigRequest);
+ }
+
+ //
+ // Set Progress string to the original request string.
+ //
+ if (Request == NULL) {
+ *Progress = NULL;
+ } else if (StrStr (Request, L"OFFSET") == NULL) {
+ *Progress = Request + StrLen (Request);
+ }
+
+ return Status;
+}
+
+/**
+
+ This function applies changes in a driver's configuration.
+ Input is a Configuration, which has the routing data for this
+ driver followed by name / value configuration pairs. The driver
+ must apply those pairs to its configurable storage. If the
+ driver's configuration is stored in a linear block of data
+ and the driver's name / value pairs are in <BlockConfig>
+ format, it may use the ConfigToBlock helper function (above) to
+ simplify the job.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Configuration A null-terminated Unicode string in
+ <ConfigString> format.
+
+ @param Progress A pointer to a string filled in with the
+ offset of the most recent '&' before the
+ first failing name / value pair (or the
+ beginn ing of the string if the failure
+ is in the first name / value pair) or
+ the terminating NULL if all was
+ successful.
+
+ @retval EFI_SUCCESS The results have been distributed or are
+ awaiting distribution.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
+ Results parameter would result
+ in this type of error.
+
+ @retval EFI_NOT_FOUND Target for the specified routing data
+ was not found
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
+
+ if (Progress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *Progress = Configuration;
+
+ if (Configuration == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check routing data in <ConfigHdr>.
+ // Note: there is no name for Name/Value storage, only GUID will be checked
+ //
+ if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
+
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
+
+ Status = gHiiConfigRouting->ConfigToBlock (
+ gHiiConfigRouting,
+ Configuration,
+ (UINT8 *) &Private->TlsAuthConfigNvData,
+ &BufferSize,
+ Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+/**
+
+ This function is called to provide results data to the driver.
+ This data consists of a unique key that is used to identify
+ which data is either being passed back or being asked for.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect. The format of the data tends to
+ vary based on the opcode that generated the callback.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original
+ exporting driver.
+ @param ActionRequest On return, points to the action requested by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
+ UINTN BufferSize;
+ TLS_AUTH_CONFIG_IFR_NVDATA *IfrNvData;
+ UINT16 LabelId;
+ EFI_DEVICE_PATH_PROTOCOL *File;
+
+ Status = EFI_SUCCESS;
+ File = NULL;
+
+ if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
+
+ mTlsAuthPrivateData = Private;
+
+ //
+ // Retrieve uncommitted data from Browser
+ //
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ IfrNvData = AllocateZeroPool (BufferSize);
+ if (IfrNvData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *) IfrNvData);
+
+ if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
+ (Action != EFI_BROWSER_ACTION_CHANGING)) {
+ Status = EFI_UNSUPPORTED;
+ goto EXIT;
+ }
+
+ if (Action == EFI_BROWSER_ACTION_CHANGING) {
+ switch (QuestionId) {
+ case KEY_TLS_AUTH_CONFIG_CLIENT_CERT:
+ case KEY_TLS_AUTH_CONFIG_SERVER_CA:
+ //
+ // Clear Cert GUID.
+ //
+ ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid));
+ if (Private->CertGuid == NULL) {
+ Private->CertGuid = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID));
+ if (Private->CertGuid == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) {
+ LabelId = TLS_AUTH_CONFIG_FORMID3_FORM;
+ } else if (QuestionId == KEY_TLS_AUTH_CONFIG_SERVER_CA) {
+ LabelId = TLS_AUTH_CONFIG_FORMID4_FORM;
+ }
+
+ //
+ // Refresh selected file.
+ //
+ CleanUpPage (LabelId, Private);
+ break;
+ case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE:
+ ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdateCAFromFile, &File);
+ break;
+
+ case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT:
+ Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE);
+ if (EFI_ERROR (Status)) {
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"ERROR: Enroll Cert Failure!",
+ NULL
+ );
+ }
+ break;
+
+ case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT:
+ if (Private->FileContext->FHandle != NULL) {
+ CloseFile (Private->FileContext->FHandle);
+ Private->FileContext->FHandle = NULL;
+ if (Private->FileContext->FileName!= NULL){
+ FreePool(Private->FileContext->FileName);
+ Private->FileContext->FileName = NULL;
+ }
+ }
+
+ if (Private->CertGuid!= NULL) {
+ FreePool (Private->CertGuid);
+ Private->CertGuid = NULL;
+ }
+ break;
+
+ case KEY_TLS_AUTH_CONFIG_DELETE_CERT:
+ UpdateDeletePage (
+ Private,
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ LABEL_CA_DELETE,
+ TLS_AUTH_CONFIG_FORMID5_FORM,
+ OPTION_DEL_CA_ESTION_ID
+ );
+ break;
+
+ default:
+ if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) &&
+ (QuestionId < (OPTION_DEL_CA_ESTION_ID + OPTION_CONFIG_RANGE))) {
+ DeleteCert (
+ Private,
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ LABEL_CA_DELETE,
+ TLS_AUTH_CONFIG_FORMID5_FORM,
+ OPTION_DEL_CA_ESTION_ID,
+ QuestionId - OPTION_DEL_CA_ESTION_ID
+ );
+ }
+ break;
+ }
+ } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
+ switch (QuestionId) {
+ case KEY_TLS_AUTH_CONFIG_CERT_GUID:
+ ASSERT (Private->CertGuid != NULL);
+ Status = StringToGuid (
+ IfrNvData->CertGuid,
+ StrLen (IfrNvData->CertGuid),
+ Private->CertGuid
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
+ break;
+ default:
+ break;
+ }
+ }
+
+EXIT:
+
+ if (!EFI_ERROR (Status)) {
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8*) IfrNvData, NULL);
+ }
+
+ FreePool (IfrNvData);
+
+ if (File != NULL){
+ FreePool(File);
+ File = NULL;
+ }
+
+ return EFI_SUCCESS;
+
+}
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
new file mode 100644
index 0000000..398f7b6
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
@@ -0,0 +1,282 @@
+/** @file
+ Header file of Miscellaneous Routines for TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_IMPL_H__
+#define __TLS_AUTH_CONFIG_IMPL_H__
+
+#include <Uefi.h>
+
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/SimpleFileSystem.h>
+
+//
+// Libraries
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Library/FileExplorerLib.h>
+#include <Library/PrintLib.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/ImageAuthentication.h>
+#include <Guid/TlsAuthentication.h>
+
+
+//
+// Include files with function prototypes
+//
+#include "TlsAuthConfigNvData.h"
+
+extern UINT8 TlsAuthConfigDxeStrings[];
+extern UINT8 TlsAuthConfigVfrBin[];
+
+#define TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('T', 'A', 'C', 'D')
+#define TLS_AUTH_CONFIG_PRIVATE_FROM_THIS(a) CR (a, TLS_AUTH_CONFIG_PRIVATE_DATA, ConfigAccess, TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE)
+
+#define TLS_AUTH_CONFIG_VAR_BASE_ATTR (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)
+
+typedef struct _TLS_AUTH_CONFIG_PRIVATE_DATA TLS_AUTH_CONFIG_PRIVATE_DATA;
+typedef struct _TLS_AUTH_CONFIG_FILE_CONTEXT TLS_AUTH_CONFIG_FILE_CONTEXT;
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+struct _TLS_AUTH_CONFIG_FILE_CONTEXT {
+ EFI_FILE_HANDLE FHandle;
+ UINT16 *FileName;
+};
+
+struct _TLS_AUTH_CONFIG_PRIVATE_DATA {
+ UINTN Signature;
+
+ EFI_HANDLE DriverHandle;
+ EFI_HII_HANDLE RegisteredHandle;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+ TLS_AUTH_CONFIG_IFR_NVDATA TlsAuthConfigNvData;
+
+ TLS_AUTH_CONFIG_FILE_CONTEXT *FileContext;
+
+ EFI_GUID *CertGuid;
+};
+
+/**
+ Unload the configuration form, this includes: delete all the configuration
+ entries, uninstall the form callback protocol, and free the resources used.
+ The form will only be unload completely when both IP4 and IP6 stack are stopped.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is unloaded.
+ @retval Others Failed to unload the form.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormUnload (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ );
+
+/**
+ Initialize the configuration form.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormInit (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ );
+
+/**
+
+ This function allows the caller to request the current
+ configuration for one or more named elements. The resulting
+ string is in <ConfigAltResp> format. Any and all alternative
+ configuration strings shall also be appended to the end of the
+ current configuration string. If they are, they must appear
+ after the current configuration. They must contain the same
+ routing (GUID, NAME, PATH) as the current configuration string.
+ They must have an additional description indicating the type of
+ alternative configuration the string represents,
+ "ALTCFG=<StringToken>". That <StringToken> (when
+ converted from Hex UNICODE to binary) is a reference to a
+ string in the associated string pack.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Request A null-terminated Unicode string in
+ <ConfigRequest> format. Note that this
+ includes the routing information as well as
+ the configurable name / value pairs. It is
+ invalid for this string to be in
+ <MultiConfigRequest> format.
+ If a NULL is passed in for the Request field,
+ all of the settings being abstracted by this function
+ will be returned in the Results field. In addition,
+ if a ConfigHdr is passed in with no request elements,
+ all of the settings being abstracted for that particular
+ ConfigHdr reference will be returned in the Results Field.
+
+ @param Progress On return, points to a character in the
+ Request string. Points to the string's null
+ terminator if request was successful. Points
+ to the most recent "&" before the first
+ failing name / value pair (or the beginning
+ of the string if the failure is in the first
+ name / value pair) if the request was not
+ successful.
+
+ @param Results A null-terminated Unicode string in
+ <MultiConfigAltResp> format which has all values
+ filled in for the names in the Request string.
+ String to be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results string is filled with the
+ values corresponding to all requested
+ names.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_NOT_FOUND Routing data doesn't match any
+ known driver. Progress set to the
+ first character in the routing header.
+ Note: There is no requirement that the
+ driver validate the routing data. It
+ must skip the <ConfigHdr> in order to
+ process the names.
+
+ @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
+ to most recent "&" before the
+ error or the beginning of the
+ string.
+
+ @retval EFI_INVALID_PARAMETER Unknown name. Progress points
+ to the & before the name in
+ question.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ );
+
+/**
+
+ This function applies changes in a driver's configuration.
+ Input is a Configuration, which has the routing data for this
+ driver followed by name / value configuration pairs. The driver
+ must apply those pairs to its configurable storage. If the
+ driver's configuration is stored in a linear block of data
+ and the driver's name / value pairs are in <BlockConfig>
+ format, it may use the ConfigToBlock helper function (above) to
+ simplify the job.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Configuration A null-terminated Unicode string in
+ <ConfigString> format.
+
+ @param Progress A pointer to a string filled in with the
+ offset of the most recent '&' before the
+ first failing name / value pair (or the
+ beginn ing of the string if the failure
+ is in the first name / value pair) or
+ the terminating NULL if all was
+ successful.
+
+ @retval EFI_SUCCESS The results have been distributed or are
+ awaiting distribution.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
+ Results parameter would result
+ in this type of error.
+
+ @retval EFI_NOT_FOUND Target for the specified routing data
+ was not found
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ );
+
+/**
+
+ This function is called to provide results data to the driver.
+ This data consists of a unique key that is used to identify
+ which data is either being passed back or being asked for.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect. The format of the data tends to
+ vary based on the opcode that generated the callback.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original
+ exporting driver.
+ @param ActionRequest On return, points to the action requested by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ );
+
+#endif
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
new file mode 100644
index 0000000..f453201
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
@@ -0,0 +1,49 @@
+/** @file
+ Header file for NV data structure definition.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_NV_DATA_H__
+#define __TLS_AUTH_CONFIG_NV_DATA_H__
+
+#include <Guid/TlsAuthConfigHii.h>
+
+#define TLS_AUTH_CONFIG_GUID_SIZE 36
+#define TLS_AUTH_CONFIG_GUID_STORAGE_SIZE 37
+
+#define TLS_AUTH_CONFIG_FORMID1_FORM 1
+#define TLS_AUTH_CONFIG_FORMID2_FORM 2
+#define TLS_AUTH_CONFIG_FORMID3_FORM 3
+#define TLS_AUTH_CONFIG_FORMID4_FORM 4
+#define TLS_AUTH_CONFIG_FORMID5_FORM 5
+
+
+#define KEY_TLS_AUTH_CONFIG_SERVER_CA 0x1000
+#define KEY_TLS_AUTH_CONFIG_CLIENT_CERT 0x1001
+#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT 0x1002
+#define KEY_TLS_AUTH_CONFIG_DELETE_CERT 0x1003
+#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE 0x1004
+#define KEY_TLS_AUTH_CONFIG_CERT_GUID 0x1005
+#define KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT 0x1006
+#define KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT 0x1007
+
+#define OPTION_DEL_CA_ESTION_ID 0x2000
+#define OPTION_CONFIG_RANGE 0x1000
+
+#define LABEL_CA_DELETE 0x1101
+#define LABEL_END 0xffff
+
+typedef struct {
+ CHAR16 CertGuid[TLS_AUTH_CONFIG_GUID_STORAGE_SIZE];
+} TLS_AUTH_CONFIG_IFR_NVDATA;
+
+#endif
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
new file mode 100644
index 0000000..fb130d9
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
@@ -0,0 +1,152 @@
+/** @file
+ VFR file used by TlsAuthConfigDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsAuthConfigNvData.h"
+
+formset
+ guid = TLS_AUTH_CONFIG_GUID,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_HELP),
+
+ varstore TLS_AUTH_CONFIG_IFR_NVDATA,
+ name = TLS_AUTH_CONFIG_IFR_NVDATA,
+ guid = TLS_AUTH_CONFIG_GUID;
+
+ //
+ // ##1 Form1: Main form for Tls Auth configration
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID1_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ //
+ // Display Server CA configration
+ //
+ goto TLS_AUTH_CONFIG_FORMID2_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_SERVER_CA;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ //
+ // Display Client cert configration
+ //
+ grayoutif TRUE; /// Current unsupported.
+ goto TLS_AUTH_CONFIG_FORMID3_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_CLIENT_CERT;
+ endif;
+ endform;
+
+ //
+ // ##2 Form2: CA configuration
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID2_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID4_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID5_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_DELETE_CERT;
+ endform;
+
+ //
+ // ##3 Form3 : Client cert configuration
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID3_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ //
+ // TODO...
+ //
+ endform;
+
+ //
+ // ##4 Form4: Enroll cert for CA
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID4_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID4_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ label TLS_AUTH_CONFIG_FORMID4_FORM;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ string varid = TLS_AUTH_CONFIG_IFR_NVDATA.CertGuid,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_CERT_GUID,
+ minsize = TLS_AUTH_CONFIG_GUID_SIZE,
+ maxsize = TLS_AUTH_CONFIG_GUID_SIZE,
+ endstring;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID1_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT;
+
+ goto TLS_AUTH_CONFIG_FORMID1_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT;
+
+ endform;
+
+ //
+ // ##5 Form5: Delete cert for CA
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID5_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT);
+
+ label LABEL_CA_DELETE;
+ label LABEL_END;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ endform;
+
+endformset;
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration
2016-12-15 2:22 ` Fu, Siyuan
@ 2016-12-22 2:52 ` Ye, Ting
2016-12-22 3:13 ` Wu, Jiaxin
0 siblings, 1 reply; 37+ messages in thread
From: Ye, Ting @ 2016-12-22 2:52 UTC (permalink / raw)
To: Fu, Siyuan, Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Zhang, Lubo, Long, Qin, Thomas Palmer
I agree. Adding new StringToGuid and GuidToString to common library seems a good idea if we don't have existing APIs.
In GuidToString, the comment indicates that SPrint will NULL terminate the string, so use Size -1 to skip the NULL. However, I see UnicodeSPrint in MdePkg returns the number of Unicode characters in the produced output buffer, not including the Null-terminator.
It looks inconsistent to me. Please check that.
Others are good to me.
Reviewed-by: Ye Ting <ting.ye@intel.com>
Best Regards,
Ting
-----Original Message-----
From: Fu, Siyuan
Sent: Thursday, December 15, 2016 10:22 AM
To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
Subject: RE: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration
Hi, Jiaxin
PrintLib support "%g" to print a GUID so you don't need to use "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" in GuidToString().
Beside of that, I do see a lot of drivers has similar internal function StringToGuid() or StrToGuid(), do we have a common library interface for this? if not I think it may worth to create one.
Other parts are good with me.
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
Best Regards
Siyuan
-----Original Message-----
From: Wu, Jiaxin
Sent: 2016年12月14日 15:34
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration
This patch provides the UI to support TLS auth configuration.
* EFI_SIGNATURE_LIST format is used for 'TlsCaCertificate'
variable. So, TLS supports multiple certificate configuration.
* The variable attribute is BS with NV, which only target at
preventing runtime phase attack.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/Include/Guid/TlsAuthConfigHii.h | 25 +
NetworkPkg/Include/Guid/TlsAuthentication.h | 29 +
NetworkPkg/NetworkPkg.dec | 7 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c | 135 ++
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf | 73 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni | 21 +
| 19 +
.../TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni | 39 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c | 1841 ++++++++++++++++++++
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h | 282 +++
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h | 49 +
NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr | 152 ++
12 files changed, 2672 insertions(+)
create mode 100644 NetworkPkg/Include/Guid/TlsAuthConfigHii.h
create mode 100644 NetworkPkg/Include/Guid/TlsAuthentication.h
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
diff --git a/NetworkPkg/Include/Guid/TlsAuthConfigHii.h b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
new file mode 100644
index 0000000..9d21426
--- /dev/null
+++ b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
@@ -0,0 +1,25 @@
+/** @file
+ GUIDs used as HII FormSet and HII Package list GUID in TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_HII_GUID_H__
+#define __TLS_AUTH_CONFIG_HII_GUID_H__
+
+#define TLS_AUTH_CONFIG_GUID \
+ { \
+ 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf } \
+ }
+
+extern EFI_GUID gTlsAuthConfigGuid;
+
+#endif
diff --git a/NetworkPkg/Include/Guid/TlsAuthentication.h b/NetworkPkg/Include/Guid/TlsAuthentication.h
new file mode 100644
index 0000000..2e800dc
--- /dev/null
+++ b/NetworkPkg/Include/Guid/TlsAuthentication.h
@@ -0,0 +1,29 @@
+/** @file
+ This file defines TlsCaCertificate variable.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTHENTICATION_H__
+#define __TLS_AUTHENTICATION_H__
+
+// Private variable for CA Certificate configuration
+//
+#define EFI_TLS_CA_CERTIFICATE_GUID \
+ { \
+ 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae } \
+ }
+
+#define EFI_TLS_CA_CERTIFICATE_VARIABLE L"TlsCaCertificate"
+
+extern EFI_GUID gEfiTlsCaCertificateGuid;
+
+#endif
diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
index 268188a..24d45f4 100644
--- a/NetworkPkg/NetworkPkg.dec
+++ b/NetworkPkg/NetworkPkg.dec
@@ -38,10 +38,17 @@
gIScsiConfigGuid = { 0x4b47d616, 0xa8d6, 0x4552, { 0x9d, 0x44, 0xcc, 0xad, 0x2e, 0xf, 0x4c, 0xf9}}
# Include/Guid/HttpBootConfigHii.h
gHttpBootConfigGuid = { 0x4d20583a, 0x7765, 0x4e7a, { 0x8a, 0x67, 0xdc, 0xde, 0x74, 0xee, 0x3e, 0xc5 }}
+ # Include/Guid/TlsAuthConfigHii.h
+ gTlsAuthConfigGuid = { 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf }}
+
+ # Include/Guid/TlsAuthentication.h
+ gEfiTlsCaCertificateGuid = { 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae }}
+
+
[PcdsFeatureFlag]
## Indicates if the IPsec IKEv2 Certificate Authentication feature is enabled or not.<BR><BR>
# TRUE - Certificate Authentication feature is enabled.<BR>
# FALSE - Does not support Certificate Authentication.<BR>
# @Prompt Enable IPsec IKEv2 Certificate Authentication.
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
new file mode 100644
index 0000000..647bc2f
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
@@ -0,0 +1,135 @@
+/** @file
+ The DriverEntryPoint for TlsAuthConfigDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsAuthConfigImpl.h"
+
+/**
+ Unloads an image.
+
+ @param ImageHandle Handle that identifies the image to be unloaded.
+
+ @retval EFI_SUCCESS The image has been unloaded.
+ @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image handle.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigDxeUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData;
+
+ Status = gBS->HandleProtocol (
+ ImageHandle,
+ &gEfiCallerIdGuid,
+ (VOID **) &PrivateData
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (PrivateData->Signature == TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE);
+
+ gBS->UninstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiCallerIdGuid,
+ PrivateData,
+ NULL
+ );
+
+ TlsAuthConfigFormUnload (PrivateData);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This is the declaration of an EFI image entry point. This entry point is
+ the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
+ both device drivers and bus drivers.
+
+ @param ImageHandle The firmware allocated handle for the UEFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval Others An unexpected error occurred.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigDxeDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData;
+
+ PrivateData = NULL;
+
+ //
+ // If already started, return.
+ //
+ Status = gBS->OpenProtocol (
+ ImageHandle,
+ &gEfiCallerIdGuid,
+ NULL,
+ ImageHandle,
+ ImageHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ return EFI_ALREADY_STARTED;
+ }
+
+ //
+ // Initialize the private data structure.
+ //
+ PrivateData = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_PRIVATE_DATA));
+ if (PrivateData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the HII configuration form.
+ //
+ Status = TlsAuthConfigFormInit (PrivateData);
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ //
+ // Install private GUID.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiCallerIdGuid,
+ PrivateData,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_ERROR;
+ }
+
+ return EFI_SUCCESS;
+
+ON_ERROR:
+ TlsAuthConfigFormUnload (PrivateData);
+ FreePool (PrivateData);
+
+ return Status;
+}
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
new file mode 100644
index 0000000..19f095e
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
@@ -0,0 +1,73 @@
+## @file
+# Provides the capability to configure Tls Authentication in a setup browser
+# By this module, user may change the content of TlsCaCertificate.
+#
+# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = TlsAuthConfigDxe
+ MODULE_UNI_FILE = TlsAuthConfigDxe.uni
+ FILE_GUID = 7ca1024f-eb17-11e5-9dba-28d2447c4829
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = TlsAuthConfigDxeDriverEntryPoint
+ UNLOAD_IMAGE = TlsAuthConfigDxeUnload
+
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
+
+[Sources]
+ TlsAuthConfigImpl.c
+ TlsAuthConfigImpl.h
+ TlsAuthConfigNvData.h
+ TlsAuthConfigDxe.c
+ TlsAuthConfigDxeStrings.uni
+ TlsAuthConfigVfr.vfr
+
+[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ UefiLib
+ UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
+ UefiDriverEntryPoint
+ DebugLib
+ HiiLib
+ DevicePathLib
+ UefiHiiServicesLib
+ FileExplorerLib
+ PrintLib
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## PRODUCES
+ gEfiHiiConfigAccessProtocolGuid ## PRODUCES
+ gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
+
+[Guids]
+ gTlsAuthConfigGuid ## PRODUCES ## GUID
+ gEfiCertX509Guid ## CONSUMES ## GUID # Indicate the cert type
+ gEfiIfrTianoGuid ## CONSUMES ## HII
+ gEfiTlsCaCertificateGuid ## PRODUCES ## GUID
+
+[Depex]
+ gEfiHiiConfigRoutingProtocolGuid AND
+ gEfiHiiDatabaseProtocolGuid
+
+[UserExtensions.TianoCore."ExtraFiles"]
+ TlsAuthConfigDxeExtra.uni
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
new file mode 100644
index 0000000..f99a14f
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
@@ -0,0 +1,21 @@
+// /** @file
+// Provides the capability to configure Tls Authentication in a setup browser
+//
+// By this module, user may change the content of TlsCaCertificate.
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+
+#string STR_MODULE_ABSTRACT #language en-US "Provides the capability to configure Tls Authentication in a setup browser"
+
+#string STR_MODULE_DESCRIPTION #language en-US "By this module, user may change the content of TlsCaCertificate."
+
--git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
new file mode 100644
index 0000000..ee4c49f
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
@@ -0,0 +1,19 @@
+// /** @file
+// TlsAuthConfigDxe Localized Strings and Content
+//
+// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+//
+// This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// **/
+
+#string STR_PROPERTIES_MODULE_NAME
+#language en-US
+"TLS Auth Config DXE"
+
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
new file mode 100644
index 0000000..a8f7e43
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
@@ -0,0 +1,39 @@
+/** @file
+ String definitions for Tls Authentication Configuration form.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#langdef en-US "English"
+
+#string STR_TLS_AUTH_CONFIG_TITLE #language en-US "Tls Auth Configuration"
+#string STR_TLS_AUTH_CONFIG_HELP #language en-US "Press <Enter> to select Tls Auth Configuration."
+
+#string STR_TLS_AUTH_CONFIG_SERVER_CA #language en-US "Server CA Configuration"
+#string STR_TLS_AUTH_CONFIG_SERVER_CA_HELP #language en-US "Press <Enter> to configure Server CA."
+#string STR_TLS_AUTH_CONFIG_CLIENT_CERT #language en-US "Client Cert Configuration"
+#string STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP #language en-US "Client cert configuration is unsupported currently."
+
+#string STR_TLS_AUTH_CONFIG_ENROLL_CERT #language en-US "Enroll Cert"
+#string STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP #language en-US "Press <Enter> to enroll cert."
+#string STR_TLS_AUTH_CONFIG_DELETE_CERT #language en-US "Delete Cert"
+#string STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP #language en-US "Press <Enter> to delete cert."
+
+#string STR_TLS_AUTH_CONFIG_ADD_CERT_FILE #language en-US "Enroll Cert Using File"
+
+#string STR_TLS_AUTH_CONFIG_CERT_GUID #language en-US "Cert GUID"
+#string STR_TLS_AUTH_CONFIG_CERT_GUID_HELP #language en-US "Input digit character in 11111111-2222-3333-4444-1234567890ab format."
+#string STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT #language en-US "Commit Changes and Exit"
+#string STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT #language en-US "Discard Changes and Exit"
+
+#string STR_CERT_TYPE_PCKS_GUID #language en-US "GUID for CERT"
+
+#string STR_NULL #language en-US ""
\ No newline at end of file
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
new file mode 100644
index 0000000..1132cac
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
@@ -0,0 +1,1841 @@
+/** @file
+ The Miscellaneous Routines for TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsAuthConfigImpl.h"
+
+VOID *mStartOpCodeHandle = NULL;
+VOID *mEndOpCodeHandle = NULL;
+EFI_IFR_GUID_LABEL *mStartLabel = NULL;
+EFI_IFR_GUID_LABEL *mEndLabel = NULL;
+
+
+CHAR16 mTlsAuthConfigStorageName[] = L"TLS_AUTH_CONFIG_IFR_NVDATA";
+
+TLS_AUTH_CONFIG_PRIVATE_DATA *mTlsAuthPrivateData = NULL;
+
+HII_VENDOR_DEVICE_PATH mTlsAuthConfigHiiVendorDevicePath = {
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ TLS_AUTH_CONFIG_GUID
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ (UINT8) (END_DEVICE_PATH_LENGTH),
+ (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
+ }
+ }
+};
+
+//
+// Possible DER-encoded certificate file suffixes, end with NULL pointer.
+//
+CHAR16* mDerPemEncodedSuffix[] = {
+ L".cer",
+ L".der",
+ L".crt",
+ L".pem",
+ NULL
+};
+
+/**
+ This code checks if the FileSuffix is one of the possible DER/PEM-encoded certificate suffix.
+
+ @param[in] FileSuffix The suffix of the input certificate file
+
+ @retval TRUE It's a DER/PEM-encoded certificate.
+ @retval FALSE It's NOT a DER/PEM-encoded certificate.
+
+**/
+BOOLEAN
+IsDerPemEncodeCertificate (
+ IN CONST CHAR16 *FileSuffix
+)
+{
+ UINTN Index;
+ for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) {
+ if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ Worker function that prints an EFI_GUID into specified Buffer.
+
+ @param[in] Guid Pointer to GUID to print.
+ @param[in] Buffer Buffer to print Guid into.
+ @param[in] BufferSize Size of Buffer.
+
+ @retval Number of characters printed.
+
+**/
+UINTN
+GuidToString (
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ UINTN Size;
+
+ Size = UnicodeSPrint (
+ Buffer,
+ BufferSize,
+ L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ (UINTN)Guid->Data1,
+ (UINTN)Guid->Data2,
+ (UINTN)Guid->Data3,
+ (UINTN)Guid->Data4[0],
+ (UINTN)Guid->Data4[1],
+ (UINTN)Guid->Data4[2],
+ (UINTN)Guid->Data4[3],
+ (UINTN)Guid->Data4[4],
+ (UINTN)Guid->Data4[5],
+ (UINTN)Guid->Data4[6],
+ (UINTN)Guid->Data4[7]
+ );
+
+ //
+ // SPrint will null terminate the string. The -1 skips the null
+ //
+ return Size - 1;
+}
+
+/**
+ Convert a String to Guid Value.
+
+ @param[in] Str Specifies the String to be converted.
+ @param[in] StrLen Number of Unicode Characters of String (exclusive \0)
+ @param[out] Guid Return the result Guid value.
+
+ @retval EFI_SUCCESS The operation is finished successfully.
+ @retval EFI_NOT_FOUND Invalid string.
+
+**/
+EFI_STATUS
+StringToGuid (
+ IN CHAR16 *Str,
+ IN UINTN StrLen,
+ OUT EFI_GUID *Guid
+ )
+{
+ CHAR16 *PtrBuffer;
+ CHAR16 *PtrPosition;
+ UINT16 *Buffer;
+ UINTN Data;
+ UINTN Index;
+ UINT16 Digits[3];
+
+ Buffer = (CHAR16 *) AllocateZeroPool (sizeof (CHAR16) * (StrLen + 1));
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ StrCpyS (Buffer, (StrLen + 1), Str);
+
+ //
+ // Data1
+ //
+ PtrBuffer = Buffer;
+ PtrPosition = PtrBuffer;
+ while (*PtrBuffer != L'\0') {
+ if (*PtrBuffer == L'-') {
+ break;
+ }
+ PtrBuffer++;
+ }
+ if (*PtrBuffer == L'\0') {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+
+ *PtrBuffer = L'\0';
+ Data = StrHexToUintn (PtrPosition);
+ Guid->Data1 = (UINT32)Data;
+
+ //
+ // Data2
+ //
+ PtrBuffer++;
+ PtrPosition = PtrBuffer;
+ while (*PtrBuffer != L'\0') {
+ if (*PtrBuffer == L'-') {
+ break;
+ }
+ PtrBuffer++;
+ }
+ if (*PtrBuffer == L'\0') {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ *PtrBuffer = L'\0';
+ Data = StrHexToUintn (PtrPosition);
+ Guid->Data2 = (UINT16)Data;
+
+ //
+ // Data3
+ //
+ PtrBuffer++;
+ PtrPosition = PtrBuffer;
+ while (*PtrBuffer != L'\0') {
+ if (*PtrBuffer == L'-') {
+ break;
+ }
+ PtrBuffer++;
+ }
+ if (*PtrBuffer == L'\0') {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ *PtrBuffer = L'\0';
+ Data = StrHexToUintn (PtrPosition);
+ Guid->Data3 = (UINT16)Data;
+
+ //
+ // Data4[0..1]
+ //
+ for ( Index = 0 ; Index < 2 ; Index++) {
+ PtrBuffer++;
+ if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ Digits[0] = *PtrBuffer;
+ PtrBuffer++;
+ Digits[1] = *PtrBuffer;
+ Digits[2] = L'\0';
+ Data = StrHexToUintn (Digits);
+ Guid->Data4[Index] = (UINT8)Data;
+ }
+
+ //
+ // skip the '-'
+ //
+ PtrBuffer++;
+ if ((*PtrBuffer != L'-' ) || ( *PtrBuffer == L'\0')) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Data4[2..7]
+ //
+ for ( ; Index < 8; Index++) {
+ PtrBuffer++;
+ if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
+ FreePool (Buffer);
+ return EFI_NOT_FOUND;
+ }
+ Digits[0] = *PtrBuffer;
+ PtrBuffer++;
+ Digits[1] = *PtrBuffer;
+ Digits[2] = L'\0';
+ Data = StrHexToUintn (Digits);
+ Guid->Data4[Index] = (UINT8)Data;
+ }
+
+ FreePool (Buffer);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ List all cert in specified database by GUID in the page
+ for user to select and delete as needed.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the vendor's signature database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the signature list.
+
+ @retval EFI_SUCCESS Success to update the signature list page
+ @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
+
+**/
+EFI_STATUS
+UpdateDeletePage (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Index;
+ UINTN CertCount;
+ UINTN GuidIndex;
+ VOID *StartOpCodeHandle;
+ VOID *EndOpCodeHandle;
+ EFI_IFR_GUID_LABEL *StartLabel;
+ EFI_IFR_GUID_LABEL *EndLabel;
+ UINTN DataSize;
+ UINT8 *Data;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINT32 ItemDataSize;
+ CHAR16 *GuidStr;
+ EFI_STRING_ID GuidID;
+ EFI_STRING_ID Help;
+
+ Data = NULL;
+ CertList = NULL;
+ Cert = NULL;
+ GuidStr = NULL;
+ StartOpCodeHandle = NULL;
+ EndOpCodeHandle = NULL;
+
+ //
+ // Initialize the container for dynamic opcodes.
+ //
+ StartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (StartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ EndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (EndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Create Hii Extend Label OpCode.
+ //
+ StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ StartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ StartLabel->Number = LabelNumber;
+
+ EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ EndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ EndLabel->Number = LABEL_END;
+
+ //
+ // Read Variable.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ goto ON_EXIT;
+ }
+
+ Data = (UINT8 *) AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, Data);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ GuidStr = AllocateZeroPool (100);
+ if (GuidStr == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Enumerate all data.
+ //
+ ItemDataSize = (UINT32) DataSize;
+ CertList = (EFI_SIGNATURE_LIST *) Data;
+ GuidIndex = 0;
+
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
+ Help = STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID);
+ } else {
+ //
+ // The signature type is not supported in current implementation.
+ //
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ continue;
+ }
+
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList
+ + sizeof (EFI_SIGNATURE_LIST)
+ + CertList->SignatureHeaderSize
+ + Index * CertList->SignatureSize);
+ //
+ // Display GUID and help
+ //
+ GuidToString (&Cert->SignatureOwner, GuidStr, 100);
+ GuidID = HiiSetString (Private->RegisteredHandle, 0, GuidStr, NULL);
+ HiiCreateCheckBoxOpCode (
+ StartOpCodeHandle,
+ (EFI_QUESTION_ID) (QuestionIdBase + GuidIndex++),
+ 0,
+ 0,
+ GuidID,
+ Help,
+ EFI_IFR_FLAG_CALLBACK,
+ 0,
+ NULL
+ );
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ON_EXIT:
+ HiiUpdateForm (
+ Private->RegisteredHandle,
+ &gTlsAuthConfigGuid,
+ FormId,
+ StartOpCodeHandle,
+ EndOpCodeHandle
+ );
+
+ if (StartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (StartOpCodeHandle);
+ }
+
+ if (EndOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (EndOpCodeHandle);
+ }
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ if (GuidStr != NULL) {
+ FreePool (GuidStr);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Delete one entry from cert database.
+
+ @param[in] PrivateData Module's private data.
+ @param[in] VariableName The variable name of the database.
+ @param[in] VendorGuid A unique identifier for the vendor.
+ @param[in] LabelNumber Label number to insert opcodes.
+ @param[in] FormId Form ID of current page.
+ @param[in] QuestionIdBase Base question id of the cert list.
+ @param[in] DeleteIndex Cert index to delete.
+
+ @retval EFI_SUCCESS Delete siganture successfully.
+ @retval EFI_NOT_FOUND Can't find the signature item,
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+**/
+EFI_STATUS
+DeleteCert (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT16 LabelNumber,
+ IN EFI_FORM_ID FormId,
+ IN EFI_QUESTION_ID QuestionIdBase,
+ IN UINTN DeleteIndex
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ UINT8 *Data;
+ UINT8 *OldData;
+ UINT32 Attr;
+ UINT32 Index;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_LIST *NewCertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINTN CertCount;
+ UINT32 Offset;
+ BOOLEAN IsItemFound;
+ UINT32 ItemDataSize;
+ UINTN GuidIndex;
+
+ Data = NULL;
+ OldData = NULL;
+ CertList = NULL;
+ Cert = NULL;
+ Attr = 0;
+
+ //
+ // Get original signature list data.
+ //
+ DataSize = 0;
+ Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize, NULL);
+ if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
+ goto ON_EXIT;
+ }
+
+ OldData = (UINT8 *) AllocateZeroPool (DataSize);
+ if (OldData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize, OldData);
+ if (EFI_ERROR(Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Allocate space for new variable.
+ //
+ Data = (UINT8*) AllocateZeroPool (DataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Enumerate all data and erasing the target item.
+ //
+ IsItemFound = FALSE;
+ ItemDataSize = (UINT32) DataSize;
+ CertList = (EFI_SIGNATURE_LIST *) OldData;
+ Offset = 0;
+ GuidIndex = 0;
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
+ //
+ // Copy EFI_SIGNATURE_LIST header then calculate the signature count in this list.
+ //
+ CopyMem (Data + Offset, CertList, (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize));
+ NewCertList = (EFI_SIGNATURE_LIST*) (Data + Offset);
+ Offset += (sizeof(EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ if (GuidIndex == DeleteIndex) {
+ //
+ // Find it! Skip it!
+ //
+ NewCertList->SignatureListSize -= CertList->SignatureSize;
+ IsItemFound = TRUE;
+ } else {
+ //
+ // This item doesn't match. Copy it to the Data buffer.
+ //
+ CopyMem (Data + Offset, (UINT8*)(Cert), CertList->SignatureSize);
+ Offset += CertList->SignatureSize;
+ }
+ GuidIndex++;
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+ }
+ } else {
+ //
+ // This List doesn't match. Just copy it to the Data buffer.
+ //
+ CopyMem (Data + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
+ Offset += CertList->SignatureListSize;
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ if (!IsItemFound) {
+ //
+ // Doesn't find the signature Item!
+ //
+ Status = EFI_NOT_FOUND;
+ goto ON_EXIT;
+ }
+
+ //
+ // Delete the EFI_SIGNATURE_LIST header if there is no signature in the list.
+ //
+ ItemDataSize = Offset;
+ CertList = (EFI_SIGNATURE_LIST *) Data;
+ Offset = 0;
+ ZeroMem (OldData, ItemDataSize);
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount));
+ if (CertCount != 0) {
+ CopyMem (OldData + Offset, (UINT8*)(CertList), CertList->SignatureListSize);
+ Offset += CertList->SignatureListSize;
+ }
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ DataSize = Offset;
+
+ Status = gRT->SetVariable(
+ VariableName,
+ VendorGuid,
+ Attr,
+ DataSize,
+ OldData
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+ if (Data != NULL) {
+ FreePool(Data);
+ }
+
+ if (OldData != NULL) {
+ FreePool(OldData);
+ }
+
+ return UpdateDeletePage (
+ Private,
+ VariableName,
+ VendorGuid,
+ LabelNumber,
+ FormId,
+ QuestionIdBase
+ );
+}
+
+
+/**
+ Close an open file handle.
+
+ @param[in] FileHandle The file handle to close.
+
+**/
+VOID
+CloseFile (
+ IN EFI_FILE_HANDLE FileHandle
+ )
+{
+ if (FileHandle != NULL) {
+ FileHandle->Close (FileHandle);
+ }
+}
+
+/**
+ Read file content into BufferPtr, the size of the allocate buffer
+ is *FileSize plus AddtionAllocateSize.
+
+ @param[in] FileHandle The file to be read.
+ @param[in, out] BufferPtr Pointers to the pointer of allocated buffer.
+ @param[out] FileSize Size of input file
+ @param[in] AddtionAllocateSize Addtion size the buffer need to be allocated.
+ In case the buffer need to contain others besides the file content.
+
+ @retval EFI_SUCCESS The file was read into the buffer.
+ @retval EFI_INVALID_PARAMETER A parameter was invalid.
+ @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
+ @retval others Unexpected error.
+
+**/
+EFI_STATUS
+ReadFileContent (
+ IN EFI_FILE_HANDLE FileHandle,
+ IN OUT VOID **BufferPtr,
+ OUT UINTN *FileSize,
+ IN UINTN AddtionAllocateSize
+ )
+
+{
+ UINTN BufferSize;
+ UINT64 SourceFileSize;
+ VOID *Buffer;
+ EFI_STATUS Status;
+
+ if ((FileHandle == NULL) || (FileSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Buffer = NULL;
+
+ //
+ // Get the file size
+ //
+ Status = FileHandle->SetPosition (FileHandle, (UINT64) -1);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = FileHandle->GetPosition (FileHandle, &SourceFileSize);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Status = FileHandle->SetPosition (FileHandle, 0);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize;
+ Buffer = AllocateZeroPool(BufferSize);
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BufferSize = (UINTN) SourceFileSize;
+ *FileSize = BufferSize;
+
+ Status = FileHandle->Read (FileHandle, &BufferSize, Buffer);
+ if (EFI_ERROR (Status) || BufferSize != *FileSize) {
+ FreePool (Buffer);
+ Buffer = NULL;
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ *BufferPtr = Buffer;
+ return Status;
+}
+
+/**
+ This function will open a file or directory referenced by DevicePath.
+
+ This function opens a file with the open mode according to the file path. The
+ Attributes is valid only for EFI_FILE_MODE_CREATE.
+
+ @param[in, out] FilePath On input, the device path to the file.
+ On output, the remaining device path.
+ @param[out] FileHandle Pointer to the file handle.
+ @param[in] OpenMode The mode to open the file with.
+ @param[in] Attributes The file's file attributes.
+
+ @retval EFI_SUCCESS The information was set.
+ @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.
+ @retval EFI_UNSUPPORTED Could not open the file path.
+ @retval EFI_NOT_FOUND The specified file could not be found on the
+ device or the file system could not be found on
+ the device.
+ @retval EFI_NO_MEDIA The device has no medium.
+ @retval EFI_MEDIA_CHANGED The device has a different medium in it or the
+ medium is no longer supported.
+ @retval EFI_DEVICE_ERROR The device reported an error.
+ @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
+ @retval EFI_WRITE_PROTECTED The file or medium is write protected.
+ @retval EFI_ACCESS_DENIED The file was opened read only.
+ @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the
+ file.
+ @retval EFI_VOLUME_FULL The volume is full.
+**/
+EFI_STATUS
+EFIAPI
+OpenFileByDevicePath (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
+ OUT EFI_FILE_HANDLE *FileHandle,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;
+ EFI_FILE_PROTOCOL *Handle1;
+ EFI_FILE_PROTOCOL *Handle2;
+ EFI_HANDLE DeviceHandle;
+
+ if ((FilePath == NULL || FileHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->LocateDevicePath (
+ &gEfiSimpleFileSystemProtocolGuid,
+ FilePath,
+ &DeviceHandle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol(
+ DeviceHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ (VOID**)&EfiSimpleFileSystemProtocol,
+ gImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EfiSimpleFileSystemProtocol->OpenVolume(EfiSimpleFileSystemProtocol, &Handle1);
+ if (EFI_ERROR (Status)) {
+ FileHandle = NULL;
+ return Status;
+ }
+
+ //
+ // go down directories one node at a time.
+ //
+ while (!IsDevicePathEnd (*FilePath)) {
+ //
+ // For file system access each node should be a file path component
+ //
+ if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
+ ) {
+ FileHandle = NULL;
+ return (EFI_INVALID_PARAMETER);
+ }
+ //
+ // Open this file path node
+ //
+ Handle2 = Handle1;
+ Handle1 = NULL;
+
+ //
+ // Try to test opening an existing file
+ //
+ Status = Handle2->Open (
+ Handle2,
+ &Handle1,
+ ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
+ OpenMode &~EFI_FILE_MODE_CREATE,
+ 0
+ );
+
+ //
+ // see if the error was that it needs to be created
+ //
+ if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode &~EFI_FILE_MODE_CREATE))) {
+ Status = Handle2->Open (
+ Handle2,
+ &Handle1,
+ ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
+ OpenMode,
+ Attributes
+ );
+ }
+ //
+ // Close the last node
+ //
+ Handle2->Close (Handle2);
+
+ if (EFI_ERROR(Status)) {
+ return (Status);
+ }
+
+ //
+ // Get the next node
+ //
+ *FilePath = NextDevicePathNode (*FilePath);
+ }
+
+ //
+ // This is a weak spot since if the undefined SHELL_FILE_HANDLE format changes this must change also!
+ //
+ *FileHandle = (VOID*)Handle1;
+ return EFI_SUCCESS;
+}
+
+/**
+ This function converts an input device structure to a Unicode string.
+
+ @param[in] DevPath A pointer to the device path structure.
+
+ @return A new allocated Unicode string that represents the device path.
+
+**/
+CHAR16 *
+EFIAPI
+DevicePathToStr (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath
+ )
+{
+ return ConvertDevicePathToText (
+ DevPath,
+ FALSE,
+ TRUE
+ );
+}
+
+
+/**
+ Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
+ The caller is responsible for freeing the allocated buffer using FreePool(). If return NULL
+ means not enough memory resource.
+
+ @param DevicePath Device path.
+
+ @retval NULL Not enough memory resourece for AllocateCopyPool.
+ @retval Other A new allocated string that represents the file name.
+
+**/
+CHAR16 *
+ExtractFileNameFromDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CHAR16 *String;
+ CHAR16 *MatchString;
+ CHAR16 *LastMatch;
+ CHAR16 *FileName;
+ UINTN Length;
+
+ ASSERT(DevicePath != NULL);
+
+ String = DevicePathToStr(DevicePath);
+ MatchString = String;
+ LastMatch = String;
+ FileName = NULL;
+
+ while(MatchString != NULL){
+ LastMatch = MatchString + 1;
+ MatchString = StrStr(LastMatch,L"\\");
+ }
+
+ Length = StrLen(LastMatch);
+ FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);
+ if (FileName != NULL) {
+ *(FileName + Length) = 0;
+ }
+
+ FreePool(String);
+
+ return FileName;
+}
+
+/**
+ Enroll a new X509 certificate into Variable.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of CA database.
+
+ @retval EFI_SUCCESS New X509 is enrolled successfully.
+ @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
+
+**/
+EFI_STATUS
+EnrollX509toVariable (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ EFI_STATUS Status;
+ UINTN X509DataSize;
+ VOID *X509Data;
+ EFI_SIGNATURE_LIST *CACert;
+ EFI_SIGNATURE_DATA *CACertData;
+ VOID *Data;
+ UINTN DataSize;
+ UINTN SigDataSize;
+ UINT32 Attr;
+
+ X509DataSize = 0;
+ SigDataSize = 0;
+ DataSize = 0;
+ X509Data = NULL;
+ CACert = NULL;
+ CACertData = NULL;
+ Data = NULL;
+
+ Status = ReadFileContent (
+ Private->FileContext->FHandle,
+ &X509Data,
+ &X509DataSize,
+ 0
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+ ASSERT (X509Data != NULL);
+
+ SigDataSize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize;
+
+ Data = AllocateZeroPool (SigDataSize);
+ if (Data == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Fill Certificate Database parameters.
+ //
+ CACert = (EFI_SIGNATURE_LIST*) Data;
+ CACert->SignatureListSize = (UINT32) SigDataSize;
+ CACert->SignatureHeaderSize = 0;
+ CACert->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 + X509DataSize);
+ CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid);
+
+ CACertData = (EFI_SIGNATURE_DATA*) ((UINT8* ) CACert + sizeof (EFI_SIGNATURE_LIST));
+ CopyGuid (&CACertData->SignatureOwner, Private->CertGuid);
+ CopyMem ((UINT8* ) (CACertData->SignatureData), X509Data, X509DataSize);
+
+ //
+ // Check if signature database entry has been already existed.
+ // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
+ // new signature data to original variable
+ //
+ Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR;
+
+ Status = gRT->GetVariable(
+ VariableName,
+ &gEfiTlsCaCertificateGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Attr |= EFI_VARIABLE_APPEND_WRITE;
+ } else if (Status != EFI_NOT_FOUND) {
+ goto ON_EXIT;
+ }
+
+ Status = gRT->SetVariable(
+ VariableName,
+ &gEfiTlsCaCertificateGuid,
+ Attr,
+ SigDataSize,
+ Data
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ON_EXIT:
+
+ CloseFile (Private->FileContext->FHandle);
+ if (Private->FileContext->FileName != NULL) {
+ FreePool(Private->FileContext->FileName);
+ Private->FileContext->FileName = NULL;
+ }
+
+ Private->FileContext->FHandle = NULL;
+
+ if (Private->CertGuid != NULL) {
+ FreePool (Private->CertGuid);
+ Private->CertGuid = NULL;
+ }
+
+ if (Data != NULL) {
+ FreePool (Data);
+ }
+
+ if (X509Data != NULL) {
+ FreePool (X509Data);
+ }
+
+ return Status;
+}
+
+/**
+ Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.
+
+ @param[in] PrivateData The module's private data.
+ @param[in] VariableName Variable name of signature database.
+
+ @retval EFI_SUCCESS New Cert enrolled successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_UNSUPPORTED The Cert file is unsupported type.
+ @retval others Fail to enroll Cert data.
+
+**/
+EFI_STATUS
+EnrollCertDatabase (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
+ IN CHAR16 *VariableName
+ )
+{
+ UINT16* FilePostFix;
+ UINTN NameLength;
+
+ if ((Private->FileContext->FileName == NULL) || (Private->FileContext->FHandle == NULL) || (Private->CertGuid == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Parse the file's postfix.
+ //
+ NameLength = StrLen (Private->FileContext->FileName);
+ if (NameLength <= 4) {
+ return EFI_INVALID_PARAMETER;
+ }
+ FilePostFix = Private->FileContext->FileName + NameLength - 4;
+
+ if (IsDerPemEncodeCertificate (FilePostFix)) {
+ //
+ // Supports DER-encoded X509 certificate.
+ //
+ return EnrollX509toVariable (Private, VariableName);
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Refresh the global UpdateData structure.
+
+**/
+VOID
+RefreshUpdateData (
+ VOID
+ )
+{
+ //
+ // Free current updated date
+ //
+ if (mStartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mStartOpCodeHandle);
+ }
+
+ //
+ // Create new OpCode Handle
+ //
+ mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ mStartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+}
+
+/**
+ Clean up the dynamic opcode at label and form specified by both LabelId.
+
+ @param[in] LabelId It is both the Form ID and Label ID for opcode deletion.
+ @param[in] PrivateData Module private data.
+
+**/
+VOID
+CleanUpPage (
+ IN UINT16 LabelId,
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData
+ )
+{
+ RefreshUpdateData ();
+
+ //
+ // Remove all op-codes from dynamic page
+ //
+ mStartLabel->Number = LabelId;
+ HiiUpdateForm (
+ PrivateData->RegisteredHandle,
+ &gTlsAuthConfigGuid,
+ LabelId,
+ mStartOpCodeHandle, // Label LabelId
+ mEndOpCodeHandle // LABEL_END
+ );
+}
+
+/**
+ Update the form base on the selected file.
+
+ @param FilePath Point to the file path.
+ @param FormId The form need to display.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+
+**/
+BOOLEAN
+UpdatePage(
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN EFI_FORM_ID FormId
+ )
+{
+ CHAR16 *FileName;
+ EFI_STRING_ID StringToken;
+
+ FileName = NULL;
+
+ if (FilePath != NULL) {
+ FileName = ExtractFileNameFromDevicePath(FilePath);
+ }
+ if (FileName == NULL) {
+ //
+ // FileName = NULL has two case:
+ // 1. FilePath == NULL, not select file.
+ // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL not enough memory resource.
+ // In these two case, no need to update the form, and exit the caller function.
+ //
+ return TRUE;
+ }
+ StringToken = HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0, FileName, NULL);
+
+ mTlsAuthPrivateData->FileContext->FileName = FileName;
+
+ OpenFileByDevicePath (
+ &FilePath,
+ &mTlsAuthPrivateData->FileContext->FHandle,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ //
+ // Create Subtitle op-code for the display string of the option.
+ //
+ RefreshUpdateData ();
+ mStartLabel->Number = FormId;
+
+ HiiCreateSubTitleOpCode (
+ mStartOpCodeHandle,
+ StringToken,
+ 0,
+ 0,
+ 0
+ );
+
+ HiiUpdateForm (
+ mTlsAuthPrivateData->RegisteredHandle,
+ &gTlsAuthConfigGuid,
+ FormId,
+ mStartOpCodeHandle, /// Label FormId
+ mEndOpCodeHandle /// LABEL_END
+ );
+
+ return TRUE;
+}
+
+/**
+ Update the form base on the input file path info.
+
+ @param FilePath Point to the file path.
+
+ @retval TRUE Exit caller function.
+ @retval FALSE Not exit caller function.
+**/
+BOOLEAN
+UpdateCAFromFile (
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ )
+{
+ return UpdatePage(FilePath, TLS_AUTH_CONFIG_FORMID4_FORM);
+}
+
+/**
+ Unload the configuration form, this includes: delete all the configuration
+ entries, uninstall the form callback protocol, and free the resources used.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is unloaded.
+ @retval Others Failed to unload the form.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormUnload (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ )
+{
+ if (Private->DriverHandle != NULL) {
+ //
+ // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
+ //
+ gBS->UninstallMultipleProtocolInterfaces (
+ Private->DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mTlsAuthConfigHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &Private->ConfigAccess,
+ NULL
+ );
+ Private->DriverHandle = NULL;
+ }
+
+ if (Private->RegisteredHandle != NULL) {
+ //
+ // Remove HII package list
+ //
+ HiiRemovePackages (Private->RegisteredHandle);
+ Private->RegisteredHandle = NULL;
+ }
+
+ if (Private->CertGuid != NULL) {
+ FreePool (Private->CertGuid);
+ }
+
+ if (Private->FileContext != NULL) {
+ FreePool (Private->FileContext);
+ }
+
+ FreePool (Private);
+
+ if (mStartOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mStartOpCodeHandle);
+ }
+
+ if (mEndOpCodeHandle != NULL) {
+ HiiFreeOpCodeHandle (mEndOpCodeHandle);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Initialize the configuration form.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormInit (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ )
+{
+ EFI_STATUS Status;
+
+ Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE;
+
+ Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig;
+ Private->ConfigAccess.RouteConfig = TlsAuthConfigAccessRouteConfig;
+ Private->ConfigAccess.Callback = TlsAuthConfigAccessCallback;
+
+ //
+ // Install Device Path Protocol and Config Access protocol to driver handle.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Private->DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &mTlsAuthConfigHiiVendorDevicePath,
+ &gEfiHiiConfigAccessProtocolGuid,
+ &Private->ConfigAccess,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Publish our HII data.
+ //
+ Private->RegisteredHandle = HiiAddPackages (
+ &gTlsAuthConfigGuid,
+ Private->DriverHandle,
+ TlsAuthConfigDxeStrings,
+ TlsAuthConfigVfrBin,
+ NULL
+ );
+ if (Private->RegisteredHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ Private->FileContext = AllocateZeroPool (sizeof (TLS_AUTH_CONFIG_FILE_CONTEXT));
+ if (Private->FileContext == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Init OpCode Handle and Allocate space for creation of Buffer
+ //
+ mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (mStartOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
+ if (mEndOpCodeHandle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ //
+ // Create Hii Extend Label OpCode as the start opcode
+ //
+ mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ mStartOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+
+ //
+ // Create Hii Extend Label OpCode as the end opcode
+ //
+ mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
+ mEndOpCodeHandle,
+ &gEfiIfrTianoGuid,
+ NULL,
+ sizeof (EFI_IFR_GUID_LABEL)
+ );
+ mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
+ mEndLabel->Number = LABEL_END;
+
+ return EFI_SUCCESS;
+
+Error:
+ TlsAuthConfigFormUnload (Private);
+ return Status;
+}
+
+/**
+
+ This function allows the caller to request the current
+ configuration for one or more named elements. The resulting
+ string is in <ConfigAltResp> format. Any and all alternative
+ configuration strings shall also be appended to the end of the
+ current configuration string. If they are, they must appear
+ after the current configuration. They must contain the same
+ routing (GUID, NAME, PATH) as the current configuration string.
+ They must have an additional description indicating the type of
+ alternative configuration the string represents,
+ "ALTCFG=<StringToken>". That <StringToken> (when
+ converted from Hex UNICODE to binary) is a reference to a
+ string in the associated string pack.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Request A null-terminated Unicode string in
+ <ConfigRequest> format. Note that this
+ includes the routing information as well as
+ the configurable name / value pairs. It is
+ invalid for this string to be in
+ <MultiConfigRequest> format.
+ If a NULL is passed in for the Request field,
+ all of the settings being abstracted by this function
+ will be returned in the Results field. In addition,
+ if a ConfigHdr is passed in with no request elements,
+ all of the settings being abstracted for that particular
+ ConfigHdr reference will be returned in the Results Field.
+
+ @param Progress On return, points to a character in the
+ Request string. Points to the string's null
+ terminator if request was successful. Points
+ to the most recent "&" before the first
+ failing name / value pair (or the beginning
+ of the string if the failure is in the first
+ name / value pair) if the request was not
+ successful.
+
+ @param Results A null-terminated Unicode string in
+ <MultiConfigAltResp> format which has all values
+ filled in for the names in the Request string.
+ String to be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results string is filled with the
+ values corresponding to all requested
+ names.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_NOT_FOUND Routing data doesn't match any
+ known driver. Progress set to the
+ first character in the routing header.
+ Note: There is no requirement that the
+ driver validate the routing data. It
+ must skip the <ConfigHdr> in order to
+ process the names.
+
+ @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
+ to most recent "&" before the
+ error or the beginning of the
+ string.
+
+ @retval EFI_INVALID_PARAMETER Unknown name. Progress points
+ to the & before the name in
+ question.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ UINTN Size;
+ EFI_STRING ConfigRequest;
+ EFI_STRING ConfigRequestHdr;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
+ BOOLEAN AllocatedRequest;
+
+ if (Progress == NULL || Results == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AllocatedRequest = FALSE;
+ ConfigRequestHdr = NULL;
+ ConfigRequest = NULL;
+ Size = 0;
+
+ Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
+
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
+
+ *Progress = Request;
+
+ if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ ConfigRequest = Request;
+ if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
+ //
+ // Request is set to NULL or OFFSET is NULL, construct full request string.
+ //
+ // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
+ // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
+ //
+ ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, Private->DriverHandle);
+ Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
+ ConfigRequest = AllocateZeroPool (Size);
+ ASSERT (ConfigRequest != NULL);
+ AllocatedRequest = TRUE;
+ UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
+ FreePool (ConfigRequestHdr);
+ ConfigRequestHdr = NULL;
+ }
+
+ Status = gHiiConfigRouting->BlockToConfig (
+ gHiiConfigRouting,
+ ConfigRequest,
+ (UINT8 *) &Private->TlsAuthConfigNvData,
+ BufferSize,
+ Results,
+ Progress
+ );
+
+ //
+ // Free the allocated config request string.
+ //
+ if (AllocatedRequest) {
+ FreePool (ConfigRequest);
+ }
+
+ //
+ // Set Progress string to the original request string.
+ //
+ if (Request == NULL) {
+ *Progress = NULL;
+ } else if (StrStr (Request, L"OFFSET") == NULL) {
+ *Progress = Request + StrLen (Request);
+ }
+
+ return Status;
+}
+
+/**
+
+ This function applies changes in a driver's configuration.
+ Input is a Configuration, which has the routing data for this
+ driver followed by name / value configuration pairs. The driver
+ must apply those pairs to its configurable storage. If the
+ driver's configuration is stored in a linear block of data
+ and the driver's name / value pairs are in <BlockConfig>
+ format, it may use the ConfigToBlock helper function (above) to
+ simplify the job.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Configuration A null-terminated Unicode string in
+ <ConfigString> format.
+
+ @param Progress A pointer to a string filled in with the
+ offset of the most recent '&' before the
+ first failing name / value pair (or the
+ beginn ing of the string if the failure
+ is in the first name / value pair) or
+ the terminating NULL if all was
+ successful.
+
+ @retval EFI_SUCCESS The results have been distributed or are
+ awaiting distribution.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
+ Results parameter would result
+ in this type of error.
+
+ @retval EFI_NOT_FOUND Target for the specified routing data
+ was not found
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ )
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
+
+ if (Progress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *Progress = Configuration;
+
+ if (Configuration == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check routing data in <ConfigHdr>.
+ // Note: there is no name for Name/Value storage, only GUID will be checked
+ //
+ if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
+ return EFI_NOT_FOUND;
+ }
+
+ Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
+
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
+
+ Status = gHiiConfigRouting->ConfigToBlock (
+ gHiiConfigRouting,
+ Configuration,
+ (UINT8 *) &Private->TlsAuthConfigNvData,
+ &BufferSize,
+ Progress
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+/**
+
+ This function is called to provide results data to the driver.
+ This data consists of a unique key that is used to identify
+ which data is either being passed back or being asked for.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect. The format of the data tends to
+ vary based on the opcode that generated the callback.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original
+ exporting driver.
+ @param ActionRequest On return, points to the action requested by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ )
+{
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+ TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
+ UINTN BufferSize;
+ TLS_AUTH_CONFIG_IFR_NVDATA *IfrNvData;
+ UINT16 LabelId;
+ EFI_DEVICE_PATH_PROTOCOL *File;
+
+ Status = EFI_SUCCESS;
+ File = NULL;
+
+ if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
+
+ mTlsAuthPrivateData = Private;
+
+ //
+ // Retrieve uncommitted data from Browser
+ //
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ IfrNvData = AllocateZeroPool (BufferSize);
+ if (IfrNvData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8 *) IfrNvData);
+
+ if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
+ (Action != EFI_BROWSER_ACTION_CHANGING)) {
+ Status = EFI_UNSUPPORTED;
+ goto EXIT;
+ }
+
+ if (Action == EFI_BROWSER_ACTION_CHANGING) {
+ switch (QuestionId) {
+ case KEY_TLS_AUTH_CONFIG_CLIENT_CERT:
+ case KEY_TLS_AUTH_CONFIG_SERVER_CA:
+ //
+ // Clear Cert GUID.
+ //
+ ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid));
+ if (Private->CertGuid == NULL) {
+ Private->CertGuid = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID));
+ if (Private->CertGuid == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) {
+ LabelId = TLS_AUTH_CONFIG_FORMID3_FORM;
+ } else if (QuestionId == KEY_TLS_AUTH_CONFIG_SERVER_CA) {
+ LabelId = TLS_AUTH_CONFIG_FORMID4_FORM;
+ }
+
+ //
+ // Refresh selected file.
+ //
+ CleanUpPage (LabelId, Private);
+ break;
+ case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE:
+ ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdateCAFromFile, &File);
+ break;
+
+ case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT:
+ Status = EnrollCertDatabase (Private, EFI_TLS_CA_CERTIFICATE_VARIABLE);
+ if (EFI_ERROR (Status)) {
+ CreatePopUp (
+ EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
+ &Key,
+ L"ERROR: Enroll Cert Failure!",
+ NULL
+ );
+ }
+ break;
+
+ case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT:
+ if (Private->FileContext->FHandle != NULL) {
+ CloseFile (Private->FileContext->FHandle);
+ Private->FileContext->FHandle = NULL;
+ if (Private->FileContext->FileName!= NULL){
+ FreePool(Private->FileContext->FileName);
+ Private->FileContext->FileName = NULL;
+ }
+ }
+
+ if (Private->CertGuid!= NULL) {
+ FreePool (Private->CertGuid);
+ Private->CertGuid = NULL;
+ }
+ break;
+
+ case KEY_TLS_AUTH_CONFIG_DELETE_CERT:
+ UpdateDeletePage (
+ Private,
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ LABEL_CA_DELETE,
+ TLS_AUTH_CONFIG_FORMID5_FORM,
+ OPTION_DEL_CA_ESTION_ID
+ );
+ break;
+
+ default:
+ if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) &&
+ (QuestionId < (OPTION_DEL_CA_ESTION_ID + OPTION_CONFIG_RANGE))) {
+ DeleteCert (
+ Private,
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ LABEL_CA_DELETE,
+ TLS_AUTH_CONFIG_FORMID5_FORM,
+ OPTION_DEL_CA_ESTION_ID,
+ QuestionId - OPTION_DEL_CA_ESTION_ID
+ );
+ }
+ break;
+ }
+ } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
+ switch (QuestionId) {
+ case KEY_TLS_AUTH_CONFIG_CERT_GUID:
+ ASSERT (Private->CertGuid != NULL);
+ Status = StringToGuid (
+ IfrNvData->CertGuid,
+ StrLen (IfrNvData->CertGuid),
+ Private->CertGuid
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
+ break;
+ default:
+ break;
+ }
+ }
+
+EXIT:
+
+ if (!EFI_ERROR (Status)) {
+ BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
+ HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName, BufferSize, (UINT8*) IfrNvData, NULL);
+ }
+
+ FreePool (IfrNvData);
+
+ if (File != NULL){
+ FreePool(File);
+ File = NULL;
+ }
+
+ return EFI_SUCCESS;
+
+}
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
new file mode 100644
index 0000000..398f7b6
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
@@ -0,0 +1,282 @@
+/** @file
+ Header file of Miscellaneous Routines for TlsAuthConfigDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_IMPL_H__
+#define __TLS_AUTH_CONFIG_IMPL_H__
+
+#include <Uefi.h>
+
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/SimpleFileSystem.h>
+
+//
+// Libraries
+//
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/HiiLib.h>
+#include <Library/UefiHiiServicesLib.h>
+#include <Library/FileExplorerLib.h>
+#include <Library/PrintLib.h>
+
+#include <Guid/MdeModuleHii.h>
+#include <Guid/ImageAuthentication.h>
+#include <Guid/TlsAuthentication.h>
+
+
+//
+// Include files with function prototypes
+//
+#include "TlsAuthConfigNvData.h"
+
+extern UINT8 TlsAuthConfigDxeStrings[];
+extern UINT8 TlsAuthConfigVfrBin[];
+
+#define TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('T', 'A', 'C', 'D')
+#define TLS_AUTH_CONFIG_PRIVATE_FROM_THIS(a) CR (a, TLS_AUTH_CONFIG_PRIVATE_DATA, ConfigAccess, TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE)
+
+#define TLS_AUTH_CONFIG_VAR_BASE_ATTR (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)
+
+typedef struct _TLS_AUTH_CONFIG_PRIVATE_DATA TLS_AUTH_CONFIG_PRIVATE_DATA;
+typedef struct _TLS_AUTH_CONFIG_FILE_CONTEXT TLS_AUTH_CONFIG_FILE_CONTEXT;
+
+///
+/// HII specific Vendor Device Path definition.
+///
+typedef struct {
+ VENDOR_DEVICE_PATH VendorDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} HII_VENDOR_DEVICE_PATH;
+
+struct _TLS_AUTH_CONFIG_FILE_CONTEXT {
+ EFI_FILE_HANDLE FHandle;
+ UINT16 *FileName;
+};
+
+struct _TLS_AUTH_CONFIG_PRIVATE_DATA {
+ UINTN Signature;
+
+ EFI_HANDLE DriverHandle;
+ EFI_HII_HANDLE RegisteredHandle;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
+ TLS_AUTH_CONFIG_IFR_NVDATA TlsAuthConfigNvData;
+
+ TLS_AUTH_CONFIG_FILE_CONTEXT *FileContext;
+
+ EFI_GUID *CertGuid;
+};
+
+/**
+ Unload the configuration form, this includes: delete all the configuration
+ entries, uninstall the form callback protocol, and free the resources used.
+ The form will only be unload completely when both IP4 and IP6 stack are stopped.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is unloaded.
+ @retval Others Failed to unload the form.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormUnload (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ );
+
+/**
+ Initialize the configuration form.
+
+ @param[in] Private Pointer to the driver private data.
+
+ @retval EFI_SUCCESS The configuration form is initialized.
+ @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
+
+**/
+EFI_STATUS
+TlsAuthConfigFormInit (
+ IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
+ );
+
+/**
+
+ This function allows the caller to request the current
+ configuration for one or more named elements. The resulting
+ string is in <ConfigAltResp> format. Any and all alternative
+ configuration strings shall also be appended to the end of the
+ current configuration string. If they are, they must appear
+ after the current configuration. They must contain the same
+ routing (GUID, NAME, PATH) as the current configuration string.
+ They must have an additional description indicating the type of
+ alternative configuration the string represents,
+ "ALTCFG=<StringToken>". That <StringToken> (when
+ converted from Hex UNICODE to binary) is a reference to a
+ string in the associated string pack.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Request A null-terminated Unicode string in
+ <ConfigRequest> format. Note that this
+ includes the routing information as well as
+ the configurable name / value pairs. It is
+ invalid for this string to be in
+ <MultiConfigRequest> format.
+ If a NULL is passed in for the Request field,
+ all of the settings being abstracted by this function
+ will be returned in the Results field. In addition,
+ if a ConfigHdr is passed in with no request elements,
+ all of the settings being abstracted for that particular
+ ConfigHdr reference will be returned in the Results Field.
+
+ @param Progress On return, points to a character in the
+ Request string. Points to the string's null
+ terminator if request was successful. Points
+ to the most recent "&" before the first
+ failing name / value pair (or the beginning
+ of the string if the failure is in the first
+ name / value pair) if the request was not
+ successful.
+
+ @param Results A null-terminated Unicode string in
+ <MultiConfigAltResp> format which has all values
+ filled in for the names in the Request string.
+ String to be allocated by the called function.
+
+ @retval EFI_SUCCESS The Results string is filled with the
+ values corresponding to all requested
+ names.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_NOT_FOUND Routing data doesn't match any
+ known driver. Progress set to the
+ first character in the routing header.
+ Note: There is no requirement that the
+ driver validate the routing data. It
+ must skip the <ConfigHdr> in order to
+ process the names.
+
+ @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
+ to most recent "&" before the
+ error or the beginning of the
+ string.
+
+ @retval EFI_INVALID_PARAMETER Unknown name. Progress points
+ to the & before the name in
+ question.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessExtractConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+ );
+
+/**
+
+ This function applies changes in a driver's configuration.
+ Input is a Configuration, which has the routing data for this
+ driver followed by name / value configuration pairs. The driver
+ must apply those pairs to its configurable storage. If the
+ driver's configuration is stored in a linear block of data
+ and the driver's name / value pairs are in <BlockConfig>
+ format, it may use the ConfigToBlock helper function (above) to
+ simplify the job.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+
+ @param Configuration A null-terminated Unicode string in
+ <ConfigString> format.
+
+ @param Progress A pointer to a string filled in with the
+ offset of the most recent '&' before the
+ first failing name / value pair (or the
+ beginn ing of the string if the failure
+ is in the first name / value pair) or
+ the terminating NULL if all was
+ successful.
+
+ @retval EFI_SUCCESS The results have been distributed or are
+ awaiting distribution.
+
+ @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
+ parts of the results that must be
+ stored awaiting possible future
+ protocols.
+
+ @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
+ Results parameter would result
+ in this type of error.
+
+ @retval EFI_NOT_FOUND Target for the specified routing data
+ was not found
+
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessRouteConfig (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+ );
+
+/**
+
+ This function is called to provide results data to the driver.
+ This data consists of a unique key that is used to identify
+ which data is either being passed back or being asked for.
+
+ @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
+ @param Action Specifies the type of action taken by the browser.
+ @param QuestionId A unique value which is sent to the original
+ exporting driver so that it can identify the type
+ of data to expect. The format of the data tends to
+ vary based on the opcode that generated the callback.
+ @param Type The type of value for the question.
+ @param Value A pointer to the data being sent to the original
+ exporting driver.
+ @param ActionRequest On return, points to the action requested by the
+ callback function.
+
+ @retval EFI_SUCCESS The callback successfully handled the action.
+ @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
+ variable and its data.
+ @retval EFI_DEVICE_ERROR The variable could not be saved.
+ @retval EFI_UNSUPPORTED The specified Action is not supported by the
+ callback.
+**/
+EFI_STATUS
+EFIAPI
+TlsAuthConfigAccessCallback (
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN OUT EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+ );
+
+#endif
+
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
new file mode 100644
index 0000000..f453201
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
@@ -0,0 +1,49 @@
+/** @file
+ Header file for NV data structure definition.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __TLS_AUTH_CONFIG_NV_DATA_H__
+#define __TLS_AUTH_CONFIG_NV_DATA_H__
+
+#include <Guid/TlsAuthConfigHii.h>
+
+#define TLS_AUTH_CONFIG_GUID_SIZE 36
+#define TLS_AUTH_CONFIG_GUID_STORAGE_SIZE 37
+
+#define TLS_AUTH_CONFIG_FORMID1_FORM 1
+#define TLS_AUTH_CONFIG_FORMID2_FORM 2
+#define TLS_AUTH_CONFIG_FORMID3_FORM 3
+#define TLS_AUTH_CONFIG_FORMID4_FORM 4
+#define TLS_AUTH_CONFIG_FORMID5_FORM 5
+
+
+#define KEY_TLS_AUTH_CONFIG_SERVER_CA 0x1000
+#define KEY_TLS_AUTH_CONFIG_CLIENT_CERT 0x1001
+#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT 0x1002
+#define KEY_TLS_AUTH_CONFIG_DELETE_CERT 0x1003
+#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE 0x1004
+#define KEY_TLS_AUTH_CONFIG_CERT_GUID 0x1005
+#define KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT 0x1006
+#define KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT 0x1007
+
+#define OPTION_DEL_CA_ESTION_ID 0x2000
+#define OPTION_CONFIG_RANGE 0x1000
+
+#define LABEL_CA_DELETE 0x1101
+#define LABEL_END 0xffff
+
+typedef struct {
+ CHAR16 CertGuid[TLS_AUTH_CONFIG_GUID_STORAGE_SIZE];
+} TLS_AUTH_CONFIG_IFR_NVDATA;
+
+#endif
diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
new file mode 100644
index 0000000..fb130d9
--- /dev/null
+++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
@@ -0,0 +1,152 @@
+/** @file
+ VFR file used by TlsAuthConfigDxe driver.
+
+ Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "TlsAuthConfigNvData.h"
+
+formset
+ guid = TLS_AUTH_CONFIG_GUID,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_HELP),
+
+ varstore TLS_AUTH_CONFIG_IFR_NVDATA,
+ name = TLS_AUTH_CONFIG_IFR_NVDATA,
+ guid = TLS_AUTH_CONFIG_GUID;
+
+ //
+ // ##1 Form1: Main form for Tls Auth configration
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID1_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ //
+ // Display Server CA configration
+ //
+ goto TLS_AUTH_CONFIG_FORMID2_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_SERVER_CA;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ //
+ // Display Client cert configration
+ //
+ grayoutif TRUE; /// Current unsupported.
+ goto TLS_AUTH_CONFIG_FORMID3_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_CLIENT_CERT;
+ endif;
+ endform;
+
+ //
+ // ##2 Form2: CA configuration
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID2_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID4_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID5_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_DELETE_CERT;
+ endform;
+
+ //
+ // ##3 Form3 : Client cert configuration
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID3_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ //
+ // TODO...
+ //
+ endform;
+
+ //
+ // ##4 Form4: Enroll cert for CA
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID4_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT);
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID4_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ label TLS_AUTH_CONFIG_FORMID4_FORM;
+ label LABEL_END;
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ string varid = TLS_AUTH_CONFIG_IFR_NVDATA.CertGuid,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID_HELP),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_CERT_GUID,
+ minsize = TLS_AUTH_CONFIG_GUID_SIZE,
+ maxsize = TLS_AUTH_CONFIG_GUID_SIZE,
+ endstring;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ goto TLS_AUTH_CONFIG_FORMID1_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT;
+
+ goto TLS_AUTH_CONFIG_FORMID1_FORM,
+ prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
+ help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
+ flags = INTERACTIVE,
+ key = KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT;
+
+ endform;
+
+ //
+ // ##5 Form5: Delete cert for CA
+ //
+ form formid = TLS_AUTH_CONFIG_FORMID5_FORM,
+ title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT);
+
+ label LABEL_CA_DELETE;
+ label LABEL_END;
+
+ subtitle text = STRING_TOKEN(STR_NULL);
+
+ endform;
+
+endformset;
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration
2016-12-22 2:52 ` Ye, Ting
@ 2016-12-22 3:13 ` Wu, Jiaxin
0 siblings, 0 replies; 37+ messages in thread
From: Wu, Jiaxin @ 2016-12-22 3:13 UTC (permalink / raw)
To: Ye, Ting, Fu, Siyuan, edk2-devel@lists.01.org
Cc: Zhang, Lubo, Long, Qin, Thomas Palmer
Thanks Ting. The standardization is in the plan. Before finished, I will keep the existing APIs.
As the return value of GuidToString, you are right, it should be "Size" instead of "Size-1". I will correct it before commit the patch.
Thanks,
Jiaxin
> -----Original Message-----
> From: Ye, Ting
> Sent: Thursday, December 22, 2016 10:52 AM
> To: Fu, Siyuan <siyuan.fu@intel.com>; Wu, Jiaxin <jiaxin.wu@intel.com>;
> edk2-devel@lists.01.org
> Cc: Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>;
> Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to
> support TLS auth configuration
>
> I agree. Adding new StringToGuid and GuidToString to common library seems
> a good idea if we don't have existing APIs.
>
> In GuidToString, the comment indicates that SPrint will NULL terminate the
> string, so use Size -1 to skip the NULL. However, I see UnicodeSPrint in
> MdePkg returns the number of Unicode characters in the produced output
> buffer, not including the Null-terminator.
> It looks inconsistent to me. Please check that.
>
> Others are good to me.
> Reviewed-by: Ye Ting <ting.ye@intel.com>
>
> Best Regards,
> Ting
>
>
> -----Original Message-----
> From: Fu, Siyuan
> Sent: Thursday, December 15, 2016 10:22 AM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>;
> Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to
> support TLS auth configuration
>
> Hi, Jiaxin
>
> PrintLib support "%g" to print a GUID so you don't need to use "%08x-%04x-
> %04x-%02x%02x-%02x%02x%02x%02x%02x%02x" in GuidToString().
> Beside of that, I do see a lot of drivers has similar internal function
> StringToGuid() or StrToGuid(), do we have a common library interface for this?
> if not I think it may worth to create one.
>
> Other parts are good with me.
> Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
>
>
> Best Regards
> Siyuan
>
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: 2016年12月14日 15:34
> To: edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang,
> Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas
> Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
> Subject: [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to
> support TLS auth configuration
>
> This patch provides the UI to support TLS auth configuration.
> * EFI_SIGNATURE_LIST format is used for 'TlsCaCertificate'
> variable. So, TLS supports multiple certificate configuration.
> * The variable attribute is BS with NV, which only target at
> preventing runtime phase attack.
>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> NetworkPkg/Include/Guid/TlsAuthConfigHii.h | 25 +
> NetworkPkg/Include/Guid/TlsAuthentication.h | 29 +
> NetworkPkg/NetworkPkg.dec | 7 +
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c | 135 ++
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf | 73 +
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni | 21 +
> .../TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni | 19 +
> .../TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni | 39 +
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c | 1841
> ++++++++++++++++++++
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h | 282 +++
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h | 49 +
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr | 152 ++
> 12 files changed, 2672 insertions(+)
> create mode 100644 NetworkPkg/Include/Guid/TlsAuthConfigHii.h
> create mode 100644 NetworkPkg/Include/Guid/TlsAuthentication.h
> create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
> create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
> create mode 100644
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
> create mode 100644
> NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
> create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
> create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
> create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
> create mode 100644 NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
>
> diff --git a/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
> b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
> new file mode 100644
> index 0000000..9d21426
> --- /dev/null
> +++ b/NetworkPkg/Include/Guid/TlsAuthConfigHii.h
> @@ -0,0 +1,25 @@
> +/** @file
> + GUIDs used as HII FormSet and HII Package list GUID in TlsAuthConfigDxe
> driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials are licensed and made
> available under
> +the terms and conditions of the BSD License that accompanies this
> distribution.
> +The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php.
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __TLS_AUTH_CONFIG_HII_GUID_H__
> +#define __TLS_AUTH_CONFIG_HII_GUID_H__
> +
> +#define TLS_AUTH_CONFIG_GUID \
> + { \
> + 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48, 0x79, 0x3d, 0xaa, 0xf, 0x65,
> 0xdf } \
> + }
> +
> +extern EFI_GUID gTlsAuthConfigGuid;
> +
> +#endif
> diff --git a/NetworkPkg/Include/Guid/TlsAuthentication.h
> b/NetworkPkg/Include/Guid/TlsAuthentication.h
> new file mode 100644
> index 0000000..2e800dc
> --- /dev/null
> +++ b/NetworkPkg/Include/Guid/TlsAuthentication.h
> @@ -0,0 +1,29 @@
> +/** @file
> + This file defines TlsCaCertificate variable.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials are licensed and made
> available under
> +the terms and conditions of the BSD License that accompanies this
> distribution.
> +The full text of the license may be found at
> +http://opensource.org/licenses/bsd-license.php.
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __TLS_AUTHENTICATION_H__
> +#define __TLS_AUTHENTICATION_H__
> +
> +// Private variable for CA Certificate configuration
> +//
> +#define EFI_TLS_CA_CERTIFICATE_GUID \
> + { \
> + 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7, 0x3b, 0x4f, 0x12, 0xb4, 0x8e,
> 0xae } \
> + }
> +
> +#define EFI_TLS_CA_CERTIFICATE_VARIABLE L"TlsCaCertificate"
> +
> +extern EFI_GUID gEfiTlsCaCertificateGuid;
> +
> +#endif
> diff --git a/NetworkPkg/NetworkPkg.dec b/NetworkPkg/NetworkPkg.dec
> index 268188a..24d45f4 100644
> --- a/NetworkPkg/NetworkPkg.dec
> +++ b/NetworkPkg/NetworkPkg.dec
> @@ -38,10 +38,17 @@
> gIScsiConfigGuid = { 0x4b47d616, 0xa8d6, 0x4552, { 0x9d, 0x44, 0xcc,
> 0xad, 0x2e, 0xf, 0x4c, 0xf9}}
>
> # Include/Guid/HttpBootConfigHii.h
> gHttpBootConfigGuid = { 0x4d20583a, 0x7765, 0x4e7a, { 0x8a, 0x67,
> 0xdc, 0xde, 0x74, 0xee, 0x3e, 0xc5 }}
>
> + # Include/Guid/TlsAuthConfigHii.h
> + gTlsAuthConfigGuid = { 0xb0eae4f8, 0x9a04, 0x4c6d, { 0xa7, 0x48,
> 0x79, 0x3d, 0xaa, 0xf, 0x65, 0xdf }}
> +
> + # Include/Guid/TlsAuthentication.h
> + gEfiTlsCaCertificateGuid = { 0xfd2340D0, 0x3dab, 0x4349, { 0xa6, 0xc7,
> 0x3b, 0x4f, 0x12, 0xb4, 0x8e, 0xae }}
> +
> +
> [PcdsFeatureFlag]
> ## Indicates if the IPsec IKEv2 Certificate Authentication feature is enabled
> or not.<BR><BR>
> # TRUE - Certificate Authentication feature is enabled.<BR>
> # FALSE - Does not support Certificate Authentication.<BR>
> # @Prompt Enable IPsec IKEv2 Certificate Authentication.
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
> new file mode 100644
> index 0000000..647bc2f
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.c
> @@ -0,0 +1,135 @@
> +/** @file
> + The DriverEntryPoint for TlsAuthConfigDxe driver.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsAuthConfigImpl.h"
> +
> +/**
> + Unloads an image.
> +
> + @param ImageHandle Handle that identifies the image to be
> unloaded.
> +
> + @retval EFI_SUCCESS The image has been unloaded.
> + @retval EFI_INVALID_PARAMETER ImageHandle is not a valid image
> handle.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsAuthConfigDxeUnload (
> + IN EFI_HANDLE ImageHandle
> + )
> +{
> + EFI_STATUS Status;
> + TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData;
> +
> + Status = gBS->HandleProtocol (
> + ImageHandle,
> + &gEfiCallerIdGuid,
> + (VOID **) &PrivateData
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + ASSERT (PrivateData->Signature ==
> TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE);
> +
> + gBS->UninstallMultipleProtocolInterfaces (
> + &ImageHandle,
> + &gEfiCallerIdGuid,
> + PrivateData,
> + NULL
> + );
> +
> + TlsAuthConfigFormUnload (PrivateData);
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This is the declaration of an EFI image entry point. This entry point is
> + the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
> + both device drivers and bus drivers.
> +
> + @param ImageHandle The firmware allocated handle for the UEFI
> image.
> + @param SystemTable A pointer to the EFI System Table.
> +
> + @retval EFI_SUCCESS The operation completed successfully.
> + @retval Others An unexpected error occurred.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsAuthConfigDxeDriverEntryPoint (
> + IN EFI_HANDLE ImageHandle,
> + IN EFI_SYSTEM_TABLE *SystemTable
> + )
> +{
> + EFI_STATUS Status;
> +
> + TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData;
> +
> + PrivateData = NULL;
> +
> + //
> + // If already started, return.
> + //
> + Status = gBS->OpenProtocol (
> + ImageHandle,
> + &gEfiCallerIdGuid,
> + NULL,
> + ImageHandle,
> + ImageHandle,
> + EFI_OPEN_PROTOCOL_TEST_PROTOCOL
> + );
> + if (!EFI_ERROR (Status)) {
> + return EFI_ALREADY_STARTED;
> + }
> +
> + //
> + // Initialize the private data structure.
> + //
> + PrivateData = AllocateZeroPool (sizeof
> (TLS_AUTH_CONFIG_PRIVATE_DATA));
> + if (PrivateData == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + //
> + // Initialize the HII configuration form.
> + //
> + Status = TlsAuthConfigFormInit (PrivateData);
> + if (EFI_ERROR (Status)) {
> + goto ON_ERROR;
> + }
> +
> + //
> + // Install private GUID.
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &ImageHandle,
> + &gEfiCallerIdGuid,
> + PrivateData,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_ERROR;
> + }
> +
> + return EFI_SUCCESS;
> +
> +ON_ERROR:
> + TlsAuthConfigFormUnload (PrivateData);
> + FreePool (PrivateData);
> +
> + return Status;
> +}
> +
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> new file mode 100644
> index 0000000..19f095e
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> @@ -0,0 +1,73 @@
> +## @file
> +# Provides the capability to configure Tls Authentication in a setup browser
> +# By this module, user may change the content of TlsCaCertificate.
> +#
> +# Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +# This program and the accompanying materials
> +# are licensed and made available under the terms and conditions of the
> BSD License
> +# which accompanies this distribution. The full text of the license may be
> found at
> +# http://opensource.org/licenses/bsd-license.php
> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +#
> +##
> +
> +[Defines]
> + INF_VERSION = 0x00010005
> + BASE_NAME = TlsAuthConfigDxe
> + MODULE_UNI_FILE = TlsAuthConfigDxe.uni
> + FILE_GUID = 7ca1024f-eb17-11e5-9dba-28d2447c4829
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + ENTRY_POINT = TlsAuthConfigDxeDriverEntryPoint
> + UNLOAD_IMAGE = TlsAuthConfigDxeUnload
> +
> +#
> +# VALID_ARCHITECTURES = IA32 X64
> +#
> +
> +[Packages]
> + MdePkg/MdePkg.dec
> + MdeModulePkg/MdeModulePkg.dec
> + NetworkPkg/NetworkPkg.dec
> +
> +[Sources]
> + TlsAuthConfigImpl.c
> + TlsAuthConfigImpl.h
> + TlsAuthConfigNvData.h
> + TlsAuthConfigDxe.c
> + TlsAuthConfigDxeStrings.uni
> + TlsAuthConfigVfr.vfr
> +
> +[LibraryClasses]
> + BaseLib
> + BaseMemoryLib
> + MemoryAllocationLib
> + UefiLib
> + UefiBootServicesTableLib
> + UefiRuntimeServicesTableLib
> + UefiDriverEntryPoint
> + DebugLib
> + HiiLib
> + DevicePathLib
> + UefiHiiServicesLib
> + FileExplorerLib
> + PrintLib
> +
> +[Protocols]
> + gEfiDevicePathProtocolGuid ## PRODUCES
> + gEfiHiiConfigAccessProtocolGuid ## PRODUCES
> + gEfiSimpleFileSystemProtocolGuid ## SOMETIMES_CONSUMES
> +
> +[Guids]
> + gTlsAuthConfigGuid ## PRODUCES ## GUID
> + gEfiCertX509Guid ## CONSUMES ## GUID # Indicate the
> cert type
> + gEfiIfrTianoGuid ## CONSUMES ## HII
> + gEfiTlsCaCertificateGuid ## PRODUCES ## GUID
> +
> +[Depex]
> + gEfiHiiConfigRoutingProtocolGuid AND
> + gEfiHiiDatabaseProtocolGuid
> +
> +[UserExtensions.TianoCore."ExtraFiles"]
> + TlsAuthConfigDxeExtra.uni
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
> new file mode 100644
> index 0000000..f99a14f
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.uni
> @@ -0,0 +1,21 @@
> +// /** @file
> +// Provides the capability to configure Tls Authentication in a setup browser
> +//
> +// By this module, user may change the content of TlsCaCertificate.
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// This program and the accompanying materials
> +// are licensed and made available under the terms and conditions of the
> BSD License
> +// which accompanies this distribution. The full text of the license may be
> found at
> +// http://opensource.org/licenses/bsd-license.php
> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +//
> +// **/
> +
> +
> +#string STR_MODULE_ABSTRACT #language en-US "Provides the
> capability to configure Tls Authentication in a setup browser"
> +
> +#string STR_MODULE_DESCRIPTION #language en-US "By this module,
> user may change the content of TlsCaCertificate."
> +
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
> new file mode 100644
> index 0000000..ee4c49f
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeExtra.uni
> @@ -0,0 +1,19 @@
> +// /** @file
> +// TlsAuthConfigDxe Localized Strings and Content
> +//
> +// Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +//
> +// This program and the accompanying materials
> +// are licensed and made available under the terms and conditions of the
> BSD License
> +// which accompanies this distribution. The full text of the license may be
> found at
> +// http://opensource.org/licenses/bsd-license.php
> +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +//
> +// **/
> +
> +#string STR_PROPERTIES_MODULE_NAME
> +#language en-US
> +"TLS Auth Config DXE"
> +
> +
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
> new file mode 100644
> index 0000000..a8f7e43
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxeStrings.uni
> @@ -0,0 +1,39 @@
> +/** @file
> + String definitions for Tls Authentication Configuration form.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#langdef en-US "English"
> +
> +#string STR_TLS_AUTH_CONFIG_TITLE #language en-US "Tls Auth
> Configuration"
> +#string STR_TLS_AUTH_CONFIG_HELP #language en-US "Press
> <Enter> to select Tls Auth Configuration."
> +
> +#string STR_TLS_AUTH_CONFIG_SERVER_CA #language
> en-US "Server CA Configuration"
> +#string STR_TLS_AUTH_CONFIG_SERVER_CA_HELP #language
> en-US "Press <Enter> to configure Server CA."
> +#string STR_TLS_AUTH_CONFIG_CLIENT_CERT #language en-US
> "Client Cert Configuration"
> +#string STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP #language
> en-US "Client cert configuration is unsupported currently."
> +
> +#string STR_TLS_AUTH_CONFIG_ENROLL_CERT #language en-US
> "Enroll Cert"
> +#string STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP #language en-US
> "Press <Enter> to enroll cert."
> +#string STR_TLS_AUTH_CONFIG_DELETE_CERT #language en-US
> "Delete Cert"
> +#string STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP #language en-US
> "Press <Enter> to delete cert."
> +
> +#string STR_TLS_AUTH_CONFIG_ADD_CERT_FILE #language en-US
> "Enroll Cert Using File"
> +
> +#string STR_TLS_AUTH_CONFIG_CERT_GUID #language en-US "Cert
> GUID"
> +#string STR_TLS_AUTH_CONFIG_CERT_GUID_HELP #language en-US
> "Input digit character in 11111111-2222-3333-4444-1234567890ab format."
> +#string STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT #language en-US
> "Commit Changes and Exit"
> +#string STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT #language en-
> US "Discard Changes and Exit"
> +
> +#string STR_CERT_TYPE_PCKS_GUID #language en-US "GUID for
> CERT"
> +
> +#string STR_NULL #language en-US ""
> \ No newline at end of file
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
> new file mode 100644
> index 0000000..1132cac
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.c
> @@ -0,0 +1,1841 @@
> +/** @file
> + The Miscellaneous Routines for TlsAuthConfigDxe driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsAuthConfigImpl.h"
> +
> +VOID *mStartOpCodeHandle = NULL;
> +VOID *mEndOpCodeHandle = NULL;
> +EFI_IFR_GUID_LABEL *mStartLabel = NULL;
> +EFI_IFR_GUID_LABEL *mEndLabel = NULL;
> +
> +
> +CHAR16 mTlsAuthConfigStorageName[] =
> L"TLS_AUTH_CONFIG_IFR_NVDATA";
> +
> +TLS_AUTH_CONFIG_PRIVATE_DATA *mTlsAuthPrivateData = NULL;
> +
> +HII_VENDOR_DEVICE_PATH mTlsAuthConfigHiiVendorDevicePath = {
> + {
> + {
> + HARDWARE_DEVICE_PATH,
> + HW_VENDOR_DP,
> + {
> + (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
> + (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
> + }
> + },
> + TLS_AUTH_CONFIG_GUID
> + },
> + {
> + END_DEVICE_PATH_TYPE,
> + END_ENTIRE_DEVICE_PATH_SUBTYPE,
> + {
> + (UINT8) (END_DEVICE_PATH_LENGTH),
> + (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
> + }
> + }
> +};
> +
> +//
> +// Possible DER-encoded certificate file suffixes, end with NULL pointer.
> +//
> +CHAR16* mDerPemEncodedSuffix[] = {
> + L".cer",
> + L".der",
> + L".crt",
> + L".pem",
> + NULL
> +};
> +
> +/**
> + This code checks if the FileSuffix is one of the possible DER/PEM-encoded
> certificate suffix.
> +
> + @param[in] FileSuffix The suffix of the input certificate file
> +
> + @retval TRUE It's a DER/PEM-encoded certificate.
> + @retval FALSE It's NOT a DER/PEM-encoded certificate.
> +
> +**/
> +BOOLEAN
> +IsDerPemEncodeCertificate (
> + IN CONST CHAR16 *FileSuffix
> +)
> +{
> + UINTN Index;
> + for (Index = 0; mDerPemEncodedSuffix[Index] != NULL; Index++) {
> + if (StrCmp (FileSuffix, mDerPemEncodedSuffix[Index]) == 0) {
> + return TRUE;
> + }
> + }
> + return FALSE;
> +}
> +
> +/**
> + Worker function that prints an EFI_GUID into specified Buffer.
> +
> + @param[in] Guid Pointer to GUID to print.
> + @param[in] Buffer Buffer to print Guid into.
> + @param[in] BufferSize Size of Buffer.
> +
> + @retval Number of characters printed.
> +
> +**/
> +UINTN
> +GuidToString (
> + IN EFI_GUID *Guid,
> + IN CHAR16 *Buffer,
> + IN UINTN BufferSize
> + )
> +{
> + UINTN Size;
> +
> + Size = UnicodeSPrint (
> + Buffer,
> + BufferSize,
> + L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
> + (UINTN)Guid->Data1,
> + (UINTN)Guid->Data2,
> + (UINTN)Guid->Data3,
> + (UINTN)Guid->Data4[0],
> + (UINTN)Guid->Data4[1],
> + (UINTN)Guid->Data4[2],
> + (UINTN)Guid->Data4[3],
> + (UINTN)Guid->Data4[4],
> + (UINTN)Guid->Data4[5],
> + (UINTN)Guid->Data4[6],
> + (UINTN)Guid->Data4[7]
> + );
> +
> + //
> + // SPrint will null terminate the string. The -1 skips the null
> + //
> + return Size - 1;
> +}
> +
> +/**
> + Convert a String to Guid Value.
> +
> + @param[in] Str Specifies the String to be converted.
> + @param[in] StrLen Number of Unicode Characters of String (exclusive
> \0)
> + @param[out] Guid Return the result Guid value.
> +
> + @retval EFI_SUCCESS The operation is finished successfully.
> + @retval EFI_NOT_FOUND Invalid string.
> +
> +**/
> +EFI_STATUS
> +StringToGuid (
> + IN CHAR16 *Str,
> + IN UINTN StrLen,
> + OUT EFI_GUID *Guid
> + )
> +{
> + CHAR16 *PtrBuffer;
> + CHAR16 *PtrPosition;
> + UINT16 *Buffer;
> + UINTN Data;
> + UINTN Index;
> + UINT16 Digits[3];
> +
> + Buffer = (CHAR16 *) AllocateZeroPool (sizeof (CHAR16) * (StrLen + 1));
> + if (Buffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + StrCpyS (Buffer, (StrLen + 1), Str);
> +
> + //
> + // Data1
> + //
> + PtrBuffer = Buffer;
> + PtrPosition = PtrBuffer;
> + while (*PtrBuffer != L'\0') {
> + if (*PtrBuffer == L'-') {
> + break;
> + }
> + PtrBuffer++;
> + }
> + if (*PtrBuffer == L'\0') {
> + FreePool (Buffer);
> + return EFI_NOT_FOUND;
> + }
> +
> + *PtrBuffer = L'\0';
> + Data = StrHexToUintn (PtrPosition);
> + Guid->Data1 = (UINT32)Data;
> +
> + //
> + // Data2
> + //
> + PtrBuffer++;
> + PtrPosition = PtrBuffer;
> + while (*PtrBuffer != L'\0') {
> + if (*PtrBuffer == L'-') {
> + break;
> + }
> + PtrBuffer++;
> + }
> + if (*PtrBuffer == L'\0') {
> + FreePool (Buffer);
> + return EFI_NOT_FOUND;
> + }
> + *PtrBuffer = L'\0';
> + Data = StrHexToUintn (PtrPosition);
> + Guid->Data2 = (UINT16)Data;
> +
> + //
> + // Data3
> + //
> + PtrBuffer++;
> + PtrPosition = PtrBuffer;
> + while (*PtrBuffer != L'\0') {
> + if (*PtrBuffer == L'-') {
> + break;
> + }
> + PtrBuffer++;
> + }
> + if (*PtrBuffer == L'\0') {
> + FreePool (Buffer);
> + return EFI_NOT_FOUND;
> + }
> + *PtrBuffer = L'\0';
> + Data = StrHexToUintn (PtrPosition);
> + Guid->Data3 = (UINT16)Data;
> +
> + //
> + // Data4[0..1]
> + //
> + for ( Index = 0 ; Index < 2 ; Index++) {
> + PtrBuffer++;
> + if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
> + FreePool (Buffer);
> + return EFI_NOT_FOUND;
> + }
> + Digits[0] = *PtrBuffer;
> + PtrBuffer++;
> + Digits[1] = *PtrBuffer;
> + Digits[2] = L'\0';
> + Data = StrHexToUintn (Digits);
> + Guid->Data4[Index] = (UINT8)Data;
> + }
> +
> + //
> + // skip the '-'
> + //
> + PtrBuffer++;
> + if ((*PtrBuffer != L'-' ) || ( *PtrBuffer == L'\0')) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // Data4[2..7]
> + //
> + for ( ; Index < 8; Index++) {
> + PtrBuffer++;
> + if ((*PtrBuffer == L'\0') || ( *(PtrBuffer + 1) == L'\0')) {
> + FreePool (Buffer);
> + return EFI_NOT_FOUND;
> + }
> + Digits[0] = *PtrBuffer;
> + PtrBuffer++;
> + Digits[1] = *PtrBuffer;
> + Digits[2] = L'\0';
> + Data = StrHexToUintn (Digits);
> + Guid->Data4[Index] = (UINT8)Data;
> + }
> +
> + FreePool (Buffer);
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + List all cert in specified database by GUID in the page
> + for user to select and delete as needed.
> +
> + @param[in] PrivateData Module's private data.
> + @param[in] VariableName The variable name of the vendor's
> signature database.
> + @param[in] VendorGuid A unique identifier for the vendor.
> + @param[in] LabelNumber Label number to insert opcodes.
> + @param[in] FormId Form ID of current page.
> + @param[in] QuestionIdBase Base question id of the signature list.
> +
> + @retval EFI_SUCCESS Success to update the signature list page
> + @retval EFI_OUT_OF_RESOURCES Unable to allocate required resources.
> +
> +**/
> +EFI_STATUS
> +UpdateDeletePage (
> + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT16 LabelNumber,
> + IN EFI_FORM_ID FormId,
> + IN EFI_QUESTION_ID QuestionIdBase
> + )
> +{
> + EFI_STATUS Status;
> + UINT32 Index;
> + UINTN CertCount;
> + UINTN GuidIndex;
> + VOID *StartOpCodeHandle;
> + VOID *EndOpCodeHandle;
> + EFI_IFR_GUID_LABEL *StartLabel;
> + EFI_IFR_GUID_LABEL *EndLabel;
> + UINTN DataSize;
> + UINT8 *Data;
> + EFI_SIGNATURE_LIST *CertList;
> + EFI_SIGNATURE_DATA *Cert;
> + UINT32 ItemDataSize;
> + CHAR16 *GuidStr;
> + EFI_STRING_ID GuidID;
> + EFI_STRING_ID Help;
> +
> + Data = NULL;
> + CertList = NULL;
> + Cert = NULL;
> + GuidStr = NULL;
> + StartOpCodeHandle = NULL;
> + EndOpCodeHandle = NULL;
> +
> + //
> + // Initialize the container for dynamic opcodes.
> + //
> + StartOpCodeHandle = HiiAllocateOpCodeHandle ();
> + if (StartOpCodeHandle == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + EndOpCodeHandle = HiiAllocateOpCodeHandle ();
> + if (EndOpCodeHandle == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Create Hii Extend Label OpCode.
> + //
> + StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
> + StartOpCodeHandle,
> + &gEfiIfrTianoGuid,
> + NULL,
> + sizeof (EFI_IFR_GUID_LABEL)
> + );
> + StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> + StartLabel->Number = LabelNumber;
> +
> + EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
> + EndOpCodeHandle,
> + &gEfiIfrTianoGuid,
> + NULL,
> + sizeof (EFI_IFR_GUID_LABEL)
> + );
> + EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> + EndLabel->Number = LABEL_END;
> +
> + //
> + // Read Variable.
> + //
> + DataSize = 0;
> + Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize,
> Data);
> + if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
> + goto ON_EXIT;
> + }
> +
> + Data = (UINT8 *) AllocateZeroPool (DataSize);
> + if (Data == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize,
> Data);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + GuidStr = AllocateZeroPool (100);
> + if (GuidStr == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Enumerate all data.
> + //
> + ItemDataSize = (UINT32) DataSize;
> + CertList = (EFI_SIGNATURE_LIST *) Data;
> + GuidIndex = 0;
> +
> + while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize))
> {
> +
> + if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
> + Help = STRING_TOKEN (STR_CERT_TYPE_PCKS_GUID);
> + } else {
> + //
> + // The signature type is not supported in current implementation.
> + //
> + ItemDataSize -= CertList->SignatureListSize;
> + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList-
> >SignatureListSize);
> + continue;
> + }
> +
> + CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) -
> CertList->SignatureHeaderSize) / CertList->SignatureSize;
> + for (Index = 0; Index < CertCount; Index++) {
> + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList
> + + sizeof (EFI_SIGNATURE_LIST)
> + + CertList->SignatureHeaderSize
> + + Index * CertList->SignatureSize);
> + //
> + // Display GUID and help
> + //
> + GuidToString (&Cert->SignatureOwner, GuidStr, 100);
> + GuidID = HiiSetString (Private->RegisteredHandle, 0, GuidStr, NULL);
> + HiiCreateCheckBoxOpCode (
> + StartOpCodeHandle,
> + (EFI_QUESTION_ID) (QuestionIdBase + GuidIndex++),
> + 0,
> + 0,
> + GuidID,
> + Help,
> + EFI_IFR_FLAG_CALLBACK,
> + 0,
> + NULL
> + );
> + }
> +
> + ItemDataSize -= CertList->SignatureListSize;
> + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList-
> >SignatureListSize);
> + }
> +
> +ON_EXIT:
> + HiiUpdateForm (
> + Private->RegisteredHandle,
> + &gTlsAuthConfigGuid,
> + FormId,
> + StartOpCodeHandle,
> + EndOpCodeHandle
> + );
> +
> + if (StartOpCodeHandle != NULL) {
> + HiiFreeOpCodeHandle (StartOpCodeHandle);
> + }
> +
> + if (EndOpCodeHandle != NULL) {
> + HiiFreeOpCodeHandle (EndOpCodeHandle);
> + }
> +
> + if (Data != NULL) {
> + FreePool (Data);
> + }
> +
> + if (GuidStr != NULL) {
> + FreePool (GuidStr);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + Delete one entry from cert database.
> +
> + @param[in] PrivateData Module's private data.
> + @param[in] VariableName The variable name of the database.
> + @param[in] VendorGuid A unique identifier for the vendor.
> + @param[in] LabelNumber Label number to insert opcodes.
> + @param[in] FormId Form ID of current page.
> + @param[in] QuestionIdBase Base question id of the cert list.
> + @param[in] DeleteIndex Cert index to delete.
> +
> + @retval EFI_SUCCESS Delete siganture successfully.
> + @retval EFI_NOT_FOUND Can't find the signature item,
> + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
> +**/
> +EFI_STATUS
> +DeleteCert (
> + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
> + IN CHAR16 *VariableName,
> + IN EFI_GUID *VendorGuid,
> + IN UINT16 LabelNumber,
> + IN EFI_FORM_ID FormId,
> + IN EFI_QUESTION_ID QuestionIdBase,
> + IN UINTN DeleteIndex
> + )
> +{
> + EFI_STATUS Status;
> + UINTN DataSize;
> + UINT8 *Data;
> + UINT8 *OldData;
> + UINT32 Attr;
> + UINT32 Index;
> + EFI_SIGNATURE_LIST *CertList;
> + EFI_SIGNATURE_LIST *NewCertList;
> + EFI_SIGNATURE_DATA *Cert;
> + UINTN CertCount;
> + UINT32 Offset;
> + BOOLEAN IsItemFound;
> + UINT32 ItemDataSize;
> + UINTN GuidIndex;
> +
> + Data = NULL;
> + OldData = NULL;
> + CertList = NULL;
> + Cert = NULL;
> + Attr = 0;
> +
> + //
> + // Get original signature list data.
> + //
> + DataSize = 0;
> + Status = gRT->GetVariable (VariableName, VendorGuid, NULL, &DataSize,
> NULL);
> + if (EFI_ERROR (Status) && Status != EFI_BUFFER_TOO_SMALL) {
> + goto ON_EXIT;
> + }
> +
> + OldData = (UINT8 *) AllocateZeroPool (DataSize);
> + if (OldData == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + Status = gRT->GetVariable (VariableName, VendorGuid, &Attr, &DataSize,
> OldData);
> + if (EFI_ERROR(Status)) {
> + goto ON_EXIT;
> + }
> +
> + //
> + // Allocate space for new variable.
> + //
> + Data = (UINT8*) AllocateZeroPool (DataSize);
> + if (Data == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Enumerate all data and erasing the target item.
> + //
> + IsItemFound = FALSE;
> + ItemDataSize = (UINT32) DataSize;
> + CertList = (EFI_SIGNATURE_LIST *) OldData;
> + Offset = 0;
> + GuidIndex = 0;
> + while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize))
> {
> + if (CompareGuid (&CertList->SignatureType, &gEfiCertX509Guid)) {
> + //
> + // Copy EFI_SIGNATURE_LIST header then calculate the signature count
> in this list.
> + //
> + CopyMem (Data + Offset, CertList, (sizeof(EFI_SIGNATURE_LIST) +
> CertList->SignatureHeaderSize));
> + NewCertList = (EFI_SIGNATURE_LIST*) (Data + Offset);
> + Offset += (sizeof(EFI_SIGNATURE_LIST) + CertList-
> >SignatureHeaderSize);
> + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof
> (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
> + CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) -
> CertList->SignatureHeaderSize) / CertList->SignatureSize;
> + for (Index = 0; Index < CertCount; Index++) {
> + if (GuidIndex == DeleteIndex) {
> + //
> + // Find it! Skip it!
> + //
> + NewCertList->SignatureListSize -= CertList->SignatureSize;
> + IsItemFound = TRUE;
> + } else {
> + //
> + // This item doesn't match. Copy it to the Data buffer.
> + //
> + CopyMem (Data + Offset, (UINT8*)(Cert), CertList->SignatureSize);
> + Offset += CertList->SignatureSize;
> + }
> + GuidIndex++;
> + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList-
> >SignatureSize);
> + }
> + } else {
> + //
> + // This List doesn't match. Just copy it to the Data buffer.
> + //
> + CopyMem (Data + Offset, (UINT8*)(CertList), CertList-
> >SignatureListSize);
> + Offset += CertList->SignatureListSize;
> + }
> +
> + ItemDataSize -= CertList->SignatureListSize;
> + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList-
> >SignatureListSize);
> + }
> +
> + if (!IsItemFound) {
> + //
> + // Doesn't find the signature Item!
> + //
> + Status = EFI_NOT_FOUND;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Delete the EFI_SIGNATURE_LIST header if there is no signature in the
> list.
> + //
> + ItemDataSize = Offset;
> + CertList = (EFI_SIGNATURE_LIST *) Data;
> + Offset = 0;
> + ZeroMem (OldData, ItemDataSize);
> + while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize))
> {
> + CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) -
> CertList->SignatureHeaderSize) / CertList->SignatureSize;
> + DEBUG ((DEBUG_INFO, " CertCount = %x\n", CertCount));
> + if (CertCount != 0) {
> + CopyMem (OldData + Offset, (UINT8*)(CertList), CertList-
> >SignatureListSize);
> + Offset += CertList->SignatureListSize;
> + }
> + ItemDataSize -= CertList->SignatureListSize;
> + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList-
> >SignatureListSize);
> + }
> +
> + DataSize = Offset;
> +
> + Status = gRT->SetVariable(
> + VariableName,
> + VendorGuid,
> + Attr,
> + DataSize,
> + OldData
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "Failed to set variable, Status = %r\n", Status));
> + goto ON_EXIT;
> + }
> +
> +ON_EXIT:
> + if (Data != NULL) {
> + FreePool(Data);
> + }
> +
> + if (OldData != NULL) {
> + FreePool(OldData);
> + }
> +
> + return UpdateDeletePage (
> + Private,
> + VariableName,
> + VendorGuid,
> + LabelNumber,
> + FormId,
> + QuestionIdBase
> + );
> +}
> +
> +
> +/**
> + Close an open file handle.
> +
> + @param[in] FileHandle The file handle to close.
> +
> +**/
> +VOID
> +CloseFile (
> + IN EFI_FILE_HANDLE FileHandle
> + )
> +{
> + if (FileHandle != NULL) {
> + FileHandle->Close (FileHandle);
> + }
> +}
> +
> +/**
> + Read file content into BufferPtr, the size of the allocate buffer
> + is *FileSize plus AddtionAllocateSize.
> +
> + @param[in] FileHandle The file to be read.
> + @param[in, out] BufferPtr Pointers to the pointer of allocated
> buffer.
> + @param[out] FileSize Size of input file
> + @param[in] AddtionAllocateSize Addtion size the buffer need to be
> allocated.
> + In case the buffer need to contain others besides the
> file content.
> +
> + @retval EFI_SUCCESS The file was read into the buffer.
> + @retval EFI_INVALID_PARAMETER A parameter was invalid.
> + @retval EFI_OUT_OF_RESOURCES A memory allocation failed.
> + @retval others Unexpected error.
> +
> +**/
> +EFI_STATUS
> +ReadFileContent (
> + IN EFI_FILE_HANDLE FileHandle,
> + IN OUT VOID **BufferPtr,
> + OUT UINTN *FileSize,
> + IN UINTN AddtionAllocateSize
> + )
> +
> +{
> + UINTN BufferSize;
> + UINT64 SourceFileSize;
> + VOID *Buffer;
> + EFI_STATUS Status;
> +
> + if ((FileHandle == NULL) || (FileSize == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Buffer = NULL;
> +
> + //
> + // Get the file size
> + //
> + Status = FileHandle->SetPosition (FileHandle, (UINT64) -1);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + Status = FileHandle->GetPosition (FileHandle, &SourceFileSize);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + Status = FileHandle->SetPosition (FileHandle, 0);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + BufferSize = (UINTN) SourceFileSize + AddtionAllocateSize;
> + Buffer = AllocateZeroPool(BufferSize);
> + if (Buffer == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + BufferSize = (UINTN) SourceFileSize;
> + *FileSize = BufferSize;
> +
> + Status = FileHandle->Read (FileHandle, &BufferSize, Buffer);
> + if (EFI_ERROR (Status) || BufferSize != *FileSize) {
> + FreePool (Buffer);
> + Buffer = NULL;
> + Status = EFI_BAD_BUFFER_SIZE;
> + goto ON_EXIT;
> + }
> +
> +ON_EXIT:
> +
> + *BufferPtr = Buffer;
> + return Status;
> +}
> +
> +/**
> + This function will open a file or directory referenced by DevicePath.
> +
> + This function opens a file with the open mode according to the file path.
> The
> + Attributes is valid only for EFI_FILE_MODE_CREATE.
> +
> + @param[in, out] FilePath On input, the device path to the file.
> + On output, the remaining device path.
> + @param[out] FileHandle Pointer to the file handle.
> + @param[in] OpenMode The mode to open the file with.
> + @param[in] Attributes The file's file attributes.
> +
> + @retval EFI_SUCCESS The information was set.
> + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid
> value.
> + @retval EFI_UNSUPPORTED Could not open the file path.
> + @retval EFI_NOT_FOUND The specified file could not be found on
> the
> + device or the file system could not be found on
> + the device.
> + @retval EFI_NO_MEDIA The device has no medium.
> + @retval EFI_MEDIA_CHANGED The device has a different medium in it
> or the
> + medium is no longer supported.
> + @retval EFI_DEVICE_ERROR The device reported an error.
> + @retval EFI_VOLUME_CORRUPTED The file system structures are
> corrupted.
> + @retval EFI_WRITE_PROTECTED The file or medium is write protected.
> + @retval EFI_ACCESS_DENIED The file was opened read only.
> + @retval EFI_OUT_OF_RESOURCES Not enough resources were available
> to open the
> + file.
> + @retval EFI_VOLUME_FULL The volume is full.
> +**/
> +EFI_STATUS
> +EFIAPI
> +OpenFileByDevicePath (
> + IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
> + OUT EFI_FILE_HANDLE *FileHandle,
> + IN UINT64 OpenMode,
> + IN UINT64 Attributes
> + )
> +{
> + EFI_STATUS Status;
> + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *EfiSimpleFileSystemProtocol;
> + EFI_FILE_PROTOCOL *Handle1;
> + EFI_FILE_PROTOCOL *Handle2;
> + EFI_HANDLE DeviceHandle;
> +
> + if ((FilePath == NULL || FileHandle == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Status = gBS->LocateDevicePath (
> + &gEfiSimpleFileSystemProtocolGuid,
> + FilePath,
> + &DeviceHandle
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = gBS->OpenProtocol(
> + DeviceHandle,
> + &gEfiSimpleFileSystemProtocolGuid,
> + (VOID**)&EfiSimpleFileSystemProtocol,
> + gImageHandle,
> + NULL,
> + EFI_OPEN_PROTOCOL_GET_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Status = EfiSimpleFileSystemProtocol-
> >OpenVolume(EfiSimpleFileSystemProtocol, &Handle1);
> + if (EFI_ERROR (Status)) {
> + FileHandle = NULL;
> + return Status;
> + }
> +
> + //
> + // go down directories one node at a time.
> + //
> + while (!IsDevicePathEnd (*FilePath)) {
> + //
> + // For file system access each node should be a file path component
> + //
> + if (DevicePathType (*FilePath) != MEDIA_DEVICE_PATH ||
> + DevicePathSubType (*FilePath) != MEDIA_FILEPATH_DP
> + ) {
> + FileHandle = NULL;
> + return (EFI_INVALID_PARAMETER);
> + }
> + //
> + // Open this file path node
> + //
> + Handle2 = Handle1;
> + Handle1 = NULL;
> +
> + //
> + // Try to test opening an existing file
> + //
> + Status = Handle2->Open (
> + Handle2,
> + &Handle1,
> + ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
> + OpenMode &~EFI_FILE_MODE_CREATE,
> + 0
> + );
> +
> + //
> + // see if the error was that it needs to be created
> + //
> + if ((EFI_ERROR (Status)) && (OpenMode != (OpenMode
> &~EFI_FILE_MODE_CREATE))) {
> + Status = Handle2->Open (
> + Handle2,
> + &Handle1,
> + ((FILEPATH_DEVICE_PATH*)*FilePath)->PathName,
> + OpenMode,
> + Attributes
> + );
> + }
> + //
> + // Close the last node
> + //
> + Handle2->Close (Handle2);
> +
> + if (EFI_ERROR(Status)) {
> + return (Status);
> + }
> +
> + //
> + // Get the next node
> + //
> + *FilePath = NextDevicePathNode (*FilePath);
> + }
> +
> + //
> + // This is a weak spot since if the undefined SHELL_FILE_HANDLE format
> changes this must change also!
> + //
> + *FileHandle = (VOID*)Handle1;
> + return EFI_SUCCESS;
> +}
> +
> +/**
> + This function converts an input device structure to a Unicode string.
> +
> + @param[in] DevPath A pointer to the device path structure.
> +
> + @return A new allocated Unicode string that represents the device path.
> +
> +**/
> +CHAR16 *
> +EFIAPI
> +DevicePathToStr (
> + IN EFI_DEVICE_PATH_PROTOCOL *DevPath
> + )
> +{
> + return ConvertDevicePathToText (
> + DevPath,
> + FALSE,
> + TRUE
> + );
> +}
> +
> +
> +/**
> + Extract filename from device path. The returned buffer is allocated using
> AllocateCopyPool.
> + The caller is responsible for freeing the allocated buffer using FreePool(). If
> return NULL
> + means not enough memory resource.
> +
> + @param DevicePath Device path.
> +
> + @retval NULL Not enough memory resourece for AllocateCopyPool.
> + @retval Other A new allocated string that represents the file name.
> +
> +**/
> +CHAR16 *
> +ExtractFileNameFromDevicePath (
> + IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
> + )
> +{
> + CHAR16 *String;
> + CHAR16 *MatchString;
> + CHAR16 *LastMatch;
> + CHAR16 *FileName;
> + UINTN Length;
> +
> + ASSERT(DevicePath != NULL);
> +
> + String = DevicePathToStr(DevicePath);
> + MatchString = String;
> + LastMatch = String;
> + FileName = NULL;
> +
> + while(MatchString != NULL){
> + LastMatch = MatchString + 1;
> + MatchString = StrStr(LastMatch,L"\\");
> + }
> +
> + Length = StrLen(LastMatch);
> + FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);
> + if (FileName != NULL) {
> + *(FileName + Length) = 0;
> + }
> +
> + FreePool(String);
> +
> + return FileName;
> +}
> +
> +/**
> + Enroll a new X509 certificate into Variable.
> +
> + @param[in] PrivateData The module's private data.
> + @param[in] VariableName Variable name of CA database.
> +
> + @retval EFI_SUCCESS New X509 is enrolled successfully.
> + @retval EFI_OUT_OF_RESOURCES Could not allocate needed resources.
> +
> +**/
> +EFI_STATUS
> +EnrollX509toVariable (
> + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
> + IN CHAR16 *VariableName
> + )
> +{
> + EFI_STATUS Status;
> + UINTN X509DataSize;
> + VOID *X509Data;
> + EFI_SIGNATURE_LIST *CACert;
> + EFI_SIGNATURE_DATA *CACertData;
> + VOID *Data;
> + UINTN DataSize;
> + UINTN SigDataSize;
> + UINT32 Attr;
> +
> + X509DataSize = 0;
> + SigDataSize = 0;
> + DataSize = 0;
> + X509Data = NULL;
> + CACert = NULL;
> + CACertData = NULL;
> + Data = NULL;
> +
> + Status = ReadFileContent (
> + Private->FileContext->FHandle,
> + &X509Data,
> + &X509DataSize,
> + 0
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> + ASSERT (X509Data != NULL);
> +
> + SigDataSize = sizeof(EFI_SIGNATURE_LIST) + sizeof(EFI_SIGNATURE_DATA)
> - 1 + X509DataSize;
> +
> + Data = AllocateZeroPool (SigDataSize);
> + if (Data == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Fill Certificate Database parameters.
> + //
> + CACert = (EFI_SIGNATURE_LIST*) Data;
> + CACert->SignatureListSize = (UINT32) SigDataSize;
> + CACert->SignatureHeaderSize = 0;
> + CACert->SignatureSize = (UINT32) (sizeof(EFI_SIGNATURE_DATA) - 1 +
> X509DataSize);
> + CopyGuid (&CACert->SignatureType, &gEfiCertX509Guid);
> +
> + CACertData = (EFI_SIGNATURE_DATA*) ((UINT8* ) CACert + sizeof
> (EFI_SIGNATURE_LIST));
> + CopyGuid (&CACertData->SignatureOwner, Private->CertGuid);
> + CopyMem ((UINT8* ) (CACertData->SignatureData), X509Data,
> X509DataSize);
> +
> + //
> + // Check if signature database entry has been already existed.
> + // If true, use EFI_VARIABLE_APPEND_WRITE attribute to append the
> + // new signature data to original variable
> + //
> + Attr = TLS_AUTH_CONFIG_VAR_BASE_ATTR;
> +
> + Status = gRT->GetVariable(
> + VariableName,
> + &gEfiTlsCaCertificateGuid,
> + NULL,
> + &DataSize,
> + NULL
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + Attr |= EFI_VARIABLE_APPEND_WRITE;
> + } else if (Status != EFI_NOT_FOUND) {
> + goto ON_EXIT;
> + }
> +
> + Status = gRT->SetVariable(
> + VariableName,
> + &gEfiTlsCaCertificateGuid,
> + Attr,
> + SigDataSize,
> + Data
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> +ON_EXIT:
> +
> + CloseFile (Private->FileContext->FHandle);
> + if (Private->FileContext->FileName != NULL) {
> + FreePool(Private->FileContext->FileName);
> + Private->FileContext->FileName = NULL;
> + }
> +
> + Private->FileContext->FHandle = NULL;
> +
> + if (Private->CertGuid != NULL) {
> + FreePool (Private->CertGuid);
> + Private->CertGuid = NULL;
> + }
> +
> + if (Data != NULL) {
> + FreePool (Data);
> + }
> +
> + if (X509Data != NULL) {
> + FreePool (X509Data);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Enroll Cert into TlsCaCertificate. The GUID will be Private->CertGuid.
> +
> + @param[in] PrivateData The module's private data.
> + @param[in] VariableName Variable name of signature database.
> +
> + @retval EFI_SUCCESS New Cert enrolled successfully.
> + @retval EFI_INVALID_PARAMETER The parameter is invalid.
> + @retval EFI_UNSUPPORTED The Cert file is unsupported type.
> + @retval others Fail to enroll Cert data.
> +
> +**/
> +EFI_STATUS
> +EnrollCertDatabase (
> + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private,
> + IN CHAR16 *VariableName
> + )
> +{
> + UINT16* FilePostFix;
> + UINTN NameLength;
> +
> + if ((Private->FileContext->FileName == NULL) || (Private->FileContext-
> >FHandle == NULL) || (Private->CertGuid == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Parse the file's postfix.
> + //
> + NameLength = StrLen (Private->FileContext->FileName);
> + if (NameLength <= 4) {
> + return EFI_INVALID_PARAMETER;
> + }
> + FilePostFix = Private->FileContext->FileName + NameLength - 4;
> +
> + if (IsDerPemEncodeCertificate (FilePostFix)) {
> + //
> + // Supports DER-encoded X509 certificate.
> + //
> + return EnrollX509toVariable (Private, VariableName);
> + }
> +
> + return EFI_UNSUPPORTED;
> +}
> +
> +/**
> + Refresh the global UpdateData structure.
> +
> +**/
> +VOID
> +RefreshUpdateData (
> + VOID
> + )
> +{
> + //
> + // Free current updated date
> + //
> + if (mStartOpCodeHandle != NULL) {
> + HiiFreeOpCodeHandle (mStartOpCodeHandle);
> + }
> +
> + //
> + // Create new OpCode Handle
> + //
> + mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
> +
> + //
> + // Create Hii Extend Label OpCode as the start opcode
> + //
> + mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
> + mStartOpCodeHandle,
> + &gEfiIfrTianoGuid,
> + NULL,
> + sizeof (EFI_IFR_GUID_LABEL)
> + );
> + mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +}
> +
> +/**
> + Clean up the dynamic opcode at label and form specified by both LabelId.
> +
> + @param[in] LabelId It is both the Form ID and Label ID for opcode
> deletion.
> + @param[in] PrivateData Module private data.
> +
> +**/
> +VOID
> +CleanUpPage (
> + IN UINT16 LabelId,
> + IN TLS_AUTH_CONFIG_PRIVATE_DATA *PrivateData
> + )
> +{
> + RefreshUpdateData ();
> +
> + //
> + // Remove all op-codes from dynamic page
> + //
> + mStartLabel->Number = LabelId;
> + HiiUpdateForm (
> + PrivateData->RegisteredHandle,
> + &gTlsAuthConfigGuid,
> + LabelId,
> + mStartOpCodeHandle, // Label LabelId
> + mEndOpCodeHandle // LABEL_END
> + );
> +}
> +
> +/**
> + Update the form base on the selected file.
> +
> + @param FilePath Point to the file path.
> + @param FormId The form need to display.
> +
> + @retval TRUE Exit caller function.
> + @retval FALSE Not exit caller function.
> +
> +**/
> +BOOLEAN
> +UpdatePage(
> + IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
> + IN EFI_FORM_ID FormId
> + )
> +{
> + CHAR16 *FileName;
> + EFI_STRING_ID StringToken;
> +
> + FileName = NULL;
> +
> + if (FilePath != NULL) {
> + FileName = ExtractFileNameFromDevicePath(FilePath);
> + }
> + if (FileName == NULL) {
> + //
> + // FileName = NULL has two case:
> + // 1. FilePath == NULL, not select file.
> + // 2. FilePath != NULL, but ExtractFileNameFromDevicePath return NULL
> not enough memory resource.
> + // In these two case, no need to update the form, and exit the caller
> function.
> + //
> + return TRUE;
> + }
> + StringToken = HiiSetString (mTlsAuthPrivateData->RegisteredHandle, 0,
> FileName, NULL);
> +
> + mTlsAuthPrivateData->FileContext->FileName = FileName;
> +
> + OpenFileByDevicePath (
> + &FilePath,
> + &mTlsAuthPrivateData->FileContext->FHandle,
> + EFI_FILE_MODE_READ,
> + 0
> + );
> + //
> + // Create Subtitle op-code for the display string of the option.
> + //
> + RefreshUpdateData ();
> + mStartLabel->Number = FormId;
> +
> + HiiCreateSubTitleOpCode (
> + mStartOpCodeHandle,
> + StringToken,
> + 0,
> + 0,
> + 0
> + );
> +
> + HiiUpdateForm (
> + mTlsAuthPrivateData->RegisteredHandle,
> + &gTlsAuthConfigGuid,
> + FormId,
> + mStartOpCodeHandle, /// Label FormId
> + mEndOpCodeHandle /// LABEL_END
> + );
> +
> + return TRUE;
> +}
> +
> +/**
> + Update the form base on the input file path info.
> +
> + @param FilePath Point to the file path.
> +
> + @retval TRUE Exit caller function.
> + @retval FALSE Not exit caller function.
> +**/
> +BOOLEAN
> +UpdateCAFromFile (
> + IN EFI_DEVICE_PATH_PROTOCOL *FilePath
> + )
> +{
> + return UpdatePage(FilePath, TLS_AUTH_CONFIG_FORMID4_FORM);
> +}
> +
> +/**
> + Unload the configuration form, this includes: delete all the configuration
> + entries, uninstall the form callback protocol, and free the resources used.
> +
> + @param[in] Private Pointer to the driver private data.
> +
> + @retval EFI_SUCCESS The configuration form is unloaded.
> + @retval Others Failed to unload the form.
> +
> +**/
> +EFI_STATUS
> +TlsAuthConfigFormUnload (
> + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
> + )
> +{
> + if (Private->DriverHandle != NULL) {
> + //
> + // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
> + //
> + gBS->UninstallMultipleProtocolInterfaces (
> + Private->DriverHandle,
> + &gEfiDevicePathProtocolGuid,
> + &mTlsAuthConfigHiiVendorDevicePath,
> + &gEfiHiiConfigAccessProtocolGuid,
> + &Private->ConfigAccess,
> + NULL
> + );
> + Private->DriverHandle = NULL;
> + }
> +
> + if (Private->RegisteredHandle != NULL) {
> + //
> + // Remove HII package list
> + //
> + HiiRemovePackages (Private->RegisteredHandle);
> + Private->RegisteredHandle = NULL;
> + }
> +
> + if (Private->CertGuid != NULL) {
> + FreePool (Private->CertGuid);
> + }
> +
> + if (Private->FileContext != NULL) {
> + FreePool (Private->FileContext);
> + }
> +
> + FreePool (Private);
> +
> + if (mStartOpCodeHandle != NULL) {
> + HiiFreeOpCodeHandle (mStartOpCodeHandle);
> + }
> +
> + if (mEndOpCodeHandle != NULL) {
> + HiiFreeOpCodeHandle (mEndOpCodeHandle);
> + }
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + Initialize the configuration form.
> +
> + @param[in] Private Pointer to the driver private data.
> +
> + @retval EFI_SUCCESS The configuration form is initialized.
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
> +
> +**/
> +EFI_STATUS
> +TlsAuthConfigFormInit (
> + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
> + )
> +{
> + EFI_STATUS Status;
> +
> + Private->Signature = TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE;
> +
> + Private->ConfigAccess.ExtractConfig = TlsAuthConfigAccessExtractConfig;
> + Private->ConfigAccess.RouteConfig = TlsAuthConfigAccessRouteConfig;
> + Private->ConfigAccess.Callback = TlsAuthConfigAccessCallback;
> +
> + //
> + // Install Device Path Protocol and Config Access protocol to driver handle.
> + //
> + Status = gBS->InstallMultipleProtocolInterfaces (
> + &Private->DriverHandle,
> + &gEfiDevicePathProtocolGuid,
> + &mTlsAuthConfigHiiVendorDevicePath,
> + &gEfiHiiConfigAccessProtocolGuid,
> + &Private->ConfigAccess,
> + NULL
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Publish our HII data.
> + //
> + Private->RegisteredHandle = HiiAddPackages (
> + &gTlsAuthConfigGuid,
> + Private->DriverHandle,
> + TlsAuthConfigDxeStrings,
> + TlsAuthConfigVfrBin,
> + NULL
> + );
> + if (Private->RegisteredHandle == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error;
> + }
> +
> + Private->FileContext = AllocateZeroPool (sizeof
> (TLS_AUTH_CONFIG_FILE_CONTEXT));
> + if (Private->FileContext == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error;
> + }
> +
> + //
> + // Init OpCode Handle and Allocate space for creation of Buffer
> + //
> + mStartOpCodeHandle = HiiAllocateOpCodeHandle ();
> + if (mStartOpCodeHandle == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error;
> + }
> +
> + mEndOpCodeHandle = HiiAllocateOpCodeHandle ();
> + if (mEndOpCodeHandle == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error;
> + }
> +
> + //
> + // Create Hii Extend Label OpCode as the start opcode
> + //
> + mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
> + mStartOpCodeHandle,
> + &gEfiIfrTianoGuid,
> + NULL,
> + sizeof (EFI_IFR_GUID_LABEL)
> + );
> + mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> +
> + //
> + // Create Hii Extend Label OpCode as the end opcode
> + //
> + mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
> + mEndOpCodeHandle,
> + &gEfiIfrTianoGuid,
> + NULL,
> + sizeof (EFI_IFR_GUID_LABEL)
> + );
> + mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
> + mEndLabel->Number = LABEL_END;
> +
> + return EFI_SUCCESS;
> +
> +Error:
> + TlsAuthConfigFormUnload (Private);
> + return Status;
> +}
> +
> +/**
> +
> + This function allows the caller to request the current
> + configuration for one or more named elements. The resulting
> + string is in <ConfigAltResp> format. Any and all alternative
> + configuration strings shall also be appended to the end of the
> + current configuration string. If they are, they must appear
> + after the current configuration. They must contain the same
> + routing (GUID, NAME, PATH) as the current configuration string.
> + They must have an additional description indicating the type of
> + alternative configuration the string represents,
> + "ALTCFG=<StringToken>". That <StringToken> (when
> + converted from Hex UNICODE to binary) is a reference to a
> + string in the associated string pack.
> +
> + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +
> + @param Request A null-terminated Unicode string in
> + <ConfigRequest> format. Note that this
> + includes the routing information as well as
> + the configurable name / value pairs. It is
> + invalid for this string to be in
> + <MultiConfigRequest> format.
> + If a NULL is passed in for the Request field,
> + all of the settings being abstracted by this function
> + will be returned in the Results field. In addition,
> + if a ConfigHdr is passed in with no request elements,
> + all of the settings being abstracted for that particular
> + ConfigHdr reference will be returned in the Results Field.
> +
> + @param Progress On return, points to a character in the
> + Request string. Points to the string's null
> + terminator if request was successful. Points
> + to the most recent "&" before the first
> + failing name / value pair (or the beginning
> + of the string if the failure is in the first
> + name / value pair) if the request was not
> + successful.
> +
> + @param Results A null-terminated Unicode string in
> + <MultiConfigAltResp> format which has all values
> + filled in for the names in the Request string.
> + String to be allocated by the called function.
> +
> + @retval EFI_SUCCESS The Results string is filled with the
> + values corresponding to all requested
> + names.
> +
> + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
> + parts of the results that must be
> + stored awaiting possible future
> + protocols.
> +
> + @retval EFI_NOT_FOUND Routing data doesn't match any
> + known driver. Progress set to the
> + first character in the routing header.
> + Note: There is no requirement that the
> + driver validate the routing data. It
> + must skip the <ConfigHdr> in order to
> + process the names.
> +
> + @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
> + to most recent "&" before the
> + error or the beginning of the
> + string.
> +
> + @retval EFI_INVALID_PARAMETER Unknown name. Progress points
> + to the & before the name in
> + question.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsAuthConfigAccessExtractConfig (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN CONST EFI_STRING Request,
> + OUT EFI_STRING *Progress,
> + OUT EFI_STRING *Results
> + )
> +{
> + EFI_STATUS Status;
> + UINTN BufferSize;
> + UINTN Size;
> + EFI_STRING ConfigRequest;
> + EFI_STRING ConfigRequestHdr;
> + TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
> + BOOLEAN AllocatedRequest;
> +
> + if (Progress == NULL || Results == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + AllocatedRequest = FALSE;
> + ConfigRequestHdr = NULL;
> + ConfigRequest = NULL;
> + Size = 0;
> +
> + Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
> +
> + BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
> + ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
> +
> + *Progress = Request;
> +
> + if ((Request != NULL) && !HiiIsConfigHdrMatch (Request,
> &gTlsAuthConfigGuid, mTlsAuthConfigStorageName)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + ConfigRequest = Request;
> + if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
> + //
> + // Request is set to NULL or OFFSET is NULL, construct full request string.
> + //
> + // Allocate and fill a buffer large enough to hold the <ConfigHdr>
> template
> + // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW"
> followed by a Null-terminator
> + //
> + ConfigRequestHdr = HiiConstructConfigHdr (&gTlsAuthConfigGuid,
> mTlsAuthConfigStorageName, Private->DriverHandle);
> + Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
> + ConfigRequest = AllocateZeroPool (Size);
> + ASSERT (ConfigRequest != NULL);
> + AllocatedRequest = TRUE;
> + UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX",
> ConfigRequestHdr, (UINT64)BufferSize);
> + FreePool (ConfigRequestHdr);
> + ConfigRequestHdr = NULL;
> + }
> +
> + Status = gHiiConfigRouting->BlockToConfig (
> + gHiiConfigRouting,
> + ConfigRequest,
> + (UINT8 *) &Private->TlsAuthConfigNvData,
> + BufferSize,
> + Results,
> + Progress
> + );
> +
> + //
> + // Free the allocated config request string.
> + //
> + if (AllocatedRequest) {
> + FreePool (ConfigRequest);
> + }
> +
> + //
> + // Set Progress string to the original request string.
> + //
> + if (Request == NULL) {
> + *Progress = NULL;
> + } else if (StrStr (Request, L"OFFSET") == NULL) {
> + *Progress = Request + StrLen (Request);
> + }
> +
> + return Status;
> +}
> +
> +/**
> +
> + This function applies changes in a driver's configuration.
> + Input is a Configuration, which has the routing data for this
> + driver followed by name / value configuration pairs. The driver
> + must apply those pairs to its configurable storage. If the
> + driver's configuration is stored in a linear block of data
> + and the driver's name / value pairs are in <BlockConfig>
> + format, it may use the ConfigToBlock helper function (above) to
> + simplify the job.
> +
> + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +
> + @param Configuration A null-terminated Unicode string in
> + <ConfigString> format.
> +
> + @param Progress A pointer to a string filled in with the
> + offset of the most recent '&' before the
> + first failing name / value pair (or the
> + beginn ing of the string if the failure
> + is in the first name / value pair) or
> + the terminating NULL if all was
> + successful.
> +
> + @retval EFI_SUCCESS The results have been distributed or are
> + awaiting distribution.
> +
> + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
> + parts of the results that must be
> + stored awaiting possible future
> + protocols.
> +
> + @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
> + Results parameter would result
> + in this type of error.
> +
> + @retval EFI_NOT_FOUND Target for the specified routing data
> + was not found
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsAuthConfigAccessRouteConfig (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN CONST EFI_STRING Configuration,
> + OUT EFI_STRING *Progress
> + )
> +{
> + EFI_STATUS Status;
> + UINTN BufferSize;
> + TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
> +
> + if (Progress == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + *Progress = Configuration;
> +
> + if (Configuration == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + //
> + // Check routing data in <ConfigHdr>.
> + // Note: there is no name for Name/Value storage, only GUID will be
> checked
> + //
> + if (!HiiIsConfigHdrMatch (Configuration, &gTlsAuthConfigGuid,
> mTlsAuthConfigStorageName)) {
> + return EFI_NOT_FOUND;
> + }
> +
> + Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
> +
> + BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
> + ZeroMem (&Private->TlsAuthConfigNvData, BufferSize);
> +
> + Status = gHiiConfigRouting->ConfigToBlock (
> + gHiiConfigRouting,
> + Configuration,
> + (UINT8 *) &Private->TlsAuthConfigNvData,
> + &BufferSize,
> + Progress
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + return Status;
> +}
> +
> +/**
> +
> + This function is called to provide results data to the driver.
> + This data consists of a unique key that is used to identify
> + which data is either being passed back or being asked for.
> +
> + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> + @param Action Specifies the type of action taken by the browser.
> + @param QuestionId A unique value which is sent to the original
> + exporting driver so that it can identify the type
> + of data to expect. The format of the data tends to
> + vary based on the opcode that generated the callback.
> + @param Type The type of value for the question.
> + @param Value A pointer to the data being sent to the original
> + exporting driver.
> + @param ActionRequest On return, points to the action requested by
> the
> + callback function.
> +
> + @retval EFI_SUCCESS The callback successfully handled the action.
> + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold
> the
> + variable and its data.
> + @retval EFI_DEVICE_ERROR The variable could not be saved.
> + @retval EFI_UNSUPPORTED The specified Action is not supported by
> the
> + callback.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsAuthConfigAccessCallback (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN EFI_BROWSER_ACTION Action,
> + IN EFI_QUESTION_ID QuestionId,
> + IN UINT8 Type,
> + IN OUT EFI_IFR_TYPE_VALUE *Value,
> + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
> + )
> +{
> + EFI_INPUT_KEY Key;
> + EFI_STATUS Status;
> + TLS_AUTH_CONFIG_PRIVATE_DATA *Private;
> + UINTN BufferSize;
> + TLS_AUTH_CONFIG_IFR_NVDATA *IfrNvData;
> + UINT16 LabelId;
> + EFI_DEVICE_PATH_PROTOCOL *File;
> +
> + Status = EFI_SUCCESS;
> + File = NULL;
> +
> + if ((This == NULL) || (Value == NULL) || (ActionRequest == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + Private = TLS_AUTH_CONFIG_PRIVATE_FROM_THIS (This);
> +
> + mTlsAuthPrivateData = Private;
> +
> + //
> + // Retrieve uncommitted data from Browser
> + //
> + BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
> + IfrNvData = AllocateZeroPool (BufferSize);
> + if (IfrNvData == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + HiiGetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName,
> BufferSize, (UINT8 *) IfrNvData);
> +
> + if ((Action != EFI_BROWSER_ACTION_CHANGED) &&
> + (Action != EFI_BROWSER_ACTION_CHANGING)) {
> + Status = EFI_UNSUPPORTED;
> + goto EXIT;
> + }
> +
> + if (Action == EFI_BROWSER_ACTION_CHANGING) {
> + switch (QuestionId) {
> + case KEY_TLS_AUTH_CONFIG_CLIENT_CERT:
> + case KEY_TLS_AUTH_CONFIG_SERVER_CA:
> + //
> + // Clear Cert GUID.
> + //
> + ZeroMem (IfrNvData->CertGuid, sizeof (IfrNvData->CertGuid));
> + if (Private->CertGuid == NULL) {
> + Private->CertGuid = (EFI_GUID *) AllocateZeroPool (sizeof (EFI_GUID));
> + if (Private->CertGuid == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> + }
> + if (QuestionId == KEY_TLS_AUTH_CONFIG_CLIENT_CERT) {
> + LabelId = TLS_AUTH_CONFIG_FORMID3_FORM;
> + } else if (QuestionId == KEY_TLS_AUTH_CONFIG_SERVER_CA) {
> + LabelId = TLS_AUTH_CONFIG_FORMID4_FORM;
> + }
> +
> + //
> + // Refresh selected file.
> + //
> + CleanUpPage (LabelId, Private);
> + break;
> + case KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE:
> + ChooseFile( NULL, NULL, (CHOOSE_HANDLER) UpdateCAFromFile, &File);
> + break;
> +
> + case KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT:
> + Status = EnrollCertDatabase (Private,
> EFI_TLS_CA_CERTIFICATE_VARIABLE);
> + if (EFI_ERROR (Status)) {
> + CreatePopUp (
> + EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
> + &Key,
> + L"ERROR: Enroll Cert Failure!",
> + NULL
> + );
> + }
> + break;
> +
> + case KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT:
> + if (Private->FileContext->FHandle != NULL) {
> + CloseFile (Private->FileContext->FHandle);
> + Private->FileContext->FHandle = NULL;
> + if (Private->FileContext->FileName!= NULL){
> + FreePool(Private->FileContext->FileName);
> + Private->FileContext->FileName = NULL;
> + }
> + }
> +
> + if (Private->CertGuid!= NULL) {
> + FreePool (Private->CertGuid);
> + Private->CertGuid = NULL;
> + }
> + break;
> +
> + case KEY_TLS_AUTH_CONFIG_DELETE_CERT:
> + UpdateDeletePage (
> + Private,
> + EFI_TLS_CA_CERTIFICATE_VARIABLE,
> + &gEfiTlsCaCertificateGuid,
> + LABEL_CA_DELETE,
> + TLS_AUTH_CONFIG_FORMID5_FORM,
> + OPTION_DEL_CA_ESTION_ID
> + );
> + break;
> +
> + default:
> + if ((QuestionId >= OPTION_DEL_CA_ESTION_ID) &&
> + (QuestionId < (OPTION_DEL_CA_ESTION_ID +
> OPTION_CONFIG_RANGE))) {
> + DeleteCert (
> + Private,
> + EFI_TLS_CA_CERTIFICATE_VARIABLE,
> + &gEfiTlsCaCertificateGuid,
> + LABEL_CA_DELETE,
> + TLS_AUTH_CONFIG_FORMID5_FORM,
> + OPTION_DEL_CA_ESTION_ID,
> + QuestionId - OPTION_DEL_CA_ESTION_ID
> + );
> + }
> + break;
> + }
> + } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
> + switch (QuestionId) {
> + case KEY_TLS_AUTH_CONFIG_CERT_GUID:
> + ASSERT (Private->CertGuid != NULL);
> + Status = StringToGuid (
> + IfrNvData->CertGuid,
> + StrLen (IfrNvData->CertGuid),
> + Private->CertGuid
> + );
> + if (EFI_ERROR (Status)) {
> + break;
> + }
> +
> + *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
> + break;
> + default:
> + break;
> + }
> + }
> +
> +EXIT:
> +
> + if (!EFI_ERROR (Status)) {
> + BufferSize = sizeof (TLS_AUTH_CONFIG_IFR_NVDATA);
> + HiiSetBrowserData (&gTlsAuthConfigGuid, mTlsAuthConfigStorageName,
> BufferSize, (UINT8*) IfrNvData, NULL);
> + }
> +
> + FreePool (IfrNvData);
> +
> + if (File != NULL){
> + FreePool(File);
> + File = NULL;
> + }
> +
> + return EFI_SUCCESS;
> +
> +}
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
> new file mode 100644
> index 0000000..398f7b6
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigImpl.h
> @@ -0,0 +1,282 @@
> +/** @file
> + Header file of Miscellaneous Routines for TlsAuthConfigDxe driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __TLS_AUTH_CONFIG_IMPL_H__
> +#define __TLS_AUTH_CONFIG_IMPL_H__
> +
> +#include <Uefi.h>
> +
> +#include <Protocol/HiiConfigAccess.h>
> +#include <Protocol/SimpleFileSystem.h>
> +
> +//
> +// Libraries
> +//
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/HiiLib.h>
> +#include <Library/UefiHiiServicesLib.h>
> +#include <Library/FileExplorerLib.h>
> +#include <Library/PrintLib.h>
> +
> +#include <Guid/MdeModuleHii.h>
> +#include <Guid/ImageAuthentication.h>
> +#include <Guid/TlsAuthentication.h>
> +
> +
> +//
> +// Include files with function prototypes
> +//
> +#include "TlsAuthConfigNvData.h"
> +
> +extern UINT8 TlsAuthConfigDxeStrings[];
> +extern UINT8 TlsAuthConfigVfrBin[];
> +
> +#define TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE SIGNATURE_32
> ('T', 'A', 'C', 'D')
> +#define TLS_AUTH_CONFIG_PRIVATE_FROM_THIS(a) CR (a,
> TLS_AUTH_CONFIG_PRIVATE_DATA, ConfigAccess,
> TLS_AUTH_CONFIG_PRIVATE_DATA_SIGNATURE)
> +
> +#define TLS_AUTH_CONFIG_VAR_BASE_ATTR
> (EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS)
> +
> +typedef struct _TLS_AUTH_CONFIG_PRIVATE_DATA
> TLS_AUTH_CONFIG_PRIVATE_DATA;
> +typedef struct _TLS_AUTH_CONFIG_FILE_CONTEXT
> TLS_AUTH_CONFIG_FILE_CONTEXT;
> +
> +///
> +/// HII specific Vendor Device Path definition.
> +///
> +typedef struct {
> + VENDOR_DEVICE_PATH VendorDevicePath;
> + EFI_DEVICE_PATH_PROTOCOL End;
> +} HII_VENDOR_DEVICE_PATH;
> +
> +struct _TLS_AUTH_CONFIG_FILE_CONTEXT {
> + EFI_FILE_HANDLE FHandle;
> + UINT16 *FileName;
> +};
> +
> +struct _TLS_AUTH_CONFIG_PRIVATE_DATA {
> + UINTN Signature;
> +
> + EFI_HANDLE DriverHandle;
> + EFI_HII_HANDLE RegisteredHandle;
> + EFI_HII_CONFIG_ACCESS_PROTOCOL ConfigAccess;
> + TLS_AUTH_CONFIG_IFR_NVDATA TlsAuthConfigNvData;
> +
> + TLS_AUTH_CONFIG_FILE_CONTEXT *FileContext;
> +
> + EFI_GUID *CertGuid;
> +};
> +
> +/**
> + Unload the configuration form, this includes: delete all the configuration
> + entries, uninstall the form callback protocol, and free the resources used.
> + The form will only be unload completely when both IP4 and IP6 stack are
> stopped.
> +
> + @param[in] Private Pointer to the driver private data.
> +
> + @retval EFI_SUCCESS The configuration form is unloaded.
> + @retval Others Failed to unload the form.
> +
> +**/
> +EFI_STATUS
> +TlsAuthConfigFormUnload (
> + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
> + );
> +
> +/**
> + Initialize the configuration form.
> +
> + @param[in] Private Pointer to the driver private data.
> +
> + @retval EFI_SUCCESS The configuration form is initialized.
> + @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
> +
> +**/
> +EFI_STATUS
> +TlsAuthConfigFormInit (
> + IN TLS_AUTH_CONFIG_PRIVATE_DATA *Private
> + );
> +
> +/**
> +
> + This function allows the caller to request the current
> + configuration for one or more named elements. The resulting
> + string is in <ConfigAltResp> format. Any and all alternative
> + configuration strings shall also be appended to the end of the
> + current configuration string. If they are, they must appear
> + after the current configuration. They must contain the same
> + routing (GUID, NAME, PATH) as the current configuration string.
> + They must have an additional description indicating the type of
> + alternative configuration the string represents,
> + "ALTCFG=<StringToken>". That <StringToken> (when
> + converted from Hex UNICODE to binary) is a reference to a
> + string in the associated string pack.
> +
> + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +
> + @param Request A null-terminated Unicode string in
> + <ConfigRequest> format. Note that this
> + includes the routing information as well as
> + the configurable name / value pairs. It is
> + invalid for this string to be in
> + <MultiConfigRequest> format.
> + If a NULL is passed in for the Request field,
> + all of the settings being abstracted by this function
> + will be returned in the Results field. In addition,
> + if a ConfigHdr is passed in with no request elements,
> + all of the settings being abstracted for that particular
> + ConfigHdr reference will be returned in the Results Field.
> +
> + @param Progress On return, points to a character in the
> + Request string. Points to the string's null
> + terminator if request was successful. Points
> + to the most recent "&" before the first
> + failing name / value pair (or the beginning
> + of the string if the failure is in the first
> + name / value pair) if the request was not
> + successful.
> +
> + @param Results A null-terminated Unicode string in
> + <MultiConfigAltResp> format which has all values
> + filled in for the names in the Request string.
> + String to be allocated by the called function.
> +
> + @retval EFI_SUCCESS The Results string is filled with the
> + values corresponding to all requested
> + names.
> +
> + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
> + parts of the results that must be
> + stored awaiting possible future
> + protocols.
> +
> + @retval EFI_NOT_FOUND Routing data doesn't match any
> + known driver. Progress set to the
> + first character in the routing header.
> + Note: There is no requirement that the
> + driver validate the routing data. It
> + must skip the <ConfigHdr> in order to
> + process the names.
> +
> + @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
> + to most recent "&" before the
> + error or the beginning of the
> + string.
> +
> + @retval EFI_INVALID_PARAMETER Unknown name. Progress points
> + to the & before the name in
> + question.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsAuthConfigAccessExtractConfig (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN CONST EFI_STRING Request,
> + OUT EFI_STRING *Progress,
> + OUT EFI_STRING *Results
> + );
> +
> +/**
> +
> + This function applies changes in a driver's configuration.
> + Input is a Configuration, which has the routing data for this
> + driver followed by name / value configuration pairs. The driver
> + must apply those pairs to its configurable storage. If the
> + driver's configuration is stored in a linear block of data
> + and the driver's name / value pairs are in <BlockConfig>
> + format, it may use the ConfigToBlock helper function (above) to
> + simplify the job.
> +
> + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> +
> + @param Configuration A null-terminated Unicode string in
> + <ConfigString> format.
> +
> + @param Progress A pointer to a string filled in with the
> + offset of the most recent '&' before the
> + first failing name / value pair (or the
> + beginn ing of the string if the failure
> + is in the first name / value pair) or
> + the terminating NULL if all was
> + successful.
> +
> + @retval EFI_SUCCESS The results have been distributed or are
> + awaiting distribution.
> +
> + @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
> + parts of the results that must be
> + stored awaiting possible future
> + protocols.
> +
> + @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
> + Results parameter would result
> + in this type of error.
> +
> + @retval EFI_NOT_FOUND Target for the specified routing data
> + was not found
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsAuthConfigAccessRouteConfig (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN CONST EFI_STRING Configuration,
> + OUT EFI_STRING *Progress
> + );
> +
> +/**
> +
> + This function is called to provide results data to the driver.
> + This data consists of a unique key that is used to identify
> + which data is either being passed back or being asked for.
> +
> + @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
> + @param Action Specifies the type of action taken by the browser.
> + @param QuestionId A unique value which is sent to the original
> + exporting driver so that it can identify the type
> + of data to expect. The format of the data tends to
> + vary based on the opcode that generated the callback.
> + @param Type The type of value for the question.
> + @param Value A pointer to the data being sent to the original
> + exporting driver.
> + @param ActionRequest On return, points to the action requested by
> the
> + callback function.
> +
> + @retval EFI_SUCCESS The callback successfully handled the action.
> + @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold
> the
> + variable and its data.
> + @retval EFI_DEVICE_ERROR The variable could not be saved.
> + @retval EFI_UNSUPPORTED The specified Action is not supported by
> the
> + callback.
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsAuthConfigAccessCallback (
> + IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
> + IN EFI_BROWSER_ACTION Action,
> + IN EFI_QUESTION_ID QuestionId,
> + IN UINT8 Type,
> + IN OUT EFI_IFR_TYPE_VALUE *Value,
> + OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
> + );
> +
> +#endif
> +
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
> new file mode 100644
> index 0000000..f453201
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigNvData.h
> @@ -0,0 +1,49 @@
> +/** @file
> + Header file for NV data structure definition.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __TLS_AUTH_CONFIG_NV_DATA_H__
> +#define __TLS_AUTH_CONFIG_NV_DATA_H__
> +
> +#include <Guid/TlsAuthConfigHii.h>
> +
> +#define TLS_AUTH_CONFIG_GUID_SIZE 36
> +#define TLS_AUTH_CONFIG_GUID_STORAGE_SIZE 37
> +
> +#define TLS_AUTH_CONFIG_FORMID1_FORM 1
> +#define TLS_AUTH_CONFIG_FORMID2_FORM 2
> +#define TLS_AUTH_CONFIG_FORMID3_FORM 3
> +#define TLS_AUTH_CONFIG_FORMID4_FORM 4
> +#define TLS_AUTH_CONFIG_FORMID5_FORM 5
> +
> +
> +#define KEY_TLS_AUTH_CONFIG_SERVER_CA 0x1000
> +#define KEY_TLS_AUTH_CONFIG_CLIENT_CERT 0x1001
> +#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT 0x1002
> +#define KEY_TLS_AUTH_CONFIG_DELETE_CERT 0x1003
> +#define KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE 0x1004
> +#define KEY_TLS_AUTH_CONFIG_CERT_GUID 0x1005
> +#define KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT 0x1006
> +#define KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT 0x1007
> +
> +#define OPTION_DEL_CA_ESTION_ID 0x2000
> +#define OPTION_CONFIG_RANGE 0x1000
> +
> +#define LABEL_CA_DELETE 0x1101
> +#define LABEL_END 0xffff
> +
> +typedef struct {
> + CHAR16 CertGuid[TLS_AUTH_CONFIG_GUID_STORAGE_SIZE];
> +} TLS_AUTH_CONFIG_IFR_NVDATA;
> +
> +#endif
> diff --git a/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
> b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
> new file mode 100644
> index 0000000..fb130d9
> --- /dev/null
> +++ b/NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigVfr.vfr
> @@ -0,0 +1,152 @@
> +/** @file
> + VFR file used by TlsAuthConfigDxe driver.
> +
> + Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +
> + This program and the accompanying materials
> + are licensed and made available under the terms and conditions of the BSD
> License
> + which accompanies this distribution. The full text of the license may be
> found at
> + http://opensource.org/licenses/bsd-license.php.
> +
> + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "TlsAuthConfigNvData.h"
> +
> +formset
> + guid = TLS_AUTH_CONFIG_GUID,
> + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE),
> + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_HELP),
> +
> + varstore TLS_AUTH_CONFIG_IFR_NVDATA,
> + name = TLS_AUTH_CONFIG_IFR_NVDATA,
> + guid = TLS_AUTH_CONFIG_GUID;
> +
> + //
> + // ##1 Form1: Main form for Tls Auth configration
> + //
> + form formid = TLS_AUTH_CONFIG_FORMID1_FORM,
> + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_TITLE);
> +
> + subtitle text = STRING_TOKEN(STR_NULL);
> +
> + //
> + // Display Server CA configration
> + //
> + goto TLS_AUTH_CONFIG_FORMID2_FORM,
> + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA),
> + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA_HELP),
> + flags = INTERACTIVE,
> + key = KEY_TLS_AUTH_CONFIG_SERVER_CA;
> +
> + subtitle text = STRING_TOKEN(STR_NULL);
> +
> + //
> + // Display Client cert configration
> + //
> + grayoutif TRUE; /// Current unsupported.
> + goto TLS_AUTH_CONFIG_FORMID3_FORM,
> + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT),
> + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT_HELP),
> + flags = INTERACTIVE,
> + key = KEY_TLS_AUTH_CONFIG_CLIENT_CERT;
> + endif;
> + endform;
> +
> + //
> + // ##2 Form2: CA configuration
> + //
> + form formid = TLS_AUTH_CONFIG_FORMID2_FORM,
> + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SERVER_CA);
> +
> + subtitle text = STRING_TOKEN(STR_NULL);
> +
> + goto TLS_AUTH_CONFIG_FORMID4_FORM,
> + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT),
> + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT_HELP),
> + flags = INTERACTIVE,
> + key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT;
> +
> + subtitle text = STRING_TOKEN(STR_NULL);
> +
> + goto TLS_AUTH_CONFIG_FORMID5_FORM,
> + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT),
> + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT_HELP),
> + flags = INTERACTIVE,
> + key = KEY_TLS_AUTH_CONFIG_DELETE_CERT;
> + endform;
> +
> + //
> + // ##3 Form3 : Client cert configuration
> + //
> + form formid = TLS_AUTH_CONFIG_FORMID3_FORM,
> + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CLIENT_CERT);
> +
> + subtitle text = STRING_TOKEN(STR_NULL);
> +
> + //
> + // TODO...
> + //
> + endform;
> +
> + //
> + // ##4 Form4: Enroll cert for CA
> + //
> + form formid = TLS_AUTH_CONFIG_FORMID4_FORM,
> + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ENROLL_CERT);
> +
> + subtitle text = STRING_TOKEN(STR_NULL);
> +
> + goto TLS_AUTH_CONFIG_FORMID4_FORM,
> + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
> + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_ADD_CERT_FILE),
> + flags = INTERACTIVE,
> + key = KEY_TLS_AUTH_CONFIG_ENROLL_CERT_FROM_FILE;
> +
> + subtitle text = STRING_TOKEN(STR_NULL);
> + label TLS_AUTH_CONFIG_FORMID4_FORM;
> + label LABEL_END;
> + subtitle text = STRING_TOKEN(STR_NULL);
> +
> + string varid = TLS_AUTH_CONFIG_IFR_NVDATA.CertGuid,
> + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID),
> + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_CERT_GUID_HELP),
> + flags = INTERACTIVE,
> + key = KEY_TLS_AUTH_CONFIG_CERT_GUID,
> + minsize = TLS_AUTH_CONFIG_GUID_SIZE,
> + maxsize = TLS_AUTH_CONFIG_GUID_SIZE,
> + endstring;
> +
> + subtitle text = STRING_TOKEN(STR_NULL);
> + subtitle text = STRING_TOKEN(STR_NULL);
> +
> + goto TLS_AUTH_CONFIG_FORMID1_FORM,
> + prompt = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
> + help = STRING_TOKEN(STR_TLS_AUTH_CONFIG_SAVE_AND_EXIT),
> + flags = INTERACTIVE,
> + key = KEY_TLS_AUTH_CONFIG_VALUE_SAVE_AND_EXIT;
> +
> + goto TLS_AUTH_CONFIG_FORMID1_FORM,
> + prompt =
> STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
> + help =
> STRING_TOKEN(STR_TLS_AUTH_CONFIG_NO_SAVE_AND_EXIT),
> + flags = INTERACTIVE,
> + key = KEY_TLS_AUTH_CONFIG_VALUE_NO_SAVE_AND_EXIT;
> +
> + endform;
> +
> + //
> + // ##5 Form5: Delete cert for CA
> + //
> + form formid = TLS_AUTH_CONFIG_FORMID5_FORM,
> + title = STRING_TOKEN(STR_TLS_AUTH_CONFIG_DELETE_CERT);
> +
> + label LABEL_CA_DELETE;
> + label LABEL_END;
> +
> + subtitle text = STRING_TOKEN(STR_NULL);
> +
> + endform;
> +
> +endformset;
> --
> 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
` (5 preceding siblings ...)
2016-12-14 7:34 ` [Patch 06/10] NetworkPkg/TlsAuthConfigDxe: Provide the UI to support TLS auth configuration Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-15 2:39 ` Fu, Siyuan
2016-12-22 7:33 ` Ye, Ting
2016-12-14 7:34 ` [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module Jiaxin Wu
` (2 subsequent siblings)
9 siblings, 2 replies; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Ye Ting, Fu Siyuan, Zhang Lubo, Long Qin, Thomas Palmer,
Wu Jiaxin
This patch is used to enable HTTPS feature. HttpDxe driver
will consume TlsDxe driver. It can both support http and https
feature, that’s depended on the information of URL, the HTTP
instance can be able to determine whether to use http or https.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/HttpDxe/HttpDriver.h | 10 +-
NetworkPkg/HttpDxe/HttpDxe.inf | 12 +-
NetworkPkg/HttpDxe/HttpImpl.c | 252 +++++-
NetworkPkg/HttpDxe/HttpProto.c | 464 +++++++---
NetworkPkg/HttpDxe/HttpProto.h | 65 +-
NetworkPkg/HttpDxe/HttpsSupport.c | 1692 +++++++++++++++++++++++++++++++++++++
NetworkPkg/HttpDxe/HttpsSupport.h | 260 ++++++
7 files changed, 2601 insertions(+), 154 deletions(-)
create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.c
create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.h
diff --git a/NetworkPkg/HttpDxe/HttpDriver.h b/NetworkPkg/HttpDxe/HttpDriver.h
index fa2372c..93a412a 100644
--- a/NetworkPkg/HttpDxe/HttpDriver.h
+++ b/NetworkPkg/HttpDxe/HttpDriver.h
@@ -22,10 +22,11 @@
//
// Libraries
//
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/NetLib.h>
@@ -48,17 +49,23 @@
#include <Protocol/Tcp6.h>
#include <Protocol/Dns4.h>
#include <Protocol/Dns6.h>
#include <Protocol/Ip4Config2.h>
#include <Protocol/Ip6Config.h>
+#include <Protocol/Tls.h>
+#include <Protocol/TlsConfig.h>
-
+#include <Guid/ImageAuthentication.h>
//
// Produced Protocols
//
#include <Protocol/Http.h>
+#include <Guid/TlsAuthentication.h>
+
+#include <IndustryStandard/Tls1.h>
+
//
// Driver Version
//
#define HTTP_DRIVER_VERSION 0xa
@@ -77,10 +84,11 @@ extern EFI_HTTP_UTILITIES_PROTOCOL *mHttpUtilities;
// Include files with function prototypes
//
#include "ComponentName.h"
#include "HttpImpl.h"
#include "HttpProto.h"
+#include "HttpsSupport.h"
#include "HttpDns.h"
typedef struct {
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UINTN NumberOfChildren;
diff --git a/NetworkPkg/HttpDxe/HttpDxe.inf b/NetworkPkg/HttpDxe/HttpDxe.inf
index bf2cbee..1118181 100644
--- a/NetworkPkg/HttpDxe/HttpDxe.inf
+++ b/NetworkPkg/HttpDxe/HttpDxe.inf
@@ -1,9 +1,9 @@
## @file
# Implementation of EFI HTTP protocol interfaces.
#
-# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
@@ -24,10 +24,11 @@
MODULE_UNI_FILE = HttpDxe.uni
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
[Sources]
ComponentName.h
ComponentName.c
HttpDns.h
@@ -36,14 +37,17 @@
HttpDriver.c
HttpImpl.h
HttpImpl.c
HttpProto.h
HttpProto.c
+ HttpsSupport.h
+ HttpsSupport.c
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
MemoryAllocationLib
BaseLib
UefiLib
DebugLib
NetLib
@@ -62,8 +66,14 @@
gEfiDns4ProtocolGuid ## SOMETIMES_CONSUMES
gEfiDns6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
gEfiDns6ProtocolGuid ## SOMETIMES_CONSUMES
gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTlsServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTlsProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTlsConfigurationProtocolGuid ## SOMETIMES_CONSUMES
+
+[Guids]
+ gEfiTlsCaCertificateGuid ## CONSUMES ## GUID
[UserExtensions.TianoCore."ExtraFiles"]
HttpDxeExtra.uni
\ No newline at end of file
diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c
index 6fcb0b7..77aa64a 100644
--- a/NetworkPkg/HttpDxe/HttpImpl.c
+++ b/NetworkPkg/HttpDxe/HttpImpl.c
@@ -239,10 +239,11 @@ EfiHttpRequest (
UINTN HostNameSize;
UINT16 RemotePort;
HTTP_PROTOCOL *HttpInstance;
BOOLEAN Configure;
BOOLEAN ReConfigure;
+ BOOLEAN TlsConfigure;
CHAR8 *RequestMsg;
CHAR8 *Url;
UINTN UrlLen;
CHAR16 *HostNameStr;
HTTP_TOKEN_WRAP *Wrap;
@@ -258,10 +259,11 @@ EfiHttpRequest (
HostName = NULL;
RequestMsg = NULL;
HostNameStr = NULL;
Wrap = NULL;
FileUrl = NULL;
+ TlsConfigure = FALSE;
if ((This == NULL) || (Token == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -343,10 +345,36 @@ EfiHttpRequest (
HttpInstance->Url = Url;
}
UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);
+
+ //
+ // From the information in Url, the HTTP instance will
+ // be able to determine whether to use http or https.
+ //
+ HttpInstance->UseHttps = IsHttpsUrl (Url);
+
+ //
+ // Check whether we need to create Tls child and open the TLS protocol.
+ //
+ if (HttpInstance->UseHttps && HttpInstance->TlsChildHandle == NULL) {
+ //
+ // Use TlsSb to create Tls child and open the TLS protocol.
+ //
+ HttpInstance->TlsChildHandle = TlsCreateChild (
+ HttpInstance->Service->ImageHandle,
+ &(HttpInstance->Tls),
+ &(HttpInstance->TlsConfiguration)
+ );
+ if (HttpInstance->TlsChildHandle == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ TlsConfigure = TRUE;
+ }
+
UrlParser = NULL;
Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser);
if (EFI_ERROR (Status)) {
goto Error1;
}
@@ -357,11 +385,15 @@ EfiHttpRequest (
goto Error1;
}
Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
if (EFI_ERROR (Status)) {
- RemotePort = HTTP_DEFAULT_PORT;
+ if (HttpInstance->UseHttps) {
+ RemotePort = HTTPS_DEFAULT_PORT;
+ } else {
+ RemotePort = HTTP_DEFAULT_PORT;
+ }
}
//
// If Configure is TRUE, it indicates the first time to call Request();
// If ReConfigure is TRUE, it indicates the request URL is not same
// with the previous call to Request();
@@ -374,13 +406,17 @@ EfiHttpRequest (
// Request() is called the first time.
//
ReConfigure = FALSE;
} else {
if ((HttpInstance->RemotePort == RemotePort) &&
- (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) {
+ (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&
+ (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&
+ !TlsConfigure &&
+ HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))) {
//
// Host Name and port number of the request URL are the same with previous call to Request().
+ // If Https protocol used, the corresponding SessionState is EfiTlsSessionDataTransferring.
// Check whether previous TCP packet sent out.
//
if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) {
//
@@ -480,10 +516,20 @@ EfiHttpRequest (
if (!HttpInstance->LocalAddressIsIPv6) {
ASSERT (HttpInstance->Tcp4 != NULL);
} else {
ASSERT (HttpInstance->Tcp6 != NULL);
}
+
+ if (HttpInstance->UseHttps && !TlsConfigure) {
+ Status = TlsCloseSession (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ goto Error1;
+ }
+
+ TlsCloseTxRxEvent (HttpInstance);
+ }
+
HttpCloseConnection (HttpInstance);
EfiHttpCancel (This, NULL);
}
//
@@ -498,17 +544,22 @@ EfiHttpRequest (
Wrap->HttpToken = Token;
Wrap->HttpInstance = HttpInstance;
if (Request != NULL) {
Wrap->TcpWrap.Method = Request->Method;
}
-
- Status = HttpInitTcp (HttpInstance, Wrap, Configure);
+
+ Status = HttpInitSession (
+ HttpInstance,
+ Wrap,
+ Configure || ReConfigure,
+ TlsConfigure
+ );
if (EFI_ERROR (Status)) {
goto Error2;
- }
+ }
- if (!Configure) {
+ if (!Configure && !ReConfigure && !TlsConfigure) {
//
// For the new HTTP token, create TX TCP token events.
//
Status = HttpCreateTcpTxEvent (Wrap);
if (EFI_ERROR (Status)) {
@@ -591,13 +642,18 @@ Error4:
if (RequestMsg != NULL) {
FreePool (RequestMsg);
}
Error3:
- HttpCloseConnection (HttpInstance);
+ if (HttpInstance->UseHttps) {
+ TlsCloseSession (HttpInstance);
+ TlsCloseTxRxEvent (HttpInstance);
+ }
Error2:
+ HttpCloseConnection (HttpInstance);
+
HttpCloseTcpConnCloseEvent (HttpInstance);
if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {
gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL;
}
@@ -729,26 +785,34 @@ HttpCancel (
} else {
return Status;
}
}
- //
- // Then check the tokens queued by EfiHttpResponse().
- //
- Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens, Token);
- if (EFI_ERROR (Status)) {
- if (Token != NULL) {
- if (Status == EFI_ABORTED) {
- return EFI_SUCCESS;
+ if (!HttpInstance->UseHttps) {
+ //
+ // Then check the tokens queued by EfiHttpResponse(), except for Https.
+ //
+ Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens, Token);
+ if (EFI_ERROR (Status)) {
+ if (Token != NULL) {
+ if (Status == EFI_ABORTED) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_FOUND;
+ }
} else {
- return EFI_NOT_FOUND;
+ return Status;
}
+ }
+ } else {
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken);
} else {
- return Status;
+ HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);
}
}
-
+
return EFI_SUCCESS;
}
/**
@@ -880,10 +944,11 @@ HttpResponseWorker (
HTTP_PROTOCOL *HttpInstance;
EFI_HTTP_TOKEN *Token;
NET_MAP_ITEM *Item;
HTTP_TOKEN_WRAP *ValueInItem;
UINTN HdrLen;
+ NET_FRAGMENT Fragment;
if (Wrap == NULL || Wrap->HttpInstance == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -897,21 +962,15 @@ HttpResponseWorker (
HttpHeaders = NULL;
SizeofHeaders = 0;
BufferSize = 0;
EndofHeader = NULL;
ValueInItem = NULL;
+ Fragment.Len = 0;
+ Fragment.Bulk = NULL;
if (HttpMsg->Data.Response != NULL) {
//
- // Need receive the HTTP headers, prepare buffer.
- //
- Status = HttpCreateTcpRxEventForHeader (HttpInstance);
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- //
// Check whether we have cached header from previous call.
//
if ((HttpInstance->CacheBody != NULL) && (HttpInstance->NextMsg != NULL)) {
//
// The data is stored at [NextMsg, CacheBody + CacheLen].
@@ -1198,13 +1257,120 @@ HttpResponseWorker (
ASSERT (HttpInstance->MsgParser != NULL);
//
// We still need receive more data when there is no cache data and MsgParser is not NULL;
//
- Status = HttpTcpReceiveBody (Wrap, HttpMsg);
- if (EFI_ERROR (Status)) {
- goto Error2;
+ if (!HttpInstance->UseHttps) {
+ Status = HttpTcpReceiveBody (Wrap, HttpMsg);
+
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ } else {
+ if (HttpInstance->TimeoutEvent == NULL) {
+ //
+ // Create TimeoutEvent for response
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &HttpInstance->TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+ }
+
+ //
+ // Start the timer, and wait Timeout seconds to receive the body packet.
+ //
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ Status = HttpsReceive (HttpInstance, &Fragment, HttpInstance->TimeoutEvent);
+
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
+
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ //
+ // Check whether we receive a complete HTTP message.
+ //
+ Status = HttpParseMessageBody (
+ HttpInstance->MsgParser,
+ (UINTN) Fragment.Len,
+ (CHAR8 *) Fragment.Bulk
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
+ //
+ // Free the MsgParse since we already have a full HTTP message.
+ //
+ HttpFreeMsgParser (HttpInstance->MsgParser);
+ HttpInstance->MsgParser = NULL;
+ }
+
+ //
+ // We receive part of header of next HTTP msg.
+ //
+ if (HttpInstance->NextMsg != NULL) {
+ HttpMsg->BodyLength = MIN ((UINTN) (HttpInstance->NextMsg - (CHAR8 *) Fragment.Bulk), HttpMsg->BodyLength);
+ CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
+
+ HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
+ if (HttpInstance->CacheLen != 0) {
+ if (HttpInstance->CacheBody != NULL) {
+ FreePool (HttpInstance->CacheBody);
+ }
+
+ HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
+ if (HttpInstance->CacheBody == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error2;
+ }
+
+ CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
+ HttpInstance->CacheOffset = 0;
+
+ HttpInstance->NextMsg = HttpInstance->CacheBody + (UINTN) (HttpInstance->NextMsg - (CHAR8 *) (Fragment.Bulk + HttpMsg->BodyLength));
+ }
+ } else {
+ HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);
+ CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
+ HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
+ if (HttpInstance->CacheLen != 0) {
+ if (HttpInstance->CacheBody != NULL) {
+ FreePool (HttpInstance->CacheBody);
+ }
+
+ HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
+ if (HttpInstance->CacheBody == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error2;
+ }
+
+ CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
+ HttpInstance->CacheOffset = 0;
+ }
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
+
+ goto Exit;
}
return Status;
Exit:
@@ -1232,19 +1398,30 @@ Error2:
Error:
Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap->HttpToken);
if (Item != NULL) {
NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);
}
-
- HttpTcpTokenCleanup (Wrap);
+
+ if (!HttpInstance->UseHttps) {
+ HttpTcpTokenCleanup (Wrap);
+ } else {
+ FreePool (Wrap);
+ }
if (HttpHeaders != NULL) {
FreePool (HttpHeaders);
+ HttpHeaders = NULL;
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
}
if (HttpMsg->Headers != NULL) {
FreePool (HttpMsg->Headers);
+ HttpMsg->Headers = NULL;
}
if (HttpInstance->CacheBody != NULL) {
FreePool (HttpInstance->CacheBody);
HttpInstance->CacheBody = NULL;
@@ -1351,13 +1528,20 @@ EfiHttpResponse (
}
Wrap->HttpInstance = HttpInstance;
Wrap->HttpToken = Token;
- Status = HttpCreateTcpRxEvent (Wrap);
- if (EFI_ERROR (Status)) {
- goto Error;
+ //
+ // Notes: For Https, receive token wrapped in HTTP_TOKEN_WRAP is not used to
+ // receive the https response. A special TlsRxToken is used for receiving TLS
+ // related messages. It should be a blocking response.
+ //
+ if (!HttpInstance->UseHttps) {
+ Status = HttpCreateTcpRxEvent (Wrap);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
}
Status = NetMapInsertTail (&HttpInstance->RxTokens, Token, Wrap);
if (EFI_ERROR (Status)) {
goto Error;
diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c
index 6373f07..77a3ee3 100644
--- a/NetworkPkg/HttpDxe/HttpProto.c
+++ b/NetworkPkg/HttpDxe/HttpProto.c
@@ -926,10 +926,26 @@ HttpCleanProtocol (
HttpInstance->Service->ImageHandle,
HttpInstance->Handle
);
}
+ if (HttpInstance->TlsConfigData.CACert != NULL) {
+ FreePool (HttpInstance->TlsConfigData.CACert);
+ HttpInstance->TlsConfigData.CACert = NULL;
+ }
+
+ if (HttpInstance->TlsConfigData.ClientCert != NULL) {
+ FreePool (HttpInstance->TlsConfigData.ClientCert);
+ HttpInstance->TlsConfigData.ClientCert = NULL;
+ }
+
+ if (HttpInstance->TlsConfigData.ClientPrivateKey != NULL) {
+ FreePool (HttpInstance->TlsConfigData.ClientPrivateKey);
+ HttpInstance->TlsConfigData.ClientPrivateKey = NULL;
+ }
+
+ TlsCloseTxRxEvent (HttpInstance);
}
/**
Establish TCP connection with HTTP server.
@@ -1183,11 +1199,12 @@ HttpConfigureTcp6 (
return EFI_SUCCESS;
}
/**
- Check existing TCP connection, if in error state, recover TCP4 connection.
+ Check existing TCP connection, if in error state, recover TCP4 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP4 protocol child is not created or configured.
@@ -1224,15 +1241,62 @@ HttpConnectTcp4 (
return EFI_SUCCESS;
} else if (Tcp4State > Tcp4StateEstablished ) {
HttpCloseConnection(HttpInstance);
}
- return HttpCreateConnection (HttpInstance);
+ Status = HttpCreateConnection (HttpInstance);
+ if (EFI_ERROR(Status)){
+ DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status));
+ return Status;
+ }
+
+ //
+ // Tls session connection.
+ //
+ if (HttpInstance->UseHttps) {
+ if (HttpInstance->TimeoutEvent == NULL) {
+ //
+ // Create TimeoutEvent for TLS connection.
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &HttpInstance->TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ //
+ // Start the timer, and wait Timeout seconds for connection.
+ //
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+
+ Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
+
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
+
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ return Status;
}
/**
- Check existing TCP connection, if in error state, recover TCP6 connection.
+ Check existing TCP connection, if in error state, recover TCP6 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP6 protocol child is not created or configured.
@@ -1269,34 +1333,92 @@ HttpConnectTcp6 (
return EFI_SUCCESS;
} else if (Tcp6State > Tcp6StateEstablished ) {
HttpCloseConnection(HttpInstance);
}
- return HttpCreateConnection (HttpInstance);
+ Status = HttpCreateConnection (HttpInstance);
+ if (EFI_ERROR(Status)){
+ DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status));
+ return Status;
+ }
+
+ //
+ // Tls session connection.
+ //
+ if (HttpInstance->UseHttps) {
+ if (HttpInstance->TimeoutEvent == NULL) {
+ //
+ // Create TimeoutEvent for TLS connection.
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &HttpInstance->TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ //
+ // Start the timer, and wait Timeout seconds for connection.
+ //
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+
+ Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
+
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
+
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ return Status;
}
/**
- Initialize TCP related data.
+ Initialize Http session.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
- @param[in] Configure The Flag indicates whether the first time to initialize Tcp.
+ @param[in] Configure The Flag indicates whether need to initialize session.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.
- @retval EFI_SUCCESS The initialization of TCP instance is done.
+ @retval EFI_SUCCESS The initialization of session is done.
@retval Others Other error as indicated.
**/
EFI_STATUS
-HttpInitTcp (
+HttpInitSession (
IN HTTP_PROTOCOL *HttpInstance,
IN HTTP_TOKEN_WRAP *Wrap,
- IN BOOLEAN Configure
+ IN BOOLEAN Configure,
+ IN BOOLEAN TlsConfigure
)
{
EFI_STATUS Status;
ASSERT (HttpInstance != NULL);
+ //
+ // Configure Tls session.
+ //
+ if (TlsConfigure) {
+ Status = TlsConfigureSession (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
if (!HttpInstance->LocalAddressIsIPv6) {
//
// Configure TCP instance.
//
if (Configure) {
@@ -1336,11 +1458,11 @@ HttpInitTcp (
return EFI_SUCCESS;
}
/**
- Send the HTTP message through TCP4 or TCP6.
+ Send the HTTP or HTTPS message through TCP4 or TCP6.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
@param[in] TxString Buffer containing the HTTP message string.
@param[in] TxStringLen Length of the HTTP message string in bytes.
@@ -1360,18 +1482,68 @@ HttpTransmitTcp (
EFI_STATUS Status;
EFI_TCP4_IO_TOKEN *Tx4Token;
EFI_TCP4_PROTOCOL *Tcp4;
EFI_TCP6_IO_TOKEN *Tx6Token;
EFI_TCP6_PROTOCOL *Tcp6;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+ NET_FRAGMENT TempFragment;
+
+ Status = EFI_SUCCESS;
+ Buffer = NULL;
+
+ //
+ // Need to encrypt data.
+ //
+ if (HttpInstance->UseHttps) {
+ //
+ // Build BufferOut data
+ //
+ BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ ((TLS_RECORD_HEADER *) Buffer)->ContentType = TLS_CONTENT_TYPE_APPLICATION_DATA;
+ ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major;
+ ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;
+ ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);
+ CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);
+
+ //
+ // Encrypt Packet.
+ //
+ Status = TlsProcessMessage (
+ HttpInstance,
+ Buffer,
+ BufferSize,
+ EfiTlsEncrypt,
+ &TempFragment
+ );
+
+ FreePool (Buffer);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
- if (!HttpInstance->LocalAddressIsIPv6) {
+ if (!HttpInstance->LocalAddressIsIPv6) {
Tcp4 = HttpInstance->Tcp4;
Tx4Token = &Wrap->TcpWrap.Tx4Token;
+
+ if (HttpInstance->UseHttps) {
+ Tx4Token->Packet.TxData->DataLength = TempFragment.Len;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;
+ } else {
+ Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
+ }
- Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
- Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
- Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
Tx4Token->CompletionToken.Status = EFI_NOT_READY;
Wrap->TcpWrap.IsTxDone = FALSE;
Status = Tcp4->Transmit (Tcp4, Tx4Token);
if (EFI_ERROR (Status)) {
@@ -1380,25 +1552,31 @@ HttpTransmitTcp (
}
} else {
Tcp6 = HttpInstance->Tcp6;
Tx6Token = &Wrap->TcpWrap.Tx6Token;
-
- Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
- Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
- Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
+
+ if (HttpInstance->UseHttps) {
+ Tx6Token->Packet.TxData->DataLength = TempFragment.Len;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;
+ } else {
+ Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
+ }
+
Tx6Token->CompletionToken.Status = EFI_NOT_READY;
Wrap->TcpWrap.IsTxDone = FALSE;
Status = Tcp6->Transmit (Tcp6, Tx6Token);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));
return Status;
}
}
-
return Status;
}
/**
Check whether the user's token or event has already
@@ -1464,11 +1642,11 @@ HttpTcpNotReady (
return EFI_SUCCESS;
}
/**
- Transmit the HTTP mssage by processing the associated HTTP token.
+ Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.
@param[in] Map The container of Tx4Token or Tx6Token.
@param[in] Item Current item to check against.
@param[in] Context The Token to check againist.
@@ -1588,167 +1766,235 @@ HttpTcpReceiveHeader (
EFI_TCP6_IO_TOKEN *Rx6Token;
EFI_TCP6_PROTOCOL *Tcp6;
CHAR8 **EndofHeader;
CHAR8 **HttpHeaders;
CHAR8 *Buffer;
+ NET_FRAGMENT Fragment;
ASSERT (HttpInstance != NULL);
EndofHeader = HttpInstance->EndofHeader;
HttpHeaders = HttpInstance->HttpHeaders;
Tcp4 = HttpInstance->Tcp4;
Tcp6 = HttpInstance->Tcp6;
Buffer = NULL;
Rx4Token = NULL;
Rx6Token = NULL;
+ Fragment.Len = 0;
+ Fragment.Bulk = NULL;
if (HttpInstance->LocalAddressIsIPv6) {
ASSERT (Tcp6 != NULL);
} else {
ASSERT (Tcp4 != NULL);
}
- if (!HttpInstance->LocalAddressIsIPv6) {
- Rx4Token = &HttpInstance->Rx4Token;
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
- if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
+ if (!HttpInstance->UseHttps) {
+ Status = HttpCreateTcpRxEventForHeader (HttpInstance);
+ if (EFI_ERROR (Status)) {
return Status;
}
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ if (!HttpInstance->UseHttps) {
+ Rx4Token = &HttpInstance->Rx4Token;
+ Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
+ if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ }
//
// Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
//
- while (*EndofHeader == NULL) {
- HttpInstance->IsRxDone = FALSE;
- Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
- Status = Tcp4->Receive (Tcp4, Rx4Token);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
- return Status;
- }
-
- while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
- Tcp4->Poll (Tcp4);
+ while (*EndofHeader == NULL) {
+ if (!HttpInstance->UseHttps) {
+ HttpInstance->IsRxDone = FALSE;
+ Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
+ Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
+ Status = Tcp4->Receive (Tcp4, Rx4Token);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
+ return Status;
+ }
+
+ while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ Tcp4->Poll (Tcp4);
+ }
+
+ if (!HttpInstance->IsRxDone) {
+ //
+ // Cancle the Token before close its Event.
+ //
+ Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
+ gBS->CloseEvent (Rx4Token->CompletionToken.Event);
+ Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
+ }
+
+ Status = Rx4Token->CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Fragment.Len = Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ Fragment.Bulk = (UINT8 *) Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
+ } else {
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
+
+ Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
+ return Status;
+ }
}
- if (!HttpInstance->IsRxDone) {
- //
- // Cancle the Token before close its Event.
- //
- Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
- gBS->CloseEvent (Rx4Token->CompletionToken.Event);
- Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
- }
-
- Status = Rx4Token->CompletionToken.Status;
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
//
// Append the response string.
//
- *BufferSize = (*SizeofHeaders) + Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ *BufferSize = *SizeofHeaders + Fragment.Len;
Buffer = AllocateZeroPool (*BufferSize);
if (Buffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
return Status;
}
-
+
if (*HttpHeaders != NULL) {
- CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
+ CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
FreePool (*HttpHeaders);
}
-
+
CopyMem (
- Buffer + (*SizeofHeaders),
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength
+ Buffer + *SizeofHeaders,
+ Fragment.Bulk,
+ Fragment.Len
);
- *HttpHeaders = Buffer;
- *SizeofHeaders = *BufferSize;
-
+ *HttpHeaders = Buffer;
+ *SizeofHeaders = *BufferSize;
+
//
// Check whether we received end of HTTP headers.
//
*EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
- }
- FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+ };
+ //
+ // Free the buffer.
+ //
+ if (Rx4Token != NULL && Rx4Token->Packet.RxData != NULL && Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
+ FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
+ Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+ Fragment.Bulk = NULL;
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
} else {
- Rx6Token = &HttpInstance->Rx6Token;
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
- if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
+ if (!HttpInstance->UseHttps) {
+ Rx6Token = &HttpInstance->Rx6Token;
+ Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
+ if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
}
//
// Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
//
- while (*EndofHeader == NULL) {
- HttpInstance->IsRxDone = FALSE;
- Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
- Status = Tcp6->Receive (Tcp6, Rx6Token);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
- return Status;
- }
-
- while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
- Tcp6->Poll (Tcp6);
+ while (*EndofHeader == NULL) {
+ if (!HttpInstance->UseHttps) {
+ HttpInstance->IsRxDone = FALSE;
+ Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
+ Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
+ Status = Tcp6->Receive (Tcp6, Rx6Token);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
+ return Status;
+ }
+
+ while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ Tcp6->Poll (Tcp6);
+ }
+
+ if (!HttpInstance->IsRxDone) {
+ //
+ // Cancle the Token before close its Event.
+ //
+ Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
+ gBS->CloseEvent (Rx6Token->CompletionToken.Event);
+ Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
+ }
+
+ Status = Rx6Token->CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Fragment.Len = Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ Fragment.Bulk = (UINT8 *) Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
+ } else {
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
+
+ Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
+ return Status;
+ }
}
- if (!HttpInstance->IsRxDone) {
- //
- // Cancle the Token before close its Event.
- //
- Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
- gBS->CloseEvent (Rx6Token->CompletionToken.Event);
- Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
- }
-
- Status = Rx6Token->CompletionToken.Status;
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
//
// Append the response string.
//
- *BufferSize = (*SizeofHeaders) + Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ *BufferSize = *SizeofHeaders + Fragment.Len;
Buffer = AllocateZeroPool (*BufferSize);
if (Buffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
return Status;
}
-
+
if (*HttpHeaders != NULL) {
- CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
+ CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
FreePool (*HttpHeaders);
}
-
+
CopyMem (
- Buffer + (*SizeofHeaders),
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength
+ Buffer + *SizeofHeaders,
+ Fragment.Bulk,
+ Fragment.Len
);
- *HttpHeaders = Buffer;
- *SizeofHeaders = *BufferSize;
-
+ *HttpHeaders = Buffer;
+ *SizeofHeaders = *BufferSize;
+
//
// Check whether we received end of HTTP headers.
//
- *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
-
+ *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
+ };
+
+ //
+ // Free the buffer.
+ //
+ if (Rx6Token != NULL && Rx6Token->Packet.RxData != NULL && Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
+ FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
+ Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+ Fragment.Bulk = NULL;
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
}
- FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
}
//
// Skip the CRLF after the HTTP headers.
//
diff --git a/NetworkPkg/HttpDxe/HttpProto.h b/NetworkPkg/HttpDxe/HttpProto.h
index e1fd785..e3b3275 100644
--- a/NetworkPkg/HttpDxe/HttpProto.h
+++ b/NetworkPkg/HttpDxe/HttpProto.h
@@ -81,10 +81,24 @@ typedef struct {
BOOLEAN IsRxDone;
UINTN BodyLen;
EFI_HTTP_METHOD Method;
} HTTP_TCP_TOKEN_WRAP;
+typedef struct {
+ EFI_TLS_VERSION Version;
+ EFI_TLS_CONNECTION_END ConnectionEnd;
+ EFI_TLS_VERIFY VerifyMethod;
+ EFI_TLS_SESSION_STATE SessionState;
+
+ VOID *CACert;
+ UINTN CACertSize;
+ VOID *ClientCert;
+ UINTN ClientCertSize;
+ VOID *ClientPrivateKey;
+ UINTN ClientPrivateKeySize;
+} TLS_CONFIG_DATA;
+
typedef struct _HTTP_PROTOCOL {
UINT32 Signature;
EFI_HTTP_PROTOCOL Http;
EFI_HANDLE Handle;
HTTP_SERVICE *Service;
@@ -151,10 +165,39 @@ typedef struct _HTTP_PROTOCOL {
NET_MAP TxTokens;
NET_MAP RxTokens;
CHAR8 *Url;
+
+ //
+ // Https Support
+ //
+ BOOLEAN UseHttps;
+
+ EFI_HANDLE TlsChildHandle; /// Tls ChildHandle
+ TLS_CONFIG_DATA TlsConfigData;
+ EFI_TLS_PROTOCOL *Tls;
+ EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfiguration;
+ EFI_TLS_SESSION_STATE TlsSessionState;
+
+ //
+ // TlsTxData used for transmitting TLS related messages.
+ //
+ EFI_TCP4_IO_TOKEN Tcp4TlsTxToken;
+ EFI_TCP4_TRANSMIT_DATA Tcp4TlsTxData;
+ EFI_TCP6_IO_TOKEN Tcp6TlsTxToken;
+ EFI_TCP6_TRANSMIT_DATA Tcp6TlsTxData;
+ BOOLEAN TlsIsTxDone;
+
+ //
+ // TlsRxData used for receiving TLS related messages.
+ //
+ EFI_TCP4_IO_TOKEN Tcp4TlsRxToken;
+ EFI_TCP4_RECEIVE_DATA Tcp4TlsRxData;
+ EFI_TCP6_IO_TOKEN Tcp6TlsRxToken;
+ EFI_TCP6_RECEIVE_DATA Tcp6TlsRxData;
+ BOOLEAN TlsIsRxDone;
} HTTP_PROTOCOL;
typedef struct {
EFI_HTTP_TOKEN *HttpToken;
HTTP_PROTOCOL *HttpInstance;
@@ -350,11 +393,12 @@ HttpConfigureTcp6 (
IN HTTP_PROTOCOL *HttpInstance,
IN HTTP_TOKEN_WRAP *Wrap
);
/**
- Check existing TCP connection, if in error state, receover TCP4 connection.
+ Check existing TCP connection, if in error state, recover TCP4 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP4 protocol child is not created or configured.
@@ -365,11 +409,12 @@ EFI_STATUS
HttpConnectTcp4 (
IN HTTP_PROTOCOL *HttpInstance
);
/**
- Check existing TCP connection, if in error state, recover TCP6 connection.
+ Check existing TCP connection, if in error state, recover TCP6 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP6 protocol child is not created or configured.
@@ -380,11 +425,11 @@ EFI_STATUS
HttpConnectTcp6 (
IN HTTP_PROTOCOL *HttpInstance
);
/**
- Send the HTTP message through TCP4 or TCP6.
+ Send the HTTP or HTTPS message through TCP4 or TCP6.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
@param[in] TxString Buffer containing the HTTP message string.
@param[in] TxStringLen Length of the HTTP message string in bytes.
@@ -441,29 +486,31 @@ HttpTcpNotReady (
IN NET_MAP_ITEM *Item,
IN VOID *Context
);
/**
- Initialize TCP related data.
+ Initialize Http session.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
- @param[in] Configure The Flag indicates whether the first time to initialize Tcp.
+ @param[in] Configure The Flag indicates whether need to initialize session.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.
- @retval EFI_SUCCESS The initialization of TCP instance is done.
+ @retval EFI_SUCCESS The initialization of session is done.
@retval Others Other error as indicated.
**/
EFI_STATUS
-HttpInitTcp (
+HttpInitSession (
IN HTTP_PROTOCOL *HttpInstance,
IN HTTP_TOKEN_WRAP *Wrap,
- IN BOOLEAN Configure
+ IN BOOLEAN Configure,
+ IN BOOLEAN TlsConfigure
);
/**
- Transmit the HTTP mssage by processing the associated HTTP token.
+ Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.
@param[in] Map The container of TxToken or Tx6Token.
@param[in] Item Current item to check against.
@param[in] Context The Token to check againist.
diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c b/NetworkPkg/HttpDxe/HttpsSupport.c
new file mode 100644
index 0000000..177b9a8
--- /dev/null
+++ b/NetworkPkg/HttpDxe/HttpsSupport.c
@@ -0,0 +1,1692 @@
+/** @file
+ Miscellaneous routines specific to Https for HttpDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "HttpDriver.h"
+
+/**
+ Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-terminated
+ ASCII string and ignore case during the search process.
+
+ This function scans the contents of the ASCII string specified by String
+ and returns the first occurrence of SearchString and ignore case during the search process.
+ If SearchString is not found in String, then NULL is returned. If the length of SearchString
+ is zero, then String is returned.
+
+ If String is NULL, then ASSERT().
+ If SearchString is NULL, then ASSERT().
+
+ @param[in] String A pointer to a Null-terminated ASCII string.
+ @param[in] SearchString A pointer to a Null-terminated ASCII string to search for.
+
+ @retval NULL If the SearchString does not appear in String.
+ @retval others If there is a match return the first occurrence of SearchingString.
+ If the length of SearchString is zero,return String.
+
+**/
+CHAR8 *
+AsciiStrCaseStr (
+ IN CONST CHAR8 *String,
+ IN CONST CHAR8 *SearchString
+ )
+{
+ CONST CHAR8 *FirstMatch;
+ CONST CHAR8 *SearchStringTmp;
+
+ CHAR8 Src;
+ CHAR8 Dst;
+
+ //
+ // ASSERT both strings are less long than PcdMaximumAsciiStringLength
+ //
+ ASSERT (AsciiStrSize (String) != 0);
+ ASSERT (AsciiStrSize (SearchString) != 0);
+
+ if (*SearchString == '\0') {
+ return (CHAR8 *) String;
+ }
+
+ while (*String != '\0') {
+ SearchStringTmp = SearchString;
+ FirstMatch = String;
+
+ while ((*SearchStringTmp != '\0')
+ && (*String != '\0')) {
+ Src = *String;
+ Dst = *SearchStringTmp;
+
+ if ((Src >= 'A') && (Src <= 'Z')) {
+ Src -= ('A' - 'a');
+ }
+
+ if ((Dst >= 'A') && (Dst <= 'Z')) {
+ Dst -= ('A' - 'a');
+ }
+
+ if (Src != Dst) {
+ break;
+ }
+
+ String++;
+ SearchStringTmp++;
+ }
+
+ if (*SearchStringTmp == '\0') {
+ return (CHAR8 *) FirstMatch;
+ }
+
+ String = FirstMatch + 1;
+ }
+
+ return NULL;
+}
+
+/**
+ The callback function to free the net buffer list.
+
+ @param[in] Arg The opaque parameter.
+
+**/
+VOID
+EFIAPI
+FreeNbufList (
+ IN VOID *Arg
+ )
+{
+ ASSERT (Arg != NULL);
+
+ NetbufFreeList ((LIST_ENTRY *) Arg);
+ FreePool (Arg);
+}
+
+/**
+ Check whether the Url is from Https.
+
+ @param[in] Url The pointer to a HTTP or HTTPS URL string.
+
+ @retval TRUE The Url is from HTTPS.
+ @retval FALSE The Url is from HTTP.
+
+**/
+BOOLEAN
+IsHttpsUrl (
+ IN CHAR8 *Url
+ )
+{
+ CHAR8 *Tmp;
+
+ Tmp = NULL;
+
+ Tmp = AsciiStrCaseStr (Url, HTTPS_FLAG);
+ if (Tmp != NULL && Tmp == Url) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+
+ @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+**/
+EFI_HANDLE
+EFIAPI
+TlsCreateChild (
+ IN EFI_HANDLE ImageHandle,
+ OUT EFI_TLS_PROTOCOL **TlsProto,
+ OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
+ )
+{
+ EFI_STATUS Status;
+ EFI_SERVICE_BINDING_PROTOCOL *TlsSb;
+ EFI_HANDLE TlsChildHandle;
+
+ TlsSb = NULL;
+ TlsChildHandle = 0;
+
+ //
+ // Locate TlsServiceBinding protocol.
+ //
+ gBS->LocateProtocol (
+ &gEfiTlsServiceBindingProtocolGuid,
+ NULL,
+ (VOID **) &TlsSb
+ );
+ if (TlsSb == NULL) {
+ return NULL;
+ }
+
+ Status = TlsSb->CreateChild (TlsSb, &TlsChildHandle);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Status = gBS->OpenProtocol (
+ TlsChildHandle,
+ &gEfiTlsProtocolGuid,
+ (VOID **) TlsProto,
+ ImageHandle,
+ TlsChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ TlsSb->DestroyChild (TlsSb, TlsChildHandle);
+ return NULL;
+ }
+
+ Status = gBS->OpenProtocol (
+ TlsChildHandle,
+ &gEfiTlsConfigurationProtocolGuid,
+ (VOID **) TlsConfiguration,
+ ImageHandle,
+ TlsChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ TlsSb->DestroyChild (TlsSb, TlsChildHandle);
+ return NULL;
+ }
+
+ return TlsChildHandle;
+}
+
+/**
+ Create event for the TLS receive and transmit tokens which are used to receive and
+ transmit TLS related messages.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+ @retval EFI_SUCCESS The events are created successfully.
+ @retval others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCreateTxRxEvent (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ //
+ // For Tcp4TlsTxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsTxDone,
+ &HttpInstance->Tcp4TlsTxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp4TlsTxData.Push = TRUE;
+ HttpInstance->Tcp4TlsTxData.Urgent = FALSE;
+ HttpInstance->Tcp4TlsTxData.DataLength = 0;
+ HttpInstance->Tcp4TlsTxData.FragmentCount = 1;
+ HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsTxData.DataLength;
+ HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp4TlsTxToken.Packet.TxData = &HttpInstance->Tcp4TlsTxData;
+ HttpInstance->Tcp4TlsTxToken.CompletionToken.Status = EFI_NOT_READY;
+
+ //
+ // For Tcp4TlsRxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsRxDone,
+ &HttpInstance->Tcp4TlsRxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp4TlsRxData.DataLength = 0;
+ HttpInstance->Tcp4TlsRxData.FragmentCount = 1;
+ HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsRxData.DataLength ;
+ HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp4TlsRxToken.Packet.RxData = &HttpInstance->Tcp4TlsRxData;
+ HttpInstance->Tcp4TlsRxToken.CompletionToken.Status = EFI_NOT_READY;
+ } else {
+ //
+ // For Tcp6TlsTxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsTxDone,
+ &HttpInstance->Tcp6TlsTxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp6TlsTxData.Push = TRUE;
+ HttpInstance->Tcp6TlsTxData.Urgent = FALSE;
+ HttpInstance->Tcp6TlsTxData.DataLength = 0;
+ HttpInstance->Tcp6TlsTxData.FragmentCount = 1;
+ HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsTxData.DataLength;
+ HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp6TlsTxToken.Packet.TxData = &HttpInstance->Tcp6TlsTxData;
+ HttpInstance->Tcp6TlsTxToken.CompletionToken.Status = EFI_NOT_READY;
+
+ //
+ // For Tcp6TlsRxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsRxDone,
+ &HttpInstance->Tcp6TlsRxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp6TlsRxData.DataLength = 0;
+ HttpInstance->Tcp6TlsRxData.FragmentCount = 1;
+ HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsRxData.DataLength ;
+ HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp6TlsRxToken.Packet.RxData = &HttpInstance->Tcp6TlsRxData;
+ HttpInstance->Tcp6TlsRxToken.CompletionToken.Status = EFI_NOT_READY;
+ }
+
+ return Status;
+
+ERROR:
+ //
+ // Error handling
+ //
+ TlsCloseTxRxEvent (HttpInstance);
+
+ return Status;
+}
+
+/**
+ Close events in the TlsTxToken and TlsRxToken.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+**/
+VOID
+EFIAPI
+TlsCloseTxRxEvent (
+ IN HTTP_PROTOCOL *HttpInstance
+ )
+{
+ ASSERT (HttpInstance != NULL);
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ if (NULL != HttpInstance->Tcp4TlsTxToken.CompletionToken.Event) {
+ gBS->CloseEvent(HttpInstance->Tcp4TlsTxToken.CompletionToken.Event);
+ HttpInstance->Tcp4TlsTxToken.CompletionToken.Event = NULL;
+ }
+
+ if (NULL != HttpInstance->Tcp4TlsRxToken.CompletionToken.Event) {
+ gBS->CloseEvent (HttpInstance->Tcp4TlsRxToken.CompletionToken.Event);
+ HttpInstance->Tcp4TlsRxToken.CompletionToken.Event = NULL;
+ }
+ } else {
+ if (NULL != HttpInstance->Tcp6TlsTxToken.CompletionToken.Event) {
+ gBS->CloseEvent(HttpInstance->Tcp6TlsTxToken.CompletionToken.Event);
+ HttpInstance->Tcp6TlsTxToken.CompletionToken.Event = NULL;
+ }
+
+ if (NULL != HttpInstance->Tcp6TlsRxToken.CompletionToken.Event) {
+ gBS->CloseEvent (HttpInstance->Tcp6TlsRxToken.CompletionToken.Event);
+ HttpInstance->Tcp6TlsRxToken.CompletionToken.Event = NULL;
+ }
+ }
+}
+
+/**
+ Read the TlsCaCertificate variable and configure it.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TlsCaCertificate is configured.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+TlsConfigCertificate (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *CACert;
+ UINTN CACertSize;
+ UINT32 Index;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINTN CertCount;
+ UINT32 ItemDataSize;
+
+ CACert = (UINT8 *) HttpInstance->TlsConfigData.CACert;
+ CACertSize = HttpInstance->TlsConfigData.CACertSize;
+
+ //
+ // Try to read the TlsCaCertificate variable.
+ //
+ CACertSize = 0;
+ Status = gRT->GetVariable (
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ NULL,
+ &CACertSize,
+ NULL
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ //
+ // Allocate buffer and read the config variable.
+ //
+ CACert = AllocatePool (CACertSize);
+ if (CACert == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gRT->GetVariable (
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ NULL,
+ &CACertSize,
+ CACert
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // GetVariable still error or the variable is corrupted.
+ // Fall back to the default value.
+ //
+ FreePool (CACert);
+
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ //
+ // Enumerate all data and erasing the target item.
+ //
+ ItemDataSize = (UINT32) CACertSize;
+ CertList = (EFI_SIGNATURE_LIST *) CACert;
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ //
+ // EfiTlsConfigDataTypeCACertificate
+ //
+ Status = HttpInstance->TlsConfiguration->SetData (
+ HttpInstance->TlsConfiguration,
+ EfiTlsConfigDataTypeCACertificate,
+ Cert->SignatureData,
+ CertList->SignatureSize - sizeof (Cert->SignatureOwner)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ return Status;
+}
+
+/**
+ Configure TLS session data.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TLS session data is configured.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigureSession (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // TlsConfigData initialization
+ //
+ HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient;
+ HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER;
+ HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted;
+
+ //
+ // EfiTlsConnectionEnd,
+ // EfiTlsVerifyMethod
+ // EfiTlsSessionState
+ //
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsConnectionEnd,
+ &(HttpInstance->TlsConfigData.ConnectionEnd),
+ sizeof (EFI_TLS_CONNECTION_END)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsVerifyMethod,
+ &HttpInstance->TlsConfigData.VerifyMethod,
+ sizeof (EFI_TLS_VERIFY)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ &(HttpInstance->TlsConfigData.SessionState),
+ sizeof (EFI_TLS_SESSION_STATE)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ //
+ // Tls Config Certificate
+ //
+ Status = TlsConfigCertificate (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "TLS Certificate Config Error!\n"));
+ goto ERROR;
+ }
+
+ //
+ // TlsCreateTxRxEvent
+ //
+ Status = TlsCreateTxRxEvent (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ return Status;
+
+ERROR:
+ TlsCloseTxRxEvent (HttpInstance);
+
+ return Status;
+}
+
+/**
+ Transmit the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+
+ @retval EFI_SUCCESS The packet is transmitted.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonTransmit (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ UINTN Size;
+
+ if ((HttpInstance == NULL) || (Packet == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Size = sizeof (EFI_TCP4_TRANSMIT_DATA) +
+ (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA);
+ } else {
+ Size = sizeof (EFI_TCP6_TRANSMIT_DATA) +
+ (Packet->BlockOpNum - 1) * sizeof (EFI_TCP6_FRAGMENT_DATA);
+ }
+
+ Data = AllocatePool (Size);
+ if (Data == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->Push = TRUE;
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->Urgent = FALSE;
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
+
+ //
+ // Build the fragment table.
+ //
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum;
+
+ NetbufBuildExt (
+ Packet,
+ (NET_FRAGMENT *) &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentTable[0],
+ &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount
+ );
+
+ HttpInstance->Tcp4TlsTxToken.Packet.TxData = (EFI_TCP4_TRANSMIT_DATA *) Data;
+
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ // Transmit the packet.
+ //
+ Status = HttpInstance->Tcp4->Transmit (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsTxToken);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ while (!HttpInstance->TlsIsTxDone) {
+ HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
+ }
+
+ HttpInstance->TlsIsTxDone = FALSE;
+ Status = HttpInstance->Tcp4TlsTxToken.CompletionToken.Status;
+ } else {
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->Push = TRUE;
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->Urgent = FALSE;
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
+
+ //
+ // Build the fragment table.
+ //
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum;
+
+ NetbufBuildExt (
+ Packet,
+ (NET_FRAGMENT *) &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentTable[0],
+ &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount
+ );
+
+ HttpInstance->Tcp6TlsTxToken.Packet.TxData = (EFI_TCP6_TRANSMIT_DATA *) Data;
+
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ // Transmit the packet.
+ //
+ Status = HttpInstance->Tcp6->Transmit (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsTxToken);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ while (!HttpInstance->TlsIsTxDone) {
+ HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
+ }
+
+ HttpInstance->TlsIsTxDone = FALSE;
+ Status = HttpInstance->Tcp6TlsTxToken.CompletionToken.Status;
+ }
+
+ON_EXIT:
+ FreePool (Data);
+
+ return Status;
+}
+
+/**
+ Receive the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The Packet is received.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_TIMEOUT The operation is time out.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonReceive (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_TCP4_RECEIVE_DATA *Tcp4RxData;
+ EFI_TCP6_RECEIVE_DATA *Tcp6RxData;
+ EFI_STATUS Status;
+ NET_FRAGMENT *Fragment;
+ UINT32 FragmentCount;
+ UINT32 CurrentFragment;
+
+ Tcp4RxData = NULL;
+ Tcp6RxData = NULL;
+
+ if ((HttpInstance == NULL) || (Packet == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FragmentCount = Packet->BlockOpNum;
+ Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));
+ if (Fragment == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Build the fragment table.
+ //
+ NetbufBuildExt (Packet, Fragment, &FragmentCount);
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Tcp4RxData = HttpInstance->Tcp4TlsRxToken.Packet.RxData;
+ if (Tcp4RxData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Tcp4RxData->FragmentCount = 1;
+ } else {
+ Tcp6RxData = HttpInstance->Tcp6TlsRxToken.Packet.RxData;
+ if (Tcp6RxData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Tcp6RxData->FragmentCount = 1;
+ }
+
+ CurrentFragment = 0;
+ Status = EFI_SUCCESS;
+
+ while (CurrentFragment < FragmentCount) {
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Tcp4RxData->DataLength = Fragment[CurrentFragment].Len;
+ Tcp4RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
+ Tcp4RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
+ Status = HttpInstance->Tcp4->Receive (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken);
+ } else {
+ Tcp6RxData->DataLength = Fragment[CurrentFragment].Len;
+ Tcp6RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
+ Tcp6RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
+ Status = HttpInstance->Tcp6->Receive (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken);
+ }
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ while (!HttpInstance->TlsIsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ //
+ // Poll until some data is received or an error occurs.
+ //
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
+ } else {
+ HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
+ }
+ }
+
+ if (!HttpInstance->TlsIsRxDone) {
+ //
+ // Timeout occurs, cancel the receive request.
+ //
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken);
+ } else {
+ HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);
+ }
+
+ Status = EFI_TIMEOUT;
+ goto ON_EXIT;
+ } else {
+ HttpInstance->TlsIsRxDone = FALSE;
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Status = HttpInstance->Tcp4TlsRxToken.CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Fragment[CurrentFragment].Len -= Tcp4RxData->FragmentTable[0].FragmentLength;
+ if (Fragment[CurrentFragment].Len == 0) {
+ CurrentFragment++;
+ } else {
+ Fragment[CurrentFragment].Bulk += Tcp4RxData->FragmentTable[0].FragmentLength;
+ }
+ } else {
+ Status = HttpInstance->Tcp6TlsRxToken.CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Fragment[CurrentFragment].Len -= Tcp6RxData->FragmentTable[0].FragmentLength;
+ if (Fragment[CurrentFragment].Len == 0) {
+ CurrentFragment++;
+ } else {
+ Fragment[CurrentFragment].Bulk += Tcp6RxData->FragmentTable[0].FragmentLength;
+ }
+ }
+ }
+
+ON_EXIT:
+
+ if (Fragment != NULL) {
+ FreePool (Fragment);
+ }
+
+ return Status;
+}
+
+/**
+ Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
+ corresponding record data. This two parts will be put into two blocks of buffers in the
+ net buffer.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[out] Pdu The received TLS PDU.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS An TLS PDU is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsReceiveOnePdu (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ OUT NET_BUF **Pdu,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_STATUS Status;
+
+ LIST_ENTRY *NbufList;
+
+ UINT32 Len;
+
+ NET_BUF *PduHdr;
+ UINT8 *Header;
+ TLS_RECORD_HEADER RecordHeader;
+
+ NET_BUF *DataSeg;
+
+ NbufList = NULL;
+ PduHdr = NULL;
+ Header = NULL;
+ DataSeg = NULL;
+
+ NbufList = AllocatePool (sizeof (LIST_ENTRY));
+ if (NbufList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InitializeListHead (NbufList);
+
+ //
+ // Allocate buffer to receive one TLS header.
+ //
+ Len = sizeof (TLS_RECORD_HEADER);
+ PduHdr = NetbufAlloc (Len);
+ if (PduHdr == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);
+ if (Header == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // First step, receive one TLS header.
+ //
+ Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ RecordHeader = *(TLS_RECORD_HEADER *) Header;
+ if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_HANDSHAKE ||
+ RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT ||
+ RecordHeader.ContentType == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC ||
+ RecordHeader.ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA) &&
+ (RecordHeader.Version.Major == 0x03) && /// Major versions are same.
+ (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor ==TLS11_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
+ ) {
+ InsertTailList (NbufList, &PduHdr->List);
+ } else {
+ Status = EFI_PROTOCOL_ERROR;
+ goto ON_EXIT;
+ }
+
+ Len = SwapBytes16(RecordHeader.Length);
+ if (Len == 0) {
+ //
+ // No TLS payload.
+ //
+ goto FORM_PDU;
+ }
+
+ //
+ // Allocate buffer to receive one TLS payload.
+ //
+ DataSeg = NetbufAlloc (Len);
+ if (DataSeg == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL);
+
+ //
+ // Second step, receive one TLS payload.
+ //
+ Status = TlsCommonReceive (HttpInstance, DataSeg, Timeout);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ InsertTailList (NbufList, &DataSeg->List);
+
+FORM_PDU:
+ //
+ // Form the PDU from a list of PDU.
+ //
+ *Pdu = NetbufFromBufList (NbufList, 0, 0, FreeNbufList, NbufList);
+ if (*Pdu == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ON_EXIT:
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Free the Nbufs in this NbufList and the NbufList itself.
+ //
+ FreeNbufList (NbufList);
+ }
+
+ return Status;
+}
+
+/**
+ Connect one TLS session by finishing the TLS handshake process.
+
+ @param[in] HttpInstance The HTTP instance private data.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The TLS session is established.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConnectSession (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *BufferOut;
+ UINTN BufferOutSize;
+ NET_BUF *PacketOut;
+ UINT8 *DataOut;
+ NET_BUF *Pdu;
+ UINT8 *BufferIn;
+ UINTN BufferInSize;
+ UINT8 *GetSessionDataBuffer;
+ UINTN GetSessionDataBufferSize;
+
+ BufferOut = NULL;
+ PacketOut = NULL;
+ DataOut = NULL;
+ Pdu = NULL;
+ BufferIn = NULL;
+
+ //
+ // Initialize TLS state.
+ //
+ HttpInstance->TlsSessionState = EfiTlsSessionNotStarted;
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ &(HttpInstance->TlsSessionState),
+ sizeof (EFI_TLS_SESSION_STATE)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Create ClientHello
+ //
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+
+ //
+ // Transmit ClientHello
+ //
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ FreePool (BufferOut);
+ NetbufFree (PacketOut);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while(HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring && \
+ ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ //
+ // Receive one TLS record.
+ //
+ Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BufferInSize = Pdu->TotalSize;
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ NetbufFree (Pdu);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn);
+
+ NetbufFree (Pdu);
+
+ //
+ // Handle Receive data.
+ //
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+
+ FreePool (BufferIn);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (BufferOutSize != 0) {
+ //
+ // Transmit the response packet.
+ //
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ NetbufFree (PacketOut);
+
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+ }
+
+ FreePool (BufferOut);
+
+ //
+ // Get the session state, then decide whether need to continue handle received packet.
+ //
+ GetSessionDataBufferSize = DEF_BUF_LEN;
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (GetSessionDataBuffer);
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool(GetSessionDataBuffer);
+ return Status;
+ }
+
+ ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
+ HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer;
+
+ FreePool (GetSessionDataBuffer);
+
+ if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
+ return EFI_ABORTED;
+ }
+ }
+
+ if (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring) {
+ Status = EFI_ABORTED;
+ }
+
+ return Status;
+}
+
+/**
+ Close the TLS session and send out the close notification message.
+
+ @param[in] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS The TLS session is closed.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseSession (
+ IN HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+
+ UINT8 *BufferOut;
+ UINTN BufferOutSize;
+
+ NET_BUF *PacketOut;
+ UINT8 *DataOut;
+
+ Status = EFI_SUCCESS;
+ BufferOut = NULL;
+ PacketOut = NULL;
+ DataOut = NULL;
+
+ if (HttpInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HttpInstance->TlsSessionState = EfiTlsSessionClosing;
+
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ &(HttpInstance->TlsSessionState),
+ sizeof (EFI_TLS_SESSION_STATE)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ FreePool (BufferOut);
+ NetbufFree (PacketOut);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+/**
+ Process one message according to the CryptMode.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Message Pointer to the message buffer needed to processed.
+ @param[in] MessageSize Pointer to the message buffer size.
+ @param[in] ProcessMode Process mode.
+ @param[in, out] Fragment Only one Fragment returned after the Message is
+ processed successfully.
+
+ @retval EFI_SUCCESS Message is processed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessMessage (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN UINT8 *Message,
+ IN UINTN MessageSize,
+ IN EFI_TLS_CRYPT_MODE ProcessMode,
+ IN OUT NET_FRAGMENT *Fragment
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+ UINT32 BufferSize;
+ UINT32 BytesCopied;
+ EFI_TLS_FRAGMENT_DATA *FragmentTable;
+ UINT32 FragmentCount;
+ EFI_TLS_FRAGMENT_DATA *OriginalFragmentTable;
+ UINTN Index;
+
+ Status = EFI_SUCCESS;
+ Buffer = NULL;
+ BufferSize = 0;
+ BytesCopied = 0;
+ FragmentTable = NULL;
+ OriginalFragmentTable = NULL;
+
+ //
+ // Rebuild fragment table from BufferIn.
+ //
+ FragmentCount = 1;
+ FragmentTable = AllocateZeroPool (FragmentCount * sizeof (EFI_TLS_FRAGMENT_DATA));
+ if (FragmentTable == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ FragmentTable->FragmentLength = (UINT32) MessageSize;
+ FragmentTable->FragmentBuffer = Message;
+
+ //
+ // Record the original FragmentTable.
+ //
+ OriginalFragmentTable = FragmentTable;
+
+ //
+ // Process the Message.
+ //
+ Status = HttpInstance->Tls->ProcessPacket (
+ HttpInstance->Tls,
+ &FragmentTable,
+ &FragmentCount,
+ ProcessMode
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Calculate the size according to FragmentTable.
+ //
+ for (Index = 0; Index < FragmentCount; Index++) {
+ BufferSize += FragmentTable[Index].FragmentLength;
+ }
+
+ //
+ // Allocate buffer for processed data.
+ //
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Copy the new FragmentTable buffer into Buffer.
+ //
+ for (Index = 0; Index < FragmentCount; Index++) {
+ CopyMem (
+ (Buffer + BytesCopied),
+ FragmentTable[Index].FragmentBuffer,
+ FragmentTable[Index].FragmentLength
+ );
+ BytesCopied += FragmentTable[Index].FragmentLength;
+
+ //
+ // Free the FragmentBuffer since it has been copied.
+ //
+ FreePool (FragmentTable[Index].FragmentBuffer);
+ }
+
+ Fragment->Len = BufferSize;
+ Fragment->Bulk = Buffer;
+
+ON_EXIT:
+
+ if (OriginalFragmentTable != NULL) {
+ FreePool (OriginalFragmentTable);
+ OriginalFragmentTable = NULL;
+ }
+
+ //
+ // Caller has the responsibility to free the FragmentTable.
+ //
+ if (FragmentTable != NULL) {
+ FreePool (FragmentTable);
+ FragmentTable = NULL;
+ }
+
+ return Status;
+}
+
+/**
+ Receive one fragment decrypted from one TLS record.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in, out] Fragment The received Fragment.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS One fragment is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED Something wrong decryption the message.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+HttpsReceive (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN OUT NET_FRAGMENT *Fragment,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_STATUS Status;
+ NET_BUF *Pdu;
+ TLS_RECORD_HEADER RecordHeader;
+ UINT8 *BufferIn;
+ UINTN BufferInSize;
+ NET_FRAGMENT TempFragment;
+ UINT8 *BufferOut;
+ UINTN BufferOutSize;
+ NET_BUF *PacketOut;
+ UINT8 *DataOut;
+ UINT8 *GetSessionDataBuffer;
+ UINTN GetSessionDataBufferSize;
+
+ Status = EFI_SUCCESS;
+ Pdu = NULL;
+ BufferIn = NULL;
+ BufferInSize = 0;
+ BufferOut = NULL;
+ BufferOutSize = 0;
+ PacketOut = NULL;
+ DataOut = NULL;
+ GetSessionDataBuffer = NULL;
+ GetSessionDataBufferSize = 0;
+
+ //
+ // Receive only one TLS record
+ //
+ Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BufferInSize = Pdu->TotalSize;
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ NetbufFree (Pdu);
+ return Status;
+ }
+
+ NetbufCopy (Pdu, 0, (UINT32) BufferInSize, BufferIn);
+
+ NetbufFree (Pdu);
+
+ //
+ // Handle Receive data.
+ //
+ RecordHeader = *(TLS_RECORD_HEADER *) BufferIn;
+
+ if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA) &&
+ (RecordHeader.Version.Major == 0x03) &&
+ (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
+ ) {
+ //
+ // Decrypt Packet.
+ //
+ Status = TlsProcessMessage (
+ HttpInstance,
+ BufferIn,
+ BufferInSize,
+ EfiTlsDecrypt,
+ &TempFragment
+ );
+
+ FreePool (BufferIn);
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_ABORTED) {
+ //
+ // Something wrong decryption the message.
+ // BuildResponsePacket() will be called to generate Error Alert message and send it out.
+ //
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool(BufferOut);
+ return Status;
+ }
+
+ if (BufferOutSize != 0) {
+ PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ NetbufFree (PacketOut);
+ }
+
+ FreePool(BufferOut);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_ABORTED;
+ }
+
+ return Status;
+ }
+
+ //
+ // Parsing buffer.
+ //
+ ASSERT (((TLS_RECORD_HEADER *) (TempFragment.Bulk))->ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA);
+
+ BufferInSize = ((TLS_RECORD_HEADER *) (TempFragment.Bulk))->Length;
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLS_RECORD_HEADER), BufferInSize);
+
+ //
+ // Free the buffer in TempFragment.
+ //
+ FreePool (TempFragment.Bulk);
+
+ } else if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT) &&
+ (RecordHeader.Version.Major == 0x03) &&
+ (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
+ ) {
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+
+ FreePool (BufferIn);
+
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+
+ if (BufferOutSize != 0) {
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ NetbufFree (PacketOut);
+ }
+
+ FreePool (BufferOut);
+
+ //
+ // Get the session state.
+ //
+ GetSessionDataBufferSize = DEF_BUF_LEN;
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (GetSessionDataBuffer);
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool (GetSessionDataBuffer);
+ return Status;
+ }
+
+ ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
+ HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer;
+
+ FreePool (GetSessionDataBuffer);
+
+ if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
+ DEBUG ((EFI_D_ERROR, "TLS Session State Error!\n"));
+ return EFI_ABORTED;
+ }
+
+ BufferIn = NULL;
+ BufferInSize = 0;
+ }
+
+ Fragment->Bulk = BufferIn;
+ Fragment->Len = (UINT32) BufferInSize;
+
+ return Status;
+}
diff --git a/NetworkPkg/HttpDxe/HttpsSupport.h b/NetworkPkg/HttpDxe/HttpsSupport.h
new file mode 100644
index 0000000..d846b76
--- /dev/null
+++ b/NetworkPkg/HttpDxe/HttpsSupport.h
@@ -0,0 +1,260 @@
+/** @file
+ The header files of miscellaneous routines specific to Https for HttpDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_HTTPS_SUPPORT_H__
+#define __EFI_HTTPS_SUPPORT_H__
+
+#define HTTPS_DEFAULT_PORT 443
+
+#define HTTPS_FLAG "https"
+
+/**
+ Check whether the Url is from Https.
+
+ @param[in] Url The pointer to a HTTP or HTTPS URL string.
+
+ @retval TRUE The Url is from HTTPS.
+ @retval FALSE The Url is from HTTP.
+
+**/
+BOOLEAN
+IsHttpsUrl (
+ IN CHAR8 *Url
+ );
+
+/**
+ Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+
+ @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+**/
+EFI_HANDLE
+EFIAPI
+TlsCreateChild (
+ IN EFI_HANDLE ImageHandle,
+ OUT EFI_TLS_PROTOCOL **TlsProto,
+ OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
+ );
+
+/**
+ Create event for the TLS receive and transmit tokens which are used to receive and
+ transmit TLS related messages.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+ @retval EFI_SUCCESS The events are created successfully.
+ @retval others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCreateTxRxEvent (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Close events in the TlsTxToken and TlsRxToken.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+**/
+VOID
+EFIAPI
+TlsCloseTxRxEvent (
+ IN HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Read the TlsCaCertificate variable and configure it.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TlsCaCertificate is configured.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_NOT_FOUND Fail to get "TlsCaCertificate" variable.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+TlsConfigCertificate (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Configure TLS session data.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TLS session data is configured.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigureSession (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Transmit the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+
+ @retval EFI_SUCCESS The packet is transmitted.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonTransmit (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet
+ );
+
+/**
+ Receive the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The Packet is received.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_TIMEOUT The operation is time out.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonReceive (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet,
+ IN EFI_EVENT Timeout
+ );
+
+/**
+ Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
+ corresponding record data. The two parts will be put into two blocks of buffers in the
+ net buffer.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[out] Pdu The received TLS PDU.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS An TLS PDU is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsReceiveOnePdu (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ OUT NET_BUF **Pdu,
+ IN EFI_EVENT Timeout
+ );
+
+/**
+ Connect one TLS session by finishing the TLS handshake process.
+
+ @param[in] HttpInstance The HTTP instance private data.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The TLS session is established.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConnectSession (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN EFI_EVENT Timeout
+ );
+
+/**
+ Close the TLS session and send out the close notification message.
+
+ @param[in] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS The TLS session is closed.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseSession (
+ IN HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Process one message according to the CryptMode.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Message Pointer to the message buffer needed to processed.
+ @param[in] MessageSize Pointer to the message buffer size.
+ @param[in] ProcessMode Process mode.
+ @param[in, out] Fragment Only one Fragment returned after the Message is
+ processed successfully.
+
+ @retval EFI_SUCCESS Message is processed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessMessage (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN UINT8 *Message,
+ IN UINTN MessageSize,
+ IN EFI_TLS_CRYPT_MODE ProcessMode,
+ IN OUT NET_FRAGMENT *Fragment
+ );
+
+/**
+ Receive one fragment decrypted from one TLS record.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in, out] Fragment The received Fragment.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS One fragment is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED Something wrong decryption the message.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+HttpsReceive (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN OUT NET_FRAGMENT *Fragment,
+ IN EFI_EVENT Timeout
+ );
+
+#endif
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6
2016-12-14 7:34 ` [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6 Jiaxin Wu
@ 2016-12-15 2:39 ` Fu, Siyuan
2016-12-15 7:14 ` Wu, Jiaxin
2016-12-22 7:33 ` Ye, Ting
1 sibling, 1 reply; 37+ messages in thread
From: Fu, Siyuan @ 2016-12-15 2:39 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Ye, Ting, Zhang, Lubo, Long, Qin, Thomas Palmer
Hi, Jiaxin
In function IsHttpsUrl(), I suggest to search string "https://" instead of only "https", in case of some incorrect scheme like "httpsabc://".
However, since there is already code to parse the URL by using HttpParseUrl(), the scheme should already been known by the Http url parser, I think it better to add a new function to the HttpLib like HttpUrlGetScheme().
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: 2016年12月14日 15:34
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6
This patch is used to enable HTTPS feature. HttpDxe driver
will consume TlsDxe driver. It can both support http and https
feature, that’s depended on the information of URL, the HTTP
instance can be able to determine whether to use http or https.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/HttpDxe/HttpDriver.h | 10 +-
NetworkPkg/HttpDxe/HttpDxe.inf | 12 +-
NetworkPkg/HttpDxe/HttpImpl.c | 252 +++++-
NetworkPkg/HttpDxe/HttpProto.c | 464 +++++++---
NetworkPkg/HttpDxe/HttpProto.h | 65 +-
NetworkPkg/HttpDxe/HttpsSupport.c | 1692 +++++++++++++++++++++++++++++++++++++
NetworkPkg/HttpDxe/HttpsSupport.h | 260 ++++++
7 files changed, 2601 insertions(+), 154 deletions(-)
create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.c
create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.h
diff --git a/NetworkPkg/HttpDxe/HttpDriver.h b/NetworkPkg/HttpDxe/HttpDriver.h
index fa2372c..93a412a 100644
--- a/NetworkPkg/HttpDxe/HttpDriver.h
+++ b/NetworkPkg/HttpDxe/HttpDriver.h
@@ -22,10 +22,11 @@
//
// Libraries
//
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/NetLib.h>
@@ -48,17 +49,23 @@
#include <Protocol/Tcp6.h>
#include <Protocol/Dns4.h>
#include <Protocol/Dns6.h>
#include <Protocol/Ip4Config2.h>
#include <Protocol/Ip6Config.h>
+#include <Protocol/Tls.h>
+#include <Protocol/TlsConfig.h>
-
+#include <Guid/ImageAuthentication.h>
//
// Produced Protocols
//
#include <Protocol/Http.h>
+#include <Guid/TlsAuthentication.h>
+
+#include <IndustryStandard/Tls1.h>
+
//
// Driver Version
//
#define HTTP_DRIVER_VERSION 0xa
@@ -77,10 +84,11 @@ extern EFI_HTTP_UTILITIES_PROTOCOL *mHttpUtilities;
// Include files with function prototypes
//
#include "ComponentName.h"
#include "HttpImpl.h"
#include "HttpProto.h"
+#include "HttpsSupport.h"
#include "HttpDns.h"
typedef struct {
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UINTN NumberOfChildren;
diff --git a/NetworkPkg/HttpDxe/HttpDxe.inf b/NetworkPkg/HttpDxe/HttpDxe.inf
index bf2cbee..1118181 100644
--- a/NetworkPkg/HttpDxe/HttpDxe.inf
+++ b/NetworkPkg/HttpDxe/HttpDxe.inf
@@ -1,9 +1,9 @@
## @file
# Implementation of EFI HTTP protocol interfaces.
#
-# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
@@ -24,10 +24,11 @@
MODULE_UNI_FILE = HttpDxe.uni
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
[Sources]
ComponentName.h
ComponentName.c
HttpDns.h
@@ -36,14 +37,17 @@
HttpDriver.c
HttpImpl.h
HttpImpl.c
HttpProto.h
HttpProto.c
+ HttpsSupport.h
+ HttpsSupport.c
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
MemoryAllocationLib
BaseLib
UefiLib
DebugLib
NetLib
@@ -62,8 +66,14 @@
gEfiDns4ProtocolGuid ## SOMETIMES_CONSUMES
gEfiDns6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
gEfiDns6ProtocolGuid ## SOMETIMES_CONSUMES
gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTlsServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTlsProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTlsConfigurationProtocolGuid ## SOMETIMES_CONSUMES
+
+[Guids]
+ gEfiTlsCaCertificateGuid ## CONSUMES ## GUID
[UserExtensions.TianoCore."ExtraFiles"]
HttpDxeExtra.uni
\ No newline at end of file
diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c
index 6fcb0b7..77aa64a 100644
--- a/NetworkPkg/HttpDxe/HttpImpl.c
+++ b/NetworkPkg/HttpDxe/HttpImpl.c
@@ -239,10 +239,11 @@ EfiHttpRequest (
UINTN HostNameSize;
UINT16 RemotePort;
HTTP_PROTOCOL *HttpInstance;
BOOLEAN Configure;
BOOLEAN ReConfigure;
+ BOOLEAN TlsConfigure;
CHAR8 *RequestMsg;
CHAR8 *Url;
UINTN UrlLen;
CHAR16 *HostNameStr;
HTTP_TOKEN_WRAP *Wrap;
@@ -258,10 +259,11 @@ EfiHttpRequest (
HostName = NULL;
RequestMsg = NULL;
HostNameStr = NULL;
Wrap = NULL;
FileUrl = NULL;
+ TlsConfigure = FALSE;
if ((This == NULL) || (Token == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -343,10 +345,36 @@ EfiHttpRequest (
HttpInstance->Url = Url;
}
UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);
+
+ //
+ // From the information in Url, the HTTP instance will
+ // be able to determine whether to use http or https.
+ //
+ HttpInstance->UseHttps = IsHttpsUrl (Url);
+
+ //
+ // Check whether we need to create Tls child and open the TLS protocol.
+ //
+ if (HttpInstance->UseHttps && HttpInstance->TlsChildHandle == NULL) {
+ //
+ // Use TlsSb to create Tls child and open the TLS protocol.
+ //
+ HttpInstance->TlsChildHandle = TlsCreateChild (
+ HttpInstance->Service->ImageHandle,
+ &(HttpInstance->Tls),
+ &(HttpInstance->TlsConfiguration)
+ );
+ if (HttpInstance->TlsChildHandle == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ TlsConfigure = TRUE;
+ }
+
UrlParser = NULL;
Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser);
if (EFI_ERROR (Status)) {
goto Error1;
}
@@ -357,11 +385,15 @@ EfiHttpRequest (
goto Error1;
}
Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
if (EFI_ERROR (Status)) {
- RemotePort = HTTP_DEFAULT_PORT;
+ if (HttpInstance->UseHttps) {
+ RemotePort = HTTPS_DEFAULT_PORT;
+ } else {
+ RemotePort = HTTP_DEFAULT_PORT;
+ }
}
//
// If Configure is TRUE, it indicates the first time to call Request();
// If ReConfigure is TRUE, it indicates the request URL is not same
// with the previous call to Request();
@@ -374,13 +406,17 @@ EfiHttpRequest (
// Request() is called the first time.
//
ReConfigure = FALSE;
} else {
if ((HttpInstance->RemotePort == RemotePort) &&
- (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) {
+ (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&
+ (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&
+ !TlsConfigure &&
+ HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))) {
//
// Host Name and port number of the request URL are the same with previous call to Request().
+ // If Https protocol used, the corresponding SessionState is EfiTlsSessionDataTransferring.
// Check whether previous TCP packet sent out.
//
if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) {
//
@@ -480,10 +516,20 @@ EfiHttpRequest (
if (!HttpInstance->LocalAddressIsIPv6) {
ASSERT (HttpInstance->Tcp4 != NULL);
} else {
ASSERT (HttpInstance->Tcp6 != NULL);
}
+
+ if (HttpInstance->UseHttps && !TlsConfigure) {
+ Status = TlsCloseSession (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ goto Error1;
+ }
+
+ TlsCloseTxRxEvent (HttpInstance);
+ }
+
HttpCloseConnection (HttpInstance);
EfiHttpCancel (This, NULL);
}
//
@@ -498,17 +544,22 @@ EfiHttpRequest (
Wrap->HttpToken = Token;
Wrap->HttpInstance = HttpInstance;
if (Request != NULL) {
Wrap->TcpWrap.Method = Request->Method;
}
-
- Status = HttpInitTcp (HttpInstance, Wrap, Configure);
+
+ Status = HttpInitSession (
+ HttpInstance,
+ Wrap,
+ Configure || ReConfigure,
+ TlsConfigure
+ );
if (EFI_ERROR (Status)) {
goto Error2;
- }
+ }
- if (!Configure) {
+ if (!Configure && !ReConfigure && !TlsConfigure) {
//
// For the new HTTP token, create TX TCP token events.
//
Status = HttpCreateTcpTxEvent (Wrap);
if (EFI_ERROR (Status)) {
@@ -591,13 +642,18 @@ Error4:
if (RequestMsg != NULL) {
FreePool (RequestMsg);
}
Error3:
- HttpCloseConnection (HttpInstance);
+ if (HttpInstance->UseHttps) {
+ TlsCloseSession (HttpInstance);
+ TlsCloseTxRxEvent (HttpInstance);
+ }
Error2:
+ HttpCloseConnection (HttpInstance);
+
HttpCloseTcpConnCloseEvent (HttpInstance);
if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {
gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL;
}
@@ -729,26 +785,34 @@ HttpCancel (
} else {
return Status;
}
}
- //
- // Then check the tokens queued by EfiHttpResponse().
- //
- Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens, Token);
- if (EFI_ERROR (Status)) {
- if (Token != NULL) {
- if (Status == EFI_ABORTED) {
- return EFI_SUCCESS;
+ if (!HttpInstance->UseHttps) {
+ //
+ // Then check the tokens queued by EfiHttpResponse(), except for Https.
+ //
+ Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens, Token);
+ if (EFI_ERROR (Status)) {
+ if (Token != NULL) {
+ if (Status == EFI_ABORTED) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_FOUND;
+ }
} else {
- return EFI_NOT_FOUND;
+ return Status;
}
+ }
+ } else {
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken);
} else {
- return Status;
+ HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);
}
}
-
+
return EFI_SUCCESS;
}
/**
@@ -880,10 +944,11 @@ HttpResponseWorker (
HTTP_PROTOCOL *HttpInstance;
EFI_HTTP_TOKEN *Token;
NET_MAP_ITEM *Item;
HTTP_TOKEN_WRAP *ValueInItem;
UINTN HdrLen;
+ NET_FRAGMENT Fragment;
if (Wrap == NULL || Wrap->HttpInstance == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -897,21 +962,15 @@ HttpResponseWorker (
HttpHeaders = NULL;
SizeofHeaders = 0;
BufferSize = 0;
EndofHeader = NULL;
ValueInItem = NULL;
+ Fragment.Len = 0;
+ Fragment.Bulk = NULL;
if (HttpMsg->Data.Response != NULL) {
//
- // Need receive the HTTP headers, prepare buffer.
- //
- Status = HttpCreateTcpRxEventForHeader (HttpInstance);
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- //
// Check whether we have cached header from previous call.
//
if ((HttpInstance->CacheBody != NULL) && (HttpInstance->NextMsg != NULL)) {
//
// The data is stored at [NextMsg, CacheBody + CacheLen].
@@ -1198,13 +1257,120 @@ HttpResponseWorker (
ASSERT (HttpInstance->MsgParser != NULL);
//
// We still need receive more data when there is no cache data and MsgParser is not NULL;
//
- Status = HttpTcpReceiveBody (Wrap, HttpMsg);
- if (EFI_ERROR (Status)) {
- goto Error2;
+ if (!HttpInstance->UseHttps) {
+ Status = HttpTcpReceiveBody (Wrap, HttpMsg);
+
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ } else {
+ if (HttpInstance->TimeoutEvent == NULL) {
+ //
+ // Create TimeoutEvent for response
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &HttpInstance->TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+ }
+
+ //
+ // Start the timer, and wait Timeout seconds to receive the body packet.
+ //
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ Status = HttpsReceive (HttpInstance, &Fragment, HttpInstance->TimeoutEvent);
+
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
+
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ //
+ // Check whether we receive a complete HTTP message.
+ //
+ Status = HttpParseMessageBody (
+ HttpInstance->MsgParser,
+ (UINTN) Fragment.Len,
+ (CHAR8 *) Fragment.Bulk
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
+ //
+ // Free the MsgParse since we already have a full HTTP message.
+ //
+ HttpFreeMsgParser (HttpInstance->MsgParser);
+ HttpInstance->MsgParser = NULL;
+ }
+
+ //
+ // We receive part of header of next HTTP msg.
+ //
+ if (HttpInstance->NextMsg != NULL) {
+ HttpMsg->BodyLength = MIN ((UINTN) (HttpInstance->NextMsg - (CHAR8 *) Fragment.Bulk), HttpMsg->BodyLength);
+ CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
+
+ HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
+ if (HttpInstance->CacheLen != 0) {
+ if (HttpInstance->CacheBody != NULL) {
+ FreePool (HttpInstance->CacheBody);
+ }
+
+ HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
+ if (HttpInstance->CacheBody == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error2;
+ }
+
+ CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
+ HttpInstance->CacheOffset = 0;
+
+ HttpInstance->NextMsg = HttpInstance->CacheBody + (UINTN) (HttpInstance->NextMsg - (CHAR8 *) (Fragment.Bulk + HttpMsg->BodyLength));
+ }
+ } else {
+ HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);
+ CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
+ HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
+ if (HttpInstance->CacheLen != 0) {
+ if (HttpInstance->CacheBody != NULL) {
+ FreePool (HttpInstance->CacheBody);
+ }
+
+ HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
+ if (HttpInstance->CacheBody == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error2;
+ }
+
+ CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
+ HttpInstance->CacheOffset = 0;
+ }
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
+
+ goto Exit;
}
return Status;
Exit:
@@ -1232,19 +1398,30 @@ Error2:
Error:
Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap->HttpToken);
if (Item != NULL) {
NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);
}
-
- HttpTcpTokenCleanup (Wrap);
+
+ if (!HttpInstance->UseHttps) {
+ HttpTcpTokenCleanup (Wrap);
+ } else {
+ FreePool (Wrap);
+ }
if (HttpHeaders != NULL) {
FreePool (HttpHeaders);
+ HttpHeaders = NULL;
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
}
if (HttpMsg->Headers != NULL) {
FreePool (HttpMsg->Headers);
+ HttpMsg->Headers = NULL;
}
if (HttpInstance->CacheBody != NULL) {
FreePool (HttpInstance->CacheBody);
HttpInstance->CacheBody = NULL;
@@ -1351,13 +1528,20 @@ EfiHttpResponse (
}
Wrap->HttpInstance = HttpInstance;
Wrap->HttpToken = Token;
- Status = HttpCreateTcpRxEvent (Wrap);
- if (EFI_ERROR (Status)) {
- goto Error;
+ //
+ // Notes: For Https, receive token wrapped in HTTP_TOKEN_WRAP is not used to
+ // receive the https response. A special TlsRxToken is used for receiving TLS
+ // related messages. It should be a blocking response.
+ //
+ if (!HttpInstance->UseHttps) {
+ Status = HttpCreateTcpRxEvent (Wrap);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
}
Status = NetMapInsertTail (&HttpInstance->RxTokens, Token, Wrap);
if (EFI_ERROR (Status)) {
goto Error;
diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c
index 6373f07..77a3ee3 100644
--- a/NetworkPkg/HttpDxe/HttpProto.c
+++ b/NetworkPkg/HttpDxe/HttpProto.c
@@ -926,10 +926,26 @@ HttpCleanProtocol (
HttpInstance->Service->ImageHandle,
HttpInstance->Handle
);
}
+ if (HttpInstance->TlsConfigData.CACert != NULL) {
+ FreePool (HttpInstance->TlsConfigData.CACert);
+ HttpInstance->TlsConfigData.CACert = NULL;
+ }
+
+ if (HttpInstance->TlsConfigData.ClientCert != NULL) {
+ FreePool (HttpInstance->TlsConfigData.ClientCert);
+ HttpInstance->TlsConfigData.ClientCert = NULL;
+ }
+
+ if (HttpInstance->TlsConfigData.ClientPrivateKey != NULL) {
+ FreePool (HttpInstance->TlsConfigData.ClientPrivateKey);
+ HttpInstance->TlsConfigData.ClientPrivateKey = NULL;
+ }
+
+ TlsCloseTxRxEvent (HttpInstance);
}
/**
Establish TCP connection with HTTP server.
@@ -1183,11 +1199,12 @@ HttpConfigureTcp6 (
return EFI_SUCCESS;
}
/**
- Check existing TCP connection, if in error state, recover TCP4 connection.
+ Check existing TCP connection, if in error state, recover TCP4 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP4 protocol child is not created or configured.
@@ -1224,15 +1241,62 @@ HttpConnectTcp4 (
return EFI_SUCCESS;
} else if (Tcp4State > Tcp4StateEstablished ) {
HttpCloseConnection(HttpInstance);
}
- return HttpCreateConnection (HttpInstance);
+ Status = HttpCreateConnection (HttpInstance);
+ if (EFI_ERROR(Status)){
+ DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status));
+ return Status;
+ }
+
+ //
+ // Tls session connection.
+ //
+ if (HttpInstance->UseHttps) {
+ if (HttpInstance->TimeoutEvent == NULL) {
+ //
+ // Create TimeoutEvent for TLS connection.
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &HttpInstance->TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ //
+ // Start the timer, and wait Timeout seconds for connection.
+ //
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+
+ Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
+
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
+
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ return Status;
}
/**
- Check existing TCP connection, if in error state, recover TCP6 connection.
+ Check existing TCP connection, if in error state, recover TCP6 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP6 protocol child is not created or configured.
@@ -1269,34 +1333,92 @@ HttpConnectTcp6 (
return EFI_SUCCESS;
} else if (Tcp6State > Tcp6StateEstablished ) {
HttpCloseConnection(HttpInstance);
}
- return HttpCreateConnection (HttpInstance);
+ Status = HttpCreateConnection (HttpInstance);
+ if (EFI_ERROR(Status)){
+ DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status));
+ return Status;
+ }
+
+ //
+ // Tls session connection.
+ //
+ if (HttpInstance->UseHttps) {
+ if (HttpInstance->TimeoutEvent == NULL) {
+ //
+ // Create TimeoutEvent for TLS connection.
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &HttpInstance->TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ //
+ // Start the timer, and wait Timeout seconds for connection.
+ //
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+
+ Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
+
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
+
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ return Status;
}
/**
- Initialize TCP related data.
+ Initialize Http session.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
- @param[in] Configure The Flag indicates whether the first time to initialize Tcp.
+ @param[in] Configure The Flag indicates whether need to initialize session.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.
- @retval EFI_SUCCESS The initialization of TCP instance is done.
+ @retval EFI_SUCCESS The initialization of session is done.
@retval Others Other error as indicated.
**/
EFI_STATUS
-HttpInitTcp (
+HttpInitSession (
IN HTTP_PROTOCOL *HttpInstance,
IN HTTP_TOKEN_WRAP *Wrap,
- IN BOOLEAN Configure
+ IN BOOLEAN Configure,
+ IN BOOLEAN TlsConfigure
)
{
EFI_STATUS Status;
ASSERT (HttpInstance != NULL);
+ //
+ // Configure Tls session.
+ //
+ if (TlsConfigure) {
+ Status = TlsConfigureSession (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
if (!HttpInstance->LocalAddressIsIPv6) {
//
// Configure TCP instance.
//
if (Configure) {
@@ -1336,11 +1458,11 @@ HttpInitTcp (
return EFI_SUCCESS;
}
/**
- Send the HTTP message through TCP4 or TCP6.
+ Send the HTTP or HTTPS message through TCP4 or TCP6.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
@param[in] TxString Buffer containing the HTTP message string.
@param[in] TxStringLen Length of the HTTP message string in bytes.
@@ -1360,18 +1482,68 @@ HttpTransmitTcp (
EFI_STATUS Status;
EFI_TCP4_IO_TOKEN *Tx4Token;
EFI_TCP4_PROTOCOL *Tcp4;
EFI_TCP6_IO_TOKEN *Tx6Token;
EFI_TCP6_PROTOCOL *Tcp6;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+ NET_FRAGMENT TempFragment;
+
+ Status = EFI_SUCCESS;
+ Buffer = NULL;
+
+ //
+ // Need to encrypt data.
+ //
+ if (HttpInstance->UseHttps) {
+ //
+ // Build BufferOut data
+ //
+ BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ ((TLS_RECORD_HEADER *) Buffer)->ContentType = TLS_CONTENT_TYPE_APPLICATION_DATA;
+ ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major;
+ ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;
+ ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);
+ CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);
+
+ //
+ // Encrypt Packet.
+ //
+ Status = TlsProcessMessage (
+ HttpInstance,
+ Buffer,
+ BufferSize,
+ EfiTlsEncrypt,
+ &TempFragment
+ );
+
+ FreePool (Buffer);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
- if (!HttpInstance->LocalAddressIsIPv6) {
+ if (!HttpInstance->LocalAddressIsIPv6) {
Tcp4 = HttpInstance->Tcp4;
Tx4Token = &Wrap->TcpWrap.Tx4Token;
+
+ if (HttpInstance->UseHttps) {
+ Tx4Token->Packet.TxData->DataLength = TempFragment.Len;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;
+ } else {
+ Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
+ }
- Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
- Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
- Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
Tx4Token->CompletionToken.Status = EFI_NOT_READY;
Wrap->TcpWrap.IsTxDone = FALSE;
Status = Tcp4->Transmit (Tcp4, Tx4Token);
if (EFI_ERROR (Status)) {
@@ -1380,25 +1552,31 @@ HttpTransmitTcp (
}
} else {
Tcp6 = HttpInstance->Tcp6;
Tx6Token = &Wrap->TcpWrap.Tx6Token;
-
- Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
- Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
- Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
+
+ if (HttpInstance->UseHttps) {
+ Tx6Token->Packet.TxData->DataLength = TempFragment.Len;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;
+ } else {
+ Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
+ }
+
Tx6Token->CompletionToken.Status = EFI_NOT_READY;
Wrap->TcpWrap.IsTxDone = FALSE;
Status = Tcp6->Transmit (Tcp6, Tx6Token);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));
return Status;
}
}
-
return Status;
}
/**
Check whether the user's token or event has already
@@ -1464,11 +1642,11 @@ HttpTcpNotReady (
return EFI_SUCCESS;
}
/**
- Transmit the HTTP mssage by processing the associated HTTP token.
+ Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.
@param[in] Map The container of Tx4Token or Tx6Token.
@param[in] Item Current item to check against.
@param[in] Context The Token to check againist.
@@ -1588,167 +1766,235 @@ HttpTcpReceiveHeader (
EFI_TCP6_IO_TOKEN *Rx6Token;
EFI_TCP6_PROTOCOL *Tcp6;
CHAR8 **EndofHeader;
CHAR8 **HttpHeaders;
CHAR8 *Buffer;
+ NET_FRAGMENT Fragment;
ASSERT (HttpInstance != NULL);
EndofHeader = HttpInstance->EndofHeader;
HttpHeaders = HttpInstance->HttpHeaders;
Tcp4 = HttpInstance->Tcp4;
Tcp6 = HttpInstance->Tcp6;
Buffer = NULL;
Rx4Token = NULL;
Rx6Token = NULL;
+ Fragment.Len = 0;
+ Fragment.Bulk = NULL;
if (HttpInstance->LocalAddressIsIPv6) {
ASSERT (Tcp6 != NULL);
} else {
ASSERT (Tcp4 != NULL);
}
- if (!HttpInstance->LocalAddressIsIPv6) {
- Rx4Token = &HttpInstance->Rx4Token;
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
- if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
+ if (!HttpInstance->UseHttps) {
+ Status = HttpCreateTcpRxEventForHeader (HttpInstance);
+ if (EFI_ERROR (Status)) {
return Status;
}
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ if (!HttpInstance->UseHttps) {
+ Rx4Token = &HttpInstance->Rx4Token;
+ Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
+ if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ }
//
// Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
//
- while (*EndofHeader == NULL) {
- HttpInstance->IsRxDone = FALSE;
- Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
- Status = Tcp4->Receive (Tcp4, Rx4Token);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
- return Status;
- }
-
- while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
- Tcp4->Poll (Tcp4);
+ while (*EndofHeader == NULL) {
+ if (!HttpInstance->UseHttps) {
+ HttpInstance->IsRxDone = FALSE;
+ Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
+ Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
+ Status = Tcp4->Receive (Tcp4, Rx4Token);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
+ return Status;
+ }
+
+ while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ Tcp4->Poll (Tcp4);
+ }
+
+ if (!HttpInstance->IsRxDone) {
+ //
+ // Cancle the Token before close its Event.
+ //
+ Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
+ gBS->CloseEvent (Rx4Token->CompletionToken.Event);
+ Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
+ }
+
+ Status = Rx4Token->CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Fragment.Len = Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ Fragment.Bulk = (UINT8 *) Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
+ } else {
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
+
+ Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
+ return Status;
+ }
}
- if (!HttpInstance->IsRxDone) {
- //
- // Cancle the Token before close its Event.
- //
- Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
- gBS->CloseEvent (Rx4Token->CompletionToken.Event);
- Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
- }
-
- Status = Rx4Token->CompletionToken.Status;
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
//
// Append the response string.
//
- *BufferSize = (*SizeofHeaders) + Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ *BufferSize = *SizeofHeaders + Fragment.Len;
Buffer = AllocateZeroPool (*BufferSize);
if (Buffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
return Status;
}
-
+
if (*HttpHeaders != NULL) {
- CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
+ CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
FreePool (*HttpHeaders);
}
-
+
CopyMem (
- Buffer + (*SizeofHeaders),
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength
+ Buffer + *SizeofHeaders,
+ Fragment.Bulk,
+ Fragment.Len
);
- *HttpHeaders = Buffer;
- *SizeofHeaders = *BufferSize;
-
+ *HttpHeaders = Buffer;
+ *SizeofHeaders = *BufferSize;
+
//
// Check whether we received end of HTTP headers.
//
*EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
- }
- FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+ };
+ //
+ // Free the buffer.
+ //
+ if (Rx4Token != NULL && Rx4Token->Packet.RxData != NULL && Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
+ FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
+ Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+ Fragment.Bulk = NULL;
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
} else {
- Rx6Token = &HttpInstance->Rx6Token;
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
- if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
+ if (!HttpInstance->UseHttps) {
+ Rx6Token = &HttpInstance->Rx6Token;
+ Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
+ if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
}
//
// Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
//
- while (*EndofHeader == NULL) {
- HttpInstance->IsRxDone = FALSE;
- Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
- Status = Tcp6->Receive (Tcp6, Rx6Token);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
- return Status;
- }
-
- while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
- Tcp6->Poll (Tcp6);
+ while (*EndofHeader == NULL) {
+ if (!HttpInstance->UseHttps) {
+ HttpInstance->IsRxDone = FALSE;
+ Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
+ Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
+ Status = Tcp6->Receive (Tcp6, Rx6Token);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
+ return Status;
+ }
+
+ while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ Tcp6->Poll (Tcp6);
+ }
+
+ if (!HttpInstance->IsRxDone) {
+ //
+ // Cancle the Token before close its Event.
+ //
+ Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
+ gBS->CloseEvent (Rx6Token->CompletionToken.Event);
+ Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
+ }
+
+ Status = Rx6Token->CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Fragment.Len = Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ Fragment.Bulk = (UINT8 *) Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
+ } else {
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
+
+ Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
+ return Status;
+ }
}
- if (!HttpInstance->IsRxDone) {
- //
- // Cancle the Token before close its Event.
- //
- Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
- gBS->CloseEvent (Rx6Token->CompletionToken.Event);
- Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
- }
-
- Status = Rx6Token->CompletionToken.Status;
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
//
// Append the response string.
//
- *BufferSize = (*SizeofHeaders) + Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ *BufferSize = *SizeofHeaders + Fragment.Len;
Buffer = AllocateZeroPool (*BufferSize);
if (Buffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
return Status;
}
-
+
if (*HttpHeaders != NULL) {
- CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
+ CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
FreePool (*HttpHeaders);
}
-
+
CopyMem (
- Buffer + (*SizeofHeaders),
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength
+ Buffer + *SizeofHeaders,
+ Fragment.Bulk,
+ Fragment.Len
);
- *HttpHeaders = Buffer;
- *SizeofHeaders = *BufferSize;
-
+ *HttpHeaders = Buffer;
+ *SizeofHeaders = *BufferSize;
+
//
// Check whether we received end of HTTP headers.
//
- *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
-
+ *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
+ };
+
+ //
+ // Free the buffer.
+ //
+ if (Rx6Token != NULL && Rx6Token->Packet.RxData != NULL && Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
+ FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
+ Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+ Fragment.Bulk = NULL;
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
}
- FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
}
//
// Skip the CRLF after the HTTP headers.
//
diff --git a/NetworkPkg/HttpDxe/HttpProto.h b/NetworkPkg/HttpDxe/HttpProto.h
index e1fd785..e3b3275 100644
--- a/NetworkPkg/HttpDxe/HttpProto.h
+++ b/NetworkPkg/HttpDxe/HttpProto.h
@@ -81,10 +81,24 @@ typedef struct {
BOOLEAN IsRxDone;
UINTN BodyLen;
EFI_HTTP_METHOD Method;
} HTTP_TCP_TOKEN_WRAP;
+typedef struct {
+ EFI_TLS_VERSION Version;
+ EFI_TLS_CONNECTION_END ConnectionEnd;
+ EFI_TLS_VERIFY VerifyMethod;
+ EFI_TLS_SESSION_STATE SessionState;
+
+ VOID *CACert;
+ UINTN CACertSize;
+ VOID *ClientCert;
+ UINTN ClientCertSize;
+ VOID *ClientPrivateKey;
+ UINTN ClientPrivateKeySize;
+} TLS_CONFIG_DATA;
+
typedef struct _HTTP_PROTOCOL {
UINT32 Signature;
EFI_HTTP_PROTOCOL Http;
EFI_HANDLE Handle;
HTTP_SERVICE *Service;
@@ -151,10 +165,39 @@ typedef struct _HTTP_PROTOCOL {
NET_MAP TxTokens;
NET_MAP RxTokens;
CHAR8 *Url;
+
+ //
+ // Https Support
+ //
+ BOOLEAN UseHttps;
+
+ EFI_HANDLE TlsChildHandle; /// Tls ChildHandle
+ TLS_CONFIG_DATA TlsConfigData;
+ EFI_TLS_PROTOCOL *Tls;
+ EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfiguration;
+ EFI_TLS_SESSION_STATE TlsSessionState;
+
+ //
+ // TlsTxData used for transmitting TLS related messages.
+ //
+ EFI_TCP4_IO_TOKEN Tcp4TlsTxToken;
+ EFI_TCP4_TRANSMIT_DATA Tcp4TlsTxData;
+ EFI_TCP6_IO_TOKEN Tcp6TlsTxToken;
+ EFI_TCP6_TRANSMIT_DATA Tcp6TlsTxData;
+ BOOLEAN TlsIsTxDone;
+
+ //
+ // TlsRxData used for receiving TLS related messages.
+ //
+ EFI_TCP4_IO_TOKEN Tcp4TlsRxToken;
+ EFI_TCP4_RECEIVE_DATA Tcp4TlsRxData;
+ EFI_TCP6_IO_TOKEN Tcp6TlsRxToken;
+ EFI_TCP6_RECEIVE_DATA Tcp6TlsRxData;
+ BOOLEAN TlsIsRxDone;
} HTTP_PROTOCOL;
typedef struct {
EFI_HTTP_TOKEN *HttpToken;
HTTP_PROTOCOL *HttpInstance;
@@ -350,11 +393,12 @@ HttpConfigureTcp6 (
IN HTTP_PROTOCOL *HttpInstance,
IN HTTP_TOKEN_WRAP *Wrap
);
/**
- Check existing TCP connection, if in error state, receover TCP4 connection.
+ Check existing TCP connection, if in error state, recover TCP4 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP4 protocol child is not created or configured.
@@ -365,11 +409,12 @@ EFI_STATUS
HttpConnectTcp4 (
IN HTTP_PROTOCOL *HttpInstance
);
/**
- Check existing TCP connection, if in error state, recover TCP6 connection.
+ Check existing TCP connection, if in error state, recover TCP6 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP6 protocol child is not created or configured.
@@ -380,11 +425,11 @@ EFI_STATUS
HttpConnectTcp6 (
IN HTTP_PROTOCOL *HttpInstance
);
/**
- Send the HTTP message through TCP4 or TCP6.
+ Send the HTTP or HTTPS message through TCP4 or TCP6.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
@param[in] TxString Buffer containing the HTTP message string.
@param[in] TxStringLen Length of the HTTP message string in bytes.
@@ -441,29 +486,31 @@ HttpTcpNotReady (
IN NET_MAP_ITEM *Item,
IN VOID *Context
);
/**
- Initialize TCP related data.
+ Initialize Http session.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
- @param[in] Configure The Flag indicates whether the first time to initialize Tcp.
+ @param[in] Configure The Flag indicates whether need to initialize session.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.
- @retval EFI_SUCCESS The initialization of TCP instance is done.
+ @retval EFI_SUCCESS The initialization of session is done.
@retval Others Other error as indicated.
**/
EFI_STATUS
-HttpInitTcp (
+HttpInitSession (
IN HTTP_PROTOCOL *HttpInstance,
IN HTTP_TOKEN_WRAP *Wrap,
- IN BOOLEAN Configure
+ IN BOOLEAN Configure,
+ IN BOOLEAN TlsConfigure
);
/**
- Transmit the HTTP mssage by processing the associated HTTP token.
+ Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.
@param[in] Map The container of TxToken or Tx6Token.
@param[in] Item Current item to check against.
@param[in] Context The Token to check againist.
diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c b/NetworkPkg/HttpDxe/HttpsSupport.c
new file mode 100644
index 0000000..177b9a8
--- /dev/null
+++ b/NetworkPkg/HttpDxe/HttpsSupport.c
@@ -0,0 +1,1692 @@
+/** @file
+ Miscellaneous routines specific to Https for HttpDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "HttpDriver.h"
+
+/**
+ Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-terminated
+ ASCII string and ignore case during the search process.
+
+ This function scans the contents of the ASCII string specified by String
+ and returns the first occurrence of SearchString and ignore case during the search process.
+ If SearchString is not found in String, then NULL is returned. If the length of SearchString
+ is zero, then String is returned.
+
+ If String is NULL, then ASSERT().
+ If SearchString is NULL, then ASSERT().
+
+ @param[in] String A pointer to a Null-terminated ASCII string.
+ @param[in] SearchString A pointer to a Null-terminated ASCII string to search for.
+
+ @retval NULL If the SearchString does not appear in String.
+ @retval others If there is a match return the first occurrence of SearchingString.
+ If the length of SearchString is zero,return String.
+
+**/
+CHAR8 *
+AsciiStrCaseStr (
+ IN CONST CHAR8 *String,
+ IN CONST CHAR8 *SearchString
+ )
+{
+ CONST CHAR8 *FirstMatch;
+ CONST CHAR8 *SearchStringTmp;
+
+ CHAR8 Src;
+ CHAR8 Dst;
+
+ //
+ // ASSERT both strings are less long than PcdMaximumAsciiStringLength
+ //
+ ASSERT (AsciiStrSize (String) != 0);
+ ASSERT (AsciiStrSize (SearchString) != 0);
+
+ if (*SearchString == '\0') {
+ return (CHAR8 *) String;
+ }
+
+ while (*String != '\0') {
+ SearchStringTmp = SearchString;
+ FirstMatch = String;
+
+ while ((*SearchStringTmp != '\0')
+ && (*String != '\0')) {
+ Src = *String;
+ Dst = *SearchStringTmp;
+
+ if ((Src >= 'A') && (Src <= 'Z')) {
+ Src -= ('A' - 'a');
+ }
+
+ if ((Dst >= 'A') && (Dst <= 'Z')) {
+ Dst -= ('A' - 'a');
+ }
+
+ if (Src != Dst) {
+ break;
+ }
+
+ String++;
+ SearchStringTmp++;
+ }
+
+ if (*SearchStringTmp == '\0') {
+ return (CHAR8 *) FirstMatch;
+ }
+
+ String = FirstMatch + 1;
+ }
+
+ return NULL;
+}
+
+/**
+ The callback function to free the net buffer list.
+
+ @param[in] Arg The opaque parameter.
+
+**/
+VOID
+EFIAPI
+FreeNbufList (
+ IN VOID *Arg
+ )
+{
+ ASSERT (Arg != NULL);
+
+ NetbufFreeList ((LIST_ENTRY *) Arg);
+ FreePool (Arg);
+}
+
+/**
+ Check whether the Url is from Https.
+
+ @param[in] Url The pointer to a HTTP or HTTPS URL string.
+
+ @retval TRUE The Url is from HTTPS.
+ @retval FALSE The Url is from HTTP.
+
+**/
+BOOLEAN
+IsHttpsUrl (
+ IN CHAR8 *Url
+ )
+{
+ CHAR8 *Tmp;
+
+ Tmp = NULL;
+
+ Tmp = AsciiStrCaseStr (Url, HTTPS_FLAG);
+ if (Tmp != NULL && Tmp == Url) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+
+ @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+**/
+EFI_HANDLE
+EFIAPI
+TlsCreateChild (
+ IN EFI_HANDLE ImageHandle,
+ OUT EFI_TLS_PROTOCOL **TlsProto,
+ OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
+ )
+{
+ EFI_STATUS Status;
+ EFI_SERVICE_BINDING_PROTOCOL *TlsSb;
+ EFI_HANDLE TlsChildHandle;
+
+ TlsSb = NULL;
+ TlsChildHandle = 0;
+
+ //
+ // Locate TlsServiceBinding protocol.
+ //
+ gBS->LocateProtocol (
+ &gEfiTlsServiceBindingProtocolGuid,
+ NULL,
+ (VOID **) &TlsSb
+ );
+ if (TlsSb == NULL) {
+ return NULL;
+ }
+
+ Status = TlsSb->CreateChild (TlsSb, &TlsChildHandle);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Status = gBS->OpenProtocol (
+ TlsChildHandle,
+ &gEfiTlsProtocolGuid,
+ (VOID **) TlsProto,
+ ImageHandle,
+ TlsChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ TlsSb->DestroyChild (TlsSb, TlsChildHandle);
+ return NULL;
+ }
+
+ Status = gBS->OpenProtocol (
+ TlsChildHandle,
+ &gEfiTlsConfigurationProtocolGuid,
+ (VOID **) TlsConfiguration,
+ ImageHandle,
+ TlsChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ TlsSb->DestroyChild (TlsSb, TlsChildHandle);
+ return NULL;
+ }
+
+ return TlsChildHandle;
+}
+
+/**
+ Create event for the TLS receive and transmit tokens which are used to receive and
+ transmit TLS related messages.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+ @retval EFI_SUCCESS The events are created successfully.
+ @retval others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCreateTxRxEvent (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ //
+ // For Tcp4TlsTxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsTxDone,
+ &HttpInstance->Tcp4TlsTxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp4TlsTxData.Push = TRUE;
+ HttpInstance->Tcp4TlsTxData.Urgent = FALSE;
+ HttpInstance->Tcp4TlsTxData.DataLength = 0;
+ HttpInstance->Tcp4TlsTxData.FragmentCount = 1;
+ HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsTxData.DataLength;
+ HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp4TlsTxToken.Packet.TxData = &HttpInstance->Tcp4TlsTxData;
+ HttpInstance->Tcp4TlsTxToken.CompletionToken.Status = EFI_NOT_READY;
+
+ //
+ // For Tcp4TlsRxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsRxDone,
+ &HttpInstance->Tcp4TlsRxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp4TlsRxData.DataLength = 0;
+ HttpInstance->Tcp4TlsRxData.FragmentCount = 1;
+ HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsRxData.DataLength ;
+ HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp4TlsRxToken.Packet.RxData = &HttpInstance->Tcp4TlsRxData;
+ HttpInstance->Tcp4TlsRxToken.CompletionToken.Status = EFI_NOT_READY;
+ } else {
+ //
+ // For Tcp6TlsTxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsTxDone,
+ &HttpInstance->Tcp6TlsTxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp6TlsTxData.Push = TRUE;
+ HttpInstance->Tcp6TlsTxData.Urgent = FALSE;
+ HttpInstance->Tcp6TlsTxData.DataLength = 0;
+ HttpInstance->Tcp6TlsTxData.FragmentCount = 1;
+ HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsTxData.DataLength;
+ HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp6TlsTxToken.Packet.TxData = &HttpInstance->Tcp6TlsTxData;
+ HttpInstance->Tcp6TlsTxToken.CompletionToken.Status = EFI_NOT_READY;
+
+ //
+ // For Tcp6TlsRxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsRxDone,
+ &HttpInstance->Tcp6TlsRxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp6TlsRxData.DataLength = 0;
+ HttpInstance->Tcp6TlsRxData.FragmentCount = 1;
+ HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsRxData.DataLength ;
+ HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp6TlsRxToken.Packet.RxData = &HttpInstance->Tcp6TlsRxData;
+ HttpInstance->Tcp6TlsRxToken.CompletionToken.Status = EFI_NOT_READY;
+ }
+
+ return Status;
+
+ERROR:
+ //
+ // Error handling
+ //
+ TlsCloseTxRxEvent (HttpInstance);
+
+ return Status;
+}
+
+/**
+ Close events in the TlsTxToken and TlsRxToken.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+**/
+VOID
+EFIAPI
+TlsCloseTxRxEvent (
+ IN HTTP_PROTOCOL *HttpInstance
+ )
+{
+ ASSERT (HttpInstance != NULL);
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ if (NULL != HttpInstance->Tcp4TlsTxToken.CompletionToken.Event) {
+ gBS->CloseEvent(HttpInstance->Tcp4TlsTxToken.CompletionToken.Event);
+ HttpInstance->Tcp4TlsTxToken.CompletionToken.Event = NULL;
+ }
+
+ if (NULL != HttpInstance->Tcp4TlsRxToken.CompletionToken.Event) {
+ gBS->CloseEvent (HttpInstance->Tcp4TlsRxToken.CompletionToken.Event);
+ HttpInstance->Tcp4TlsRxToken.CompletionToken.Event = NULL;
+ }
+ } else {
+ if (NULL != HttpInstance->Tcp6TlsTxToken.CompletionToken.Event) {
+ gBS->CloseEvent(HttpInstance->Tcp6TlsTxToken.CompletionToken.Event);
+ HttpInstance->Tcp6TlsTxToken.CompletionToken.Event = NULL;
+ }
+
+ if (NULL != HttpInstance->Tcp6TlsRxToken.CompletionToken.Event) {
+ gBS->CloseEvent (HttpInstance->Tcp6TlsRxToken.CompletionToken.Event);
+ HttpInstance->Tcp6TlsRxToken.CompletionToken.Event = NULL;
+ }
+ }
+}
+
+/**
+ Read the TlsCaCertificate variable and configure it.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TlsCaCertificate is configured.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+TlsConfigCertificate (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *CACert;
+ UINTN CACertSize;
+ UINT32 Index;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINTN CertCount;
+ UINT32 ItemDataSize;
+
+ CACert = (UINT8 *) HttpInstance->TlsConfigData.CACert;
+ CACertSize = HttpInstance->TlsConfigData.CACertSize;
+
+ //
+ // Try to read the TlsCaCertificate variable.
+ //
+ CACertSize = 0;
+ Status = gRT->GetVariable (
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ NULL,
+ &CACertSize,
+ NULL
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ //
+ // Allocate buffer and read the config variable.
+ //
+ CACert = AllocatePool (CACertSize);
+ if (CACert == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gRT->GetVariable (
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ NULL,
+ &CACertSize,
+ CACert
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // GetVariable still error or the variable is corrupted.
+ // Fall back to the default value.
+ //
+ FreePool (CACert);
+
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ //
+ // Enumerate all data and erasing the target item.
+ //
+ ItemDataSize = (UINT32) CACertSize;
+ CertList = (EFI_SIGNATURE_LIST *) CACert;
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ //
+ // EfiTlsConfigDataTypeCACertificate
+ //
+ Status = HttpInstance->TlsConfiguration->SetData (
+ HttpInstance->TlsConfiguration,
+ EfiTlsConfigDataTypeCACertificate,
+ Cert->SignatureData,
+ CertList->SignatureSize - sizeof (Cert->SignatureOwner)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ return Status;
+}
+
+/**
+ Configure TLS session data.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TLS session data is configured.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigureSession (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // TlsConfigData initialization
+ //
+ HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient;
+ HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER;
+ HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted;
+
+ //
+ // EfiTlsConnectionEnd,
+ // EfiTlsVerifyMethod
+ // EfiTlsSessionState
+ //
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsConnectionEnd,
+ &(HttpInstance->TlsConfigData.ConnectionEnd),
+ sizeof (EFI_TLS_CONNECTION_END)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsVerifyMethod,
+ &HttpInstance->TlsConfigData.VerifyMethod,
+ sizeof (EFI_TLS_VERIFY)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ &(HttpInstance->TlsConfigData.SessionState),
+ sizeof (EFI_TLS_SESSION_STATE)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ //
+ // Tls Config Certificate
+ //
+ Status = TlsConfigCertificate (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "TLS Certificate Config Error!\n"));
+ goto ERROR;
+ }
+
+ //
+ // TlsCreateTxRxEvent
+ //
+ Status = TlsCreateTxRxEvent (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ return Status;
+
+ERROR:
+ TlsCloseTxRxEvent (HttpInstance);
+
+ return Status;
+}
+
+/**
+ Transmit the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+
+ @retval EFI_SUCCESS The packet is transmitted.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonTransmit (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ UINTN Size;
+
+ if ((HttpInstance == NULL) || (Packet == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Size = sizeof (EFI_TCP4_TRANSMIT_DATA) +
+ (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA);
+ } else {
+ Size = sizeof (EFI_TCP6_TRANSMIT_DATA) +
+ (Packet->BlockOpNum - 1) * sizeof (EFI_TCP6_FRAGMENT_DATA);
+ }
+
+ Data = AllocatePool (Size);
+ if (Data == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->Push = TRUE;
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->Urgent = FALSE;
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
+
+ //
+ // Build the fragment table.
+ //
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum;
+
+ NetbufBuildExt (
+ Packet,
+ (NET_FRAGMENT *) &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentTable[0],
+ &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount
+ );
+
+ HttpInstance->Tcp4TlsTxToken.Packet.TxData = (EFI_TCP4_TRANSMIT_DATA *) Data;
+
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ // Transmit the packet.
+ //
+ Status = HttpInstance->Tcp4->Transmit (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsTxToken);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ while (!HttpInstance->TlsIsTxDone) {
+ HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
+ }
+
+ HttpInstance->TlsIsTxDone = FALSE;
+ Status = HttpInstance->Tcp4TlsTxToken.CompletionToken.Status;
+ } else {
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->Push = TRUE;
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->Urgent = FALSE;
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
+
+ //
+ // Build the fragment table.
+ //
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum;
+
+ NetbufBuildExt (
+ Packet,
+ (NET_FRAGMENT *) &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentTable[0],
+ &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount
+ );
+
+ HttpInstance->Tcp6TlsTxToken.Packet.TxData = (EFI_TCP6_TRANSMIT_DATA *) Data;
+
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ // Transmit the packet.
+ //
+ Status = HttpInstance->Tcp6->Transmit (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsTxToken);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ while (!HttpInstance->TlsIsTxDone) {
+ HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
+ }
+
+ HttpInstance->TlsIsTxDone = FALSE;
+ Status = HttpInstance->Tcp6TlsTxToken.CompletionToken.Status;
+ }
+
+ON_EXIT:
+ FreePool (Data);
+
+ return Status;
+}
+
+/**
+ Receive the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The Packet is received.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_TIMEOUT The operation is time out.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonReceive (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_TCP4_RECEIVE_DATA *Tcp4RxData;
+ EFI_TCP6_RECEIVE_DATA *Tcp6RxData;
+ EFI_STATUS Status;
+ NET_FRAGMENT *Fragment;
+ UINT32 FragmentCount;
+ UINT32 CurrentFragment;
+
+ Tcp4RxData = NULL;
+ Tcp6RxData = NULL;
+
+ if ((HttpInstance == NULL) || (Packet == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FragmentCount = Packet->BlockOpNum;
+ Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));
+ if (Fragment == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Build the fragment table.
+ //
+ NetbufBuildExt (Packet, Fragment, &FragmentCount);
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Tcp4RxData = HttpInstance->Tcp4TlsRxToken.Packet.RxData;
+ if (Tcp4RxData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Tcp4RxData->FragmentCount = 1;
+ } else {
+ Tcp6RxData = HttpInstance->Tcp6TlsRxToken.Packet.RxData;
+ if (Tcp6RxData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Tcp6RxData->FragmentCount = 1;
+ }
+
+ CurrentFragment = 0;
+ Status = EFI_SUCCESS;
+
+ while (CurrentFragment < FragmentCount) {
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Tcp4RxData->DataLength = Fragment[CurrentFragment].Len;
+ Tcp4RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
+ Tcp4RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
+ Status = HttpInstance->Tcp4->Receive (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken);
+ } else {
+ Tcp6RxData->DataLength = Fragment[CurrentFragment].Len;
+ Tcp6RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
+ Tcp6RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
+ Status = HttpInstance->Tcp6->Receive (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken);
+ }
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ while (!HttpInstance->TlsIsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ //
+ // Poll until some data is received or an error occurs.
+ //
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
+ } else {
+ HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
+ }
+ }
+
+ if (!HttpInstance->TlsIsRxDone) {
+ //
+ // Timeout occurs, cancel the receive request.
+ //
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken);
+ } else {
+ HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);
+ }
+
+ Status = EFI_TIMEOUT;
+ goto ON_EXIT;
+ } else {
+ HttpInstance->TlsIsRxDone = FALSE;
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Status = HttpInstance->Tcp4TlsRxToken.CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Fragment[CurrentFragment].Len -= Tcp4RxData->FragmentTable[0].FragmentLength;
+ if (Fragment[CurrentFragment].Len == 0) {
+ CurrentFragment++;
+ } else {
+ Fragment[CurrentFragment].Bulk += Tcp4RxData->FragmentTable[0].FragmentLength;
+ }
+ } else {
+ Status = HttpInstance->Tcp6TlsRxToken.CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Fragment[CurrentFragment].Len -= Tcp6RxData->FragmentTable[0].FragmentLength;
+ if (Fragment[CurrentFragment].Len == 0) {
+ CurrentFragment++;
+ } else {
+ Fragment[CurrentFragment].Bulk += Tcp6RxData->FragmentTable[0].FragmentLength;
+ }
+ }
+ }
+
+ON_EXIT:
+
+ if (Fragment != NULL) {
+ FreePool (Fragment);
+ }
+
+ return Status;
+}
+
+/**
+ Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
+ corresponding record data. This two parts will be put into two blocks of buffers in the
+ net buffer.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[out] Pdu The received TLS PDU.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS An TLS PDU is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsReceiveOnePdu (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ OUT NET_BUF **Pdu,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_STATUS Status;
+
+ LIST_ENTRY *NbufList;
+
+ UINT32 Len;
+
+ NET_BUF *PduHdr;
+ UINT8 *Header;
+ TLS_RECORD_HEADER RecordHeader;
+
+ NET_BUF *DataSeg;
+
+ NbufList = NULL;
+ PduHdr = NULL;
+ Header = NULL;
+ DataSeg = NULL;
+
+ NbufList = AllocatePool (sizeof (LIST_ENTRY));
+ if (NbufList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InitializeListHead (NbufList);
+
+ //
+ // Allocate buffer to receive one TLS header.
+ //
+ Len = sizeof (TLS_RECORD_HEADER);
+ PduHdr = NetbufAlloc (Len);
+ if (PduHdr == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);
+ if (Header == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // First step, receive one TLS header.
+ //
+ Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ RecordHeader = *(TLS_RECORD_HEADER *) Header;
+ if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_HANDSHAKE ||
+ RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT ||
+ RecordHeader.ContentType == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC ||
+ RecordHeader.ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA) &&
+ (RecordHeader.Version.Major == 0x03) && /// Major versions are same.
+ (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor ==TLS11_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
+ ) {
+ InsertTailList (NbufList, &PduHdr->List);
+ } else {
+ Status = EFI_PROTOCOL_ERROR;
+ goto ON_EXIT;
+ }
+
+ Len = SwapBytes16(RecordHeader.Length);
+ if (Len == 0) {
+ //
+ // No TLS payload.
+ //
+ goto FORM_PDU;
+ }
+
+ //
+ // Allocate buffer to receive one TLS payload.
+ //
+ DataSeg = NetbufAlloc (Len);
+ if (DataSeg == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL);
+
+ //
+ // Second step, receive one TLS payload.
+ //
+ Status = TlsCommonReceive (HttpInstance, DataSeg, Timeout);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ InsertTailList (NbufList, &DataSeg->List);
+
+FORM_PDU:
+ //
+ // Form the PDU from a list of PDU.
+ //
+ *Pdu = NetbufFromBufList (NbufList, 0, 0, FreeNbufList, NbufList);
+ if (*Pdu == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ON_EXIT:
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Free the Nbufs in this NbufList and the NbufList itself.
+ //
+ FreeNbufList (NbufList);
+ }
+
+ return Status;
+}
+
+/**
+ Connect one TLS session by finishing the TLS handshake process.
+
+ @param[in] HttpInstance The HTTP instance private data.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The TLS session is established.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConnectSession (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *BufferOut;
+ UINTN BufferOutSize;
+ NET_BUF *PacketOut;
+ UINT8 *DataOut;
+ NET_BUF *Pdu;
+ UINT8 *BufferIn;
+ UINTN BufferInSize;
+ UINT8 *GetSessionDataBuffer;
+ UINTN GetSessionDataBufferSize;
+
+ BufferOut = NULL;
+ PacketOut = NULL;
+ DataOut = NULL;
+ Pdu = NULL;
+ BufferIn = NULL;
+
+ //
+ // Initialize TLS state.
+ //
+ HttpInstance->TlsSessionState = EfiTlsSessionNotStarted;
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ &(HttpInstance->TlsSessionState),
+ sizeof (EFI_TLS_SESSION_STATE)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Create ClientHello
+ //
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+
+ //
+ // Transmit ClientHello
+ //
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ FreePool (BufferOut);
+ NetbufFree (PacketOut);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while(HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring && \
+ ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ //
+ // Receive one TLS record.
+ //
+ Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BufferInSize = Pdu->TotalSize;
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ NetbufFree (Pdu);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn);
+
+ NetbufFree (Pdu);
+
+ //
+ // Handle Receive data.
+ //
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+
+ FreePool (BufferIn);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (BufferOutSize != 0) {
+ //
+ // Transmit the response packet.
+ //
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ NetbufFree (PacketOut);
+
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+ }
+
+ FreePool (BufferOut);
+
+ //
+ // Get the session state, then decide whether need to continue handle received packet.
+ //
+ GetSessionDataBufferSize = DEF_BUF_LEN;
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (GetSessionDataBuffer);
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool(GetSessionDataBuffer);
+ return Status;
+ }
+
+ ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
+ HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer;
+
+ FreePool (GetSessionDataBuffer);
+
+ if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
+ return EFI_ABORTED;
+ }
+ }
+
+ if (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring) {
+ Status = EFI_ABORTED;
+ }
+
+ return Status;
+}
+
+/**
+ Close the TLS session and send out the close notification message.
+
+ @param[in] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS The TLS session is closed.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseSession (
+ IN HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+
+ UINT8 *BufferOut;
+ UINTN BufferOutSize;
+
+ NET_BUF *PacketOut;
+ UINT8 *DataOut;
+
+ Status = EFI_SUCCESS;
+ BufferOut = NULL;
+ PacketOut = NULL;
+ DataOut = NULL;
+
+ if (HttpInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HttpInstance->TlsSessionState = EfiTlsSessionClosing;
+
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ &(HttpInstance->TlsSessionState),
+ sizeof (EFI_TLS_SESSION_STATE)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ FreePool (BufferOut);
+ NetbufFree (PacketOut);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+/**
+ Process one message according to the CryptMode.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Message Pointer to the message buffer needed to processed.
+ @param[in] MessageSize Pointer to the message buffer size.
+ @param[in] ProcessMode Process mode.
+ @param[in, out] Fragment Only one Fragment returned after the Message is
+ processed successfully.
+
+ @retval EFI_SUCCESS Message is processed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessMessage (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN UINT8 *Message,
+ IN UINTN MessageSize,
+ IN EFI_TLS_CRYPT_MODE ProcessMode,
+ IN OUT NET_FRAGMENT *Fragment
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+ UINT32 BufferSize;
+ UINT32 BytesCopied;
+ EFI_TLS_FRAGMENT_DATA *FragmentTable;
+ UINT32 FragmentCount;
+ EFI_TLS_FRAGMENT_DATA *OriginalFragmentTable;
+ UINTN Index;
+
+ Status = EFI_SUCCESS;
+ Buffer = NULL;
+ BufferSize = 0;
+ BytesCopied = 0;
+ FragmentTable = NULL;
+ OriginalFragmentTable = NULL;
+
+ //
+ // Rebuild fragment table from BufferIn.
+ //
+ FragmentCount = 1;
+ FragmentTable = AllocateZeroPool (FragmentCount * sizeof (EFI_TLS_FRAGMENT_DATA));
+ if (FragmentTable == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ FragmentTable->FragmentLength = (UINT32) MessageSize;
+ FragmentTable->FragmentBuffer = Message;
+
+ //
+ // Record the original FragmentTable.
+ //
+ OriginalFragmentTable = FragmentTable;
+
+ //
+ // Process the Message.
+ //
+ Status = HttpInstance->Tls->ProcessPacket (
+ HttpInstance->Tls,
+ &FragmentTable,
+ &FragmentCount,
+ ProcessMode
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Calculate the size according to FragmentTable.
+ //
+ for (Index = 0; Index < FragmentCount; Index++) {
+ BufferSize += FragmentTable[Index].FragmentLength;
+ }
+
+ //
+ // Allocate buffer for processed data.
+ //
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Copy the new FragmentTable buffer into Buffer.
+ //
+ for (Index = 0; Index < FragmentCount; Index++) {
+ CopyMem (
+ (Buffer + BytesCopied),
+ FragmentTable[Index].FragmentBuffer,
+ FragmentTable[Index].FragmentLength
+ );
+ BytesCopied += FragmentTable[Index].FragmentLength;
+
+ //
+ // Free the FragmentBuffer since it has been copied.
+ //
+ FreePool (FragmentTable[Index].FragmentBuffer);
+ }
+
+ Fragment->Len = BufferSize;
+ Fragment->Bulk = Buffer;
+
+ON_EXIT:
+
+ if (OriginalFragmentTable != NULL) {
+ FreePool (OriginalFragmentTable);
+ OriginalFragmentTable = NULL;
+ }
+
+ //
+ // Caller has the responsibility to free the FragmentTable.
+ //
+ if (FragmentTable != NULL) {
+ FreePool (FragmentTable);
+ FragmentTable = NULL;
+ }
+
+ return Status;
+}
+
+/**
+ Receive one fragment decrypted from one TLS record.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in, out] Fragment The received Fragment.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS One fragment is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED Something wrong decryption the message.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+HttpsReceive (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN OUT NET_FRAGMENT *Fragment,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_STATUS Status;
+ NET_BUF *Pdu;
+ TLS_RECORD_HEADER RecordHeader;
+ UINT8 *BufferIn;
+ UINTN BufferInSize;
+ NET_FRAGMENT TempFragment;
+ UINT8 *BufferOut;
+ UINTN BufferOutSize;
+ NET_BUF *PacketOut;
+ UINT8 *DataOut;
+ UINT8 *GetSessionDataBuffer;
+ UINTN GetSessionDataBufferSize;
+
+ Status = EFI_SUCCESS;
+ Pdu = NULL;
+ BufferIn = NULL;
+ BufferInSize = 0;
+ BufferOut = NULL;
+ BufferOutSize = 0;
+ PacketOut = NULL;
+ DataOut = NULL;
+ GetSessionDataBuffer = NULL;
+ GetSessionDataBufferSize = 0;
+
+ //
+ // Receive only one TLS record
+ //
+ Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BufferInSize = Pdu->TotalSize;
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ NetbufFree (Pdu);
+ return Status;
+ }
+
+ NetbufCopy (Pdu, 0, (UINT32) BufferInSize, BufferIn);
+
+ NetbufFree (Pdu);
+
+ //
+ // Handle Receive data.
+ //
+ RecordHeader = *(TLS_RECORD_HEADER *) BufferIn;
+
+ if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA) &&
+ (RecordHeader.Version.Major == 0x03) &&
+ (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
+ ) {
+ //
+ // Decrypt Packet.
+ //
+ Status = TlsProcessMessage (
+ HttpInstance,
+ BufferIn,
+ BufferInSize,
+ EfiTlsDecrypt,
+ &TempFragment
+ );
+
+ FreePool (BufferIn);
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_ABORTED) {
+ //
+ // Something wrong decryption the message.
+ // BuildResponsePacket() will be called to generate Error Alert message and send it out.
+ //
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool(BufferOut);
+ return Status;
+ }
+
+ if (BufferOutSize != 0) {
+ PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ NetbufFree (PacketOut);
+ }
+
+ FreePool(BufferOut);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_ABORTED;
+ }
+
+ return Status;
+ }
+
+ //
+ // Parsing buffer.
+ //
+ ASSERT (((TLS_RECORD_HEADER *) (TempFragment.Bulk))->ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA);
+
+ BufferInSize = ((TLS_RECORD_HEADER *) (TempFragment.Bulk))->Length;
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLS_RECORD_HEADER), BufferInSize);
+
+ //
+ // Free the buffer in TempFragment.
+ //
+ FreePool (TempFragment.Bulk);
+
+ } else if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT) &&
+ (RecordHeader.Version.Major == 0x03) &&
+ (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
+ ) {
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+
+ FreePool (BufferIn);
+
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+
+ if (BufferOutSize != 0) {
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ NetbufFree (PacketOut);
+ }
+
+ FreePool (BufferOut);
+
+ //
+ // Get the session state.
+ //
+ GetSessionDataBufferSize = DEF_BUF_LEN;
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (GetSessionDataBuffer);
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool (GetSessionDataBuffer);
+ return Status;
+ }
+
+ ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
+ HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer;
+
+ FreePool (GetSessionDataBuffer);
+
+ if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
+ DEBUG ((EFI_D_ERROR, "TLS Session State Error!\n"));
+ return EFI_ABORTED;
+ }
+
+ BufferIn = NULL;
+ BufferInSize = 0;
+ }
+
+ Fragment->Bulk = BufferIn;
+ Fragment->Len = (UINT32) BufferInSize;
+
+ return Status;
+}
diff --git a/NetworkPkg/HttpDxe/HttpsSupport.h b/NetworkPkg/HttpDxe/HttpsSupport.h
new file mode 100644
index 0000000..d846b76
--- /dev/null
+++ b/NetworkPkg/HttpDxe/HttpsSupport.h
@@ -0,0 +1,260 @@
+/** @file
+ The header files of miscellaneous routines specific to Https for HttpDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_HTTPS_SUPPORT_H__
+#define __EFI_HTTPS_SUPPORT_H__
+
+#define HTTPS_DEFAULT_PORT 443
+
+#define HTTPS_FLAG "https"
+
+/**
+ Check whether the Url is from Https.
+
+ @param[in] Url The pointer to a HTTP or HTTPS URL string.
+
+ @retval TRUE The Url is from HTTPS.
+ @retval FALSE The Url is from HTTP.
+
+**/
+BOOLEAN
+IsHttpsUrl (
+ IN CHAR8 *Url
+ );
+
+/**
+ Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+
+ @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+**/
+EFI_HANDLE
+EFIAPI
+TlsCreateChild (
+ IN EFI_HANDLE ImageHandle,
+ OUT EFI_TLS_PROTOCOL **TlsProto,
+ OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
+ );
+
+/**
+ Create event for the TLS receive and transmit tokens which are used to receive and
+ transmit TLS related messages.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+ @retval EFI_SUCCESS The events are created successfully.
+ @retval others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCreateTxRxEvent (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Close events in the TlsTxToken and TlsRxToken.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+**/
+VOID
+EFIAPI
+TlsCloseTxRxEvent (
+ IN HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Read the TlsCaCertificate variable and configure it.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TlsCaCertificate is configured.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_NOT_FOUND Fail to get "TlsCaCertificate" variable.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+TlsConfigCertificate (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Configure TLS session data.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TLS session data is configured.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigureSession (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Transmit the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+
+ @retval EFI_SUCCESS The packet is transmitted.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonTransmit (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet
+ );
+
+/**
+ Receive the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The Packet is received.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_TIMEOUT The operation is time out.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonReceive (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet,
+ IN EFI_EVENT Timeout
+ );
+
+/**
+ Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
+ corresponding record data. The two parts will be put into two blocks of buffers in the
+ net buffer.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[out] Pdu The received TLS PDU.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS An TLS PDU is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsReceiveOnePdu (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ OUT NET_BUF **Pdu,
+ IN EFI_EVENT Timeout
+ );
+
+/**
+ Connect one TLS session by finishing the TLS handshake process.
+
+ @param[in] HttpInstance The HTTP instance private data.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The TLS session is established.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConnectSession (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN EFI_EVENT Timeout
+ );
+
+/**
+ Close the TLS session and send out the close notification message.
+
+ @param[in] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS The TLS session is closed.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseSession (
+ IN HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Process one message according to the CryptMode.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Message Pointer to the message buffer needed to processed.
+ @param[in] MessageSize Pointer to the message buffer size.
+ @param[in] ProcessMode Process mode.
+ @param[in, out] Fragment Only one Fragment returned after the Message is
+ processed successfully.
+
+ @retval EFI_SUCCESS Message is processed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessMessage (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN UINT8 *Message,
+ IN UINTN MessageSize,
+ IN EFI_TLS_CRYPT_MODE ProcessMode,
+ IN OUT NET_FRAGMENT *Fragment
+ );
+
+/**
+ Receive one fragment decrypted from one TLS record.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in, out] Fragment The received Fragment.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS One fragment is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED Something wrong decryption the message.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+HttpsReceive (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN OUT NET_FRAGMENT *Fragment,
+ IN EFI_EVENT Timeout
+ );
+
+#endif
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6
2016-12-15 2:39 ` Fu, Siyuan
@ 2016-12-15 7:14 ` Wu, Jiaxin
0 siblings, 0 replies; 37+ messages in thread
From: Wu, Jiaxin @ 2016-12-15 7:14 UTC (permalink / raw)
To: Fu, Siyuan, edk2-devel@lists.01.org
Cc: Ye, Ting, Zhang, Lubo, Long, Qin, Thomas Palmer
Good suggestion, I will change the flag to "https://" before commit the patch.
Even we have a library to get the URI scheme, we still need check whether it's http or https.
Thanks,
Jiaxin
> -----Original Message-----
> From: Fu, Siyuan
> Sent: Thursday, December 15, 2016 10:39 AM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>;
> Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4
> and IPv6
>
> Hi, Jiaxin
>
> In function IsHttpsUrl(), I suggest to search string "https://" instead of only
> "https", in case of some incorrect scheme like "httpsabc://".
> However, since there is already code to parse the URL by using
> HttpParseUrl(), the scheme should already been known by the Http url
> parser, I think it better to add a new function to the HttpLib like
> HttpUrlGetScheme().
>
> Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
>
>
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: 2016年12月14日 15:34
> To: edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang,
> Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas
> Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
> Subject: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and
> IPv6
>
> This patch is used to enable HTTPS feature. HttpDxe driver
> will consume TlsDxe driver. It can both support http and https
> feature, that’s depended on the information of URL, the HTTP
> instance can be able to determine whether to use http or https.
>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> NetworkPkg/HttpDxe/HttpDriver.h | 10 +-
> NetworkPkg/HttpDxe/HttpDxe.inf | 12 +-
> NetworkPkg/HttpDxe/HttpImpl.c | 252 +++++-
> NetworkPkg/HttpDxe/HttpProto.c | 464 +++++++---
> NetworkPkg/HttpDxe/HttpProto.h | 65 +-
> NetworkPkg/HttpDxe/HttpsSupport.c | 1692
> +++++++++++++++++++++++++++++++++++++
> NetworkPkg/HttpDxe/HttpsSupport.h | 260 ++++++
> 7 files changed, 2601 insertions(+), 154 deletions(-)
> create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.c
> create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.h
>
> diff --git a/NetworkPkg/HttpDxe/HttpDriver.h
> b/NetworkPkg/HttpDxe/HttpDriver.h
> index fa2372c..93a412a 100644
> --- a/NetworkPkg/HttpDxe/HttpDriver.h
> +++ b/NetworkPkg/HttpDxe/HttpDriver.h
> @@ -22,10 +22,11 @@
>
> //
> // Libraries
> //
> #include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> #include <Library/MemoryAllocationLib.h>
> #include <Library/BaseLib.h>
> #include <Library/UefiLib.h>
> #include <Library/DebugLib.h>
> #include <Library/NetLib.h>
> @@ -48,17 +49,23 @@
> #include <Protocol/Tcp6.h>
> #include <Protocol/Dns4.h>
> #include <Protocol/Dns6.h>
> #include <Protocol/Ip4Config2.h>
> #include <Protocol/Ip6Config.h>
> +#include <Protocol/Tls.h>
> +#include <Protocol/TlsConfig.h>
>
> -
> +#include <Guid/ImageAuthentication.h>
> //
> // Produced Protocols
> //
> #include <Protocol/Http.h>
>
> +#include <Guid/TlsAuthentication.h>
> +
> +#include <IndustryStandard/Tls1.h>
> +
> //
> // Driver Version
> //
> #define HTTP_DRIVER_VERSION 0xa
>
> @@ -77,10 +84,11 @@ extern EFI_HTTP_UTILITIES_PROTOCOL
> *mHttpUtilities;
> // Include files with function prototypes
> //
> #include "ComponentName.h"
> #include "HttpImpl.h"
> #include "HttpProto.h"
> +#include "HttpsSupport.h"
> #include "HttpDns.h"
>
> typedef struct {
> EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
> UINTN NumberOfChildren;
> diff --git a/NetworkPkg/HttpDxe/HttpDxe.inf
> b/NetworkPkg/HttpDxe/HttpDxe.inf
> index bf2cbee..1118181 100644
> --- a/NetworkPkg/HttpDxe/HttpDxe.inf
> +++ b/NetworkPkg/HttpDxe/HttpDxe.inf
> @@ -1,9 +1,9 @@
> ## @file
> # Implementation of EFI HTTP protocol interfaces.
> #
> -# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
> #
> # This program and the accompanying materials
> # are licensed and made available under the terms and conditions of the
> BSD License
> # which accompanies this distribution. The full text of the license may be
> found at
> # http://opensource.org/licenses/bsd-license.php.
> @@ -24,10 +24,11 @@
> MODULE_UNI_FILE = HttpDxe.uni
>
> [Packages]
> MdePkg/MdePkg.dec
> MdeModulePkg/MdeModulePkg.dec
> + NetworkPkg/NetworkPkg.dec
>
> [Sources]
> ComponentName.h
> ComponentName.c
> HttpDns.h
> @@ -36,14 +37,17 @@
> HttpDriver.c
> HttpImpl.h
> HttpImpl.c
> HttpProto.h
> HttpProto.c
> + HttpsSupport.h
> + HttpsSupport.c
>
> [LibraryClasses]
> UefiDriverEntryPoint
> UefiBootServicesTableLib
> + UefiRuntimeServicesTableLib
> MemoryAllocationLib
> BaseLib
> UefiLib
> DebugLib
> NetLib
> @@ -62,8 +66,14 @@
> gEfiDns4ProtocolGuid ## SOMETIMES_CONSUMES
> gEfiDns6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
> gEfiDns6ProtocolGuid ## SOMETIMES_CONSUMES
> gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES
> gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES
> + gEfiTlsServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
> + gEfiTlsProtocolGuid ## SOMETIMES_CONSUMES
> + gEfiTlsConfigurationProtocolGuid ## SOMETIMES_CONSUMES
> +
> +[Guids]
> + gEfiTlsCaCertificateGuid ## CONSUMES ## GUID
>
> [UserExtensions.TianoCore."ExtraFiles"]
> HttpDxeExtra.uni
> \ No newline at end of file
> diff --git a/NetworkPkg/HttpDxe/HttpImpl.c
> b/NetworkPkg/HttpDxe/HttpImpl.c
> index 6fcb0b7..77aa64a 100644
> --- a/NetworkPkg/HttpDxe/HttpImpl.c
> +++ b/NetworkPkg/HttpDxe/HttpImpl.c
> @@ -239,10 +239,11 @@ EfiHttpRequest (
> UINTN HostNameSize;
> UINT16 RemotePort;
> HTTP_PROTOCOL *HttpInstance;
> BOOLEAN Configure;
> BOOLEAN ReConfigure;
> + BOOLEAN TlsConfigure;
> CHAR8 *RequestMsg;
> CHAR8 *Url;
> UINTN UrlLen;
> CHAR16 *HostNameStr;
> HTTP_TOKEN_WRAP *Wrap;
> @@ -258,10 +259,11 @@ EfiHttpRequest (
> HostName = NULL;
> RequestMsg = NULL;
> HostNameStr = NULL;
> Wrap = NULL;
> FileUrl = NULL;
> + TlsConfigure = FALSE;
>
> if ((This == NULL) || (Token == NULL)) {
> return EFI_INVALID_PARAMETER;
> }
>
> @@ -343,10 +345,36 @@ EfiHttpRequest (
> HttpInstance->Url = Url;
> }
>
>
> UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);
> +
> + //
> + // From the information in Url, the HTTP instance will
> + // be able to determine whether to use http or https.
> + //
> + HttpInstance->UseHttps = IsHttpsUrl (Url);
> +
> + //
> + // Check whether we need to create Tls child and open the TLS protocol.
> + //
> + if (HttpInstance->UseHttps && HttpInstance->TlsChildHandle == NULL) {
> + //
> + // Use TlsSb to create Tls child and open the TLS protocol.
> + //
> + HttpInstance->TlsChildHandle = TlsCreateChild (
> + HttpInstance->Service->ImageHandle,
> + &(HttpInstance->Tls),
> + &(HttpInstance->TlsConfiguration)
> + );
> + if (HttpInstance->TlsChildHandle == NULL) {
> + return EFI_DEVICE_ERROR;
> + }
> +
> + TlsConfigure = TRUE;
> + }
> +
> UrlParser = NULL;
> Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser);
> if (EFI_ERROR (Status)) {
> goto Error1;
> }
> @@ -357,11 +385,15 @@ EfiHttpRequest (
> goto Error1;
> }
>
> Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
> if (EFI_ERROR (Status)) {
> - RemotePort = HTTP_DEFAULT_PORT;
> + if (HttpInstance->UseHttps) {
> + RemotePort = HTTPS_DEFAULT_PORT;
> + } else {
> + RemotePort = HTTP_DEFAULT_PORT;
> + }
> }
> //
> // If Configure is TRUE, it indicates the first time to call Request();
> // If ReConfigure is TRUE, it indicates the request URL is not same
> // with the previous call to Request();
> @@ -374,13 +406,17 @@ EfiHttpRequest (
> // Request() is called the first time.
> //
> ReConfigure = FALSE;
> } else {
> if ((HttpInstance->RemotePort == RemotePort) &&
> - (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) {
> + (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&
> + (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&
> + !TlsConfigure &&
> + HttpInstance->TlsSessionState ==
> EfiTlsSessionDataTransferring))) {
> //
> // Host Name and port number of the request URL are the same with
> previous call to Request().
> + // If Https protocol used, the corresponding SessionState is
> EfiTlsSessionDataTransferring.
> // Check whether previous TCP packet sent out.
> //
>
> if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens,
> HttpTcpNotReady, NULL))) {
> //
> @@ -480,10 +516,20 @@ EfiHttpRequest (
> if (!HttpInstance->LocalAddressIsIPv6) {
> ASSERT (HttpInstance->Tcp4 != NULL);
> } else {
> ASSERT (HttpInstance->Tcp6 != NULL);
> }
> +
> + if (HttpInstance->UseHttps && !TlsConfigure) {
> + Status = TlsCloseSession (HttpInstance);
> + if (EFI_ERROR (Status)) {
> + goto Error1;
> + }
> +
> + TlsCloseTxRxEvent (HttpInstance);
> + }
> +
> HttpCloseConnection (HttpInstance);
> EfiHttpCancel (This, NULL);
> }
>
> //
> @@ -498,17 +544,22 @@ EfiHttpRequest (
> Wrap->HttpToken = Token;
> Wrap->HttpInstance = HttpInstance;
> if (Request != NULL) {
> Wrap->TcpWrap.Method = Request->Method;
> }
> -
> - Status = HttpInitTcp (HttpInstance, Wrap, Configure);
> +
> + Status = HttpInitSession (
> + HttpInstance,
> + Wrap,
> + Configure || ReConfigure,
> + TlsConfigure
> + );
> if (EFI_ERROR (Status)) {
> goto Error2;
> - }
> + }
>
> - if (!Configure) {
> + if (!Configure && !ReConfigure && !TlsConfigure) {
> //
> // For the new HTTP token, create TX TCP token events.
> //
> Status = HttpCreateTcpTxEvent (Wrap);
> if (EFI_ERROR (Status)) {
> @@ -591,13 +642,18 @@ Error4:
> if (RequestMsg != NULL) {
> FreePool (RequestMsg);
> }
>
> Error3:
> - HttpCloseConnection (HttpInstance);
> + if (HttpInstance->UseHttps) {
> + TlsCloseSession (HttpInstance);
> + TlsCloseTxRxEvent (HttpInstance);
> + }
>
> Error2:
> + HttpCloseConnection (HttpInstance);
> +
> HttpCloseTcpConnCloseEvent (HttpInstance);
> if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {
> gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
> Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL;
> }
> @@ -729,26 +785,34 @@ HttpCancel (
> } else {
> return Status;
> }
> }
>
> - //
> - // Then check the tokens queued by EfiHttpResponse().
> - //
> - Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens,
> Token);
> - if (EFI_ERROR (Status)) {
> - if (Token != NULL) {
> - if (Status == EFI_ABORTED) {
> - return EFI_SUCCESS;
> + if (!HttpInstance->UseHttps) {
> + //
> + // Then check the tokens queued by EfiHttpResponse(), except for Https.
> + //
> + Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens,
> Token);
> + if (EFI_ERROR (Status)) {
> + if (Token != NULL) {
> + if (Status == EFI_ABORTED) {
> + return EFI_SUCCESS;
> + } else {
> + return EFI_NOT_FOUND;
> + }
> } else {
> - return EFI_NOT_FOUND;
> + return Status;
> }
> + }
> + } else {
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance-
> >Tcp4TlsRxToken.CompletionToken);
> } else {
> - return Status;
> + HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance-
> >Tcp6TlsRxToken.CompletionToken);
> }
> }
> -
> +
> return EFI_SUCCESS;
> }
>
>
> /**
> @@ -880,10 +944,11 @@ HttpResponseWorker (
> HTTP_PROTOCOL *HttpInstance;
> EFI_HTTP_TOKEN *Token;
> NET_MAP_ITEM *Item;
> HTTP_TOKEN_WRAP *ValueInItem;
> UINTN HdrLen;
> + NET_FRAGMENT Fragment;
>
> if (Wrap == NULL || Wrap->HttpInstance == NULL) {
> return EFI_INVALID_PARAMETER;
> }
>
> @@ -897,21 +962,15 @@ HttpResponseWorker (
> HttpHeaders = NULL;
> SizeofHeaders = 0;
> BufferSize = 0;
> EndofHeader = NULL;
> ValueInItem = NULL;
> + Fragment.Len = 0;
> + Fragment.Bulk = NULL;
>
> if (HttpMsg->Data.Response != NULL) {
> //
> - // Need receive the HTTP headers, prepare buffer.
> - //
> - Status = HttpCreateTcpRxEventForHeader (HttpInstance);
> - if (EFI_ERROR (Status)) {
> - goto Error;
> - }
> -
> - //
> // Check whether we have cached header from previous call.
> //
> if ((HttpInstance->CacheBody != NULL) && (HttpInstance->NextMsg !=
> NULL)) {
> //
> // The data is stored at [NextMsg, CacheBody + CacheLen].
> @@ -1198,13 +1257,120 @@ HttpResponseWorker (
> ASSERT (HttpInstance->MsgParser != NULL);
>
> //
> // We still need receive more data when there is no cache data and
> MsgParser is not NULL;
> //
> - Status = HttpTcpReceiveBody (Wrap, HttpMsg);
> - if (EFI_ERROR (Status)) {
> - goto Error2;
> + if (!HttpInstance->UseHttps) {
> + Status = HttpTcpReceiveBody (Wrap, HttpMsg);
> +
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> +
> + } else {
> + if (HttpInstance->TimeoutEvent == NULL) {
> + //
> + // Create TimeoutEvent for response
> + //
> + Status = gBS->CreateEvent (
> + EVT_TIMER,
> + TPL_CALLBACK,
> + NULL,
> + NULL,
> + &HttpInstance->TimeoutEvent
> + );
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> + }
> +
> + //
> + // Start the timer, and wait Timeout seconds to receive the body packet.
> + //
> + Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative,
> HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> +
> + Status = HttpsReceive (HttpInstance, &Fragment, HttpInstance-
> >TimeoutEvent);
> +
> + gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
> +
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> +
> + //
> + // Check whether we receive a complete HTTP message.
> + //
> + Status = HttpParseMessageBody (
> + HttpInstance->MsgParser,
> + (UINTN) Fragment.Len,
> + (CHAR8 *) Fragment.Bulk
> + );
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> +
> + if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
> + //
> + // Free the MsgParse since we already have a full HTTP message.
> + //
> + HttpFreeMsgParser (HttpInstance->MsgParser);
> + HttpInstance->MsgParser = NULL;
> + }
> +
> + //
> + // We receive part of header of next HTTP msg.
> + //
> + if (HttpInstance->NextMsg != NULL) {
> + HttpMsg->BodyLength = MIN ((UINTN) (HttpInstance->NextMsg -
> (CHAR8 *) Fragment.Bulk), HttpMsg->BodyLength);
> + CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
> +
> + HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
> + if (HttpInstance->CacheLen != 0) {
> + if (HttpInstance->CacheBody != NULL) {
> + FreePool (HttpInstance->CacheBody);
> + }
> +
> + HttpInstance->CacheBody = AllocateZeroPool (HttpInstance-
> >CacheLen);
> + if (HttpInstance->CacheBody == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error2;
> + }
> +
> + CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg-
> >BodyLength, HttpInstance->CacheLen);
> + HttpInstance->CacheOffset = 0;
> +
> + HttpInstance->NextMsg = HttpInstance->CacheBody + (UINTN)
> (HttpInstance->NextMsg - (CHAR8 *) (Fragment.Bulk + HttpMsg-
> >BodyLength));
> + }
> + } else {
> + HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg-
> >BodyLength);
> + CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
> + HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
> + if (HttpInstance->CacheLen != 0) {
> + if (HttpInstance->CacheBody != NULL) {
> + FreePool (HttpInstance->CacheBody);
> + }
> +
> + HttpInstance->CacheBody = AllocateZeroPool (HttpInstance-
> >CacheLen);
> + if (HttpInstance->CacheBody == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error2;
> + }
> +
> + CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg-
> >BodyLength, HttpInstance->CacheLen);
> + HttpInstance->CacheOffset = 0;
> + }
> + }
> +
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> + }
> +
> + goto Exit;
> }
>
> return Status;
>
> Exit:
> @@ -1232,19 +1398,30 @@ Error2:
> Error:
> Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap-
> >HttpToken);
> if (Item != NULL) {
> NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);
> }
> -
> - HttpTcpTokenCleanup (Wrap);
> +
> + if (!HttpInstance->UseHttps) {
> + HttpTcpTokenCleanup (Wrap);
> + } else {
> + FreePool (Wrap);
> + }
>
> if (HttpHeaders != NULL) {
> FreePool (HttpHeaders);
> + HttpHeaders = NULL;
> + }
> +
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> }
>
> if (HttpMsg->Headers != NULL) {
> FreePool (HttpMsg->Headers);
> + HttpMsg->Headers = NULL;
> }
>
> if (HttpInstance->CacheBody != NULL) {
> FreePool (HttpInstance->CacheBody);
> HttpInstance->CacheBody = NULL;
> @@ -1351,13 +1528,20 @@ EfiHttpResponse (
> }
>
> Wrap->HttpInstance = HttpInstance;
> Wrap->HttpToken = Token;
>
> - Status = HttpCreateTcpRxEvent (Wrap);
> - if (EFI_ERROR (Status)) {
> - goto Error;
> + //
> + // Notes: For Https, receive token wrapped in HTTP_TOKEN_WRAP is not
> used to
> + // receive the https response. A special TlsRxToken is used for receiving
> TLS
> + // related messages. It should be a blocking response.
> + //
> + if (!HttpInstance->UseHttps) {
> + Status = HttpCreateTcpRxEvent (Wrap);
> + if (EFI_ERROR (Status)) {
> + goto Error;
> + }
> }
>
> Status = NetMapInsertTail (&HttpInstance->RxTokens, Token, Wrap);
> if (EFI_ERROR (Status)) {
> goto Error;
> diff --git a/NetworkPkg/HttpDxe/HttpProto.c
> b/NetworkPkg/HttpDxe/HttpProto.c
> index 6373f07..77a3ee3 100644
> --- a/NetworkPkg/HttpDxe/HttpProto.c
> +++ b/NetworkPkg/HttpDxe/HttpProto.c
> @@ -926,10 +926,26 @@ HttpCleanProtocol (
> HttpInstance->Service->ImageHandle,
> HttpInstance->Handle
> );
> }
>
> + if (HttpInstance->TlsConfigData.CACert != NULL) {
> + FreePool (HttpInstance->TlsConfigData.CACert);
> + HttpInstance->TlsConfigData.CACert = NULL;
> + }
> +
> + if (HttpInstance->TlsConfigData.ClientCert != NULL) {
> + FreePool (HttpInstance->TlsConfigData.ClientCert);
> + HttpInstance->TlsConfigData.ClientCert = NULL;
> + }
> +
> + if (HttpInstance->TlsConfigData.ClientPrivateKey != NULL) {
> + FreePool (HttpInstance->TlsConfigData.ClientPrivateKey);
> + HttpInstance->TlsConfigData.ClientPrivateKey = NULL;
> + }
> +
> + TlsCloseTxRxEvent (HttpInstance);
> }
>
> /**
> Establish TCP connection with HTTP server.
>
> @@ -1183,11 +1199,12 @@ HttpConfigureTcp6 (
> return EFI_SUCCESS;
>
> }
>
> /**
> - Check existing TCP connection, if in error state, recover TCP4 connection.
> + Check existing TCP connection, if in error state, recover TCP4 connection.
> Then,
> + connect one TLS session if required.
>
> @param[in] HttpInstance The HTTP instance private data.
>
> @retval EFI_SUCCESS The TCP connection is established.
> @retval EFI_NOT_READY TCP4 protocol child is not created or
> configured.
> @@ -1224,15 +1241,62 @@ HttpConnectTcp4 (
> return EFI_SUCCESS;
> } else if (Tcp4State > Tcp4StateEstablished ) {
> HttpCloseConnection(HttpInstance);
> }
>
> - return HttpCreateConnection (HttpInstance);
> + Status = HttpCreateConnection (HttpInstance);
> + if (EFI_ERROR(Status)){
> + DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status));
> + return Status;
> + }
> +
> + //
> + // Tls session connection.
> + //
> + if (HttpInstance->UseHttps) {
> + if (HttpInstance->TimeoutEvent == NULL) {
> + //
> + // Create TimeoutEvent for TLS connection.
> + //
> + Status = gBS->CreateEvent (
> + EVT_TIMER,
> + TPL_CALLBACK,
> + NULL,
> + NULL,
> + &HttpInstance->TimeoutEvent
> + );
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> + }
> +
> + //
> + // Start the timer, and wait Timeout seconds for connection.
> + //
> + Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative,
> HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> +
> + Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
> +
> + gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
> +
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> + }
> +
> + return Status;
> }
>
> /**
> - Check existing TCP connection, if in error state, recover TCP6 connection.
> + Check existing TCP connection, if in error state, recover TCP6 connection.
> Then,
> + connect one TLS session if required.
>
> @param[in] HttpInstance The HTTP instance private data.
>
> @retval EFI_SUCCESS The TCP connection is established.
> @retval EFI_NOT_READY TCP6 protocol child is not created or
> configured.
> @@ -1269,34 +1333,92 @@ HttpConnectTcp6 (
> return EFI_SUCCESS;
> } else if (Tcp6State > Tcp6StateEstablished ) {
> HttpCloseConnection(HttpInstance);
> }
>
> - return HttpCreateConnection (HttpInstance);
> + Status = HttpCreateConnection (HttpInstance);
> + if (EFI_ERROR(Status)){
> + DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status));
> + return Status;
> + }
> +
> + //
> + // Tls session connection.
> + //
> + if (HttpInstance->UseHttps) {
> + if (HttpInstance->TimeoutEvent == NULL) {
> + //
> + // Create TimeoutEvent for TLS connection.
> + //
> + Status = gBS->CreateEvent (
> + EVT_TIMER,
> + TPL_CALLBACK,
> + NULL,
> + NULL,
> + &HttpInstance->TimeoutEvent
> + );
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> + }
> +
> + //
> + // Start the timer, and wait Timeout seconds for connection.
> + //
> + Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative,
> HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> +
> + Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
> +
> + gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
> +
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> + }
> +
> + return Status;
> }
>
> /**
> - Initialize TCP related data.
> + Initialize Http session.
>
> @param[in] HttpInstance The HTTP instance private data.
> @param[in] Wrap The HTTP token's wrap data.
> - @param[in] Configure The Flag indicates whether the first time to
> initialize Tcp.
> + @param[in] Configure The Flag indicates whether need to initialize
> session.
> + @param[in] TlsConfigure The Flag indicates whether it's the new Tls
> session.
>
> - @retval EFI_SUCCESS The initialization of TCP instance is done.
> + @retval EFI_SUCCESS The initialization of session is done.
> @retval Others Other error as indicated.
>
> **/
> EFI_STATUS
> -HttpInitTcp (
> +HttpInitSession (
> IN HTTP_PROTOCOL *HttpInstance,
> IN HTTP_TOKEN_WRAP *Wrap,
> - IN BOOLEAN Configure
> + IN BOOLEAN Configure,
> + IN BOOLEAN TlsConfigure
> )
> {
> EFI_STATUS Status;
> ASSERT (HttpInstance != NULL);
>
> + //
> + // Configure Tls session.
> + //
> + if (TlsConfigure) {
> + Status = TlsConfigureSession (HttpInstance);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + }
> +
> if (!HttpInstance->LocalAddressIsIPv6) {
> //
> // Configure TCP instance.
> //
> if (Configure) {
> @@ -1336,11 +1458,11 @@ HttpInitTcp (
> return EFI_SUCCESS;
>
> }
>
> /**
> - Send the HTTP message through TCP4 or TCP6.
> + Send the HTTP or HTTPS message through TCP4 or TCP6.
>
> @param[in] HttpInstance The HTTP instance private data.
> @param[in] Wrap The HTTP token's wrap data.
> @param[in] TxString Buffer containing the HTTP message string.
> @param[in] TxStringLen Length of the HTTP message string in bytes.
> @@ -1360,18 +1482,68 @@ HttpTransmitTcp (
> EFI_STATUS Status;
> EFI_TCP4_IO_TOKEN *Tx4Token;
> EFI_TCP4_PROTOCOL *Tcp4;
> EFI_TCP6_IO_TOKEN *Tx6Token;
> EFI_TCP6_PROTOCOL *Tcp6;
> + UINT8 *Buffer;
> + UINTN BufferSize;
> + NET_FRAGMENT TempFragment;
> +
> + Status = EFI_SUCCESS;
> + Buffer = NULL;
> +
> + //
> + // Need to encrypt data.
> + //
> + if (HttpInstance->UseHttps) {
> + //
> + // Build BufferOut data
> + //
> + BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;
> + Buffer = AllocateZeroPool (BufferSize);
> + if (Buffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> + ((TLS_RECORD_HEADER *) Buffer)->ContentType =
> TLS_CONTENT_TYPE_APPLICATION_DATA;
> + ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance-
> >TlsConfigData.Version.Major;
> + ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance-
> >TlsConfigData.Version.Minor;
> + ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);
> + CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);
> +
> + //
> + // Encrypt Packet.
> + //
> + Status = TlsProcessMessage (
> + HttpInstance,
> + Buffer,
> + BufferSize,
> + EfiTlsEncrypt,
> + &TempFragment
> + );
> +
> + FreePool (Buffer);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + }
>
> - if (!HttpInstance->LocalAddressIsIPv6) {
> + if (!HttpInstance->LocalAddressIsIPv6) {
> Tcp4 = HttpInstance->Tcp4;
> Tx4Token = &Wrap->TcpWrap.Tx4Token;
> +
> + if (HttpInstance->UseHttps) {
> + Tx4Token->Packet.TxData->DataLength = TempFragment.Len;
> + Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength =
> TempFragment.Len;
> + Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID
> *) TempFragment.Bulk;
> + } else {
> + Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
> + Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength =
> (UINT32) TxStringLen;
> + Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID
> *) TxString;
> + }
>
> - Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
> - Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32)
> TxStringLen;
> - Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)
> TxString;
> Tx4Token->CompletionToken.Status = EFI_NOT_READY;
>
> Wrap->TcpWrap.IsTxDone = FALSE;
> Status = Tcp4->Transmit (Tcp4, Tx4Token);
> if (EFI_ERROR (Status)) {
> @@ -1380,25 +1552,31 @@ HttpTransmitTcp (
> }
>
> } else {
> Tcp6 = HttpInstance->Tcp6;
> Tx6Token = &Wrap->TcpWrap.Tx6Token;
> -
> - Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
> - Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32)
> TxStringLen;
> - Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)
> TxString;
> +
> + if (HttpInstance->UseHttps) {
> + Tx6Token->Packet.TxData->DataLength = TempFragment.Len;
> + Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength =
> TempFragment.Len;
> + Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID
> *) TempFragment.Bulk;
> + } else {
> + Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
> + Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength =
> (UINT32) TxStringLen;
> + Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID
> *) TxString;
> + }
> +
> Tx6Token->CompletionToken.Status = EFI_NOT_READY;
>
> Wrap->TcpWrap.IsTxDone = FALSE;
> Status = Tcp6->Transmit (Tcp6, Tx6Token);
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));
> return Status;
> }
> }
>
> -
> return Status;
> }
>
> /**
> Check whether the user's token or event has already
> @@ -1464,11 +1642,11 @@ HttpTcpNotReady (
>
> return EFI_SUCCESS;
> }
>
> /**
> - Transmit the HTTP mssage by processing the associated HTTP token.
> + Transmit the HTTP or HTTPS mssage by processing the associated HTTP
> token.
>
> @param[in] Map The container of Tx4Token or Tx6Token.
> @param[in] Item Current item to check against.
> @param[in] Context The Token to check againist.
>
> @@ -1588,167 +1766,235 @@ HttpTcpReceiveHeader (
> EFI_TCP6_IO_TOKEN *Rx6Token;
> EFI_TCP6_PROTOCOL *Tcp6;
> CHAR8 **EndofHeader;
> CHAR8 **HttpHeaders;
> CHAR8 *Buffer;
> + NET_FRAGMENT Fragment;
>
> ASSERT (HttpInstance != NULL);
>
> EndofHeader = HttpInstance->EndofHeader;
> HttpHeaders = HttpInstance->HttpHeaders;
> Tcp4 = HttpInstance->Tcp4;
> Tcp6 = HttpInstance->Tcp6;
> Buffer = NULL;
> Rx4Token = NULL;
> Rx6Token = NULL;
> + Fragment.Len = 0;
> + Fragment.Bulk = NULL;
>
> if (HttpInstance->LocalAddressIsIPv6) {
> ASSERT (Tcp6 != NULL);
> } else {
> ASSERT (Tcp4 != NULL);
> }
>
> - if (!HttpInstance->LocalAddressIsIPv6) {
> - Rx4Token = &HttpInstance->Rx4Token;
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer =
> AllocateZeroPool (DEF_BUF_LEN);
> - if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer ==
> NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> + if (!HttpInstance->UseHttps) {
> + Status = HttpCreateTcpRxEventForHeader (HttpInstance);
> + if (EFI_ERROR (Status)) {
> return Status;
> }
> + }
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + if (!HttpInstance->UseHttps) {
> + Rx4Token = &HttpInstance->Rx4Token;
> + Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer =
> AllocateZeroPool (DEF_BUF_LEN);
> + if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer ==
> NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> + }
>
> //
> // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not
> NULL.
> //
> - while (*EndofHeader == NULL) {
> - HttpInstance->IsRxDone = FALSE;
> - Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength =
> DEF_BUF_LEN;
> - Status = Tcp4->Receive (Tcp4, Rx4Token);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
> - return Status;
> - }
> -
> - while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> - Tcp4->Poll (Tcp4);
> + while (*EndofHeader == NULL) {
> + if (!HttpInstance->UseHttps) {
> + HttpInstance->IsRxDone = FALSE;
> + Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
> + Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength =
> DEF_BUF_LEN;
> + Status = Tcp4->Receive (Tcp4, Rx4Token);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
> + return Status;
> + }
> +
> + while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> + Tcp4->Poll (Tcp4);
> + }
> +
> + if (!HttpInstance->IsRxDone) {
> + //
> + // Cancle the Token before close its Event.
> + //
> + Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
> + gBS->CloseEvent (Rx4Token->CompletionToken.Event);
> + Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
> + }
> +
> + Status = Rx4Token->CompletionToken.Status;
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Fragment.Len = Rx4Token->Packet.RxData-
> >FragmentTable[0].FragmentLength;
> + Fragment.Bulk = (UINT8 *) Rx4Token->Packet.RxData-
> >FragmentTable[0].FragmentBuffer;
> + } else {
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> + }
> +
> + Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
> + return Status;
> + }
> }
>
> - if (!HttpInstance->IsRxDone) {
> - //
> - // Cancle the Token before close its Event.
> - //
> - Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
> - gBS->CloseEvent (Rx4Token->CompletionToken.Event);
> - Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
> - }
> -
> - Status = Rx4Token->CompletionToken.Status;
> - if (EFI_ERROR (Status)) {
> - return Status;
> - }
> -
> //
> // Append the response string.
> //
> - *BufferSize = (*SizeofHeaders) + Rx4Token->Packet.RxData-
> >FragmentTable[0].FragmentLength;
> + *BufferSize = *SizeofHeaders + Fragment.Len;
> Buffer = AllocateZeroPool (*BufferSize);
> if (Buffer == NULL) {
> Status = EFI_OUT_OF_RESOURCES;
> return Status;
> }
> -
> +
> if (*HttpHeaders != NULL) {
> - CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
> + CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
> FreePool (*HttpHeaders);
> }
> -
> +
> CopyMem (
> - Buffer + (*SizeofHeaders),
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength
> + Buffer + *SizeofHeaders,
> + Fragment.Bulk,
> + Fragment.Len
> );
> - *HttpHeaders = Buffer;
> - *SizeofHeaders = *BufferSize;
> -
> + *HttpHeaders = Buffer;
> + *SizeofHeaders = *BufferSize;
> +
> //
> // Check whether we received end of HTTP headers.
> //
> *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
> - }
> - FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
> + };
>
> + //
> + // Free the buffer.
> + //
> + if (Rx4Token != NULL && Rx4Token->Packet.RxData != NULL &&
> Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
> + FreePool (Rx4Token->Packet.RxData-
> >FragmentTable[0].FragmentBuffer);
> + Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
> + Fragment.Bulk = NULL;
> + }
> +
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> + }
> } else {
> - Rx6Token = &HttpInstance->Rx6Token;
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer =
> AllocateZeroPool (DEF_BUF_LEN);
> - if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer ==
> NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - return Status;
> + if (!HttpInstance->UseHttps) {
> + Rx6Token = &HttpInstance->Rx6Token;
> + Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer =
> AllocateZeroPool (DEF_BUF_LEN);
> + if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer ==
> NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> }
>
> //
> // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not
> NULL.
> //
> - while (*EndofHeader == NULL) {
> - HttpInstance->IsRxDone = FALSE;
> - Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength =
> DEF_BUF_LEN;
> - Status = Tcp6->Receive (Tcp6, Rx6Token);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
> - return Status;
> - }
> -
> - while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> - Tcp6->Poll (Tcp6);
> + while (*EndofHeader == NULL) {
> + if (!HttpInstance->UseHttps) {
> + HttpInstance->IsRxDone = FALSE;
> + Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
> + Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength =
> DEF_BUF_LEN;
> + Status = Tcp6->Receive (Tcp6, Rx6Token);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
> + return Status;
> + }
> +
> + while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> + Tcp6->Poll (Tcp6);
> + }
> +
> + if (!HttpInstance->IsRxDone) {
> + //
> + // Cancle the Token before close its Event.
> + //
> + Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
> + gBS->CloseEvent (Rx6Token->CompletionToken.Event);
> + Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
> + }
> +
> + Status = Rx6Token->CompletionToken.Status;
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Fragment.Len = Rx6Token->Packet.RxData-
> >FragmentTable[0].FragmentLength;
> + Fragment.Bulk = (UINT8 *) Rx6Token->Packet.RxData-
> >FragmentTable[0].FragmentBuffer;
> + } else {
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> + }
> +
> + Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
> + return Status;
> + }
> }
>
> - if (!HttpInstance->IsRxDone) {
> - //
> - // Cancle the Token before close its Event.
> - //
> - Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
> - gBS->CloseEvent (Rx6Token->CompletionToken.Event);
> - Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
> - }
> -
> - Status = Rx6Token->CompletionToken.Status;
> - if (EFI_ERROR (Status)) {
> - return Status;
> - }
> -
> //
> // Append the response string.
> //
> - *BufferSize = (*SizeofHeaders) + Rx6Token->Packet.RxData-
> >FragmentTable[0].FragmentLength;
> + *BufferSize = *SizeofHeaders + Fragment.Len;
> Buffer = AllocateZeroPool (*BufferSize);
> if (Buffer == NULL) {
> Status = EFI_OUT_OF_RESOURCES;
> return Status;
> }
> -
> +
> if (*HttpHeaders != NULL) {
> - CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
> + CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
> FreePool (*HttpHeaders);
> }
> -
> +
> CopyMem (
> - Buffer + (*SizeofHeaders),
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength
> + Buffer + *SizeofHeaders,
> + Fragment.Bulk,
> + Fragment.Len
> );
> - *HttpHeaders = Buffer;
> - *SizeofHeaders = *BufferSize;
> -
> + *HttpHeaders = Buffer;
> + *SizeofHeaders = *BufferSize;
> +
> //
> // Check whether we received end of HTTP headers.
> //
> - *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
> -
> + *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
> + };
> +
> + //
> + // Free the buffer.
> + //
> + if (Rx6Token != NULL && Rx6Token->Packet.RxData != NULL &&
> Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
> + FreePool (Rx6Token->Packet.RxData-
> >FragmentTable[0].FragmentBuffer);
> + Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
> + Fragment.Bulk = NULL;
> + }
> +
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> }
> - FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
> }
>
> //
> // Skip the CRLF after the HTTP headers.
> //
> diff --git a/NetworkPkg/HttpDxe/HttpProto.h
> b/NetworkPkg/HttpDxe/HttpProto.h
> index e1fd785..e3b3275 100644
> --- a/NetworkPkg/HttpDxe/HttpProto.h
> +++ b/NetworkPkg/HttpDxe/HttpProto.h
> @@ -81,10 +81,24 @@ typedef struct {
> BOOLEAN IsRxDone;
> UINTN BodyLen;
> EFI_HTTP_METHOD Method;
> } HTTP_TCP_TOKEN_WRAP;
>
> +typedef struct {
> + EFI_TLS_VERSION Version;
> + EFI_TLS_CONNECTION_END ConnectionEnd;
> + EFI_TLS_VERIFY VerifyMethod;
> + EFI_TLS_SESSION_STATE SessionState;
> +
> + VOID *CACert;
> + UINTN CACertSize;
> + VOID *ClientCert;
> + UINTN ClientCertSize;
> + VOID *ClientPrivateKey;
> + UINTN ClientPrivateKeySize;
> +} TLS_CONFIG_DATA;
> +
> typedef struct _HTTP_PROTOCOL {
> UINT32 Signature;
> EFI_HTTP_PROTOCOL Http;
> EFI_HANDLE Handle;
> HTTP_SERVICE *Service;
> @@ -151,10 +165,39 @@ typedef struct _HTTP_PROTOCOL {
>
> NET_MAP TxTokens;
> NET_MAP RxTokens;
>
> CHAR8 *Url;
> +
> + //
> + // Https Support
> + //
> + BOOLEAN UseHttps;
> +
> + EFI_HANDLE TlsChildHandle; /// Tls ChildHandle
> + TLS_CONFIG_DATA TlsConfigData;
> + EFI_TLS_PROTOCOL *Tls;
> + EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfiguration;
> + EFI_TLS_SESSION_STATE TlsSessionState;
> +
> + //
> + // TlsTxData used for transmitting TLS related messages.
> + //
> + EFI_TCP4_IO_TOKEN Tcp4TlsTxToken;
> + EFI_TCP4_TRANSMIT_DATA Tcp4TlsTxData;
> + EFI_TCP6_IO_TOKEN Tcp6TlsTxToken;
> + EFI_TCP6_TRANSMIT_DATA Tcp6TlsTxData;
> + BOOLEAN TlsIsTxDone;
> +
> + //
> + // TlsRxData used for receiving TLS related messages.
> + //
> + EFI_TCP4_IO_TOKEN Tcp4TlsRxToken;
> + EFI_TCP4_RECEIVE_DATA Tcp4TlsRxData;
> + EFI_TCP6_IO_TOKEN Tcp6TlsRxToken;
> + EFI_TCP6_RECEIVE_DATA Tcp6TlsRxData;
> + BOOLEAN TlsIsRxDone;
> } HTTP_PROTOCOL;
>
> typedef struct {
> EFI_HTTP_TOKEN *HttpToken;
> HTTP_PROTOCOL *HttpInstance;
> @@ -350,11 +393,12 @@ HttpConfigureTcp6 (
> IN HTTP_PROTOCOL *HttpInstance,
> IN HTTP_TOKEN_WRAP *Wrap
> );
>
> /**
> - Check existing TCP connection, if in error state, receover TCP4 connection.
> + Check existing TCP connection, if in error state, recover TCP4 connection.
> Then,
> + connect one TLS session if required.
>
> @param[in] HttpInstance The HTTP instance private data.
>
> @retval EFI_SUCCESS The TCP connection is established.
> @retval EFI_NOT_READY TCP4 protocol child is not created or
> configured.
> @@ -365,11 +409,12 @@ EFI_STATUS
> HttpConnectTcp4 (
> IN HTTP_PROTOCOL *HttpInstance
> );
>
> /**
> - Check existing TCP connection, if in error state, recover TCP6 connection.
> + Check existing TCP connection, if in error state, recover TCP6 connection.
> Then,
> + connect one TLS session if required.
>
> @param[in] HttpInstance The HTTP instance private data.
>
> @retval EFI_SUCCESS The TCP connection is established.
> @retval EFI_NOT_READY TCP6 protocol child is not created or
> configured.
> @@ -380,11 +425,11 @@ EFI_STATUS
> HttpConnectTcp6 (
> IN HTTP_PROTOCOL *HttpInstance
> );
>
> /**
> - Send the HTTP message through TCP4 or TCP6.
> + Send the HTTP or HTTPS message through TCP4 or TCP6.
>
> @param[in] HttpInstance The HTTP instance private data.
> @param[in] Wrap The HTTP token's wrap data.
> @param[in] TxString Buffer containing the HTTP message string.
> @param[in] TxStringLen Length of the HTTP message string in bytes.
> @@ -441,29 +486,31 @@ HttpTcpNotReady (
> IN NET_MAP_ITEM *Item,
> IN VOID *Context
> );
>
> /**
> - Initialize TCP related data.
> + Initialize Http session.
>
> @param[in] HttpInstance The HTTP instance private data.
> @param[in] Wrap The HTTP token's wrap data.
> - @param[in] Configure The Flag indicates whether the first time to
> initialize Tcp.
> + @param[in] Configure The Flag indicates whether need to initialize
> session.
> + @param[in] TlsConfigure The Flag indicates whether it's the new Tls
> session.
>
> - @retval EFI_SUCCESS The initialization of TCP instance is done.
> + @retval EFI_SUCCESS The initialization of session is done.
> @retval Others Other error as indicated.
>
> **/
> EFI_STATUS
> -HttpInitTcp (
> +HttpInitSession (
> IN HTTP_PROTOCOL *HttpInstance,
> IN HTTP_TOKEN_WRAP *Wrap,
> - IN BOOLEAN Configure
> + IN BOOLEAN Configure,
> + IN BOOLEAN TlsConfigure
> );
>
> /**
> - Transmit the HTTP mssage by processing the associated HTTP token.
> + Transmit the HTTP or HTTPS mssage by processing the associated HTTP
> token.
>
> @param[in] Map The container of TxToken or Tx6Token.
> @param[in] Item Current item to check against.
> @param[in] Context The Token to check againist.
>
> diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c
> b/NetworkPkg/HttpDxe/HttpsSupport.c
> new file mode 100644
> index 0000000..177b9a8
> --- /dev/null
> +++ b/NetworkPkg/HttpDxe/HttpsSupport.c
> @@ -0,0 +1,1692 @@
> +/** @file
> + Miscellaneous routines specific to Https for HttpDxe driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "HttpDriver.h"
> +
> +/**
> + Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-
> terminated
> + ASCII string and ignore case during the search process.
> +
> + This function scans the contents of the ASCII string specified by String
> + and returns the first occurrence of SearchString and ignore case during the
> search process.
> + If SearchString is not found in String, then NULL is returned. If the length of
> SearchString
> + is zero, then String is returned.
> +
> + If String is NULL, then ASSERT().
> + If SearchString is NULL, then ASSERT().
> +
> + @param[in] String A pointer to a Null-terminated ASCII string.
> + @param[in] SearchString A pointer to a Null-terminated ASCII string to
> search for.
> +
> + @retval NULL If the SearchString does not appear in String.
> + @retval others If there is a match return the first occurrence of
> SearchingString.
> + If the length of SearchString is zero,return String.
> +
> +**/
> +CHAR8 *
> +AsciiStrCaseStr (
> + IN CONST CHAR8 *String,
> + IN CONST CHAR8 *SearchString
> + )
> +{
> + CONST CHAR8 *FirstMatch;
> + CONST CHAR8 *SearchStringTmp;
> +
> + CHAR8 Src;
> + CHAR8 Dst;
> +
> + //
> + // ASSERT both strings are less long than PcdMaximumAsciiStringLength
> + //
> + ASSERT (AsciiStrSize (String) != 0);
> + ASSERT (AsciiStrSize (SearchString) != 0);
> +
> + if (*SearchString == '\0') {
> + return (CHAR8 *) String;
> + }
> +
> + while (*String != '\0') {
> + SearchStringTmp = SearchString;
> + FirstMatch = String;
> +
> + while ((*SearchStringTmp != '\0')
> + && (*String != '\0')) {
> + Src = *String;
> + Dst = *SearchStringTmp;
> +
> + if ((Src >= 'A') && (Src <= 'Z')) {
> + Src -= ('A' - 'a');
> + }
> +
> + if ((Dst >= 'A') && (Dst <= 'Z')) {
> + Dst -= ('A' - 'a');
> + }
> +
> + if (Src != Dst) {
> + break;
> + }
> +
> + String++;
> + SearchStringTmp++;
> + }
> +
> + if (*SearchStringTmp == '\0') {
> + return (CHAR8 *) FirstMatch;
> + }
> +
> + String = FirstMatch + 1;
> + }
> +
> + return NULL;
> +}
> +
> +/**
> + The callback function to free the net buffer list.
> +
> + @param[in] Arg The opaque parameter.
> +
> +**/
> +VOID
> +EFIAPI
> +FreeNbufList (
> + IN VOID *Arg
> + )
> +{
> + ASSERT (Arg != NULL);
> +
> + NetbufFreeList ((LIST_ENTRY *) Arg);
> + FreePool (Arg);
> +}
> +
> +/**
> + Check whether the Url is from Https.
> +
> + @param[in] Url The pointer to a HTTP or HTTPS URL string.
> +
> + @retval TRUE The Url is from HTTPS.
> + @retval FALSE The Url is from HTTP.
> +
> +**/
> +BOOLEAN
> +IsHttpsUrl (
> + IN CHAR8 *Url
> + )
> +{
> + CHAR8 *Tmp;
> +
> + Tmp = NULL;
> +
> + Tmp = AsciiStrCaseStr (Url, HTTPS_FLAG);
> + if (Tmp != NULL && Tmp == Url) {
> + return TRUE;
> + }
> +
> + return FALSE;
> +}
> +
> +/**
> + Creates a Tls child handle, open EFI_TLS_PROTOCOL and
> EFI_TLS_CONFIGURATION_PROTOCOL.
> +
> + @param[in] ImageHandle The firmware allocated handle for the UEFI
> image.
> + @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[out] TlsConfiguration Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> +
> + @return The child handle with opened EFI_TLS_PROTOCOL and
> EFI_TLS_CONFIGURATION_PROTOCOL.
> +
> +**/
> +EFI_HANDLE
> +EFIAPI
> +TlsCreateChild (
> + IN EFI_HANDLE ImageHandle,
> + OUT EFI_TLS_PROTOCOL **TlsProto,
> + OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
> + )
> +{
> + EFI_STATUS Status;
> + EFI_SERVICE_BINDING_PROTOCOL *TlsSb;
> + EFI_HANDLE TlsChildHandle;
> +
> + TlsSb = NULL;
> + TlsChildHandle = 0;
> +
> + //
> + // Locate TlsServiceBinding protocol.
> + //
> + gBS->LocateProtocol (
> + &gEfiTlsServiceBindingProtocolGuid,
> + NULL,
> + (VOID **) &TlsSb
> + );
> + if (TlsSb == NULL) {
> + return NULL;
> + }
> +
> + Status = TlsSb->CreateChild (TlsSb, &TlsChildHandle);
> + if (EFI_ERROR (Status)) {
> + return NULL;
> + }
> +
> + Status = gBS->OpenProtocol (
> + TlsChildHandle,
> + &gEfiTlsProtocolGuid,
> + (VOID **) TlsProto,
> + ImageHandle,
> + TlsChildHandle,
> + EFI_OPEN_PROTOCOL_GET_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + TlsSb->DestroyChild (TlsSb, TlsChildHandle);
> + return NULL;
> + }
> +
> + Status = gBS->OpenProtocol (
> + TlsChildHandle,
> + &gEfiTlsConfigurationProtocolGuid,
> + (VOID **) TlsConfiguration,
> + ImageHandle,
> + TlsChildHandle,
> + EFI_OPEN_PROTOCOL_GET_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + TlsSb->DestroyChild (TlsSb, TlsChildHandle);
> + return NULL;
> + }
> +
> + return TlsChildHandle;
> +}
> +
> +/**
> + Create event for the TLS receive and transmit tokens which are used to
> receive and
> + transmit TLS related messages.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> +
> + @retval EFI_SUCCESS The events are created successfully.
> + @retval others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCreateTxRxEvent (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + //
> + // For Tcp4TlsTxToken.
> + //
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + HttpCommonNotify,
> + &HttpInstance->TlsIsTxDone,
> + &HttpInstance->Tcp4TlsTxToken.CompletionToken.Event
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + HttpInstance->Tcp4TlsTxData.Push = TRUE;
> + HttpInstance->Tcp4TlsTxData.Urgent = FALSE;
> + HttpInstance->Tcp4TlsTxData.DataLength = 0;
> + HttpInstance->Tcp4TlsTxData.FragmentCount = 1;
> + HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentLength =
> HttpInstance->Tcp4TlsTxData.DataLength;
> + HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
> + HttpInstance->Tcp4TlsTxToken.Packet.TxData = &HttpInstance-
> >Tcp4TlsTxData;
> + HttpInstance->Tcp4TlsTxToken.CompletionToken.Status =
> EFI_NOT_READY;
> +
> + //
> + // For Tcp4TlsRxToken.
> + //
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + HttpCommonNotify,
> + &HttpInstance->TlsIsRxDone,
> + &HttpInstance->Tcp4TlsRxToken.CompletionToken.Event
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + HttpInstance->Tcp4TlsRxData.DataLength = 0;
> + HttpInstance->Tcp4TlsRxData.FragmentCount = 1;
> + HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentLength =
> HttpInstance->Tcp4TlsRxData.DataLength ;
> + HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
> + HttpInstance->Tcp4TlsRxToken.Packet.RxData = &HttpInstance-
> >Tcp4TlsRxData;
> + HttpInstance->Tcp4TlsRxToken.CompletionToken.Status =
> EFI_NOT_READY;
> + } else {
> + //
> + // For Tcp6TlsTxToken.
> + //
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + HttpCommonNotify,
> + &HttpInstance->TlsIsTxDone,
> + &HttpInstance->Tcp6TlsTxToken.CompletionToken.Event
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + HttpInstance->Tcp6TlsTxData.Push = TRUE;
> + HttpInstance->Tcp6TlsTxData.Urgent = FALSE;
> + HttpInstance->Tcp6TlsTxData.DataLength = 0;
> + HttpInstance->Tcp6TlsTxData.FragmentCount = 1;
> + HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentLength =
> HttpInstance->Tcp6TlsTxData.DataLength;
> + HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
> + HttpInstance->Tcp6TlsTxToken.Packet.TxData = &HttpInstance-
> >Tcp6TlsTxData;
> + HttpInstance->Tcp6TlsTxToken.CompletionToken.Status =
> EFI_NOT_READY;
> +
> + //
> + // For Tcp6TlsRxToken.
> + //
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + HttpCommonNotify,
> + &HttpInstance->TlsIsRxDone,
> + &HttpInstance->Tcp6TlsRxToken.CompletionToken.Event
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + HttpInstance->Tcp6TlsRxData.DataLength = 0;
> + HttpInstance->Tcp6TlsRxData.FragmentCount = 1;
> + HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentLength =
> HttpInstance->Tcp6TlsRxData.DataLength ;
> + HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
> + HttpInstance->Tcp6TlsRxToken.Packet.RxData = &HttpInstance-
> >Tcp6TlsRxData;
> + HttpInstance->Tcp6TlsRxToken.CompletionToken.Status =
> EFI_NOT_READY;
> + }
> +
> + return Status;
> +
> +ERROR:
> + //
> + // Error handling
> + //
> + TlsCloseTxRxEvent (HttpInstance);
> +
> + return Status;
> +}
> +
> +/**
> + Close events in the TlsTxToken and TlsRxToken.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsCloseTxRxEvent (
> + IN HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + ASSERT (HttpInstance != NULL);
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + if (NULL != HttpInstance->Tcp4TlsTxToken.CompletionToken.Event) {
> + gBS->CloseEvent(HttpInstance-
> >Tcp4TlsTxToken.CompletionToken.Event);
> + HttpInstance->Tcp4TlsTxToken.CompletionToken.Event = NULL;
> + }
> +
> + if (NULL != HttpInstance->Tcp4TlsRxToken.CompletionToken.Event) {
> + gBS->CloseEvent (HttpInstance-
> >Tcp4TlsRxToken.CompletionToken.Event);
> + HttpInstance->Tcp4TlsRxToken.CompletionToken.Event = NULL;
> + }
> + } else {
> + if (NULL != HttpInstance->Tcp6TlsTxToken.CompletionToken.Event) {
> + gBS->CloseEvent(HttpInstance-
> >Tcp6TlsTxToken.CompletionToken.Event);
> + HttpInstance->Tcp6TlsTxToken.CompletionToken.Event = NULL;
> + }
> +
> + if (NULL != HttpInstance->Tcp6TlsRxToken.CompletionToken.Event) {
> + gBS->CloseEvent (HttpInstance-
> >Tcp6TlsRxToken.CompletionToken.Event);
> + HttpInstance->Tcp6TlsRxToken.CompletionToken.Event = NULL;
> + }
> + }
> +}
> +
> +/**
> + Read the TlsCaCertificate variable and configure it.
> +
> + @param[in, out] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS TlsCaCertificate is configured.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +TlsConfigCertificate (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 *CACert;
> + UINTN CACertSize;
> + UINT32 Index;
> + EFI_SIGNATURE_LIST *CertList;
> + EFI_SIGNATURE_DATA *Cert;
> + UINTN CertCount;
> + UINT32 ItemDataSize;
> +
> + CACert = (UINT8 *) HttpInstance->TlsConfigData.CACert;
> + CACertSize = HttpInstance->TlsConfigData.CACertSize;
> +
> + //
> + // Try to read the TlsCaCertificate variable.
> + //
> + CACertSize = 0;
> + Status = gRT->GetVariable (
> + EFI_TLS_CA_CERTIFICATE_VARIABLE,
> + &gEfiTlsCaCertificateGuid,
> + NULL,
> + &CACertSize,
> + NULL
> + );
> +
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + //
> + // Allocate buffer and read the config variable.
> + //
> + CACert = AllocatePool (CACertSize);
> + if (CACert == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = gRT->GetVariable (
> + EFI_TLS_CA_CERTIFICATE_VARIABLE,
> + &gEfiTlsCaCertificateGuid,
> + NULL,
> + &CACertSize,
> + CACert
> + );
> + if (EFI_ERROR (Status)) {
> + //
> + // GetVariable still error or the variable is corrupted.
> + // Fall back to the default value.
> + //
> + FreePool (CACert);
> +
> + return EFI_NOT_FOUND;
> + }
> + }
> +
> + //
> + // Enumerate all data and erasing the target item.
> + //
> + ItemDataSize = (UINT32) CACertSize;
> + CertList = (EFI_SIGNATURE_LIST *) CACert;
> + while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize))
> {
> + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof
> (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
> + CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) -
> CertList->SignatureHeaderSize) / CertList->SignatureSize;
> + for (Index = 0; Index < CertCount; Index++) {
> + //
> + // EfiTlsConfigDataTypeCACertificate
> + //
> + Status = HttpInstance->TlsConfiguration->SetData (
> + HttpInstance->TlsConfiguration,
> + EfiTlsConfigDataTypeCACertificate,
> + Cert->SignatureData,
> + CertList->SignatureSize - sizeof (Cert-
> >SignatureOwner)
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList-
> >SignatureSize);
> + }
> +
> + ItemDataSize -= CertList->SignatureListSize;
> + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList-
> >SignatureListSize);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Configure TLS session data.
> +
> + @param[in, out] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS TLS session data is configured.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigureSession (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + EFI_STATUS Status;
> +
> + //
> + // TlsConfigData initialization
> + //
> + HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient;
> + HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER;
> + HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted;
> +
> + //
> + // EfiTlsConnectionEnd,
> + // EfiTlsVerifyMethod
> + // EfiTlsSessionState
> + //
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsConnectionEnd,
> + &(HttpInstance->TlsConfigData.ConnectionEnd),
> + sizeof (EFI_TLS_CONNECTION_END)
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsVerifyMethod,
> + &HttpInstance->TlsConfigData.VerifyMethod,
> + sizeof (EFI_TLS_VERIFY)
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + &(HttpInstance->TlsConfigData.SessionState),
> + sizeof (EFI_TLS_SESSION_STATE)
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + //
> + // Tls Config Certificate
> + //
> + Status = TlsConfigCertificate (HttpInstance);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "TLS Certificate Config Error!\n"));
> + goto ERROR;
> + }
> +
> + //
> + // TlsCreateTxRxEvent
> + //
> + Status = TlsCreateTxRxEvent (HttpInstance);
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + return Status;
> +
> +ERROR:
> + TlsCloseTxRxEvent (HttpInstance);
> +
> + return Status;
> +}
> +
> +/**
> + Transmit the Packet by processing the associated HTTPS token.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Packet The packet to transmit.
> +
> + @retval EFI_SUCCESS The packet is transmitted.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_DEVICE_ERROR An unexpected system or network error
> occurred.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCommonTransmit (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + IN NET_BUF *Packet
> + )
> +{
> + EFI_STATUS Status;
> + VOID *Data;
> + UINTN Size;
> +
> + if ((HttpInstance == NULL) || (Packet == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + Size = sizeof (EFI_TCP4_TRANSMIT_DATA) +
> + (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA);
> + } else {
> + Size = sizeof (EFI_TCP6_TRANSMIT_DATA) +
> + (Packet->BlockOpNum - 1) * sizeof (EFI_TCP6_FRAGMENT_DATA);
> + }
> +
> + Data = AllocatePool (Size);
> + if (Data == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + ((EFI_TCP4_TRANSMIT_DATA *) Data)->Push = TRUE;
> + ((EFI_TCP4_TRANSMIT_DATA *) Data)->Urgent = FALSE;
> + ((EFI_TCP4_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
> +
> + //
> + // Build the fragment table.
> + //
> + ((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount = Packet-
> >BlockOpNum;
> +
> + NetbufBuildExt (
> + Packet,
> + (NET_FRAGMENT *) &((EFI_TCP4_TRANSMIT_DATA *) Data)-
> >FragmentTable[0],
> + &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount
> + );
> +
> + HttpInstance->Tcp4TlsTxToken.Packet.TxData =
> (EFI_TCP4_TRANSMIT_DATA *) Data;
> +
> + Status = EFI_DEVICE_ERROR;
> +
> + //
> + // Transmit the packet.
> + //
> + Status = HttpInstance->Tcp4->Transmit (HttpInstance->Tcp4,
> &HttpInstance->Tcp4TlsTxToken);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + while (!HttpInstance->TlsIsTxDone) {
> + HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
> + }
> +
> + HttpInstance->TlsIsTxDone = FALSE;
> + Status = HttpInstance->Tcp4TlsTxToken.CompletionToken.Status;
> + } else {
> + ((EFI_TCP6_TRANSMIT_DATA *) Data)->Push = TRUE;
> + ((EFI_TCP6_TRANSMIT_DATA *) Data)->Urgent = FALSE;
> + ((EFI_TCP6_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
> +
> + //
> + // Build the fragment table.
> + //
> + ((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount = Packet-
> >BlockOpNum;
> +
> + NetbufBuildExt (
> + Packet,
> + (NET_FRAGMENT *) &((EFI_TCP6_TRANSMIT_DATA *) Data)-
> >FragmentTable[0],
> + &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount
> + );
> +
> + HttpInstance->Tcp6TlsTxToken.Packet.TxData =
> (EFI_TCP6_TRANSMIT_DATA *) Data;
> +
> + Status = EFI_DEVICE_ERROR;
> +
> + //
> + // Transmit the packet.
> + //
> + Status = HttpInstance->Tcp6->Transmit (HttpInstance->Tcp6,
> &HttpInstance->Tcp6TlsTxToken);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + while (!HttpInstance->TlsIsTxDone) {
> + HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
> + }
> +
> + HttpInstance->TlsIsTxDone = FALSE;
> + Status = HttpInstance->Tcp6TlsTxToken.CompletionToken.Status;
> + }
> +
> +ON_EXIT:
> + FreePool (Data);
> +
> + return Status;
> +}
> +
> +/**
> + Receive the Packet by processing the associated HTTPS token.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Packet The packet to transmit.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS The Packet is received.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_TIMEOUT The operation is time out.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCommonReceive (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + IN NET_BUF *Packet,
> + IN EFI_EVENT Timeout
> + )
> +{
> + EFI_TCP4_RECEIVE_DATA *Tcp4RxData;
> + EFI_TCP6_RECEIVE_DATA *Tcp6RxData;
> + EFI_STATUS Status;
> + NET_FRAGMENT *Fragment;
> + UINT32 FragmentCount;
> + UINT32 CurrentFragment;
> +
> + Tcp4RxData = NULL;
> + Tcp6RxData = NULL;
> +
> + if ((HttpInstance == NULL) || (Packet == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + FragmentCount = Packet->BlockOpNum;
> + Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));
> + if (Fragment == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Build the fragment table.
> + //
> + NetbufBuildExt (Packet, Fragment, &FragmentCount);
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + Tcp4RxData = HttpInstance->Tcp4TlsRxToken.Packet.RxData;
> + if (Tcp4RxData == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + Tcp4RxData->FragmentCount = 1;
> + } else {
> + Tcp6RxData = HttpInstance->Tcp6TlsRxToken.Packet.RxData;
> + if (Tcp6RxData == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + Tcp6RxData->FragmentCount = 1;
> + }
> +
> + CurrentFragment = 0;
> + Status = EFI_SUCCESS;
> +
> + while (CurrentFragment < FragmentCount) {
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + Tcp4RxData->DataLength = Fragment[CurrentFragment].Len;
> + Tcp4RxData->FragmentTable[0].FragmentLength =
> Fragment[CurrentFragment].Len;
> + Tcp4RxData->FragmentTable[0].FragmentBuffer =
> Fragment[CurrentFragment].Bulk;
> + Status = HttpInstance->Tcp4->Receive (HttpInstance->Tcp4,
> &HttpInstance->Tcp4TlsRxToken);
> + } else {
> + Tcp6RxData->DataLength = Fragment[CurrentFragment].Len;
> + Tcp6RxData->FragmentTable[0].FragmentLength =
> Fragment[CurrentFragment].Len;
> + Tcp6RxData->FragmentTable[0].FragmentBuffer =
> Fragment[CurrentFragment].Bulk;
> + Status = HttpInstance->Tcp6->Receive (HttpInstance->Tcp6,
> &HttpInstance->Tcp6TlsRxToken);
> + }
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + while (!HttpInstance->TlsIsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> + //
> + // Poll until some data is received or an error occurs.
> + //
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
> + } else {
> + HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
> + }
> + }
> +
> + if (!HttpInstance->TlsIsRxDone) {
> + //
> + // Timeout occurs, cancel the receive request.
> + //
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance-
> >Tcp4TlsRxToken.CompletionToken);
> + } else {
> + HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance-
> >Tcp6TlsRxToken.CompletionToken);
> + }
> +
> + Status = EFI_TIMEOUT;
> + goto ON_EXIT;
> + } else {
> + HttpInstance->TlsIsRxDone = FALSE;
> + }
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + Status = HttpInstance->Tcp4TlsRxToken.CompletionToken.Status;
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + Fragment[CurrentFragment].Len -= Tcp4RxData-
> >FragmentTable[0].FragmentLength;
> + if (Fragment[CurrentFragment].Len == 0) {
> + CurrentFragment++;
> + } else {
> + Fragment[CurrentFragment].Bulk += Tcp4RxData-
> >FragmentTable[0].FragmentLength;
> + }
> + } else {
> + Status = HttpInstance->Tcp6TlsRxToken.CompletionToken.Status;
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + Fragment[CurrentFragment].Len -= Tcp6RxData-
> >FragmentTable[0].FragmentLength;
> + if (Fragment[CurrentFragment].Len == 0) {
> + CurrentFragment++;
> + } else {
> + Fragment[CurrentFragment].Bulk += Tcp6RxData-
> >FragmentTable[0].FragmentLength;
> + }
> + }
> + }
> +
> +ON_EXIT:
> +
> + if (Fragment != NULL) {
> + FreePool (Fragment);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
> + corresponding record data. This two parts will be put into two blocks of
> buffers in the
> + net buffer.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[out] Pdu The received TLS PDU.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS An TLS PDU is received.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsReceiveOnePdu (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + OUT NET_BUF **Pdu,
> + IN EFI_EVENT Timeout
> + )
> +{
> + EFI_STATUS Status;
> +
> + LIST_ENTRY *NbufList;
> +
> + UINT32 Len;
> +
> + NET_BUF *PduHdr;
> + UINT8 *Header;
> + TLS_RECORD_HEADER RecordHeader;
> +
> + NET_BUF *DataSeg;
> +
> + NbufList = NULL;
> + PduHdr = NULL;
> + Header = NULL;
> + DataSeg = NULL;
> +
> + NbufList = AllocatePool (sizeof (LIST_ENTRY));
> + if (NbufList == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + InitializeListHead (NbufList);
> +
> + //
> + // Allocate buffer to receive one TLS header.
> + //
> + Len = sizeof (TLS_RECORD_HEADER);
> + PduHdr = NetbufAlloc (Len);
> + if (PduHdr == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);
> + if (Header == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // First step, receive one TLS header.
> + //
> + Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + RecordHeader = *(TLS_RECORD_HEADER *) Header;
> + if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_HANDSHAKE ||
> + RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT ||
> + RecordHeader.ContentType ==
> TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC ||
> + RecordHeader.ContentType ==
> TLS_CONTENT_TYPE_APPLICATION_DATA) &&
> + (RecordHeader.Version.Major == 0x03) && /// Major versions are same.
> + (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor ==TLS11_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
> + ) {
> + InsertTailList (NbufList, &PduHdr->List);
> + } else {
> + Status = EFI_PROTOCOL_ERROR;
> + goto ON_EXIT;
> + }
> +
> + Len = SwapBytes16(RecordHeader.Length);
> + if (Len == 0) {
> + //
> + // No TLS payload.
> + //
> + goto FORM_PDU;
> + }
> +
> + //
> + // Allocate buffer to receive one TLS payload.
> + //
> + DataSeg = NetbufAlloc (Len);
> + if (DataSeg == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL);
> +
> + //
> + // Second step, receive one TLS payload.
> + //
> + Status = TlsCommonReceive (HttpInstance, DataSeg, Timeout);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + InsertTailList (NbufList, &DataSeg->List);
> +
> +FORM_PDU:
> + //
> + // Form the PDU from a list of PDU.
> + //
> + *Pdu = NetbufFromBufList (NbufList, 0, 0, FreeNbufList, NbufList);
> + if (*Pdu == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + }
> +
> +ON_EXIT:
> +
> + if (EFI_ERROR (Status)) {
> + //
> + // Free the Nbufs in this NbufList and the NbufList itself.
> + //
> + FreeNbufList (NbufList);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Connect one TLS session by finishing the TLS handshake process.
> +
> + @param[in] HttpInstance The HTTP instance private data.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS The TLS session is established.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConnectSession (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN EFI_EVENT Timeout
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 *BufferOut;
> + UINTN BufferOutSize;
> + NET_BUF *PacketOut;
> + UINT8 *DataOut;
> + NET_BUF *Pdu;
> + UINT8 *BufferIn;
> + UINTN BufferInSize;
> + UINT8 *GetSessionDataBuffer;
> + UINTN GetSessionDataBufferSize;
> +
> + BufferOut = NULL;
> + PacketOut = NULL;
> + DataOut = NULL;
> + Pdu = NULL;
> + BufferIn = NULL;
> +
> + //
> + // Initialize TLS state.
> + //
> + HttpInstance->TlsSessionState = EfiTlsSessionNotStarted;
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + &(HttpInstance->TlsSessionState),
> + sizeof (EFI_TLS_SESSION_STATE)
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Create ClientHello
> + //
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + FreePool (BufferOut);
> + return Status;
> + }
> +
> + //
> + // Transmit ClientHello
> + //
> + PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + FreePool (BufferOut);
> + NetbufFree (PacketOut);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + while(HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring && \
> + ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
> + //
> + // Receive one TLS record.
> + //
> + Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + BufferInSize = Pdu->TotalSize;
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + NetbufFree (Pdu);
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn);
> +
> + NetbufFree (Pdu);
> +
> + //
> + // Handle Receive data.
> + //
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + BufferIn,
> + BufferInSize,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + BufferIn,
> + BufferInSize,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> +
> + FreePool (BufferIn);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + if (BufferOutSize != 0) {
> + //
> + // Transmit the response packet.
> + //
> + PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> +
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + NetbufFree (PacketOut);
> +
> + if (EFI_ERROR (Status)) {
> + FreePool (BufferOut);
> + return Status;
> + }
> + }
> +
> + FreePool (BufferOut);
> +
> + //
> + // Get the session state, then decide whether need to continue handle
> received packet.
> + //
> + GetSessionDataBufferSize = DEF_BUF_LEN;
> + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
> + if (GetSessionDataBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->GetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + GetSessionDataBuffer,
> + &GetSessionDataBufferSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (GetSessionDataBuffer);
> + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
> + if (GetSessionDataBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->GetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + GetSessionDataBuffer,
> + &GetSessionDataBufferSize
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + FreePool(GetSessionDataBuffer);
> + return Status;
> + }
> +
> + ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
> + HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *)
> GetSessionDataBuffer;
> +
> + FreePool (GetSessionDataBuffer);
> +
> + if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
> + return EFI_ABORTED;
> + }
> + }
> +
> + if (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring) {
> + Status = EFI_ABORTED;
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Close the TLS session and send out the close notification message.
> +
> + @param[in] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS The TLS session is closed.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCloseSession (
> + IN HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + EFI_STATUS Status;
> +
> + UINT8 *BufferOut;
> + UINTN BufferOutSize;
> +
> + NET_BUF *PacketOut;
> + UINT8 *DataOut;
> +
> + Status = EFI_SUCCESS;
> + BufferOut = NULL;
> + PacketOut = NULL;
> + DataOut = NULL;
> +
> + if (HttpInstance == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + HttpInstance->TlsSessionState = EfiTlsSessionClosing;
> +
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + &(HttpInstance->TlsSessionState),
> + sizeof (EFI_TLS_SESSION_STATE)
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> +
> + if (EFI_ERROR (Status)) {
> + FreePool (BufferOut);
> + return Status;
> + }
> +
> + PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> +
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + FreePool (BufferOut);
> + NetbufFree (PacketOut);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Process one message according to the CryptMode.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Message Pointer to the message buffer needed to
> processed.
> + @param[in] MessageSize Pointer to the message buffer size.
> + @param[in] ProcessMode Process mode.
> + @param[in, out] Fragment Only one Fragment returned after the
> Message is
> + processed successfully.
> +
> + @retval EFI_SUCCESS Message is processed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessMessage (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN UINT8 *Message,
> + IN UINTN MessageSize,
> + IN EFI_TLS_CRYPT_MODE ProcessMode,
> + IN OUT NET_FRAGMENT *Fragment
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 *Buffer;
> + UINT32 BufferSize;
> + UINT32 BytesCopied;
> + EFI_TLS_FRAGMENT_DATA *FragmentTable;
> + UINT32 FragmentCount;
> + EFI_TLS_FRAGMENT_DATA *OriginalFragmentTable;
> + UINTN Index;
> +
> + Status = EFI_SUCCESS;
> + Buffer = NULL;
> + BufferSize = 0;
> + BytesCopied = 0;
> + FragmentTable = NULL;
> + OriginalFragmentTable = NULL;
> +
> + //
> + // Rebuild fragment table from BufferIn.
> + //
> + FragmentCount = 1;
> + FragmentTable = AllocateZeroPool (FragmentCount * sizeof
> (EFI_TLS_FRAGMENT_DATA));
> + if (FragmentTable == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + FragmentTable->FragmentLength = (UINT32) MessageSize;
> + FragmentTable->FragmentBuffer = Message;
> +
> + //
> + // Record the original FragmentTable.
> + //
> + OriginalFragmentTable = FragmentTable;
> +
> + //
> + // Process the Message.
> + //
> + Status = HttpInstance->Tls->ProcessPacket (
> + HttpInstance->Tls,
> + &FragmentTable,
> + &FragmentCount,
> + ProcessMode
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + //
> + // Calculate the size according to FragmentTable.
> + //
> + for (Index = 0; Index < FragmentCount; Index++) {
> + BufferSize += FragmentTable[Index].FragmentLength;
> + }
> +
> + //
> + // Allocate buffer for processed data.
> + //
> + Buffer = AllocateZeroPool (BufferSize);
> + if (Buffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Copy the new FragmentTable buffer into Buffer.
> + //
> + for (Index = 0; Index < FragmentCount; Index++) {
> + CopyMem (
> + (Buffer + BytesCopied),
> + FragmentTable[Index].FragmentBuffer,
> + FragmentTable[Index].FragmentLength
> + );
> + BytesCopied += FragmentTable[Index].FragmentLength;
> +
> + //
> + // Free the FragmentBuffer since it has been copied.
> + //
> + FreePool (FragmentTable[Index].FragmentBuffer);
> + }
> +
> + Fragment->Len = BufferSize;
> + Fragment->Bulk = Buffer;
> +
> +ON_EXIT:
> +
> + if (OriginalFragmentTable != NULL) {
> + FreePool (OriginalFragmentTable);
> + OriginalFragmentTable = NULL;
> + }
> +
> + //
> + // Caller has the responsibility to free the FragmentTable.
> + //
> + if (FragmentTable != NULL) {
> + FreePool (FragmentTable);
> + FragmentTable = NULL;
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Receive one fragment decrypted from one TLS record.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in, out] Fragment The received Fragment.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS One fragment is received.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED Something wrong decryption the message.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +HttpsReceive (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN OUT NET_FRAGMENT *Fragment,
> + IN EFI_EVENT Timeout
> + )
> +{
> + EFI_STATUS Status;
> + NET_BUF *Pdu;
> + TLS_RECORD_HEADER RecordHeader;
> + UINT8 *BufferIn;
> + UINTN BufferInSize;
> + NET_FRAGMENT TempFragment;
> + UINT8 *BufferOut;
> + UINTN BufferOutSize;
> + NET_BUF *PacketOut;
> + UINT8 *DataOut;
> + UINT8 *GetSessionDataBuffer;
> + UINTN GetSessionDataBufferSize;
> +
> + Status = EFI_SUCCESS;
> + Pdu = NULL;
> + BufferIn = NULL;
> + BufferInSize = 0;
> + BufferOut = NULL;
> + BufferOutSize = 0;
> + PacketOut = NULL;
> + DataOut = NULL;
> + GetSessionDataBuffer = NULL;
> + GetSessionDataBufferSize = 0;
> +
> + //
> + // Receive only one TLS record
> + //
> + Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + BufferInSize = Pdu->TotalSize;
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + NetbufFree (Pdu);
> + return Status;
> + }
> +
> + NetbufCopy (Pdu, 0, (UINT32) BufferInSize, BufferIn);
> +
> + NetbufFree (Pdu);
> +
> + //
> + // Handle Receive data.
> + //
> + RecordHeader = *(TLS_RECORD_HEADER *) BufferIn;
> +
> + if ((RecordHeader.ContentType ==
> TLS_CONTENT_TYPE_APPLICATION_DATA) &&
> + (RecordHeader.Version.Major == 0x03) &&
> + (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
> + ) {
> + //
> + // Decrypt Packet.
> + //
> + Status = TlsProcessMessage (
> + HttpInstance,
> + BufferIn,
> + BufferInSize,
> + EfiTlsDecrypt,
> + &TempFragment
> + );
> +
> + FreePool (BufferIn);
> +
> + if (EFI_ERROR (Status)) {
> + if (Status == EFI_ABORTED) {
> + //
> + // Something wrong decryption the message.
> + // BuildResponsePacket() will be called to generate Error Alert message
> and send it out.
> + //
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + FreePool(BufferOut);
> + return Status;
> + }
> +
> + if (BufferOutSize != 0) {
> + PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> +
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + NetbufFree (PacketOut);
> + }
> +
> + FreePool(BufferOut);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + return EFI_ABORTED;
> + }
> +
> + return Status;
> + }
> +
> + //
> + // Parsing buffer.
> + //
> + ASSERT (((TLS_RECORD_HEADER *) (TempFragment.Bulk))->ContentType
> == TLS_CONTENT_TYPE_APPLICATION_DATA);
> +
> + BufferInSize = ((TLS_RECORD_HEADER *) (TempFragment.Bulk))->Length;
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + CopyMem (BufferIn, TempFragment.Bulk + sizeof
> (TLS_RECORD_HEADER), BufferInSize);
> +
> + //
> + // Free the buffer in TempFragment.
> + //
> + FreePool (TempFragment.Bulk);
> +
> + } else if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT) &&
> + (RecordHeader.Version.Major == 0x03) &&
> + (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
> + ) {
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + BufferIn,
> + BufferInSize,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + BufferIn,
> + BufferInSize,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> +
> + FreePool (BufferIn);
> +
> + if (EFI_ERROR (Status)) {
> + FreePool (BufferOut);
> + return Status;
> + }
> +
> + if (BufferOutSize != 0) {
> + PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> +
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + NetbufFree (PacketOut);
> + }
> +
> + FreePool (BufferOut);
> +
> + //
> + // Get the session state.
> + //
> + GetSessionDataBufferSize = DEF_BUF_LEN;
> + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
> + if (GetSessionDataBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->GetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + GetSessionDataBuffer,
> + &GetSessionDataBufferSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (GetSessionDataBuffer);
> + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
> + if (GetSessionDataBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->GetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + GetSessionDataBuffer,
> + &GetSessionDataBufferSize
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + FreePool (GetSessionDataBuffer);
> + return Status;
> + }
> +
> + ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
> + HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *)
> GetSessionDataBuffer;
> +
> + FreePool (GetSessionDataBuffer);
> +
> + if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
> + DEBUG ((EFI_D_ERROR, "TLS Session State Error!\n"));
> + return EFI_ABORTED;
> + }
> +
> + BufferIn = NULL;
> + BufferInSize = 0;
> + }
> +
> + Fragment->Bulk = BufferIn;
> + Fragment->Len = (UINT32) BufferInSize;
> +
> + return Status;
> +}
> diff --git a/NetworkPkg/HttpDxe/HttpsSupport.h
> b/NetworkPkg/HttpDxe/HttpsSupport.h
> new file mode 100644
> index 0000000..d846b76
> --- /dev/null
> +++ b/NetworkPkg/HttpDxe/HttpsSupport.h
> @@ -0,0 +1,260 @@
> +/** @file
> + The header files of miscellaneous routines specific to Https for HttpDxe
> driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __EFI_HTTPS_SUPPORT_H__
> +#define __EFI_HTTPS_SUPPORT_H__
> +
> +#define HTTPS_DEFAULT_PORT 443
> +
> +#define HTTPS_FLAG "https"
> +
> +/**
> + Check whether the Url is from Https.
> +
> + @param[in] Url The pointer to a HTTP or HTTPS URL string.
> +
> + @retval TRUE The Url is from HTTPS.
> + @retval FALSE The Url is from HTTP.
> +
> +**/
> +BOOLEAN
> +IsHttpsUrl (
> + IN CHAR8 *Url
> + );
> +
> +/**
> + Creates a Tls child handle, open EFI_TLS_PROTOCOL and
> EFI_TLS_CONFIGURATION_PROTOCOL.
> +
> + @param[in] ImageHandle The firmware allocated handle for the UEFI
> image.
> + @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[out] TlsConfiguration Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> +
> + @return The child handle with opened EFI_TLS_PROTOCOL and
> EFI_TLS_CONFIGURATION_PROTOCOL.
> +
> +**/
> +EFI_HANDLE
> +EFIAPI
> +TlsCreateChild (
> + IN EFI_HANDLE ImageHandle,
> + OUT EFI_TLS_PROTOCOL **TlsProto,
> + OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
> + );
> +
> +/**
> + Create event for the TLS receive and transmit tokens which are used to
> receive and
> + transmit TLS related messages.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> +
> + @retval EFI_SUCCESS The events are created successfully.
> + @retval others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCreateTxRxEvent (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Close events in the TlsTxToken and TlsRxToken.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsCloseTxRxEvent (
> + IN HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Read the TlsCaCertificate variable and configure it.
> +
> + @param[in, out] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS TlsCaCertificate is configured.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_NOT_FOUND Fail to get "TlsCaCertificate" variable.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +TlsConfigCertificate (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Configure TLS session data.
> +
> + @param[in, out] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS TLS session data is configured.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigureSession (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Transmit the Packet by processing the associated HTTPS token.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Packet The packet to transmit.
> +
> + @retval EFI_SUCCESS The packet is transmitted.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_DEVICE_ERROR An unexpected system or network error
> occurred.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCommonTransmit (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + IN NET_BUF *Packet
> + );
> +
> +/**
> + Receive the Packet by processing the associated HTTPS token.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Packet The packet to transmit.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS The Packet is received.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_TIMEOUT The operation is time out.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCommonReceive (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + IN NET_BUF *Packet,
> + IN EFI_EVENT Timeout
> + );
> +
> +/**
> + Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
> + corresponding record data. The two parts will be put into two blocks of
> buffers in the
> + net buffer.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[out] Pdu The received TLS PDU.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS An TLS PDU is received.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsReceiveOnePdu (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + OUT NET_BUF **Pdu,
> + IN EFI_EVENT Timeout
> + );
> +
> +/**
> + Connect one TLS session by finishing the TLS handshake process.
> +
> + @param[in] HttpInstance The HTTP instance private data.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS The TLS session is established.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConnectSession (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN EFI_EVENT Timeout
> + );
> +
> +/**
> + Close the TLS session and send out the close notification message.
> +
> + @param[in] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS The TLS session is closed.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCloseSession (
> + IN HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Process one message according to the CryptMode.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Message Pointer to the message buffer needed to
> processed.
> + @param[in] MessageSize Pointer to the message buffer size.
> + @param[in] ProcessMode Process mode.
> + @param[in, out] Fragment Only one Fragment returned after the
> Message is
> + processed successfully.
> +
> + @retval EFI_SUCCESS Message is processed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessMessage (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN UINT8 *Message,
> + IN UINTN MessageSize,
> + IN EFI_TLS_CRYPT_MODE ProcessMode,
> + IN OUT NET_FRAGMENT *Fragment
> + );
> +
> +/**
> + Receive one fragment decrypted from one TLS record.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in, out] Fragment The received Fragment.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS One fragment is received.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED Something wrong decryption the message.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +HttpsReceive (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN OUT NET_FRAGMENT *Fragment,
> + IN EFI_EVENT Timeout
> + );
> +
> +#endif
> --
> 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6
2016-12-14 7:34 ` [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6 Jiaxin Wu
2016-12-15 2:39 ` Fu, Siyuan
@ 2016-12-22 7:33 ` Ye, Ting
2016-12-22 8:30 ` Wu, Jiaxin
1 sibling, 1 reply; 37+ messages in thread
From: Ye, Ting @ 2016-12-22 7:33 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Fu, Siyuan, Zhang, Lubo, Long, Qin, Thomas Palmer
Hi Jiaxin,
Some comments included below.
1. In TlsConfigCertificate, HttpInstance->TlsConfigData.CACert is not used and local variable "CACert" is not freed after calling TlsConfiguration->SetData.
2. In TlsConfigureSession, several gotos are useless. Suggest to replace with return status directly.
3. This two parts will be ==> These
Others are good to me.
Reviewed-by: Ye Ting <ting.ye@intel.com>
Best Regards,
Ye Ting
-----Original Message-----
From: Wu, Jiaxin
Sent: Wednesday, December 14, 2016 3:34 PM
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6
This patch is used to enable HTTPS feature. HttpDxe driver
will consume TlsDxe driver. It can both support http and https
feature, that’s depended on the information of URL, the HTTP
instance can be able to determine whether to use http or https.
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/HttpDxe/HttpDriver.h | 10 +-
NetworkPkg/HttpDxe/HttpDxe.inf | 12 +-
NetworkPkg/HttpDxe/HttpImpl.c | 252 +++++-
NetworkPkg/HttpDxe/HttpProto.c | 464 +++++++---
NetworkPkg/HttpDxe/HttpProto.h | 65 +-
NetworkPkg/HttpDxe/HttpsSupport.c | 1692 +++++++++++++++++++++++++++++++++++++
NetworkPkg/HttpDxe/HttpsSupport.h | 260 ++++++
7 files changed, 2601 insertions(+), 154 deletions(-)
create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.c
create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.h
diff --git a/NetworkPkg/HttpDxe/HttpDriver.h b/NetworkPkg/HttpDxe/HttpDriver.h
index fa2372c..93a412a 100644
--- a/NetworkPkg/HttpDxe/HttpDriver.h
+++ b/NetworkPkg/HttpDxe/HttpDriver.h
@@ -22,10 +22,11 @@
//
// Libraries
//
#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/BaseLib.h>
#include <Library/UefiLib.h>
#include <Library/DebugLib.h>
#include <Library/NetLib.h>
@@ -48,17 +49,23 @@
#include <Protocol/Tcp6.h>
#include <Protocol/Dns4.h>
#include <Protocol/Dns6.h>
#include <Protocol/Ip4Config2.h>
#include <Protocol/Ip6Config.h>
+#include <Protocol/Tls.h>
+#include <Protocol/TlsConfig.h>
-
+#include <Guid/ImageAuthentication.h>
//
// Produced Protocols
//
#include <Protocol/Http.h>
+#include <Guid/TlsAuthentication.h>
+
+#include <IndustryStandard/Tls1.h>
+
//
// Driver Version
//
#define HTTP_DRIVER_VERSION 0xa
@@ -77,10 +84,11 @@ extern EFI_HTTP_UTILITIES_PROTOCOL *mHttpUtilities;
// Include files with function prototypes
//
#include "ComponentName.h"
#include "HttpImpl.h"
#include "HttpProto.h"
+#include "HttpsSupport.h"
#include "HttpDns.h"
typedef struct {
EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
UINTN NumberOfChildren;
diff --git a/NetworkPkg/HttpDxe/HttpDxe.inf b/NetworkPkg/HttpDxe/HttpDxe.inf
index bf2cbee..1118181 100644
--- a/NetworkPkg/HttpDxe/HttpDxe.inf
+++ b/NetworkPkg/HttpDxe/HttpDxe.inf
@@ -1,9 +1,9 @@
## @file
# Implementation of EFI HTTP protocol interfaces.
#
-# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
@@ -24,10 +24,11 @@
MODULE_UNI_FILE = HttpDxe.uni
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
+ NetworkPkg/NetworkPkg.dec
[Sources]
ComponentName.h
ComponentName.c
HttpDns.h
@@ -36,14 +37,17 @@
HttpDriver.c
HttpImpl.h
HttpImpl.c
HttpProto.h
HttpProto.c
+ HttpsSupport.h
+ HttpsSupport.c
[LibraryClasses]
UefiDriverEntryPoint
UefiBootServicesTableLib
+ UefiRuntimeServicesTableLib
MemoryAllocationLib
BaseLib
UefiLib
DebugLib
NetLib
@@ -62,8 +66,14 @@
gEfiDns4ProtocolGuid ## SOMETIMES_CONSUMES
gEfiDns6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
gEfiDns6ProtocolGuid ## SOMETIMES_CONSUMES
gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES
gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTlsServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTlsProtocolGuid ## SOMETIMES_CONSUMES
+ gEfiTlsConfigurationProtocolGuid ## SOMETIMES_CONSUMES
+
+[Guids]
+ gEfiTlsCaCertificateGuid ## CONSUMES ## GUID
[UserExtensions.TianoCore."ExtraFiles"]
HttpDxeExtra.uni
\ No newline at end of file
diff --git a/NetworkPkg/HttpDxe/HttpImpl.c b/NetworkPkg/HttpDxe/HttpImpl.c
index 6fcb0b7..77aa64a 100644
--- a/NetworkPkg/HttpDxe/HttpImpl.c
+++ b/NetworkPkg/HttpDxe/HttpImpl.c
@@ -239,10 +239,11 @@ EfiHttpRequest (
UINTN HostNameSize;
UINT16 RemotePort;
HTTP_PROTOCOL *HttpInstance;
BOOLEAN Configure;
BOOLEAN ReConfigure;
+ BOOLEAN TlsConfigure;
CHAR8 *RequestMsg;
CHAR8 *Url;
UINTN UrlLen;
CHAR16 *HostNameStr;
HTTP_TOKEN_WRAP *Wrap;
@@ -258,10 +259,11 @@ EfiHttpRequest (
HostName = NULL;
RequestMsg = NULL;
HostNameStr = NULL;
Wrap = NULL;
FileUrl = NULL;
+ TlsConfigure = FALSE;
if ((This == NULL) || (Token == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -343,10 +345,36 @@ EfiHttpRequest (
HttpInstance->Url = Url;
}
UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);
+
+ //
+ // From the information in Url, the HTTP instance will
+ // be able to determine whether to use http or https.
+ //
+ HttpInstance->UseHttps = IsHttpsUrl (Url);
+
+ //
+ // Check whether we need to create Tls child and open the TLS protocol.
+ //
+ if (HttpInstance->UseHttps && HttpInstance->TlsChildHandle == NULL) {
+ //
+ // Use TlsSb to create Tls child and open the TLS protocol.
+ //
+ HttpInstance->TlsChildHandle = TlsCreateChild (
+ HttpInstance->Service->ImageHandle,
+ &(HttpInstance->Tls),
+ &(HttpInstance->TlsConfiguration)
+ );
+ if (HttpInstance->TlsChildHandle == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ TlsConfigure = TRUE;
+ }
+
UrlParser = NULL;
Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser);
if (EFI_ERROR (Status)) {
goto Error1;
}
@@ -357,11 +385,15 @@ EfiHttpRequest (
goto Error1;
}
Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
if (EFI_ERROR (Status)) {
- RemotePort = HTTP_DEFAULT_PORT;
+ if (HttpInstance->UseHttps) {
+ RemotePort = HTTPS_DEFAULT_PORT;
+ } else {
+ RemotePort = HTTP_DEFAULT_PORT;
+ }
}
//
// If Configure is TRUE, it indicates the first time to call Request();
// If ReConfigure is TRUE, it indicates the request URL is not same
// with the previous call to Request();
@@ -374,13 +406,17 @@ EfiHttpRequest (
// Request() is called the first time.
//
ReConfigure = FALSE;
} else {
if ((HttpInstance->RemotePort == RemotePort) &&
- (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) {
+ (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&
+ (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&
+ !TlsConfigure &&
+ HttpInstance->TlsSessionState == EfiTlsSessionDataTransferring))) {
//
// Host Name and port number of the request URL are the same with previous call to Request().
+ // If Https protocol used, the corresponding SessionState is EfiTlsSessionDataTransferring.
// Check whether previous TCP packet sent out.
//
if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens, HttpTcpNotReady, NULL))) {
//
@@ -480,10 +516,20 @@ EfiHttpRequest (
if (!HttpInstance->LocalAddressIsIPv6) {
ASSERT (HttpInstance->Tcp4 != NULL);
} else {
ASSERT (HttpInstance->Tcp6 != NULL);
}
+
+ if (HttpInstance->UseHttps && !TlsConfigure) {
+ Status = TlsCloseSession (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ goto Error1;
+ }
+
+ TlsCloseTxRxEvent (HttpInstance);
+ }
+
HttpCloseConnection (HttpInstance);
EfiHttpCancel (This, NULL);
}
//
@@ -498,17 +544,22 @@ EfiHttpRequest (
Wrap->HttpToken = Token;
Wrap->HttpInstance = HttpInstance;
if (Request != NULL) {
Wrap->TcpWrap.Method = Request->Method;
}
-
- Status = HttpInitTcp (HttpInstance, Wrap, Configure);
+
+ Status = HttpInitSession (
+ HttpInstance,
+ Wrap,
+ Configure || ReConfigure,
+ TlsConfigure
+ );
if (EFI_ERROR (Status)) {
goto Error2;
- }
+ }
- if (!Configure) {
+ if (!Configure && !ReConfigure && !TlsConfigure) {
//
// For the new HTTP token, create TX TCP token events.
//
Status = HttpCreateTcpTxEvent (Wrap);
if (EFI_ERROR (Status)) {
@@ -591,13 +642,18 @@ Error4:
if (RequestMsg != NULL) {
FreePool (RequestMsg);
}
Error3:
- HttpCloseConnection (HttpInstance);
+ if (HttpInstance->UseHttps) {
+ TlsCloseSession (HttpInstance);
+ TlsCloseTxRxEvent (HttpInstance);
+ }
Error2:
+ HttpCloseConnection (HttpInstance);
+
HttpCloseTcpConnCloseEvent (HttpInstance);
if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {
gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL;
}
@@ -729,26 +785,34 @@ HttpCancel (
} else {
return Status;
}
}
- //
- // Then check the tokens queued by EfiHttpResponse().
- //
- Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens, Token);
- if (EFI_ERROR (Status)) {
- if (Token != NULL) {
- if (Status == EFI_ABORTED) {
- return EFI_SUCCESS;
+ if (!HttpInstance->UseHttps) {
+ //
+ // Then check the tokens queued by EfiHttpResponse(), except for Https.
+ //
+ Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens, Token);
+ if (EFI_ERROR (Status)) {
+ if (Token != NULL) {
+ if (Status == EFI_ABORTED) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_FOUND;
+ }
} else {
- return EFI_NOT_FOUND;
+ return Status;
}
+ }
+ } else {
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken);
} else {
- return Status;
+ HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);
}
}
-
+
return EFI_SUCCESS;
}
/**
@@ -880,10 +944,11 @@ HttpResponseWorker (
HTTP_PROTOCOL *HttpInstance;
EFI_HTTP_TOKEN *Token;
NET_MAP_ITEM *Item;
HTTP_TOKEN_WRAP *ValueInItem;
UINTN HdrLen;
+ NET_FRAGMENT Fragment;
if (Wrap == NULL || Wrap->HttpInstance == NULL) {
return EFI_INVALID_PARAMETER;
}
@@ -897,21 +962,15 @@ HttpResponseWorker (
HttpHeaders = NULL;
SizeofHeaders = 0;
BufferSize = 0;
EndofHeader = NULL;
ValueInItem = NULL;
+ Fragment.Len = 0;
+ Fragment.Bulk = NULL;
if (HttpMsg->Data.Response != NULL) {
//
- // Need receive the HTTP headers, prepare buffer.
- //
- Status = HttpCreateTcpRxEventForHeader (HttpInstance);
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- //
// Check whether we have cached header from previous call.
//
if ((HttpInstance->CacheBody != NULL) && (HttpInstance->NextMsg != NULL)) {
//
// The data is stored at [NextMsg, CacheBody + CacheLen].
@@ -1198,13 +1257,120 @@ HttpResponseWorker (
ASSERT (HttpInstance->MsgParser != NULL);
//
// We still need receive more data when there is no cache data and MsgParser is not NULL;
//
- Status = HttpTcpReceiveBody (Wrap, HttpMsg);
- if (EFI_ERROR (Status)) {
- goto Error2;
+ if (!HttpInstance->UseHttps) {
+ Status = HttpTcpReceiveBody (Wrap, HttpMsg);
+
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ } else {
+ if (HttpInstance->TimeoutEvent == NULL) {
+ //
+ // Create TimeoutEvent for response
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &HttpInstance->TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+ }
+
+ //
+ // Start the timer, and wait Timeout seconds to receive the body packet.
+ //
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ Status = HttpsReceive (HttpInstance, &Fragment, HttpInstance->TimeoutEvent);
+
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
+
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ //
+ // Check whether we receive a complete HTTP message.
+ //
+ Status = HttpParseMessageBody (
+ HttpInstance->MsgParser,
+ (UINTN) Fragment.Len,
+ (CHAR8 *) Fragment.Bulk
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error2;
+ }
+
+ if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
+ //
+ // Free the MsgParse since we already have a full HTTP message.
+ //
+ HttpFreeMsgParser (HttpInstance->MsgParser);
+ HttpInstance->MsgParser = NULL;
+ }
+
+ //
+ // We receive part of header of next HTTP msg.
+ //
+ if (HttpInstance->NextMsg != NULL) {
+ HttpMsg->BodyLength = MIN ((UINTN) (HttpInstance->NextMsg - (CHAR8 *) Fragment.Bulk), HttpMsg->BodyLength);
+ CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
+
+ HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
+ if (HttpInstance->CacheLen != 0) {
+ if (HttpInstance->CacheBody != NULL) {
+ FreePool (HttpInstance->CacheBody);
+ }
+
+ HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
+ if (HttpInstance->CacheBody == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error2;
+ }
+
+ CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
+ HttpInstance->CacheOffset = 0;
+
+ HttpInstance->NextMsg = HttpInstance->CacheBody + (UINTN) (HttpInstance->NextMsg - (CHAR8 *) (Fragment.Bulk + HttpMsg->BodyLength));
+ }
+ } else {
+ HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg->BodyLength);
+ CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
+ HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
+ if (HttpInstance->CacheLen != 0) {
+ if (HttpInstance->CacheBody != NULL) {
+ FreePool (HttpInstance->CacheBody);
+ }
+
+ HttpInstance->CacheBody = AllocateZeroPool (HttpInstance->CacheLen);
+ if (HttpInstance->CacheBody == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error2;
+ }
+
+ CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg->BodyLength, HttpInstance->CacheLen);
+ HttpInstance->CacheOffset = 0;
+ }
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
+
+ goto Exit;
}
return Status;
Exit:
@@ -1232,19 +1398,30 @@ Error2:
Error:
Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap->HttpToken);
if (Item != NULL) {
NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);
}
-
- HttpTcpTokenCleanup (Wrap);
+
+ if (!HttpInstance->UseHttps) {
+ HttpTcpTokenCleanup (Wrap);
+ } else {
+ FreePool (Wrap);
+ }
if (HttpHeaders != NULL) {
FreePool (HttpHeaders);
+ HttpHeaders = NULL;
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
}
if (HttpMsg->Headers != NULL) {
FreePool (HttpMsg->Headers);
+ HttpMsg->Headers = NULL;
}
if (HttpInstance->CacheBody != NULL) {
FreePool (HttpInstance->CacheBody);
HttpInstance->CacheBody = NULL;
@@ -1351,13 +1528,20 @@ EfiHttpResponse (
}
Wrap->HttpInstance = HttpInstance;
Wrap->HttpToken = Token;
- Status = HttpCreateTcpRxEvent (Wrap);
- if (EFI_ERROR (Status)) {
- goto Error;
+ //
+ // Notes: For Https, receive token wrapped in HTTP_TOKEN_WRAP is not used to
+ // receive the https response. A special TlsRxToken is used for receiving TLS
+ // related messages. It should be a blocking response.
+ //
+ if (!HttpInstance->UseHttps) {
+ Status = HttpCreateTcpRxEvent (Wrap);
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
}
Status = NetMapInsertTail (&HttpInstance->RxTokens, Token, Wrap);
if (EFI_ERROR (Status)) {
goto Error;
diff --git a/NetworkPkg/HttpDxe/HttpProto.c b/NetworkPkg/HttpDxe/HttpProto.c
index 6373f07..77a3ee3 100644
--- a/NetworkPkg/HttpDxe/HttpProto.c
+++ b/NetworkPkg/HttpDxe/HttpProto.c
@@ -926,10 +926,26 @@ HttpCleanProtocol (
HttpInstance->Service->ImageHandle,
HttpInstance->Handle
);
}
+ if (HttpInstance->TlsConfigData.CACert != NULL) {
+ FreePool (HttpInstance->TlsConfigData.CACert);
+ HttpInstance->TlsConfigData.CACert = NULL;
+ }
+
+ if (HttpInstance->TlsConfigData.ClientCert != NULL) {
+ FreePool (HttpInstance->TlsConfigData.ClientCert);
+ HttpInstance->TlsConfigData.ClientCert = NULL;
+ }
+
+ if (HttpInstance->TlsConfigData.ClientPrivateKey != NULL) {
+ FreePool (HttpInstance->TlsConfigData.ClientPrivateKey);
+ HttpInstance->TlsConfigData.ClientPrivateKey = NULL;
+ }
+
+ TlsCloseTxRxEvent (HttpInstance);
}
/**
Establish TCP connection with HTTP server.
@@ -1183,11 +1199,12 @@ HttpConfigureTcp6 (
return EFI_SUCCESS;
}
/**
- Check existing TCP connection, if in error state, recover TCP4 connection.
+ Check existing TCP connection, if in error state, recover TCP4 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP4 protocol child is not created or configured.
@@ -1224,15 +1241,62 @@ HttpConnectTcp4 (
return EFI_SUCCESS;
} else if (Tcp4State > Tcp4StateEstablished ) {
HttpCloseConnection(HttpInstance);
}
- return HttpCreateConnection (HttpInstance);
+ Status = HttpCreateConnection (HttpInstance);
+ if (EFI_ERROR(Status)){
+ DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status));
+ return Status;
+ }
+
+ //
+ // Tls session connection.
+ //
+ if (HttpInstance->UseHttps) {
+ if (HttpInstance->TimeoutEvent == NULL) {
+ //
+ // Create TimeoutEvent for TLS connection.
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &HttpInstance->TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ //
+ // Start the timer, and wait Timeout seconds for connection.
+ //
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+
+ Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
+
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
+
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ return Status;
}
/**
- Check existing TCP connection, if in error state, recover TCP6 connection.
+ Check existing TCP connection, if in error state, recover TCP6 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP6 protocol child is not created or configured.
@@ -1269,34 +1333,92 @@ HttpConnectTcp6 (
return EFI_SUCCESS;
} else if (Tcp6State > Tcp6StateEstablished ) {
HttpCloseConnection(HttpInstance);
}
- return HttpCreateConnection (HttpInstance);
+ Status = HttpCreateConnection (HttpInstance);
+ if (EFI_ERROR(Status)){
+ DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status));
+ return Status;
+ }
+
+ //
+ // Tls session connection.
+ //
+ if (HttpInstance->UseHttps) {
+ if (HttpInstance->TimeoutEvent == NULL) {
+ //
+ // Create TimeoutEvent for TLS connection.
+ //
+ Status = gBS->CreateEvent (
+ EVT_TIMER,
+ TPL_CALLBACK,
+ NULL,
+ NULL,
+ &HttpInstance->TimeoutEvent
+ );
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ //
+ // Start the timer, and wait Timeout seconds for connection.
+ //
+ Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative, HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+
+ Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
+
+ gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
+
+ if (EFI_ERROR (Status)) {
+ TlsCloseTxRxEvent (HttpInstance);
+ return Status;
+ }
+ }
+
+ return Status;
}
/**
- Initialize TCP related data.
+ Initialize Http session.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
- @param[in] Configure The Flag indicates whether the first time to initialize Tcp.
+ @param[in] Configure The Flag indicates whether need to initialize session.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.
- @retval EFI_SUCCESS The initialization of TCP instance is done.
+ @retval EFI_SUCCESS The initialization of session is done.
@retval Others Other error as indicated.
**/
EFI_STATUS
-HttpInitTcp (
+HttpInitSession (
IN HTTP_PROTOCOL *HttpInstance,
IN HTTP_TOKEN_WRAP *Wrap,
- IN BOOLEAN Configure
+ IN BOOLEAN Configure,
+ IN BOOLEAN TlsConfigure
)
{
EFI_STATUS Status;
ASSERT (HttpInstance != NULL);
+ //
+ // Configure Tls session.
+ //
+ if (TlsConfigure) {
+ Status = TlsConfigureSession (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
if (!HttpInstance->LocalAddressIsIPv6) {
//
// Configure TCP instance.
//
if (Configure) {
@@ -1336,11 +1458,11 @@ HttpInitTcp (
return EFI_SUCCESS;
}
/**
- Send the HTTP message through TCP4 or TCP6.
+ Send the HTTP or HTTPS message through TCP4 or TCP6.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
@param[in] TxString Buffer containing the HTTP message string.
@param[in] TxStringLen Length of the HTTP message string in bytes.
@@ -1360,18 +1482,68 @@ HttpTransmitTcp (
EFI_STATUS Status;
EFI_TCP4_IO_TOKEN *Tx4Token;
EFI_TCP4_PROTOCOL *Tcp4;
EFI_TCP6_IO_TOKEN *Tx6Token;
EFI_TCP6_PROTOCOL *Tcp6;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+ NET_FRAGMENT TempFragment;
+
+ Status = EFI_SUCCESS;
+ Buffer = NULL;
+
+ //
+ // Need to encrypt data.
+ //
+ if (HttpInstance->UseHttps) {
+ //
+ // Build BufferOut data
+ //
+ BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ ((TLS_RECORD_HEADER *) Buffer)->ContentType = TLS_CONTENT_TYPE_APPLICATION_DATA;
+ ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance->TlsConfigData.Version.Major;
+ ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance->TlsConfigData.Version.Minor;
+ ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);
+ CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);
+
+ //
+ // Encrypt Packet.
+ //
+ Status = TlsProcessMessage (
+ HttpInstance,
+ Buffer,
+ BufferSize,
+ EfiTlsEncrypt,
+ &TempFragment
+ );
+
+ FreePool (Buffer);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
- if (!HttpInstance->LocalAddressIsIPv6) {
+ if (!HttpInstance->LocalAddressIsIPv6) {
Tcp4 = HttpInstance->Tcp4;
Tx4Token = &Wrap->TcpWrap.Tx4Token;
+
+ if (HttpInstance->UseHttps) {
+ Tx4Token->Packet.TxData->DataLength = TempFragment.Len;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;
+ } else {
+ Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
+ Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
+ }
- Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
- Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
- Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
Tx4Token->CompletionToken.Status = EFI_NOT_READY;
Wrap->TcpWrap.IsTxDone = FALSE;
Status = Tcp4->Transmit (Tcp4, Tx4Token);
if (EFI_ERROR (Status)) {
@@ -1380,25 +1552,31 @@ HttpTransmitTcp (
}
} else {
Tcp6 = HttpInstance->Tcp6;
Tx6Token = &Wrap->TcpWrap.Tx6Token;
-
- Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
- Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
- Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
+
+ if (HttpInstance->UseHttps) {
+ Tx6Token->Packet.TxData->DataLength = TempFragment.Len;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = TempFragment.Len;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TempFragment.Bulk;
+ } else {
+ Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32) TxStringLen;
+ Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *) TxString;
+ }
+
Tx6Token->CompletionToken.Status = EFI_NOT_READY;
Wrap->TcpWrap.IsTxDone = FALSE;
Status = Tcp6->Transmit (Tcp6, Tx6Token);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));
return Status;
}
}
-
return Status;
}
/**
Check whether the user's token or event has already
@@ -1464,11 +1642,11 @@ HttpTcpNotReady (
return EFI_SUCCESS;
}
/**
- Transmit the HTTP mssage by processing the associated HTTP token.
+ Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.
@param[in] Map The container of Tx4Token or Tx6Token.
@param[in] Item Current item to check against.
@param[in] Context The Token to check againist.
@@ -1588,167 +1766,235 @@ HttpTcpReceiveHeader (
EFI_TCP6_IO_TOKEN *Rx6Token;
EFI_TCP6_PROTOCOL *Tcp6;
CHAR8 **EndofHeader;
CHAR8 **HttpHeaders;
CHAR8 *Buffer;
+ NET_FRAGMENT Fragment;
ASSERT (HttpInstance != NULL);
EndofHeader = HttpInstance->EndofHeader;
HttpHeaders = HttpInstance->HttpHeaders;
Tcp4 = HttpInstance->Tcp4;
Tcp6 = HttpInstance->Tcp6;
Buffer = NULL;
Rx4Token = NULL;
Rx6Token = NULL;
+ Fragment.Len = 0;
+ Fragment.Bulk = NULL;
if (HttpInstance->LocalAddressIsIPv6) {
ASSERT (Tcp6 != NULL);
} else {
ASSERT (Tcp4 != NULL);
}
- if (!HttpInstance->LocalAddressIsIPv6) {
- Rx4Token = &HttpInstance->Rx4Token;
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
- if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
+ if (!HttpInstance->UseHttps) {
+ Status = HttpCreateTcpRxEventForHeader (HttpInstance);
+ if (EFI_ERROR (Status)) {
return Status;
}
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ if (!HttpInstance->UseHttps) {
+ Rx4Token = &HttpInstance->Rx4Token;
+ Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
+ if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+ }
//
// Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
//
- while (*EndofHeader == NULL) {
- HttpInstance->IsRxDone = FALSE;
- Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
- Status = Tcp4->Receive (Tcp4, Rx4Token);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
- return Status;
- }
-
- while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
- Tcp4->Poll (Tcp4);
+ while (*EndofHeader == NULL) {
+ if (!HttpInstance->UseHttps) {
+ HttpInstance->IsRxDone = FALSE;
+ Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
+ Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
+ Status = Tcp4->Receive (Tcp4, Rx4Token);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
+ return Status;
+ }
+
+ while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ Tcp4->Poll (Tcp4);
+ }
+
+ if (!HttpInstance->IsRxDone) {
+ //
+ // Cancle the Token before close its Event.
+ //
+ Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
+ gBS->CloseEvent (Rx4Token->CompletionToken.Event);
+ Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
+ }
+
+ Status = Rx4Token->CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Fragment.Len = Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ Fragment.Bulk = (UINT8 *) Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
+ } else {
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
+
+ Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
+ return Status;
+ }
}
- if (!HttpInstance->IsRxDone) {
- //
- // Cancle the Token before close its Event.
- //
- Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
- gBS->CloseEvent (Rx4Token->CompletionToken.Event);
- Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
- }
-
- Status = Rx4Token->CompletionToken.Status;
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
//
// Append the response string.
//
- *BufferSize = (*SizeofHeaders) + Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ *BufferSize = *SizeofHeaders + Fragment.Len;
Buffer = AllocateZeroPool (*BufferSize);
if (Buffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
return Status;
}
-
+
if (*HttpHeaders != NULL) {
- CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
+ CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
FreePool (*HttpHeaders);
}
-
+
CopyMem (
- Buffer + (*SizeofHeaders),
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength
+ Buffer + *SizeofHeaders,
+ Fragment.Bulk,
+ Fragment.Len
);
- *HttpHeaders = Buffer;
- *SizeofHeaders = *BufferSize;
-
+ *HttpHeaders = Buffer;
+ *SizeofHeaders = *BufferSize;
+
//
// Check whether we received end of HTTP headers.
//
*EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
- }
- FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
- Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+ };
+ //
+ // Free the buffer.
+ //
+ if (Rx4Token != NULL && Rx4Token->Packet.RxData != NULL && Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
+ FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
+ Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+ Fragment.Bulk = NULL;
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
} else {
- Rx6Token = &HttpInstance->Rx6Token;
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
- if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- return Status;
+ if (!HttpInstance->UseHttps) {
+ Rx6Token = &HttpInstance->Rx6Token;
+ Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = AllocateZeroPool (DEF_BUF_LEN);
+ if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
}
//
// Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not NULL.
//
- while (*EndofHeader == NULL) {
- HttpInstance->IsRxDone = FALSE;
- Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
- Status = Tcp6->Receive (Tcp6, Rx6Token);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
- return Status;
- }
-
- while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
- Tcp6->Poll (Tcp6);
+ while (*EndofHeader == NULL) {
+ if (!HttpInstance->UseHttps) {
+ HttpInstance->IsRxDone = FALSE;
+ Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
+ Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength = DEF_BUF_LEN;
+ Status = Tcp6->Receive (Tcp6, Rx6Token);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
+ return Status;
+ }
+
+ while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ Tcp6->Poll (Tcp6);
+ }
+
+ if (!HttpInstance->IsRxDone) {
+ //
+ // Cancle the Token before close its Event.
+ //
+ Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
+ gBS->CloseEvent (Rx6Token->CompletionToken.Event);
+ Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
+ }
+
+ Status = Rx6Token->CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Fragment.Len = Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ Fragment.Bulk = (UINT8 *) Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer;
+ } else {
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
+ }
+
+ Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
+ return Status;
+ }
}
- if (!HttpInstance->IsRxDone) {
- //
- // Cancle the Token before close its Event.
- //
- Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
- gBS->CloseEvent (Rx6Token->CompletionToken.Event);
- Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
- }
-
- Status = Rx6Token->CompletionToken.Status;
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
//
// Append the response string.
//
- *BufferSize = (*SizeofHeaders) + Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength;
+ *BufferSize = *SizeofHeaders + Fragment.Len;
Buffer = AllocateZeroPool (*BufferSize);
if (Buffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
return Status;
}
-
+
if (*HttpHeaders != NULL) {
- CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
+ CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
FreePool (*HttpHeaders);
}
-
+
CopyMem (
- Buffer + (*SizeofHeaders),
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength
+ Buffer + *SizeofHeaders,
+ Fragment.Bulk,
+ Fragment.Len
);
- *HttpHeaders = Buffer;
- *SizeofHeaders = *BufferSize;
-
+ *HttpHeaders = Buffer;
+ *SizeofHeaders = *BufferSize;
+
//
// Check whether we received end of HTTP headers.
//
- *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
-
+ *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
+ };
+
+ //
+ // Free the buffer.
+ //
+ if (Rx6Token != NULL && Rx6Token->Packet.RxData != NULL && Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
+ FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
+ Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
+ Fragment.Bulk = NULL;
+ }
+
+ if (Fragment.Bulk != NULL) {
+ FreePool (Fragment.Bulk);
+ Fragment.Bulk = NULL;
}
- FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
- Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
}
//
// Skip the CRLF after the HTTP headers.
//
diff --git a/NetworkPkg/HttpDxe/HttpProto.h b/NetworkPkg/HttpDxe/HttpProto.h
index e1fd785..e3b3275 100644
--- a/NetworkPkg/HttpDxe/HttpProto.h
+++ b/NetworkPkg/HttpDxe/HttpProto.h
@@ -81,10 +81,24 @@ typedef struct {
BOOLEAN IsRxDone;
UINTN BodyLen;
EFI_HTTP_METHOD Method;
} HTTP_TCP_TOKEN_WRAP;
+typedef struct {
+ EFI_TLS_VERSION Version;
+ EFI_TLS_CONNECTION_END ConnectionEnd;
+ EFI_TLS_VERIFY VerifyMethod;
+ EFI_TLS_SESSION_STATE SessionState;
+
+ VOID *CACert;
+ UINTN CACertSize;
+ VOID *ClientCert;
+ UINTN ClientCertSize;
+ VOID *ClientPrivateKey;
+ UINTN ClientPrivateKeySize;
+} TLS_CONFIG_DATA;
+
typedef struct _HTTP_PROTOCOL {
UINT32 Signature;
EFI_HTTP_PROTOCOL Http;
EFI_HANDLE Handle;
HTTP_SERVICE *Service;
@@ -151,10 +165,39 @@ typedef struct _HTTP_PROTOCOL {
NET_MAP TxTokens;
NET_MAP RxTokens;
CHAR8 *Url;
+
+ //
+ // Https Support
+ //
+ BOOLEAN UseHttps;
+
+ EFI_HANDLE TlsChildHandle; /// Tls ChildHandle
+ TLS_CONFIG_DATA TlsConfigData;
+ EFI_TLS_PROTOCOL *Tls;
+ EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfiguration;
+ EFI_TLS_SESSION_STATE TlsSessionState;
+
+ //
+ // TlsTxData used for transmitting TLS related messages.
+ //
+ EFI_TCP4_IO_TOKEN Tcp4TlsTxToken;
+ EFI_TCP4_TRANSMIT_DATA Tcp4TlsTxData;
+ EFI_TCP6_IO_TOKEN Tcp6TlsTxToken;
+ EFI_TCP6_TRANSMIT_DATA Tcp6TlsTxData;
+ BOOLEAN TlsIsTxDone;
+
+ //
+ // TlsRxData used for receiving TLS related messages.
+ //
+ EFI_TCP4_IO_TOKEN Tcp4TlsRxToken;
+ EFI_TCP4_RECEIVE_DATA Tcp4TlsRxData;
+ EFI_TCP6_IO_TOKEN Tcp6TlsRxToken;
+ EFI_TCP6_RECEIVE_DATA Tcp6TlsRxData;
+ BOOLEAN TlsIsRxDone;
} HTTP_PROTOCOL;
typedef struct {
EFI_HTTP_TOKEN *HttpToken;
HTTP_PROTOCOL *HttpInstance;
@@ -350,11 +393,12 @@ HttpConfigureTcp6 (
IN HTTP_PROTOCOL *HttpInstance,
IN HTTP_TOKEN_WRAP *Wrap
);
/**
- Check existing TCP connection, if in error state, receover TCP4 connection.
+ Check existing TCP connection, if in error state, recover TCP4 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP4 protocol child is not created or configured.
@@ -365,11 +409,12 @@ EFI_STATUS
HttpConnectTcp4 (
IN HTTP_PROTOCOL *HttpInstance
);
/**
- Check existing TCP connection, if in error state, recover TCP6 connection.
+ Check existing TCP connection, if in error state, recover TCP6 connection. Then,
+ connect one TLS session if required.
@param[in] HttpInstance The HTTP instance private data.
@retval EFI_SUCCESS The TCP connection is established.
@retval EFI_NOT_READY TCP6 protocol child is not created or configured.
@@ -380,11 +425,11 @@ EFI_STATUS
HttpConnectTcp6 (
IN HTTP_PROTOCOL *HttpInstance
);
/**
- Send the HTTP message through TCP4 or TCP6.
+ Send the HTTP or HTTPS message through TCP4 or TCP6.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
@param[in] TxString Buffer containing the HTTP message string.
@param[in] TxStringLen Length of the HTTP message string in bytes.
@@ -441,29 +486,31 @@ HttpTcpNotReady (
IN NET_MAP_ITEM *Item,
IN VOID *Context
);
/**
- Initialize TCP related data.
+ Initialize Http session.
@param[in] HttpInstance The HTTP instance private data.
@param[in] Wrap The HTTP token's wrap data.
- @param[in] Configure The Flag indicates whether the first time to initialize Tcp.
+ @param[in] Configure The Flag indicates whether need to initialize session.
+ @param[in] TlsConfigure The Flag indicates whether it's the new Tls session.
- @retval EFI_SUCCESS The initialization of TCP instance is done.
+ @retval EFI_SUCCESS The initialization of session is done.
@retval Others Other error as indicated.
**/
EFI_STATUS
-HttpInitTcp (
+HttpInitSession (
IN HTTP_PROTOCOL *HttpInstance,
IN HTTP_TOKEN_WRAP *Wrap,
- IN BOOLEAN Configure
+ IN BOOLEAN Configure,
+ IN BOOLEAN TlsConfigure
);
/**
- Transmit the HTTP mssage by processing the associated HTTP token.
+ Transmit the HTTP or HTTPS mssage by processing the associated HTTP token.
@param[in] Map The container of TxToken or Tx6Token.
@param[in] Item Current item to check against.
@param[in] Context The Token to check againist.
diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c b/NetworkPkg/HttpDxe/HttpsSupport.c
new file mode 100644
index 0000000..177b9a8
--- /dev/null
+++ b/NetworkPkg/HttpDxe/HttpsSupport.c
@@ -0,0 +1,1692 @@
+/** @file
+ Miscellaneous routines specific to Https for HttpDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "HttpDriver.h"
+
+/**
+ Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-terminated
+ ASCII string and ignore case during the search process.
+
+ This function scans the contents of the ASCII string specified by String
+ and returns the first occurrence of SearchString and ignore case during the search process.
+ If SearchString is not found in String, then NULL is returned. If the length of SearchString
+ is zero, then String is returned.
+
+ If String is NULL, then ASSERT().
+ If SearchString is NULL, then ASSERT().
+
+ @param[in] String A pointer to a Null-terminated ASCII string.
+ @param[in] SearchString A pointer to a Null-terminated ASCII string to search for.
+
+ @retval NULL If the SearchString does not appear in String.
+ @retval others If there is a match return the first occurrence of SearchingString.
+ If the length of SearchString is zero,return String.
+
+**/
+CHAR8 *
+AsciiStrCaseStr (
+ IN CONST CHAR8 *String,
+ IN CONST CHAR8 *SearchString
+ )
+{
+ CONST CHAR8 *FirstMatch;
+ CONST CHAR8 *SearchStringTmp;
+
+ CHAR8 Src;
+ CHAR8 Dst;
+
+ //
+ // ASSERT both strings are less long than PcdMaximumAsciiStringLength
+ //
+ ASSERT (AsciiStrSize (String) != 0);
+ ASSERT (AsciiStrSize (SearchString) != 0);
+
+ if (*SearchString == '\0') {
+ return (CHAR8 *) String;
+ }
+
+ while (*String != '\0') {
+ SearchStringTmp = SearchString;
+ FirstMatch = String;
+
+ while ((*SearchStringTmp != '\0')
+ && (*String != '\0')) {
+ Src = *String;
+ Dst = *SearchStringTmp;
+
+ if ((Src >= 'A') && (Src <= 'Z')) {
+ Src -= ('A' - 'a');
+ }
+
+ if ((Dst >= 'A') && (Dst <= 'Z')) {
+ Dst -= ('A' - 'a');
+ }
+
+ if (Src != Dst) {
+ break;
+ }
+
+ String++;
+ SearchStringTmp++;
+ }
+
+ if (*SearchStringTmp == '\0') {
+ return (CHAR8 *) FirstMatch;
+ }
+
+ String = FirstMatch + 1;
+ }
+
+ return NULL;
+}
+
+/**
+ The callback function to free the net buffer list.
+
+ @param[in] Arg The opaque parameter.
+
+**/
+VOID
+EFIAPI
+FreeNbufList (
+ IN VOID *Arg
+ )
+{
+ ASSERT (Arg != NULL);
+
+ NetbufFreeList ((LIST_ENTRY *) Arg);
+ FreePool (Arg);
+}
+
+/**
+ Check whether the Url is from Https.
+
+ @param[in] Url The pointer to a HTTP or HTTPS URL string.
+
+ @retval TRUE The Url is from HTTPS.
+ @retval FALSE The Url is from HTTP.
+
+**/
+BOOLEAN
+IsHttpsUrl (
+ IN CHAR8 *Url
+ )
+{
+ CHAR8 *Tmp;
+
+ Tmp = NULL;
+
+ Tmp = AsciiStrCaseStr (Url, HTTPS_FLAG);
+ if (Tmp != NULL && Tmp == Url) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+
+ @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+**/
+EFI_HANDLE
+EFIAPI
+TlsCreateChild (
+ IN EFI_HANDLE ImageHandle,
+ OUT EFI_TLS_PROTOCOL **TlsProto,
+ OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
+ )
+{
+ EFI_STATUS Status;
+ EFI_SERVICE_BINDING_PROTOCOL *TlsSb;
+ EFI_HANDLE TlsChildHandle;
+
+ TlsSb = NULL;
+ TlsChildHandle = 0;
+
+ //
+ // Locate TlsServiceBinding protocol.
+ //
+ gBS->LocateProtocol (
+ &gEfiTlsServiceBindingProtocolGuid,
+ NULL,
+ (VOID **) &TlsSb
+ );
+ if (TlsSb == NULL) {
+ return NULL;
+ }
+
+ Status = TlsSb->CreateChild (TlsSb, &TlsChildHandle);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Status = gBS->OpenProtocol (
+ TlsChildHandle,
+ &gEfiTlsProtocolGuid,
+ (VOID **) TlsProto,
+ ImageHandle,
+ TlsChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ TlsSb->DestroyChild (TlsSb, TlsChildHandle);
+ return NULL;
+ }
+
+ Status = gBS->OpenProtocol (
+ TlsChildHandle,
+ &gEfiTlsConfigurationProtocolGuid,
+ (VOID **) TlsConfiguration,
+ ImageHandle,
+ TlsChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ TlsSb->DestroyChild (TlsSb, TlsChildHandle);
+ return NULL;
+ }
+
+ return TlsChildHandle;
+}
+
+/**
+ Create event for the TLS receive and transmit tokens which are used to receive and
+ transmit TLS related messages.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+ @retval EFI_SUCCESS The events are created successfully.
+ @retval others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCreateTxRxEvent (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ //
+ // For Tcp4TlsTxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsTxDone,
+ &HttpInstance->Tcp4TlsTxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp4TlsTxData.Push = TRUE;
+ HttpInstance->Tcp4TlsTxData.Urgent = FALSE;
+ HttpInstance->Tcp4TlsTxData.DataLength = 0;
+ HttpInstance->Tcp4TlsTxData.FragmentCount = 1;
+ HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsTxData.DataLength;
+ HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp4TlsTxToken.Packet.TxData = &HttpInstance->Tcp4TlsTxData;
+ HttpInstance->Tcp4TlsTxToken.CompletionToken.Status = EFI_NOT_READY;
+
+ //
+ // For Tcp4TlsRxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsRxDone,
+ &HttpInstance->Tcp4TlsRxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp4TlsRxData.DataLength = 0;
+ HttpInstance->Tcp4TlsRxData.FragmentCount = 1;
+ HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp4TlsRxData.DataLength ;
+ HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp4TlsRxToken.Packet.RxData = &HttpInstance->Tcp4TlsRxData;
+ HttpInstance->Tcp4TlsRxToken.CompletionToken.Status = EFI_NOT_READY;
+ } else {
+ //
+ // For Tcp6TlsTxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsTxDone,
+ &HttpInstance->Tcp6TlsTxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp6TlsTxData.Push = TRUE;
+ HttpInstance->Tcp6TlsTxData.Urgent = FALSE;
+ HttpInstance->Tcp6TlsTxData.DataLength = 0;
+ HttpInstance->Tcp6TlsTxData.FragmentCount = 1;
+ HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsTxData.DataLength;
+ HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp6TlsTxToken.Packet.TxData = &HttpInstance->Tcp6TlsTxData;
+ HttpInstance->Tcp6TlsTxToken.CompletionToken.Status = EFI_NOT_READY;
+
+ //
+ // For Tcp6TlsRxToken.
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ HttpCommonNotify,
+ &HttpInstance->TlsIsRxDone,
+ &HttpInstance->Tcp6TlsRxToken.CompletionToken.Event
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ HttpInstance->Tcp6TlsRxData.DataLength = 0;
+ HttpInstance->Tcp6TlsRxData.FragmentCount = 1;
+ HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentLength = HttpInstance->Tcp6TlsRxData.DataLength ;
+ HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
+ HttpInstance->Tcp6TlsRxToken.Packet.RxData = &HttpInstance->Tcp6TlsRxData;
+ HttpInstance->Tcp6TlsRxToken.CompletionToken.Status = EFI_NOT_READY;
+ }
+
+ return Status;
+
+ERROR:
+ //
+ // Error handling
+ //
+ TlsCloseTxRxEvent (HttpInstance);
+
+ return Status;
+}
+
+/**
+ Close events in the TlsTxToken and TlsRxToken.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+**/
+VOID
+EFIAPI
+TlsCloseTxRxEvent (
+ IN HTTP_PROTOCOL *HttpInstance
+ )
+{
+ ASSERT (HttpInstance != NULL);
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ if (NULL != HttpInstance->Tcp4TlsTxToken.CompletionToken.Event) {
+ gBS->CloseEvent(HttpInstance->Tcp4TlsTxToken.CompletionToken.Event);
+ HttpInstance->Tcp4TlsTxToken.CompletionToken.Event = NULL;
+ }
+
+ if (NULL != HttpInstance->Tcp4TlsRxToken.CompletionToken.Event) {
+ gBS->CloseEvent (HttpInstance->Tcp4TlsRxToken.CompletionToken.Event);
+ HttpInstance->Tcp4TlsRxToken.CompletionToken.Event = NULL;
+ }
+ } else {
+ if (NULL != HttpInstance->Tcp6TlsTxToken.CompletionToken.Event) {
+ gBS->CloseEvent(HttpInstance->Tcp6TlsTxToken.CompletionToken.Event);
+ HttpInstance->Tcp6TlsTxToken.CompletionToken.Event = NULL;
+ }
+
+ if (NULL != HttpInstance->Tcp6TlsRxToken.CompletionToken.Event) {
+ gBS->CloseEvent (HttpInstance->Tcp6TlsRxToken.CompletionToken.Event);
+ HttpInstance->Tcp6TlsRxToken.CompletionToken.Event = NULL;
+ }
+ }
+}
+
+/**
+ Read the TlsCaCertificate variable and configure it.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TlsCaCertificate is configured.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+TlsConfigCertificate (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *CACert;
+ UINTN CACertSize;
+ UINT32 Index;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINTN CertCount;
+ UINT32 ItemDataSize;
+
+ CACert = (UINT8 *) HttpInstance->TlsConfigData.CACert;
+ CACertSize = HttpInstance->TlsConfigData.CACertSize;
+
+ //
+ // Try to read the TlsCaCertificate variable.
+ //
+ CACertSize = 0;
+ Status = gRT->GetVariable (
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ NULL,
+ &CACertSize,
+ NULL
+ );
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ //
+ // Allocate buffer and read the config variable.
+ //
+ CACert = AllocatePool (CACertSize);
+ if (CACert == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gRT->GetVariable (
+ EFI_TLS_CA_CERTIFICATE_VARIABLE,
+ &gEfiTlsCaCertificateGuid,
+ NULL,
+ &CACertSize,
+ CACert
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // GetVariable still error or the variable is corrupted.
+ // Fall back to the default value.
+ //
+ FreePool (CACert);
+
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ //
+ // Enumerate all data and erasing the target item.
+ //
+ ItemDataSize = (UINT32) CACertSize;
+ CertList = (EFI_SIGNATURE_LIST *) CACert;
+ while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize)) {
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ for (Index = 0; Index < CertCount; Index++) {
+ //
+ // EfiTlsConfigDataTypeCACertificate
+ //
+ Status = HttpInstance->TlsConfiguration->SetData (
+ HttpInstance->TlsConfiguration,
+ EfiTlsConfigDataTypeCACertificate,
+ Cert->SignatureData,
+ CertList->SignatureSize - sizeof (Cert->SignatureOwner)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+ }
+
+ ItemDataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+
+ return Status;
+}
+
+/**
+ Configure TLS session data.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TLS session data is configured.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigureSession (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // TlsConfigData initialization
+ //
+ HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient;
+ HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER;
+ HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted;
+
+ //
+ // EfiTlsConnectionEnd,
+ // EfiTlsVerifyMethod
+ // EfiTlsSessionState
+ //
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsConnectionEnd,
+ &(HttpInstance->TlsConfigData.ConnectionEnd),
+ sizeof (EFI_TLS_CONNECTION_END)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsVerifyMethod,
+ &HttpInstance->TlsConfigData.VerifyMethod,
+ sizeof (EFI_TLS_VERIFY)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ &(HttpInstance->TlsConfigData.SessionState),
+ sizeof (EFI_TLS_SESSION_STATE)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ //
+ // Tls Config Certificate
+ //
+ Status = TlsConfigCertificate (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "TLS Certificate Config Error!\n"));
+ goto ERROR;
+ }
+
+ //
+ // TlsCreateTxRxEvent
+ //
+ Status = TlsCreateTxRxEvent (HttpInstance);
+ if (EFI_ERROR (Status)) {
+ goto ERROR;
+ }
+
+ return Status;
+
+ERROR:
+ TlsCloseTxRxEvent (HttpInstance);
+
+ return Status;
+}
+
+/**
+ Transmit the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+
+ @retval EFI_SUCCESS The packet is transmitted.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonTransmit (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet
+ )
+{
+ EFI_STATUS Status;
+ VOID *Data;
+ UINTN Size;
+
+ if ((HttpInstance == NULL) || (Packet == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Size = sizeof (EFI_TCP4_TRANSMIT_DATA) +
+ (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA);
+ } else {
+ Size = sizeof (EFI_TCP6_TRANSMIT_DATA) +
+ (Packet->BlockOpNum - 1) * sizeof (EFI_TCP6_FRAGMENT_DATA);
+ }
+
+ Data = AllocatePool (Size);
+ if (Data == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->Push = TRUE;
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->Urgent = FALSE;
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
+
+ //
+ // Build the fragment table.
+ //
+ ((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum;
+
+ NetbufBuildExt (
+ Packet,
+ (NET_FRAGMENT *) &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentTable[0],
+ &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount
+ );
+
+ HttpInstance->Tcp4TlsTxToken.Packet.TxData = (EFI_TCP4_TRANSMIT_DATA *) Data;
+
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ // Transmit the packet.
+ //
+ Status = HttpInstance->Tcp4->Transmit (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsTxToken);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ while (!HttpInstance->TlsIsTxDone) {
+ HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
+ }
+
+ HttpInstance->TlsIsTxDone = FALSE;
+ Status = HttpInstance->Tcp4TlsTxToken.CompletionToken.Status;
+ } else {
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->Push = TRUE;
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->Urgent = FALSE;
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
+
+ //
+ // Build the fragment table.
+ //
+ ((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount = Packet->BlockOpNum;
+
+ NetbufBuildExt (
+ Packet,
+ (NET_FRAGMENT *) &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentTable[0],
+ &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount
+ );
+
+ HttpInstance->Tcp6TlsTxToken.Packet.TxData = (EFI_TCP6_TRANSMIT_DATA *) Data;
+
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ // Transmit the packet.
+ //
+ Status = HttpInstance->Tcp6->Transmit (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsTxToken);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ while (!HttpInstance->TlsIsTxDone) {
+ HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
+ }
+
+ HttpInstance->TlsIsTxDone = FALSE;
+ Status = HttpInstance->Tcp6TlsTxToken.CompletionToken.Status;
+ }
+
+ON_EXIT:
+ FreePool (Data);
+
+ return Status;
+}
+
+/**
+ Receive the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The Packet is received.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_TIMEOUT The operation is time out.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonReceive (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_TCP4_RECEIVE_DATA *Tcp4RxData;
+ EFI_TCP6_RECEIVE_DATA *Tcp6RxData;
+ EFI_STATUS Status;
+ NET_FRAGMENT *Fragment;
+ UINT32 FragmentCount;
+ UINT32 CurrentFragment;
+
+ Tcp4RxData = NULL;
+ Tcp6RxData = NULL;
+
+ if ((HttpInstance == NULL) || (Packet == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FragmentCount = Packet->BlockOpNum;
+ Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));
+ if (Fragment == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Build the fragment table.
+ //
+ NetbufBuildExt (Packet, Fragment, &FragmentCount);
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Tcp4RxData = HttpInstance->Tcp4TlsRxToken.Packet.RxData;
+ if (Tcp4RxData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Tcp4RxData->FragmentCount = 1;
+ } else {
+ Tcp6RxData = HttpInstance->Tcp6TlsRxToken.Packet.RxData;
+ if (Tcp6RxData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Tcp6RxData->FragmentCount = 1;
+ }
+
+ CurrentFragment = 0;
+ Status = EFI_SUCCESS;
+
+ while (CurrentFragment < FragmentCount) {
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Tcp4RxData->DataLength = Fragment[CurrentFragment].Len;
+ Tcp4RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
+ Tcp4RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
+ Status = HttpInstance->Tcp4->Receive (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken);
+ } else {
+ Tcp6RxData->DataLength = Fragment[CurrentFragment].Len;
+ Tcp6RxData->FragmentTable[0].FragmentLength = Fragment[CurrentFragment].Len;
+ Tcp6RxData->FragmentTable[0].FragmentBuffer = Fragment[CurrentFragment].Bulk;
+ Status = HttpInstance->Tcp6->Receive (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken);
+ }
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ while (!HttpInstance->TlsIsRxDone && ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ //
+ // Poll until some data is received or an error occurs.
+ //
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
+ } else {
+ HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
+ }
+ }
+
+ if (!HttpInstance->TlsIsRxDone) {
+ //
+ // Timeout occurs, cancel the receive request.
+ //
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance->Tcp4TlsRxToken.CompletionToken);
+ } else {
+ HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance->Tcp6TlsRxToken.CompletionToken);
+ }
+
+ Status = EFI_TIMEOUT;
+ goto ON_EXIT;
+ } else {
+ HttpInstance->TlsIsRxDone = FALSE;
+ }
+
+ if (!HttpInstance->LocalAddressIsIPv6) {
+ Status = HttpInstance->Tcp4TlsRxToken.CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Fragment[CurrentFragment].Len -= Tcp4RxData->FragmentTable[0].FragmentLength;
+ if (Fragment[CurrentFragment].Len == 0) {
+ CurrentFragment++;
+ } else {
+ Fragment[CurrentFragment].Bulk += Tcp4RxData->FragmentTable[0].FragmentLength;
+ }
+ } else {
+ Status = HttpInstance->Tcp6TlsRxToken.CompletionToken.Status;
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ Fragment[CurrentFragment].Len -= Tcp6RxData->FragmentTable[0].FragmentLength;
+ if (Fragment[CurrentFragment].Len == 0) {
+ CurrentFragment++;
+ } else {
+ Fragment[CurrentFragment].Bulk += Tcp6RxData->FragmentTable[0].FragmentLength;
+ }
+ }
+ }
+
+ON_EXIT:
+
+ if (Fragment != NULL) {
+ FreePool (Fragment);
+ }
+
+ return Status;
+}
+
+/**
+ Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
+ corresponding record data. This two parts will be put into two blocks of buffers in the
+ net buffer.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[out] Pdu The received TLS PDU.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS An TLS PDU is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsReceiveOnePdu (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ OUT NET_BUF **Pdu,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_STATUS Status;
+
+ LIST_ENTRY *NbufList;
+
+ UINT32 Len;
+
+ NET_BUF *PduHdr;
+ UINT8 *Header;
+ TLS_RECORD_HEADER RecordHeader;
+
+ NET_BUF *DataSeg;
+
+ NbufList = NULL;
+ PduHdr = NULL;
+ Header = NULL;
+ DataSeg = NULL;
+
+ NbufList = AllocatePool (sizeof (LIST_ENTRY));
+ if (NbufList == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ InitializeListHead (NbufList);
+
+ //
+ // Allocate buffer to receive one TLS header.
+ //
+ Len = sizeof (TLS_RECORD_HEADER);
+ PduHdr = NetbufAlloc (Len);
+ if (PduHdr == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);
+ if (Header == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // First step, receive one TLS header.
+ //
+ Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ RecordHeader = *(TLS_RECORD_HEADER *) Header;
+ if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_HANDSHAKE ||
+ RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT ||
+ RecordHeader.ContentType == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC ||
+ RecordHeader.ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA) &&
+ (RecordHeader.Version.Major == 0x03) && /// Major versions are same.
+ (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor ==TLS11_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
+ ) {
+ InsertTailList (NbufList, &PduHdr->List);
+ } else {
+ Status = EFI_PROTOCOL_ERROR;
+ goto ON_EXIT;
+ }
+
+ Len = SwapBytes16(RecordHeader.Length);
+ if (Len == 0) {
+ //
+ // No TLS payload.
+ //
+ goto FORM_PDU;
+ }
+
+ //
+ // Allocate buffer to receive one TLS payload.
+ //
+ DataSeg = NetbufAlloc (Len);
+ if (DataSeg == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL);
+
+ //
+ // Second step, receive one TLS payload.
+ //
+ Status = TlsCommonReceive (HttpInstance, DataSeg, Timeout);
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ InsertTailList (NbufList, &DataSeg->List);
+
+FORM_PDU:
+ //
+ // Form the PDU from a list of PDU.
+ //
+ *Pdu = NetbufFromBufList (NbufList, 0, 0, FreeNbufList, NbufList);
+ if (*Pdu == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ON_EXIT:
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Free the Nbufs in this NbufList and the NbufList itself.
+ //
+ FreeNbufList (NbufList);
+ }
+
+ return Status;
+}
+
+/**
+ Connect one TLS session by finishing the TLS handshake process.
+
+ @param[in] HttpInstance The HTTP instance private data.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The TLS session is established.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConnectSession (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *BufferOut;
+ UINTN BufferOutSize;
+ NET_BUF *PacketOut;
+ UINT8 *DataOut;
+ NET_BUF *Pdu;
+ UINT8 *BufferIn;
+ UINTN BufferInSize;
+ UINT8 *GetSessionDataBuffer;
+ UINTN GetSessionDataBufferSize;
+
+ BufferOut = NULL;
+ PacketOut = NULL;
+ DataOut = NULL;
+ Pdu = NULL;
+ BufferIn = NULL;
+
+ //
+ // Initialize TLS state.
+ //
+ HttpInstance->TlsSessionState = EfiTlsSessionNotStarted;
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ &(HttpInstance->TlsSessionState),
+ sizeof (EFI_TLS_SESSION_STATE)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Create ClientHello
+ //
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+
+ //
+ // Transmit ClientHello
+ //
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ FreePool (BufferOut);
+ NetbufFree (PacketOut);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ while(HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring && \
+ ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
+ //
+ // Receive one TLS record.
+ //
+ Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BufferInSize = Pdu->TotalSize;
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ NetbufFree (Pdu);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn);
+
+ NetbufFree (Pdu);
+
+ //
+ // Handle Receive data.
+ //
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+
+ FreePool (BufferIn);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (BufferOutSize != 0) {
+ //
+ // Transmit the response packet.
+ //
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ NetbufFree (PacketOut);
+
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+ }
+
+ FreePool (BufferOut);
+
+ //
+ // Get the session state, then decide whether need to continue handle received packet.
+ //
+ GetSessionDataBufferSize = DEF_BUF_LEN;
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (GetSessionDataBuffer);
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool(GetSessionDataBuffer);
+ return Status;
+ }
+
+ ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
+ HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer;
+
+ FreePool (GetSessionDataBuffer);
+
+ if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
+ return EFI_ABORTED;
+ }
+ }
+
+ if (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring) {
+ Status = EFI_ABORTED;
+ }
+
+ return Status;
+}
+
+/**
+ Close the TLS session and send out the close notification message.
+
+ @param[in] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS The TLS session is closed.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseSession (
+ IN HTTP_PROTOCOL *HttpInstance
+ )
+{
+ EFI_STATUS Status;
+
+ UINT8 *BufferOut;
+ UINTN BufferOutSize;
+
+ NET_BUF *PacketOut;
+ UINT8 *DataOut;
+
+ Status = EFI_SUCCESS;
+ BufferOut = NULL;
+ PacketOut = NULL;
+ DataOut = NULL;
+
+ if (HttpInstance == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ HttpInstance->TlsSessionState = EfiTlsSessionClosing;
+
+ Status = HttpInstance->Tls->SetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ &(HttpInstance->TlsSessionState),
+ sizeof (EFI_TLS_SESSION_STATE)
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ FreePool (BufferOut);
+ NetbufFree (PacketOut);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+/**
+ Process one message according to the CryptMode.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Message Pointer to the message buffer needed to processed.
+ @param[in] MessageSize Pointer to the message buffer size.
+ @param[in] ProcessMode Process mode.
+ @param[in, out] Fragment Only one Fragment returned after the Message is
+ processed successfully.
+
+ @retval EFI_SUCCESS Message is processed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessMessage (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN UINT8 *Message,
+ IN UINTN MessageSize,
+ IN EFI_TLS_CRYPT_MODE ProcessMode,
+ IN OUT NET_FRAGMENT *Fragment
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+ UINT32 BufferSize;
+ UINT32 BytesCopied;
+ EFI_TLS_FRAGMENT_DATA *FragmentTable;
+ UINT32 FragmentCount;
+ EFI_TLS_FRAGMENT_DATA *OriginalFragmentTable;
+ UINTN Index;
+
+ Status = EFI_SUCCESS;
+ Buffer = NULL;
+ BufferSize = 0;
+ BytesCopied = 0;
+ FragmentTable = NULL;
+ OriginalFragmentTable = NULL;
+
+ //
+ // Rebuild fragment table from BufferIn.
+ //
+ FragmentCount = 1;
+ FragmentTable = AllocateZeroPool (FragmentCount * sizeof (EFI_TLS_FRAGMENT_DATA));
+ if (FragmentTable == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ FragmentTable->FragmentLength = (UINT32) MessageSize;
+ FragmentTable->FragmentBuffer = Message;
+
+ //
+ // Record the original FragmentTable.
+ //
+ OriginalFragmentTable = FragmentTable;
+
+ //
+ // Process the Message.
+ //
+ Status = HttpInstance->Tls->ProcessPacket (
+ HttpInstance->Tls,
+ &FragmentTable,
+ &FragmentCount,
+ ProcessMode
+ );
+ if (EFI_ERROR (Status)) {
+ goto ON_EXIT;
+ }
+
+ //
+ // Calculate the size according to FragmentTable.
+ //
+ for (Index = 0; Index < FragmentCount; Index++) {
+ BufferSize += FragmentTable[Index].FragmentLength;
+ }
+
+ //
+ // Allocate buffer for processed data.
+ //
+ Buffer = AllocateZeroPool (BufferSize);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto ON_EXIT;
+ }
+
+ //
+ // Copy the new FragmentTable buffer into Buffer.
+ //
+ for (Index = 0; Index < FragmentCount; Index++) {
+ CopyMem (
+ (Buffer + BytesCopied),
+ FragmentTable[Index].FragmentBuffer,
+ FragmentTable[Index].FragmentLength
+ );
+ BytesCopied += FragmentTable[Index].FragmentLength;
+
+ //
+ // Free the FragmentBuffer since it has been copied.
+ //
+ FreePool (FragmentTable[Index].FragmentBuffer);
+ }
+
+ Fragment->Len = BufferSize;
+ Fragment->Bulk = Buffer;
+
+ON_EXIT:
+
+ if (OriginalFragmentTable != NULL) {
+ FreePool (OriginalFragmentTable);
+ OriginalFragmentTable = NULL;
+ }
+
+ //
+ // Caller has the responsibility to free the FragmentTable.
+ //
+ if (FragmentTable != NULL) {
+ FreePool (FragmentTable);
+ FragmentTable = NULL;
+ }
+
+ return Status;
+}
+
+/**
+ Receive one fragment decrypted from one TLS record.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in, out] Fragment The received Fragment.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS One fragment is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED Something wrong decryption the message.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+HttpsReceive (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN OUT NET_FRAGMENT *Fragment,
+ IN EFI_EVENT Timeout
+ )
+{
+ EFI_STATUS Status;
+ NET_BUF *Pdu;
+ TLS_RECORD_HEADER RecordHeader;
+ UINT8 *BufferIn;
+ UINTN BufferInSize;
+ NET_FRAGMENT TempFragment;
+ UINT8 *BufferOut;
+ UINTN BufferOutSize;
+ NET_BUF *PacketOut;
+ UINT8 *DataOut;
+ UINT8 *GetSessionDataBuffer;
+ UINTN GetSessionDataBufferSize;
+
+ Status = EFI_SUCCESS;
+ Pdu = NULL;
+ BufferIn = NULL;
+ BufferInSize = 0;
+ BufferOut = NULL;
+ BufferOutSize = 0;
+ PacketOut = NULL;
+ DataOut = NULL;
+ GetSessionDataBuffer = NULL;
+ GetSessionDataBufferSize = 0;
+
+ //
+ // Receive only one TLS record
+ //
+ Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ BufferInSize = Pdu->TotalSize;
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ NetbufFree (Pdu);
+ return Status;
+ }
+
+ NetbufCopy (Pdu, 0, (UINT32) BufferInSize, BufferIn);
+
+ NetbufFree (Pdu);
+
+ //
+ // Handle Receive data.
+ //
+ RecordHeader = *(TLS_RECORD_HEADER *) BufferIn;
+
+ if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA) &&
+ (RecordHeader.Version.Major == 0x03) &&
+ (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
+ ) {
+ //
+ // Decrypt Packet.
+ //
+ Status = TlsProcessMessage (
+ HttpInstance,
+ BufferIn,
+ BufferInSize,
+ EfiTlsDecrypt,
+ &TempFragment
+ );
+
+ FreePool (BufferIn);
+
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_ABORTED) {
+ //
+ // Something wrong decryption the message.
+ // BuildResponsePacket() will be called to generate Error Alert message and send it out.
+ //
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ NULL,
+ 0,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool(BufferOut);
+ return Status;
+ }
+
+ if (BufferOutSize != 0) {
+ PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ NetbufFree (PacketOut);
+ }
+
+ FreePool(BufferOut);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_ABORTED;
+ }
+
+ return Status;
+ }
+
+ //
+ // Parsing buffer.
+ //
+ ASSERT (((TLS_RECORD_HEADER *) (TempFragment.Bulk))->ContentType == TLS_CONTENT_TYPE_APPLICATION_DATA);
+
+ BufferInSize = ((TLS_RECORD_HEADER *) (TempFragment.Bulk))->Length;
+ BufferIn = AllocateZeroPool (BufferInSize);
+ if (BufferIn == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ CopyMem (BufferIn, TempFragment.Bulk + sizeof (TLS_RECORD_HEADER), BufferInSize);
+
+ //
+ // Free the buffer in TempFragment.
+ //
+ FreePool (TempFragment.Bulk);
+
+ } else if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT) &&
+ (RecordHeader.Version.Major == 0x03) &&
+ (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
+ RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
+ ) {
+ BufferOutSize = DEF_BUF_LEN;
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (BufferOut);
+ BufferOut = AllocateZeroPool (BufferOutSize);
+ if (BufferOut == NULL) {
+ FreePool (BufferIn);
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->BuildResponsePacket (
+ HttpInstance->Tls,
+ BufferIn,
+ BufferInSize,
+ BufferOut,
+ &BufferOutSize
+ );
+ }
+
+ FreePool (BufferIn);
+
+ if (EFI_ERROR (Status)) {
+ FreePool (BufferOut);
+ return Status;
+ }
+
+ if (BufferOutSize != 0) {
+ PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
+ DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize, NET_BUF_TAIL);
+ CopyMem (DataOut, BufferOut, BufferOutSize);
+
+ Status = TlsCommonTransmit (HttpInstance, PacketOut);
+
+ NetbufFree (PacketOut);
+ }
+
+ FreePool (BufferOut);
+
+ //
+ // Get the session state.
+ //
+ GetSessionDataBufferSize = DEF_BUF_LEN;
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ FreePool (GetSessionDataBuffer);
+ GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
+ if (GetSessionDataBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ return Status;
+ }
+
+ Status = HttpInstance->Tls->GetSessionData (
+ HttpInstance->Tls,
+ EfiTlsSessionState,
+ GetSessionDataBuffer,
+ &GetSessionDataBufferSize
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ FreePool (GetSessionDataBuffer);
+ return Status;
+ }
+
+ ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
+ HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *) GetSessionDataBuffer;
+
+ FreePool (GetSessionDataBuffer);
+
+ if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
+ DEBUG ((EFI_D_ERROR, "TLS Session State Error!\n"));
+ return EFI_ABORTED;
+ }
+
+ BufferIn = NULL;
+ BufferInSize = 0;
+ }
+
+ Fragment->Bulk = BufferIn;
+ Fragment->Len = (UINT32) BufferInSize;
+
+ return Status;
+}
diff --git a/NetworkPkg/HttpDxe/HttpsSupport.h b/NetworkPkg/HttpDxe/HttpsSupport.h
new file mode 100644
index 0000000..d846b76
--- /dev/null
+++ b/NetworkPkg/HttpDxe/HttpsSupport.h
@@ -0,0 +1,260 @@
+/** @file
+ The header files of miscellaneous routines specific to Https for HttpDxe driver.
+
+Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __EFI_HTTPS_SUPPORT_H__
+#define __EFI_HTTPS_SUPPORT_H__
+
+#define HTTPS_DEFAULT_PORT 443
+
+#define HTTPS_FLAG "https"
+
+/**
+ Check whether the Url is from Https.
+
+ @param[in] Url The pointer to a HTTP or HTTPS URL string.
+
+ @retval TRUE The Url is from HTTPS.
+ @retval FALSE The Url is from HTTP.
+
+**/
+BOOLEAN
+IsHttpsUrl (
+ IN CHAR8 *Url
+ );
+
+/**
+ Creates a Tls child handle, open EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+ @param[in] ImageHandle The firmware allocated handle for the UEFI image.
+ @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
+ @param[out] TlsConfiguration Pointer to the EFI_TLS_CONFIGURATION_PROTOCOL instance.
+
+ @return The child handle with opened EFI_TLS_PROTOCOL and EFI_TLS_CONFIGURATION_PROTOCOL.
+
+**/
+EFI_HANDLE
+EFIAPI
+TlsCreateChild (
+ IN EFI_HANDLE ImageHandle,
+ OUT EFI_TLS_PROTOCOL **TlsProto,
+ OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
+ );
+
+/**
+ Create event for the TLS receive and transmit tokens which are used to receive and
+ transmit TLS related messages.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+ @retval EFI_SUCCESS The events are created successfully.
+ @retval others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCreateTxRxEvent (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Close events in the TlsTxToken and TlsRxToken.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+
+**/
+VOID
+EFIAPI
+TlsCloseTxRxEvent (
+ IN HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Read the TlsCaCertificate variable and configure it.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TlsCaCertificate is configured.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_NOT_FOUND Fail to get "TlsCaCertificate" variable.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+TlsConfigCertificate (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Configure TLS session data.
+
+ @param[in, out] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS TLS session data is configured.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConfigureSession (
+ IN OUT HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Transmit the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+
+ @retval EFI_SUCCESS The packet is transmitted.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_DEVICE_ERROR An unexpected system or network error occurred.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonTransmit (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet
+ );
+
+/**
+ Receive the Packet by processing the associated HTTPS token.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Packet The packet to transmit.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The Packet is received.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_TIMEOUT The operation is time out.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCommonReceive (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ IN NET_BUF *Packet,
+ IN EFI_EVENT Timeout
+ );
+
+/**
+ Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
+ corresponding record data. The two parts will be put into two blocks of buffers in the
+ net buffer.
+
+ @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[out] Pdu The received TLS PDU.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS An TLS PDU is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsReceiveOnePdu (
+ IN OUT HTTP_PROTOCOL *HttpInstance,
+ OUT NET_BUF **Pdu,
+ IN EFI_EVENT Timeout
+ );
+
+/**
+ Connect one TLS session by finishing the TLS handshake process.
+
+ @param[in] HttpInstance The HTTP instance private data.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS The TLS session is established.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED TLS session state is incorrect.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsConnectSession (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN EFI_EVENT Timeout
+ );
+
+/**
+ Close the TLS session and send out the close notification message.
+
+ @param[in] HttpInstance The HTTP instance private data.
+
+ @retval EFI_SUCCESS The TLS session is closed.
+ @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other error as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsCloseSession (
+ IN HTTP_PROTOCOL *HttpInstance
+ );
+
+/**
+ Process one message according to the CryptMode.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in] Message Pointer to the message buffer needed to processed.
+ @param[in] MessageSize Pointer to the message buffer size.
+ @param[in] ProcessMode Process mode.
+ @param[in, out] Fragment Only one Fragment returned after the Message is
+ processed successfully.
+
+ @retval EFI_SUCCESS Message is processed successfully.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsProcessMessage (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN UINT8 *Message,
+ IN UINTN MessageSize,
+ IN EFI_TLS_CRYPT_MODE ProcessMode,
+ IN OUT NET_FRAGMENT *Fragment
+ );
+
+/**
+ Receive one fragment decrypted from one TLS record.
+
+ @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
+ @param[in, out] Fragment The received Fragment.
+ @param[in] Timeout The time to wait for connection done.
+
+ @retval EFI_SUCCESS One fragment is received.
+ @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
+ @retval EFI_ABORTED Something wrong decryption the message.
+ @retval Others Other errors as indicated.
+
+**/
+EFI_STATUS
+EFIAPI
+HttpsReceive (
+ IN HTTP_PROTOCOL *HttpInstance,
+ IN OUT NET_FRAGMENT *Fragment,
+ IN EFI_EVENT Timeout
+ );
+
+#endif
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6
2016-12-22 7:33 ` Ye, Ting
@ 2016-12-22 8:30 ` Wu, Jiaxin
0 siblings, 0 replies; 37+ messages in thread
From: Wu, Jiaxin @ 2016-12-22 8:30 UTC (permalink / raw)
To: Ye, Ting, edk2-devel@lists.01.org
Cc: Fu, Siyuan, Zhang, Lubo, Long, Qin, Thomas Palmer
Hi Ting,
Thanks. I will correct/refine the implementation according your comments.
Thanks,
Jiaxin
> -----Original Message-----
> From: Ye, Ting
> Sent: Thursday, December 22, 2016 3:34 PM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>;
> Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>
> Subject: RE: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4
> and IPv6
>
> Hi Jiaxin,
>
> Some comments included below.
>
> 1. In TlsConfigCertificate, HttpInstance->TlsConfigData.CACert is not used
> and local variable "CACert" is not freed after calling TlsConfiguration-
> >SetData.
> 2. In TlsConfigureSession, several gotos are useless. Suggest to replace with
> return status directly.
> 3. This two parts will be ==> These
>
> Others are good to me.
>
> Reviewed-by: Ye Ting <ting.ye@intel.com>
>
> Best Regards,
> Ye Ting
>
>
>
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: Wednesday, December 14, 2016 3:34 PM
> To: edk2-devel@lists.01.org
> Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang,
> Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas
> Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
> Subject: [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and
> IPv6
>
> This patch is used to enable HTTPS feature. HttpDxe driver
> will consume TlsDxe driver. It can both support http and https
> feature, that’s depended on the information of URL, the HTTP
> instance can be able to determine whether to use http or https.
>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> NetworkPkg/HttpDxe/HttpDriver.h | 10 +-
> NetworkPkg/HttpDxe/HttpDxe.inf | 12 +-
> NetworkPkg/HttpDxe/HttpImpl.c | 252 +++++-
> NetworkPkg/HttpDxe/HttpProto.c | 464 +++++++---
> NetworkPkg/HttpDxe/HttpProto.h | 65 +-
> NetworkPkg/HttpDxe/HttpsSupport.c | 1692
> +++++++++++++++++++++++++++++++++++++
> NetworkPkg/HttpDxe/HttpsSupport.h | 260 ++++++
> 7 files changed, 2601 insertions(+), 154 deletions(-)
> create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.c
> create mode 100644 NetworkPkg/HttpDxe/HttpsSupport.h
>
> diff --git a/NetworkPkg/HttpDxe/HttpDriver.h
> b/NetworkPkg/HttpDxe/HttpDriver.h
> index fa2372c..93a412a 100644
> --- a/NetworkPkg/HttpDxe/HttpDriver.h
> +++ b/NetworkPkg/HttpDxe/HttpDriver.h
> @@ -22,10 +22,11 @@
>
> //
> // Libraries
> //
> #include <Library/UefiBootServicesTableLib.h>
> +#include <Library/UefiRuntimeServicesTableLib.h>
> #include <Library/MemoryAllocationLib.h>
> #include <Library/BaseLib.h>
> #include <Library/UefiLib.h>
> #include <Library/DebugLib.h>
> #include <Library/NetLib.h>
> @@ -48,17 +49,23 @@
> #include <Protocol/Tcp6.h>
> #include <Protocol/Dns4.h>
> #include <Protocol/Dns6.h>
> #include <Protocol/Ip4Config2.h>
> #include <Protocol/Ip6Config.h>
> +#include <Protocol/Tls.h>
> +#include <Protocol/TlsConfig.h>
>
> -
> +#include <Guid/ImageAuthentication.h>
> //
> // Produced Protocols
> //
> #include <Protocol/Http.h>
>
> +#include <Guid/TlsAuthentication.h>
> +
> +#include <IndustryStandard/Tls1.h>
> +
> //
> // Driver Version
> //
> #define HTTP_DRIVER_VERSION 0xa
>
> @@ -77,10 +84,11 @@ extern EFI_HTTP_UTILITIES_PROTOCOL
> *mHttpUtilities;
> // Include files with function prototypes
> //
> #include "ComponentName.h"
> #include "HttpImpl.h"
> #include "HttpProto.h"
> +#include "HttpsSupport.h"
> #include "HttpDns.h"
>
> typedef struct {
> EFI_SERVICE_BINDING_PROTOCOL *ServiceBinding;
> UINTN NumberOfChildren;
> diff --git a/NetworkPkg/HttpDxe/HttpDxe.inf
> b/NetworkPkg/HttpDxe/HttpDxe.inf
> index bf2cbee..1118181 100644
> --- a/NetworkPkg/HttpDxe/HttpDxe.inf
> +++ b/NetworkPkg/HttpDxe/HttpDxe.inf
> @@ -1,9 +1,9 @@
> ## @file
> # Implementation of EFI HTTP protocol interfaces.
> #
> -# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
> #
> # This program and the accompanying materials
> # are licensed and made available under the terms and conditions of the
> BSD License
> # which accompanies this distribution. The full text of the license may be
> found at
> # http://opensource.org/licenses/bsd-license.php.
> @@ -24,10 +24,11 @@
> MODULE_UNI_FILE = HttpDxe.uni
>
> [Packages]
> MdePkg/MdePkg.dec
> MdeModulePkg/MdeModulePkg.dec
> + NetworkPkg/NetworkPkg.dec
>
> [Sources]
> ComponentName.h
> ComponentName.c
> HttpDns.h
> @@ -36,14 +37,17 @@
> HttpDriver.c
> HttpImpl.h
> HttpImpl.c
> HttpProto.h
> HttpProto.c
> + HttpsSupport.h
> + HttpsSupport.c
>
> [LibraryClasses]
> UefiDriverEntryPoint
> UefiBootServicesTableLib
> + UefiRuntimeServicesTableLib
> MemoryAllocationLib
> BaseLib
> UefiLib
> DebugLib
> NetLib
> @@ -62,8 +66,14 @@
> gEfiDns4ProtocolGuid ## SOMETIMES_CONSUMES
> gEfiDns6ServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
> gEfiDns6ProtocolGuid ## SOMETIMES_CONSUMES
> gEfiIp4Config2ProtocolGuid ## SOMETIMES_CONSUMES
> gEfiIp6ConfigProtocolGuid ## SOMETIMES_CONSUMES
> + gEfiTlsServiceBindingProtocolGuid ## SOMETIMES_CONSUMES
> + gEfiTlsProtocolGuid ## SOMETIMES_CONSUMES
> + gEfiTlsConfigurationProtocolGuid ## SOMETIMES_CONSUMES
> +
> +[Guids]
> + gEfiTlsCaCertificateGuid ## CONSUMES ## GUID
>
> [UserExtensions.TianoCore."ExtraFiles"]
> HttpDxeExtra.uni
> \ No newline at end of file
> diff --git a/NetworkPkg/HttpDxe/HttpImpl.c
> b/NetworkPkg/HttpDxe/HttpImpl.c
> index 6fcb0b7..77aa64a 100644
> --- a/NetworkPkg/HttpDxe/HttpImpl.c
> +++ b/NetworkPkg/HttpDxe/HttpImpl.c
> @@ -239,10 +239,11 @@ EfiHttpRequest (
> UINTN HostNameSize;
> UINT16 RemotePort;
> HTTP_PROTOCOL *HttpInstance;
> BOOLEAN Configure;
> BOOLEAN ReConfigure;
> + BOOLEAN TlsConfigure;
> CHAR8 *RequestMsg;
> CHAR8 *Url;
> UINTN UrlLen;
> CHAR16 *HostNameStr;
> HTTP_TOKEN_WRAP *Wrap;
> @@ -258,10 +259,11 @@ EfiHttpRequest (
> HostName = NULL;
> RequestMsg = NULL;
> HostNameStr = NULL;
> Wrap = NULL;
> FileUrl = NULL;
> + TlsConfigure = FALSE;
>
> if ((This == NULL) || (Token == NULL)) {
> return EFI_INVALID_PARAMETER;
> }
>
> @@ -343,10 +345,36 @@ EfiHttpRequest (
> HttpInstance->Url = Url;
> }
>
>
> UnicodeStrToAsciiStrS (Request->Url, Url, UrlLen);
> +
> + //
> + // From the information in Url, the HTTP instance will
> + // be able to determine whether to use http or https.
> + //
> + HttpInstance->UseHttps = IsHttpsUrl (Url);
> +
> + //
> + // Check whether we need to create Tls child and open the TLS protocol.
> + //
> + if (HttpInstance->UseHttps && HttpInstance->TlsChildHandle == NULL) {
> + //
> + // Use TlsSb to create Tls child and open the TLS protocol.
> + //
> + HttpInstance->TlsChildHandle = TlsCreateChild (
> + HttpInstance->Service->ImageHandle,
> + &(HttpInstance->Tls),
> + &(HttpInstance->TlsConfiguration)
> + );
> + if (HttpInstance->TlsChildHandle == NULL) {
> + return EFI_DEVICE_ERROR;
> + }
> +
> + TlsConfigure = TRUE;
> + }
> +
> UrlParser = NULL;
> Status = HttpParseUrl (Url, (UINT32) AsciiStrLen (Url), FALSE, &UrlParser);
> if (EFI_ERROR (Status)) {
> goto Error1;
> }
> @@ -357,11 +385,15 @@ EfiHttpRequest (
> goto Error1;
> }
>
> Status = HttpUrlGetPort (Url, UrlParser, &RemotePort);
> if (EFI_ERROR (Status)) {
> - RemotePort = HTTP_DEFAULT_PORT;
> + if (HttpInstance->UseHttps) {
> + RemotePort = HTTPS_DEFAULT_PORT;
> + } else {
> + RemotePort = HTTP_DEFAULT_PORT;
> + }
> }
> //
> // If Configure is TRUE, it indicates the first time to call Request();
> // If ReConfigure is TRUE, it indicates the request URL is not same
> // with the previous call to Request();
> @@ -374,13 +406,17 @@ EfiHttpRequest (
> // Request() is called the first time.
> //
> ReConfigure = FALSE;
> } else {
> if ((HttpInstance->RemotePort == RemotePort) &&
> - (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0)) {
> + (AsciiStrCmp (HttpInstance->RemoteHost, HostName) == 0) &&
> + (!HttpInstance->UseHttps || (HttpInstance->UseHttps &&
> + !TlsConfigure &&
> + HttpInstance->TlsSessionState ==
> EfiTlsSessionDataTransferring))) {
> //
> // Host Name and port number of the request URL are the same with
> previous call to Request().
> + // If Https protocol used, the corresponding SessionState is
> EfiTlsSessionDataTransferring.
> // Check whether previous TCP packet sent out.
> //
>
> if (EFI_ERROR (NetMapIterate (&HttpInstance->TxTokens,
> HttpTcpNotReady, NULL))) {
> //
> @@ -480,10 +516,20 @@ EfiHttpRequest (
> if (!HttpInstance->LocalAddressIsIPv6) {
> ASSERT (HttpInstance->Tcp4 != NULL);
> } else {
> ASSERT (HttpInstance->Tcp6 != NULL);
> }
> +
> + if (HttpInstance->UseHttps && !TlsConfigure) {
> + Status = TlsCloseSession (HttpInstance);
> + if (EFI_ERROR (Status)) {
> + goto Error1;
> + }
> +
> + TlsCloseTxRxEvent (HttpInstance);
> + }
> +
> HttpCloseConnection (HttpInstance);
> EfiHttpCancel (This, NULL);
> }
>
> //
> @@ -498,17 +544,22 @@ EfiHttpRequest (
> Wrap->HttpToken = Token;
> Wrap->HttpInstance = HttpInstance;
> if (Request != NULL) {
> Wrap->TcpWrap.Method = Request->Method;
> }
> -
> - Status = HttpInitTcp (HttpInstance, Wrap, Configure);
> +
> + Status = HttpInitSession (
> + HttpInstance,
> + Wrap,
> + Configure || ReConfigure,
> + TlsConfigure
> + );
> if (EFI_ERROR (Status)) {
> goto Error2;
> - }
> + }
>
> - if (!Configure) {
> + if (!Configure && !ReConfigure && !TlsConfigure) {
> //
> // For the new HTTP token, create TX TCP token events.
> //
> Status = HttpCreateTcpTxEvent (Wrap);
> if (EFI_ERROR (Status)) {
> @@ -591,13 +642,18 @@ Error4:
> if (RequestMsg != NULL) {
> FreePool (RequestMsg);
> }
>
> Error3:
> - HttpCloseConnection (HttpInstance);
> + if (HttpInstance->UseHttps) {
> + TlsCloseSession (HttpInstance);
> + TlsCloseTxRxEvent (HttpInstance);
> + }
>
> Error2:
> + HttpCloseConnection (HttpInstance);
> +
> HttpCloseTcpConnCloseEvent (HttpInstance);
> if (NULL != Wrap->TcpWrap.Tx4Token.CompletionToken.Event) {
> gBS->CloseEvent (Wrap->TcpWrap.Tx4Token.CompletionToken.Event);
> Wrap->TcpWrap.Tx4Token.CompletionToken.Event = NULL;
> }
> @@ -729,26 +785,34 @@ HttpCancel (
> } else {
> return Status;
> }
> }
>
> - //
> - // Then check the tokens queued by EfiHttpResponse().
> - //
> - Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens,
> Token);
> - if (EFI_ERROR (Status)) {
> - if (Token != NULL) {
> - if (Status == EFI_ABORTED) {
> - return EFI_SUCCESS;
> + if (!HttpInstance->UseHttps) {
> + //
> + // Then check the tokens queued by EfiHttpResponse(), except for Https.
> + //
> + Status = NetMapIterate (&HttpInstance->RxTokens, HttpCancelTokens,
> Token);
> + if (EFI_ERROR (Status)) {
> + if (Token != NULL) {
> + if (Status == EFI_ABORTED) {
> + return EFI_SUCCESS;
> + } else {
> + return EFI_NOT_FOUND;
> + }
> } else {
> - return EFI_NOT_FOUND;
> + return Status;
> }
> + }
> + } else {
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance-
> >Tcp4TlsRxToken.CompletionToken);
> } else {
> - return Status;
> + HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance-
> >Tcp6TlsRxToken.CompletionToken);
> }
> }
> -
> +
> return EFI_SUCCESS;
> }
>
>
> /**
> @@ -880,10 +944,11 @@ HttpResponseWorker (
> HTTP_PROTOCOL *HttpInstance;
> EFI_HTTP_TOKEN *Token;
> NET_MAP_ITEM *Item;
> HTTP_TOKEN_WRAP *ValueInItem;
> UINTN HdrLen;
> + NET_FRAGMENT Fragment;
>
> if (Wrap == NULL || Wrap->HttpInstance == NULL) {
> return EFI_INVALID_PARAMETER;
> }
>
> @@ -897,21 +962,15 @@ HttpResponseWorker (
> HttpHeaders = NULL;
> SizeofHeaders = 0;
> BufferSize = 0;
> EndofHeader = NULL;
> ValueInItem = NULL;
> + Fragment.Len = 0;
> + Fragment.Bulk = NULL;
>
> if (HttpMsg->Data.Response != NULL) {
> //
> - // Need receive the HTTP headers, prepare buffer.
> - //
> - Status = HttpCreateTcpRxEventForHeader (HttpInstance);
> - if (EFI_ERROR (Status)) {
> - goto Error;
> - }
> -
> - //
> // Check whether we have cached header from previous call.
> //
> if ((HttpInstance->CacheBody != NULL) && (HttpInstance->NextMsg !=
> NULL)) {
> //
> // The data is stored at [NextMsg, CacheBody + CacheLen].
> @@ -1198,13 +1257,120 @@ HttpResponseWorker (
> ASSERT (HttpInstance->MsgParser != NULL);
>
> //
> // We still need receive more data when there is no cache data and
> MsgParser is not NULL;
> //
> - Status = HttpTcpReceiveBody (Wrap, HttpMsg);
> - if (EFI_ERROR (Status)) {
> - goto Error2;
> + if (!HttpInstance->UseHttps) {
> + Status = HttpTcpReceiveBody (Wrap, HttpMsg);
> +
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> +
> + } else {
> + if (HttpInstance->TimeoutEvent == NULL) {
> + //
> + // Create TimeoutEvent for response
> + //
> + Status = gBS->CreateEvent (
> + EVT_TIMER,
> + TPL_CALLBACK,
> + NULL,
> + NULL,
> + &HttpInstance->TimeoutEvent
> + );
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> + }
> +
> + //
> + // Start the timer, and wait Timeout seconds to receive the body packet.
> + //
> + Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative,
> HTTP_RESPONSE_TIMEOUT * TICKS_PER_SECOND);
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> +
> + Status = HttpsReceive (HttpInstance, &Fragment, HttpInstance-
> >TimeoutEvent);
> +
> + gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
> +
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> +
> + //
> + // Check whether we receive a complete HTTP message.
> + //
> + Status = HttpParseMessageBody (
> + HttpInstance->MsgParser,
> + (UINTN) Fragment.Len,
> + (CHAR8 *) Fragment.Bulk
> + );
> + if (EFI_ERROR (Status)) {
> + goto Error2;
> + }
> +
> + if (HttpIsMessageComplete (HttpInstance->MsgParser)) {
> + //
> + // Free the MsgParse since we already have a full HTTP message.
> + //
> + HttpFreeMsgParser (HttpInstance->MsgParser);
> + HttpInstance->MsgParser = NULL;
> + }
> +
> + //
> + // We receive part of header of next HTTP msg.
> + //
> + if (HttpInstance->NextMsg != NULL) {
> + HttpMsg->BodyLength = MIN ((UINTN) (HttpInstance->NextMsg -
> (CHAR8 *) Fragment.Bulk), HttpMsg->BodyLength);
> + CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
> +
> + HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
> + if (HttpInstance->CacheLen != 0) {
> + if (HttpInstance->CacheBody != NULL) {
> + FreePool (HttpInstance->CacheBody);
> + }
> +
> + HttpInstance->CacheBody = AllocateZeroPool (HttpInstance-
> >CacheLen);
> + if (HttpInstance->CacheBody == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error2;
> + }
> +
> + CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg-
> >BodyLength, HttpInstance->CacheLen);
> + HttpInstance->CacheOffset = 0;
> +
> + HttpInstance->NextMsg = HttpInstance->CacheBody + (UINTN)
> (HttpInstance->NextMsg - (CHAR8 *) (Fragment.Bulk + HttpMsg-
> >BodyLength));
> + }
> + } else {
> + HttpMsg->BodyLength = MIN (Fragment.Len, (UINT32) HttpMsg-
> >BodyLength);
> + CopyMem (HttpMsg->Body, Fragment.Bulk, HttpMsg->BodyLength);
> + HttpInstance->CacheLen = Fragment.Len - HttpMsg->BodyLength;
> + if (HttpInstance->CacheLen != 0) {
> + if (HttpInstance->CacheBody != NULL) {
> + FreePool (HttpInstance->CacheBody);
> + }
> +
> + HttpInstance->CacheBody = AllocateZeroPool (HttpInstance-
> >CacheLen);
> + if (HttpInstance->CacheBody == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto Error2;
> + }
> +
> + CopyMem (HttpInstance->CacheBody, Fragment.Bulk + HttpMsg-
> >BodyLength, HttpInstance->CacheLen);
> + HttpInstance->CacheOffset = 0;
> + }
> + }
> +
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> + }
> +
> + goto Exit;
> }
>
> return Status;
>
> Exit:
> @@ -1232,19 +1398,30 @@ Error2:
> Error:
> Item = NetMapFindKey (&Wrap->HttpInstance->RxTokens, Wrap-
> >HttpToken);
> if (Item != NULL) {
> NetMapRemoveItem (&Wrap->HttpInstance->RxTokens, Item, NULL);
> }
> -
> - HttpTcpTokenCleanup (Wrap);
> +
> + if (!HttpInstance->UseHttps) {
> + HttpTcpTokenCleanup (Wrap);
> + } else {
> + FreePool (Wrap);
> + }
>
> if (HttpHeaders != NULL) {
> FreePool (HttpHeaders);
> + HttpHeaders = NULL;
> + }
> +
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> }
>
> if (HttpMsg->Headers != NULL) {
> FreePool (HttpMsg->Headers);
> + HttpMsg->Headers = NULL;
> }
>
> if (HttpInstance->CacheBody != NULL) {
> FreePool (HttpInstance->CacheBody);
> HttpInstance->CacheBody = NULL;
> @@ -1351,13 +1528,20 @@ EfiHttpResponse (
> }
>
> Wrap->HttpInstance = HttpInstance;
> Wrap->HttpToken = Token;
>
> - Status = HttpCreateTcpRxEvent (Wrap);
> - if (EFI_ERROR (Status)) {
> - goto Error;
> + //
> + // Notes: For Https, receive token wrapped in HTTP_TOKEN_WRAP is not
> used to
> + // receive the https response. A special TlsRxToken is used for receiving
> TLS
> + // related messages. It should be a blocking response.
> + //
> + if (!HttpInstance->UseHttps) {
> + Status = HttpCreateTcpRxEvent (Wrap);
> + if (EFI_ERROR (Status)) {
> + goto Error;
> + }
> }
>
> Status = NetMapInsertTail (&HttpInstance->RxTokens, Token, Wrap);
> if (EFI_ERROR (Status)) {
> goto Error;
> diff --git a/NetworkPkg/HttpDxe/HttpProto.c
> b/NetworkPkg/HttpDxe/HttpProto.c
> index 6373f07..77a3ee3 100644
> --- a/NetworkPkg/HttpDxe/HttpProto.c
> +++ b/NetworkPkg/HttpDxe/HttpProto.c
> @@ -926,10 +926,26 @@ HttpCleanProtocol (
> HttpInstance->Service->ImageHandle,
> HttpInstance->Handle
> );
> }
>
> + if (HttpInstance->TlsConfigData.CACert != NULL) {
> + FreePool (HttpInstance->TlsConfigData.CACert);
> + HttpInstance->TlsConfigData.CACert = NULL;
> + }
> +
> + if (HttpInstance->TlsConfigData.ClientCert != NULL) {
> + FreePool (HttpInstance->TlsConfigData.ClientCert);
> + HttpInstance->TlsConfigData.ClientCert = NULL;
> + }
> +
> + if (HttpInstance->TlsConfigData.ClientPrivateKey != NULL) {
> + FreePool (HttpInstance->TlsConfigData.ClientPrivateKey);
> + HttpInstance->TlsConfigData.ClientPrivateKey = NULL;
> + }
> +
> + TlsCloseTxRxEvent (HttpInstance);
> }
>
> /**
> Establish TCP connection with HTTP server.
>
> @@ -1183,11 +1199,12 @@ HttpConfigureTcp6 (
> return EFI_SUCCESS;
>
> }
>
> /**
> - Check existing TCP connection, if in error state, recover TCP4 connection.
> + Check existing TCP connection, if in error state, recover TCP4 connection.
> Then,
> + connect one TLS session if required.
>
> @param[in] HttpInstance The HTTP instance private data.
>
> @retval EFI_SUCCESS The TCP connection is established.
> @retval EFI_NOT_READY TCP4 protocol child is not created or
> configured.
> @@ -1224,15 +1241,62 @@ HttpConnectTcp4 (
> return EFI_SUCCESS;
> } else if (Tcp4State > Tcp4StateEstablished ) {
> HttpCloseConnection(HttpInstance);
> }
>
> - return HttpCreateConnection (HttpInstance);
> + Status = HttpCreateConnection (HttpInstance);
> + if (EFI_ERROR(Status)){
> + DEBUG ((EFI_D_ERROR, "Tcp4 Connection fail - %x\n", Status));
> + return Status;
> + }
> +
> + //
> + // Tls session connection.
> + //
> + if (HttpInstance->UseHttps) {
> + if (HttpInstance->TimeoutEvent == NULL) {
> + //
> + // Create TimeoutEvent for TLS connection.
> + //
> + Status = gBS->CreateEvent (
> + EVT_TIMER,
> + TPL_CALLBACK,
> + NULL,
> + NULL,
> + &HttpInstance->TimeoutEvent
> + );
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> + }
> +
> + //
> + // Start the timer, and wait Timeout seconds for connection.
> + //
> + Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative,
> HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> +
> + Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
> +
> + gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
> +
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> + }
> +
> + return Status;
> }
>
> /**
> - Check existing TCP connection, if in error state, recover TCP6 connection.
> + Check existing TCP connection, if in error state, recover TCP6 connection.
> Then,
> + connect one TLS session if required.
>
> @param[in] HttpInstance The HTTP instance private data.
>
> @retval EFI_SUCCESS The TCP connection is established.
> @retval EFI_NOT_READY TCP6 protocol child is not created or
> configured.
> @@ -1269,34 +1333,92 @@ HttpConnectTcp6 (
> return EFI_SUCCESS;
> } else if (Tcp6State > Tcp6StateEstablished ) {
> HttpCloseConnection(HttpInstance);
> }
>
> - return HttpCreateConnection (HttpInstance);
> + Status = HttpCreateConnection (HttpInstance);
> + if (EFI_ERROR(Status)){
> + DEBUG ((EFI_D_ERROR, "Tcp6 Connection fail - %x\n", Status));
> + return Status;
> + }
> +
> + //
> + // Tls session connection.
> + //
> + if (HttpInstance->UseHttps) {
> + if (HttpInstance->TimeoutEvent == NULL) {
> + //
> + // Create TimeoutEvent for TLS connection.
> + //
> + Status = gBS->CreateEvent (
> + EVT_TIMER,
> + TPL_CALLBACK,
> + NULL,
> + NULL,
> + &HttpInstance->TimeoutEvent
> + );
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> + }
> +
> + //
> + // Start the timer, and wait Timeout seconds for connection.
> + //
> + Status = gBS->SetTimer (HttpInstance->TimeoutEvent, TimerRelative,
> HTTP_CONNECTION_TIMEOUT * TICKS_PER_SECOND);
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> +
> + Status = TlsConnectSession (HttpInstance, HttpInstance->TimeoutEvent);
> +
> + gBS->SetTimer (HttpInstance->TimeoutEvent, TimerCancel, 0);
> +
> + if (EFI_ERROR (Status)) {
> + TlsCloseTxRxEvent (HttpInstance);
> + return Status;
> + }
> + }
> +
> + return Status;
> }
>
> /**
> - Initialize TCP related data.
> + Initialize Http session.
>
> @param[in] HttpInstance The HTTP instance private data.
> @param[in] Wrap The HTTP token's wrap data.
> - @param[in] Configure The Flag indicates whether the first time to
> initialize Tcp.
> + @param[in] Configure The Flag indicates whether need to initialize
> session.
> + @param[in] TlsConfigure The Flag indicates whether it's the new Tls
> session.
>
> - @retval EFI_SUCCESS The initialization of TCP instance is done.
> + @retval EFI_SUCCESS The initialization of session is done.
> @retval Others Other error as indicated.
>
> **/
> EFI_STATUS
> -HttpInitTcp (
> +HttpInitSession (
> IN HTTP_PROTOCOL *HttpInstance,
> IN HTTP_TOKEN_WRAP *Wrap,
> - IN BOOLEAN Configure
> + IN BOOLEAN Configure,
> + IN BOOLEAN TlsConfigure
> )
> {
> EFI_STATUS Status;
> ASSERT (HttpInstance != NULL);
>
> + //
> + // Configure Tls session.
> + //
> + if (TlsConfigure) {
> + Status = TlsConfigureSession (HttpInstance);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + }
> +
> if (!HttpInstance->LocalAddressIsIPv6) {
> //
> // Configure TCP instance.
> //
> if (Configure) {
> @@ -1336,11 +1458,11 @@ HttpInitTcp (
> return EFI_SUCCESS;
>
> }
>
> /**
> - Send the HTTP message through TCP4 or TCP6.
> + Send the HTTP or HTTPS message through TCP4 or TCP6.
>
> @param[in] HttpInstance The HTTP instance private data.
> @param[in] Wrap The HTTP token's wrap data.
> @param[in] TxString Buffer containing the HTTP message string.
> @param[in] TxStringLen Length of the HTTP message string in bytes.
> @@ -1360,18 +1482,68 @@ HttpTransmitTcp (
> EFI_STATUS Status;
> EFI_TCP4_IO_TOKEN *Tx4Token;
> EFI_TCP4_PROTOCOL *Tcp4;
> EFI_TCP6_IO_TOKEN *Tx6Token;
> EFI_TCP6_PROTOCOL *Tcp6;
> + UINT8 *Buffer;
> + UINTN BufferSize;
> + NET_FRAGMENT TempFragment;
> +
> + Status = EFI_SUCCESS;
> + Buffer = NULL;
> +
> + //
> + // Need to encrypt data.
> + //
> + if (HttpInstance->UseHttps) {
> + //
> + // Build BufferOut data
> + //
> + BufferSize = sizeof (TLS_RECORD_HEADER) + TxStringLen;
> + Buffer = AllocateZeroPool (BufferSize);
> + if (Buffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> + ((TLS_RECORD_HEADER *) Buffer)->ContentType =
> TLS_CONTENT_TYPE_APPLICATION_DATA;
> + ((TLS_RECORD_HEADER *) Buffer)->Version.Major = HttpInstance-
> >TlsConfigData.Version.Major;
> + ((TLS_RECORD_HEADER *) Buffer)->Version.Minor = HttpInstance-
> >TlsConfigData.Version.Minor;
> + ((TLS_RECORD_HEADER *) Buffer)->Length = (UINT16) (TxStringLen);
> + CopyMem (Buffer + sizeof (TLS_RECORD_HEADER), TxString, TxStringLen);
> +
> + //
> + // Encrypt Packet.
> + //
> + Status = TlsProcessMessage (
> + HttpInstance,
> + Buffer,
> + BufferSize,
> + EfiTlsEncrypt,
> + &TempFragment
> + );
> +
> + FreePool (Buffer);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> + }
>
> - if (!HttpInstance->LocalAddressIsIPv6) {
> + if (!HttpInstance->LocalAddressIsIPv6) {
> Tcp4 = HttpInstance->Tcp4;
> Tx4Token = &Wrap->TcpWrap.Tx4Token;
> +
> + if (HttpInstance->UseHttps) {
> + Tx4Token->Packet.TxData->DataLength = TempFragment.Len;
> + Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength =
> TempFragment.Len;
> + Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID
> *) TempFragment.Bulk;
> + } else {
> + Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
> + Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength =
> (UINT32) TxStringLen;
> + Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID
> *) TxString;
> + }
>
> - Tx4Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
> - Tx4Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32)
> TxStringLen;
> - Tx4Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)
> TxString;
> Tx4Token->CompletionToken.Status = EFI_NOT_READY;
>
> Wrap->TcpWrap.IsTxDone = FALSE;
> Status = Tcp4->Transmit (Tcp4, Tx4Token);
> if (EFI_ERROR (Status)) {
> @@ -1380,25 +1552,31 @@ HttpTransmitTcp (
> }
>
> } else {
> Tcp6 = HttpInstance->Tcp6;
> Tx6Token = &Wrap->TcpWrap.Tx6Token;
> -
> - Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
> - Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength = (UINT32)
> TxStringLen;
> - Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID *)
> TxString;
> +
> + if (HttpInstance->UseHttps) {
> + Tx6Token->Packet.TxData->DataLength = TempFragment.Len;
> + Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength =
> TempFragment.Len;
> + Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID
> *) TempFragment.Bulk;
> + } else {
> + Tx6Token->Packet.TxData->DataLength = (UINT32) TxStringLen;
> + Tx6Token->Packet.TxData->FragmentTable[0].FragmentLength =
> (UINT32) TxStringLen;
> + Tx6Token->Packet.TxData->FragmentTable[0].FragmentBuffer = (VOID
> *) TxString;
> + }
> +
> Tx6Token->CompletionToken.Status = EFI_NOT_READY;
>
> Wrap->TcpWrap.IsTxDone = FALSE;
> Status = Tcp6->Transmit (Tcp6, Tx6Token);
> if (EFI_ERROR (Status)) {
> DEBUG ((EFI_D_ERROR, "Transmit failed: %r\n", Status));
> return Status;
> }
> }
>
> -
> return Status;
> }
>
> /**
> Check whether the user's token or event has already
> @@ -1464,11 +1642,11 @@ HttpTcpNotReady (
>
> return EFI_SUCCESS;
> }
>
> /**
> - Transmit the HTTP mssage by processing the associated HTTP token.
> + Transmit the HTTP or HTTPS mssage by processing the associated HTTP
> token.
>
> @param[in] Map The container of Tx4Token or Tx6Token.
> @param[in] Item Current item to check against.
> @param[in] Context The Token to check againist.
>
> @@ -1588,167 +1766,235 @@ HttpTcpReceiveHeader (
> EFI_TCP6_IO_TOKEN *Rx6Token;
> EFI_TCP6_PROTOCOL *Tcp6;
> CHAR8 **EndofHeader;
> CHAR8 **HttpHeaders;
> CHAR8 *Buffer;
> + NET_FRAGMENT Fragment;
>
> ASSERT (HttpInstance != NULL);
>
> EndofHeader = HttpInstance->EndofHeader;
> HttpHeaders = HttpInstance->HttpHeaders;
> Tcp4 = HttpInstance->Tcp4;
> Tcp6 = HttpInstance->Tcp6;
> Buffer = NULL;
> Rx4Token = NULL;
> Rx6Token = NULL;
> + Fragment.Len = 0;
> + Fragment.Bulk = NULL;
>
> if (HttpInstance->LocalAddressIsIPv6) {
> ASSERT (Tcp6 != NULL);
> } else {
> ASSERT (Tcp4 != NULL);
> }
>
> - if (!HttpInstance->LocalAddressIsIPv6) {
> - Rx4Token = &HttpInstance->Rx4Token;
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer =
> AllocateZeroPool (DEF_BUF_LEN);
> - if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer ==
> NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> + if (!HttpInstance->UseHttps) {
> + Status = HttpCreateTcpRxEventForHeader (HttpInstance);
> + if (EFI_ERROR (Status)) {
> return Status;
> }
> + }
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + if (!HttpInstance->UseHttps) {
> + Rx4Token = &HttpInstance->Rx4Token;
> + Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer =
> AllocateZeroPool (DEF_BUF_LEN);
> + if (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer ==
> NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> + }
>
> //
> // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not
> NULL.
> //
> - while (*EndofHeader == NULL) {
> - HttpInstance->IsRxDone = FALSE;
> - Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength =
> DEF_BUF_LEN;
> - Status = Tcp4->Receive (Tcp4, Rx4Token);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
> - return Status;
> - }
> -
> - while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> - Tcp4->Poll (Tcp4);
> + while (*EndofHeader == NULL) {
> + if (!HttpInstance->UseHttps) {
> + HttpInstance->IsRxDone = FALSE;
> + Rx4Token->Packet.RxData->DataLength = DEF_BUF_LEN;
> + Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength =
> DEF_BUF_LEN;
> + Status = Tcp4->Receive (Tcp4, Rx4Token);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
> + return Status;
> + }
> +
> + while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> + Tcp4->Poll (Tcp4);
> + }
> +
> + if (!HttpInstance->IsRxDone) {
> + //
> + // Cancle the Token before close its Event.
> + //
> + Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
> + gBS->CloseEvent (Rx4Token->CompletionToken.Event);
> + Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
> + }
> +
> + Status = Rx4Token->CompletionToken.Status;
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Fragment.Len = Rx4Token->Packet.RxData-
> >FragmentTable[0].FragmentLength;
> + Fragment.Bulk = (UINT8 *) Rx4Token->Packet.RxData-
> >FragmentTable[0].FragmentBuffer;
> + } else {
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> + }
> +
> + Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Tcp4 receive failed: %r\n", Status));
> + return Status;
> + }
> }
>
> - if (!HttpInstance->IsRxDone) {
> - //
> - // Cancle the Token before close its Event.
> - //
> - Tcp4->Cancel (HttpInstance->Tcp4, &Rx4Token->CompletionToken);
> - gBS->CloseEvent (Rx4Token->CompletionToken.Event);
> - Rx4Token->CompletionToken.Status = EFI_TIMEOUT;
> - }
> -
> - Status = Rx4Token->CompletionToken.Status;
> - if (EFI_ERROR (Status)) {
> - return Status;
> - }
> -
> //
> // Append the response string.
> //
> - *BufferSize = (*SizeofHeaders) + Rx4Token->Packet.RxData-
> >FragmentTable[0].FragmentLength;
> + *BufferSize = *SizeofHeaders + Fragment.Len;
> Buffer = AllocateZeroPool (*BufferSize);
> if (Buffer == NULL) {
> Status = EFI_OUT_OF_RESOURCES;
> return Status;
> }
> -
> +
> if (*HttpHeaders != NULL) {
> - CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
> + CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
> FreePool (*HttpHeaders);
> }
> -
> +
> CopyMem (
> - Buffer + (*SizeofHeaders),
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentLength
> + Buffer + *SizeofHeaders,
> + Fragment.Bulk,
> + Fragment.Len
> );
> - *HttpHeaders = Buffer;
> - *SizeofHeaders = *BufferSize;
> -
> + *HttpHeaders = Buffer;
> + *SizeofHeaders = *BufferSize;
> +
> //
> // Check whether we received end of HTTP headers.
> //
> *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
> - }
> - FreePool (Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
> - Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
> + };
>
> + //
> + // Free the buffer.
> + //
> + if (Rx4Token != NULL && Rx4Token->Packet.RxData != NULL &&
> Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
> + FreePool (Rx4Token->Packet.RxData-
> >FragmentTable[0].FragmentBuffer);
> + Rx4Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
> + Fragment.Bulk = NULL;
> + }
> +
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> + }
> } else {
> - Rx6Token = &HttpInstance->Rx6Token;
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer =
> AllocateZeroPool (DEF_BUF_LEN);
> - if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer ==
> NULL) {
> - Status = EFI_OUT_OF_RESOURCES;
> - return Status;
> + if (!HttpInstance->UseHttps) {
> + Rx6Token = &HttpInstance->Rx6Token;
> + Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer =
> AllocateZeroPool (DEF_BUF_LEN);
> + if (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer ==
> NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> }
>
> //
> // Receive the HTTP headers only when EFI_HTTP_RESPONSE_DATA is not
> NULL.
> //
> - while (*EndofHeader == NULL) {
> - HttpInstance->IsRxDone = FALSE;
> - Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength =
> DEF_BUF_LEN;
> - Status = Tcp6->Receive (Tcp6, Rx6Token);
> - if (EFI_ERROR (Status)) {
> - DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
> - return Status;
> - }
> -
> - while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> - Tcp6->Poll (Tcp6);
> + while (*EndofHeader == NULL) {
> + if (!HttpInstance->UseHttps) {
> + HttpInstance->IsRxDone = FALSE;
> + Rx6Token->Packet.RxData->DataLength = DEF_BUF_LEN;
> + Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength =
> DEF_BUF_LEN;
> + Status = Tcp6->Receive (Tcp6, Rx6Token);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
> + return Status;
> + }
> +
> + while (!HttpInstance->IsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> + Tcp6->Poll (Tcp6);
> + }
> +
> + if (!HttpInstance->IsRxDone) {
> + //
> + // Cancle the Token before close its Event.
> + //
> + Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
> + gBS->CloseEvent (Rx6Token->CompletionToken.Event);
> + Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
> + }
> +
> + Status = Rx6Token->CompletionToken.Status;
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Fragment.Len = Rx6Token->Packet.RxData-
> >FragmentTable[0].FragmentLength;
> + Fragment.Bulk = (UINT8 *) Rx6Token->Packet.RxData-
> >FragmentTable[0].FragmentBuffer;
> + } else {
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> + }
> +
> + Status = HttpsReceive (HttpInstance, &Fragment, Timeout);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "Tcp6 receive failed: %r\n", Status));
> + return Status;
> + }
> }
>
> - if (!HttpInstance->IsRxDone) {
> - //
> - // Cancle the Token before close its Event.
> - //
> - Tcp6->Cancel (HttpInstance->Tcp6, &Rx6Token->CompletionToken);
> - gBS->CloseEvent (Rx6Token->CompletionToken.Event);
> - Rx6Token->CompletionToken.Status = EFI_TIMEOUT;
> - }
> -
> - Status = Rx6Token->CompletionToken.Status;
> - if (EFI_ERROR (Status)) {
> - return Status;
> - }
> -
> //
> // Append the response string.
> //
> - *BufferSize = (*SizeofHeaders) + Rx6Token->Packet.RxData-
> >FragmentTable[0].FragmentLength;
> + *BufferSize = *SizeofHeaders + Fragment.Len;
> Buffer = AllocateZeroPool (*BufferSize);
> if (Buffer == NULL) {
> Status = EFI_OUT_OF_RESOURCES;
> return Status;
> }
> -
> +
> if (*HttpHeaders != NULL) {
> - CopyMem (Buffer, *HttpHeaders, (*SizeofHeaders));
> + CopyMem (Buffer, *HttpHeaders, *SizeofHeaders);
> FreePool (*HttpHeaders);
> }
> -
> +
> CopyMem (
> - Buffer + (*SizeofHeaders),
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer,
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentLength
> + Buffer + *SizeofHeaders,
> + Fragment.Bulk,
> + Fragment.Len
> );
> - *HttpHeaders = Buffer;
> - *SizeofHeaders = *BufferSize;
> -
> + *HttpHeaders = Buffer;
> + *SizeofHeaders = *BufferSize;
> +
> //
> // Check whether we received end of HTTP headers.
> //
> - *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
> -
> + *EndofHeader = AsciiStrStr (*HttpHeaders, HTTP_END_OF_HDR_STR);
> + };
> +
> + //
> + // Free the buffer.
> + //
> + if (Rx6Token != NULL && Rx6Token->Packet.RxData != NULL &&
> Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer != NULL) {
> + FreePool (Rx6Token->Packet.RxData-
> >FragmentTable[0].FragmentBuffer);
> + Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
> + Fragment.Bulk = NULL;
> + }
> +
> + if (Fragment.Bulk != NULL) {
> + FreePool (Fragment.Bulk);
> + Fragment.Bulk = NULL;
> }
> - FreePool (Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer);
> - Rx6Token->Packet.RxData->FragmentTable[0].FragmentBuffer = NULL;
> }
>
> //
> // Skip the CRLF after the HTTP headers.
> //
> diff --git a/NetworkPkg/HttpDxe/HttpProto.h
> b/NetworkPkg/HttpDxe/HttpProto.h
> index e1fd785..e3b3275 100644
> --- a/NetworkPkg/HttpDxe/HttpProto.h
> +++ b/NetworkPkg/HttpDxe/HttpProto.h
> @@ -81,10 +81,24 @@ typedef struct {
> BOOLEAN IsRxDone;
> UINTN BodyLen;
> EFI_HTTP_METHOD Method;
> } HTTP_TCP_TOKEN_WRAP;
>
> +typedef struct {
> + EFI_TLS_VERSION Version;
> + EFI_TLS_CONNECTION_END ConnectionEnd;
> + EFI_TLS_VERIFY VerifyMethod;
> + EFI_TLS_SESSION_STATE SessionState;
> +
> + VOID *CACert;
> + UINTN CACertSize;
> + VOID *ClientCert;
> + UINTN ClientCertSize;
> + VOID *ClientPrivateKey;
> + UINTN ClientPrivateKeySize;
> +} TLS_CONFIG_DATA;
> +
> typedef struct _HTTP_PROTOCOL {
> UINT32 Signature;
> EFI_HTTP_PROTOCOL Http;
> EFI_HANDLE Handle;
> HTTP_SERVICE *Service;
> @@ -151,10 +165,39 @@ typedef struct _HTTP_PROTOCOL {
>
> NET_MAP TxTokens;
> NET_MAP RxTokens;
>
> CHAR8 *Url;
> +
> + //
> + // Https Support
> + //
> + BOOLEAN UseHttps;
> +
> + EFI_HANDLE TlsChildHandle; /// Tls ChildHandle
> + TLS_CONFIG_DATA TlsConfigData;
> + EFI_TLS_PROTOCOL *Tls;
> + EFI_TLS_CONFIGURATION_PROTOCOL *TlsConfiguration;
> + EFI_TLS_SESSION_STATE TlsSessionState;
> +
> + //
> + // TlsTxData used for transmitting TLS related messages.
> + //
> + EFI_TCP4_IO_TOKEN Tcp4TlsTxToken;
> + EFI_TCP4_TRANSMIT_DATA Tcp4TlsTxData;
> + EFI_TCP6_IO_TOKEN Tcp6TlsTxToken;
> + EFI_TCP6_TRANSMIT_DATA Tcp6TlsTxData;
> + BOOLEAN TlsIsTxDone;
> +
> + //
> + // TlsRxData used for receiving TLS related messages.
> + //
> + EFI_TCP4_IO_TOKEN Tcp4TlsRxToken;
> + EFI_TCP4_RECEIVE_DATA Tcp4TlsRxData;
> + EFI_TCP6_IO_TOKEN Tcp6TlsRxToken;
> + EFI_TCP6_RECEIVE_DATA Tcp6TlsRxData;
> + BOOLEAN TlsIsRxDone;
> } HTTP_PROTOCOL;
>
> typedef struct {
> EFI_HTTP_TOKEN *HttpToken;
> HTTP_PROTOCOL *HttpInstance;
> @@ -350,11 +393,12 @@ HttpConfigureTcp6 (
> IN HTTP_PROTOCOL *HttpInstance,
> IN HTTP_TOKEN_WRAP *Wrap
> );
>
> /**
> - Check existing TCP connection, if in error state, receover TCP4 connection.
> + Check existing TCP connection, if in error state, recover TCP4 connection.
> Then,
> + connect one TLS session if required.
>
> @param[in] HttpInstance The HTTP instance private data.
>
> @retval EFI_SUCCESS The TCP connection is established.
> @retval EFI_NOT_READY TCP4 protocol child is not created or
> configured.
> @@ -365,11 +409,12 @@ EFI_STATUS
> HttpConnectTcp4 (
> IN HTTP_PROTOCOL *HttpInstance
> );
>
> /**
> - Check existing TCP connection, if in error state, recover TCP6 connection.
> + Check existing TCP connection, if in error state, recover TCP6 connection.
> Then,
> + connect one TLS session if required.
>
> @param[in] HttpInstance The HTTP instance private data.
>
> @retval EFI_SUCCESS The TCP connection is established.
> @retval EFI_NOT_READY TCP6 protocol child is not created or
> configured.
> @@ -380,11 +425,11 @@ EFI_STATUS
> HttpConnectTcp6 (
> IN HTTP_PROTOCOL *HttpInstance
> );
>
> /**
> - Send the HTTP message through TCP4 or TCP6.
> + Send the HTTP or HTTPS message through TCP4 or TCP6.
>
> @param[in] HttpInstance The HTTP instance private data.
> @param[in] Wrap The HTTP token's wrap data.
> @param[in] TxString Buffer containing the HTTP message string.
> @param[in] TxStringLen Length of the HTTP message string in bytes.
> @@ -441,29 +486,31 @@ HttpTcpNotReady (
> IN NET_MAP_ITEM *Item,
> IN VOID *Context
> );
>
> /**
> - Initialize TCP related data.
> + Initialize Http session.
>
> @param[in] HttpInstance The HTTP instance private data.
> @param[in] Wrap The HTTP token's wrap data.
> - @param[in] Configure The Flag indicates whether the first time to
> initialize Tcp.
> + @param[in] Configure The Flag indicates whether need to initialize
> session.
> + @param[in] TlsConfigure The Flag indicates whether it's the new Tls
> session.
>
> - @retval EFI_SUCCESS The initialization of TCP instance is done.
> + @retval EFI_SUCCESS The initialization of session is done.
> @retval Others Other error as indicated.
>
> **/
> EFI_STATUS
> -HttpInitTcp (
> +HttpInitSession (
> IN HTTP_PROTOCOL *HttpInstance,
> IN HTTP_TOKEN_WRAP *Wrap,
> - IN BOOLEAN Configure
> + IN BOOLEAN Configure,
> + IN BOOLEAN TlsConfigure
> );
>
> /**
> - Transmit the HTTP mssage by processing the associated HTTP token.
> + Transmit the HTTP or HTTPS mssage by processing the associated HTTP
> token.
>
> @param[in] Map The container of TxToken or Tx6Token.
> @param[in] Item Current item to check against.
> @param[in] Context The Token to check againist.
>
> diff --git a/NetworkPkg/HttpDxe/HttpsSupport.c
> b/NetworkPkg/HttpDxe/HttpsSupport.c
> new file mode 100644
> index 0000000..177b9a8
> --- /dev/null
> +++ b/NetworkPkg/HttpDxe/HttpsSupport.c
> @@ -0,0 +1,1692 @@
> +/** @file
> + Miscellaneous routines specific to Https for HttpDxe driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +(C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#include "HttpDriver.h"
> +
> +/**
> + Returns the first occurrence of a Null-terminated ASCII sub-string in a Null-
> terminated
> + ASCII string and ignore case during the search process.
> +
> + This function scans the contents of the ASCII string specified by String
> + and returns the first occurrence of SearchString and ignore case during the
> search process.
> + If SearchString is not found in String, then NULL is returned. If the length of
> SearchString
> + is zero, then String is returned.
> +
> + If String is NULL, then ASSERT().
> + If SearchString is NULL, then ASSERT().
> +
> + @param[in] String A pointer to a Null-terminated ASCII string.
> + @param[in] SearchString A pointer to a Null-terminated ASCII string to
> search for.
> +
> + @retval NULL If the SearchString does not appear in String.
> + @retval others If there is a match return the first occurrence of
> SearchingString.
> + If the length of SearchString is zero,return String.
> +
> +**/
> +CHAR8 *
> +AsciiStrCaseStr (
> + IN CONST CHAR8 *String,
> + IN CONST CHAR8 *SearchString
> + )
> +{
> + CONST CHAR8 *FirstMatch;
> + CONST CHAR8 *SearchStringTmp;
> +
> + CHAR8 Src;
> + CHAR8 Dst;
> +
> + //
> + // ASSERT both strings are less long than PcdMaximumAsciiStringLength
> + //
> + ASSERT (AsciiStrSize (String) != 0);
> + ASSERT (AsciiStrSize (SearchString) != 0);
> +
> + if (*SearchString == '\0') {
> + return (CHAR8 *) String;
> + }
> +
> + while (*String != '\0') {
> + SearchStringTmp = SearchString;
> + FirstMatch = String;
> +
> + while ((*SearchStringTmp != '\0')
> + && (*String != '\0')) {
> + Src = *String;
> + Dst = *SearchStringTmp;
> +
> + if ((Src >= 'A') && (Src <= 'Z')) {
> + Src -= ('A' - 'a');
> + }
> +
> + if ((Dst >= 'A') && (Dst <= 'Z')) {
> + Dst -= ('A' - 'a');
> + }
> +
> + if (Src != Dst) {
> + break;
> + }
> +
> + String++;
> + SearchStringTmp++;
> + }
> +
> + if (*SearchStringTmp == '\0') {
> + return (CHAR8 *) FirstMatch;
> + }
> +
> + String = FirstMatch + 1;
> + }
> +
> + return NULL;
> +}
> +
> +/**
> + The callback function to free the net buffer list.
> +
> + @param[in] Arg The opaque parameter.
> +
> +**/
> +VOID
> +EFIAPI
> +FreeNbufList (
> + IN VOID *Arg
> + )
> +{
> + ASSERT (Arg != NULL);
> +
> + NetbufFreeList ((LIST_ENTRY *) Arg);
> + FreePool (Arg);
> +}
> +
> +/**
> + Check whether the Url is from Https.
> +
> + @param[in] Url The pointer to a HTTP or HTTPS URL string.
> +
> + @retval TRUE The Url is from HTTPS.
> + @retval FALSE The Url is from HTTP.
> +
> +**/
> +BOOLEAN
> +IsHttpsUrl (
> + IN CHAR8 *Url
> + )
> +{
> + CHAR8 *Tmp;
> +
> + Tmp = NULL;
> +
> + Tmp = AsciiStrCaseStr (Url, HTTPS_FLAG);
> + if (Tmp != NULL && Tmp == Url) {
> + return TRUE;
> + }
> +
> + return FALSE;
> +}
> +
> +/**
> + Creates a Tls child handle, open EFI_TLS_PROTOCOL and
> EFI_TLS_CONFIGURATION_PROTOCOL.
> +
> + @param[in] ImageHandle The firmware allocated handle for the UEFI
> image.
> + @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[out] TlsConfiguration Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> +
> + @return The child handle with opened EFI_TLS_PROTOCOL and
> EFI_TLS_CONFIGURATION_PROTOCOL.
> +
> +**/
> +EFI_HANDLE
> +EFIAPI
> +TlsCreateChild (
> + IN EFI_HANDLE ImageHandle,
> + OUT EFI_TLS_PROTOCOL **TlsProto,
> + OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
> + )
> +{
> + EFI_STATUS Status;
> + EFI_SERVICE_BINDING_PROTOCOL *TlsSb;
> + EFI_HANDLE TlsChildHandle;
> +
> + TlsSb = NULL;
> + TlsChildHandle = 0;
> +
> + //
> + // Locate TlsServiceBinding protocol.
> + //
> + gBS->LocateProtocol (
> + &gEfiTlsServiceBindingProtocolGuid,
> + NULL,
> + (VOID **) &TlsSb
> + );
> + if (TlsSb == NULL) {
> + return NULL;
> + }
> +
> + Status = TlsSb->CreateChild (TlsSb, &TlsChildHandle);
> + if (EFI_ERROR (Status)) {
> + return NULL;
> + }
> +
> + Status = gBS->OpenProtocol (
> + TlsChildHandle,
> + &gEfiTlsProtocolGuid,
> + (VOID **) TlsProto,
> + ImageHandle,
> + TlsChildHandle,
> + EFI_OPEN_PROTOCOL_GET_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + TlsSb->DestroyChild (TlsSb, TlsChildHandle);
> + return NULL;
> + }
> +
> + Status = gBS->OpenProtocol (
> + TlsChildHandle,
> + &gEfiTlsConfigurationProtocolGuid,
> + (VOID **) TlsConfiguration,
> + ImageHandle,
> + TlsChildHandle,
> + EFI_OPEN_PROTOCOL_GET_PROTOCOL
> + );
> + if (EFI_ERROR (Status)) {
> + TlsSb->DestroyChild (TlsSb, TlsChildHandle);
> + return NULL;
> + }
> +
> + return TlsChildHandle;
> +}
> +
> +/**
> + Create event for the TLS receive and transmit tokens which are used to
> receive and
> + transmit TLS related messages.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> +
> + @retval EFI_SUCCESS The events are created successfully.
> + @retval others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCreateTxRxEvent (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + EFI_STATUS Status;
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + //
> + // For Tcp4TlsTxToken.
> + //
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + HttpCommonNotify,
> + &HttpInstance->TlsIsTxDone,
> + &HttpInstance->Tcp4TlsTxToken.CompletionToken.Event
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + HttpInstance->Tcp4TlsTxData.Push = TRUE;
> + HttpInstance->Tcp4TlsTxData.Urgent = FALSE;
> + HttpInstance->Tcp4TlsTxData.DataLength = 0;
> + HttpInstance->Tcp4TlsTxData.FragmentCount = 1;
> + HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentLength =
> HttpInstance->Tcp4TlsTxData.DataLength;
> + HttpInstance->Tcp4TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
> + HttpInstance->Tcp4TlsTxToken.Packet.TxData = &HttpInstance-
> >Tcp4TlsTxData;
> + HttpInstance->Tcp4TlsTxToken.CompletionToken.Status =
> EFI_NOT_READY;
> +
> + //
> + // For Tcp4TlsRxToken.
> + //
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + HttpCommonNotify,
> + &HttpInstance->TlsIsRxDone,
> + &HttpInstance->Tcp4TlsRxToken.CompletionToken.Event
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + HttpInstance->Tcp4TlsRxData.DataLength = 0;
> + HttpInstance->Tcp4TlsRxData.FragmentCount = 1;
> + HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentLength =
> HttpInstance->Tcp4TlsRxData.DataLength ;
> + HttpInstance->Tcp4TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
> + HttpInstance->Tcp4TlsRxToken.Packet.RxData = &HttpInstance-
> >Tcp4TlsRxData;
> + HttpInstance->Tcp4TlsRxToken.CompletionToken.Status =
> EFI_NOT_READY;
> + } else {
> + //
> + // For Tcp6TlsTxToken.
> + //
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + HttpCommonNotify,
> + &HttpInstance->TlsIsTxDone,
> + &HttpInstance->Tcp6TlsTxToken.CompletionToken.Event
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + HttpInstance->Tcp6TlsTxData.Push = TRUE;
> + HttpInstance->Tcp6TlsTxData.Urgent = FALSE;
> + HttpInstance->Tcp6TlsTxData.DataLength = 0;
> + HttpInstance->Tcp6TlsTxData.FragmentCount = 1;
> + HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentLength =
> HttpInstance->Tcp6TlsTxData.DataLength;
> + HttpInstance->Tcp6TlsTxData.FragmentTable[0].FragmentBuffer = NULL;
> + HttpInstance->Tcp6TlsTxToken.Packet.TxData = &HttpInstance-
> >Tcp6TlsTxData;
> + HttpInstance->Tcp6TlsTxToken.CompletionToken.Status =
> EFI_NOT_READY;
> +
> + //
> + // For Tcp6TlsRxToken.
> + //
> + Status = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_NOTIFY,
> + HttpCommonNotify,
> + &HttpInstance->TlsIsRxDone,
> + &HttpInstance->Tcp6TlsRxToken.CompletionToken.Event
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + HttpInstance->Tcp6TlsRxData.DataLength = 0;
> + HttpInstance->Tcp6TlsRxData.FragmentCount = 1;
> + HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentLength =
> HttpInstance->Tcp6TlsRxData.DataLength ;
> + HttpInstance->Tcp6TlsRxData.FragmentTable[0].FragmentBuffer = NULL;
> + HttpInstance->Tcp6TlsRxToken.Packet.RxData = &HttpInstance-
> >Tcp6TlsRxData;
> + HttpInstance->Tcp6TlsRxToken.CompletionToken.Status =
> EFI_NOT_READY;
> + }
> +
> + return Status;
> +
> +ERROR:
> + //
> + // Error handling
> + //
> + TlsCloseTxRxEvent (HttpInstance);
> +
> + return Status;
> +}
> +
> +/**
> + Close events in the TlsTxToken and TlsRxToken.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsCloseTxRxEvent (
> + IN HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + ASSERT (HttpInstance != NULL);
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + if (NULL != HttpInstance->Tcp4TlsTxToken.CompletionToken.Event) {
> + gBS->CloseEvent(HttpInstance-
> >Tcp4TlsTxToken.CompletionToken.Event);
> + HttpInstance->Tcp4TlsTxToken.CompletionToken.Event = NULL;
> + }
> +
> + if (NULL != HttpInstance->Tcp4TlsRxToken.CompletionToken.Event) {
> + gBS->CloseEvent (HttpInstance-
> >Tcp4TlsRxToken.CompletionToken.Event);
> + HttpInstance->Tcp4TlsRxToken.CompletionToken.Event = NULL;
> + }
> + } else {
> + if (NULL != HttpInstance->Tcp6TlsTxToken.CompletionToken.Event) {
> + gBS->CloseEvent(HttpInstance-
> >Tcp6TlsTxToken.CompletionToken.Event);
> + HttpInstance->Tcp6TlsTxToken.CompletionToken.Event = NULL;
> + }
> +
> + if (NULL != HttpInstance->Tcp6TlsRxToken.CompletionToken.Event) {
> + gBS->CloseEvent (HttpInstance-
> >Tcp6TlsRxToken.CompletionToken.Event);
> + HttpInstance->Tcp6TlsRxToken.CompletionToken.Event = NULL;
> + }
> + }
> +}
> +
> +/**
> + Read the TlsCaCertificate variable and configure it.
> +
> + @param[in, out] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS TlsCaCertificate is configured.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_NOT_FOUND Fail to get 'TlsCaCertificate' variable.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +TlsConfigCertificate (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 *CACert;
> + UINTN CACertSize;
> + UINT32 Index;
> + EFI_SIGNATURE_LIST *CertList;
> + EFI_SIGNATURE_DATA *Cert;
> + UINTN CertCount;
> + UINT32 ItemDataSize;
> +
> + CACert = (UINT8 *) HttpInstance->TlsConfigData.CACert;
> + CACertSize = HttpInstance->TlsConfigData.CACertSize;
> +
> + //
> + // Try to read the TlsCaCertificate variable.
> + //
> + CACertSize = 0;
> + Status = gRT->GetVariable (
> + EFI_TLS_CA_CERTIFICATE_VARIABLE,
> + &gEfiTlsCaCertificateGuid,
> + NULL,
> + &CACertSize,
> + NULL
> + );
> +
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + //
> + // Allocate buffer and read the config variable.
> + //
> + CACert = AllocatePool (CACertSize);
> + if (CACert == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = gRT->GetVariable (
> + EFI_TLS_CA_CERTIFICATE_VARIABLE,
> + &gEfiTlsCaCertificateGuid,
> + NULL,
> + &CACertSize,
> + CACert
> + );
> + if (EFI_ERROR (Status)) {
> + //
> + // GetVariable still error or the variable is corrupted.
> + // Fall back to the default value.
> + //
> + FreePool (CACert);
> +
> + return EFI_NOT_FOUND;
> + }
> + }
> +
> + //
> + // Enumerate all data and erasing the target item.
> + //
> + ItemDataSize = (UINT32) CACertSize;
> + CertList = (EFI_SIGNATURE_LIST *) CACert;
> + while ((ItemDataSize > 0) && (ItemDataSize >= CertList->SignatureListSize))
> {
> + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof
> (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
> + CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) -
> CertList->SignatureHeaderSize) / CertList->SignatureSize;
> + for (Index = 0; Index < CertCount; Index++) {
> + //
> + // EfiTlsConfigDataTypeCACertificate
> + //
> + Status = HttpInstance->TlsConfiguration->SetData (
> + HttpInstance->TlsConfiguration,
> + EfiTlsConfigDataTypeCACertificate,
> + Cert->SignatureData,
> + CertList->SignatureSize - sizeof (Cert-
> >SignatureOwner)
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList-
> >SignatureSize);
> + }
> +
> + ItemDataSize -= CertList->SignatureListSize;
> + CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList-
> >SignatureListSize);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Configure TLS session data.
> +
> + @param[in, out] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS TLS session data is configured.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigureSession (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + EFI_STATUS Status;
> +
> + //
> + // TlsConfigData initialization
> + //
> + HttpInstance->TlsConfigData.ConnectionEnd = EfiTlsClient;
> + HttpInstance->TlsConfigData.VerifyMethod = EFI_TLS_VERIFY_PEER;
> + HttpInstance->TlsConfigData.SessionState = EfiTlsSessionNotStarted;
> +
> + //
> + // EfiTlsConnectionEnd,
> + // EfiTlsVerifyMethod
> + // EfiTlsSessionState
> + //
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsConnectionEnd,
> + &(HttpInstance->TlsConfigData.ConnectionEnd),
> + sizeof (EFI_TLS_CONNECTION_END)
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsVerifyMethod,
> + &HttpInstance->TlsConfigData.VerifyMethod,
> + sizeof (EFI_TLS_VERIFY)
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + &(HttpInstance->TlsConfigData.SessionState),
> + sizeof (EFI_TLS_SESSION_STATE)
> + );
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + //
> + // Tls Config Certificate
> + //
> + Status = TlsConfigCertificate (HttpInstance);
> + if (EFI_ERROR (Status)) {
> + DEBUG ((EFI_D_ERROR, "TLS Certificate Config Error!\n"));
> + goto ERROR;
> + }
> +
> + //
> + // TlsCreateTxRxEvent
> + //
> + Status = TlsCreateTxRxEvent (HttpInstance);
> + if (EFI_ERROR (Status)) {
> + goto ERROR;
> + }
> +
> + return Status;
> +
> +ERROR:
> + TlsCloseTxRxEvent (HttpInstance);
> +
> + return Status;
> +}
> +
> +/**
> + Transmit the Packet by processing the associated HTTPS token.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Packet The packet to transmit.
> +
> + @retval EFI_SUCCESS The packet is transmitted.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_DEVICE_ERROR An unexpected system or network error
> occurred.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCommonTransmit (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + IN NET_BUF *Packet
> + )
> +{
> + EFI_STATUS Status;
> + VOID *Data;
> + UINTN Size;
> +
> + if ((HttpInstance == NULL) || (Packet == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + Size = sizeof (EFI_TCP4_TRANSMIT_DATA) +
> + (Packet->BlockOpNum - 1) * sizeof (EFI_TCP4_FRAGMENT_DATA);
> + } else {
> + Size = sizeof (EFI_TCP6_TRANSMIT_DATA) +
> + (Packet->BlockOpNum - 1) * sizeof (EFI_TCP6_FRAGMENT_DATA);
> + }
> +
> + Data = AllocatePool (Size);
> + if (Data == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + ((EFI_TCP4_TRANSMIT_DATA *) Data)->Push = TRUE;
> + ((EFI_TCP4_TRANSMIT_DATA *) Data)->Urgent = FALSE;
> + ((EFI_TCP4_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
> +
> + //
> + // Build the fragment table.
> + //
> + ((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount = Packet-
> >BlockOpNum;
> +
> + NetbufBuildExt (
> + Packet,
> + (NET_FRAGMENT *) &((EFI_TCP4_TRANSMIT_DATA *) Data)-
> >FragmentTable[0],
> + &((EFI_TCP4_TRANSMIT_DATA *) Data)->FragmentCount
> + );
> +
> + HttpInstance->Tcp4TlsTxToken.Packet.TxData =
> (EFI_TCP4_TRANSMIT_DATA *) Data;
> +
> + Status = EFI_DEVICE_ERROR;
> +
> + //
> + // Transmit the packet.
> + //
> + Status = HttpInstance->Tcp4->Transmit (HttpInstance->Tcp4,
> &HttpInstance->Tcp4TlsTxToken);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + while (!HttpInstance->TlsIsTxDone) {
> + HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
> + }
> +
> + HttpInstance->TlsIsTxDone = FALSE;
> + Status = HttpInstance->Tcp4TlsTxToken.CompletionToken.Status;
> + } else {
> + ((EFI_TCP6_TRANSMIT_DATA *) Data)->Push = TRUE;
> + ((EFI_TCP6_TRANSMIT_DATA *) Data)->Urgent = FALSE;
> + ((EFI_TCP6_TRANSMIT_DATA *) Data)->DataLength = Packet->TotalSize;
> +
> + //
> + // Build the fragment table.
> + //
> + ((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount = Packet-
> >BlockOpNum;
> +
> + NetbufBuildExt (
> + Packet,
> + (NET_FRAGMENT *) &((EFI_TCP6_TRANSMIT_DATA *) Data)-
> >FragmentTable[0],
> + &((EFI_TCP6_TRANSMIT_DATA *) Data)->FragmentCount
> + );
> +
> + HttpInstance->Tcp6TlsTxToken.Packet.TxData =
> (EFI_TCP6_TRANSMIT_DATA *) Data;
> +
> + Status = EFI_DEVICE_ERROR;
> +
> + //
> + // Transmit the packet.
> + //
> + Status = HttpInstance->Tcp6->Transmit (HttpInstance->Tcp6,
> &HttpInstance->Tcp6TlsTxToken);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + while (!HttpInstance->TlsIsTxDone) {
> + HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
> + }
> +
> + HttpInstance->TlsIsTxDone = FALSE;
> + Status = HttpInstance->Tcp6TlsTxToken.CompletionToken.Status;
> + }
> +
> +ON_EXIT:
> + FreePool (Data);
> +
> + return Status;
> +}
> +
> +/**
> + Receive the Packet by processing the associated HTTPS token.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Packet The packet to transmit.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS The Packet is received.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_TIMEOUT The operation is time out.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCommonReceive (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + IN NET_BUF *Packet,
> + IN EFI_EVENT Timeout
> + )
> +{
> + EFI_TCP4_RECEIVE_DATA *Tcp4RxData;
> + EFI_TCP6_RECEIVE_DATA *Tcp6RxData;
> + EFI_STATUS Status;
> + NET_FRAGMENT *Fragment;
> + UINT32 FragmentCount;
> + UINT32 CurrentFragment;
> +
> + Tcp4RxData = NULL;
> + Tcp6RxData = NULL;
> +
> + if ((HttpInstance == NULL) || (Packet == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + FragmentCount = Packet->BlockOpNum;
> + Fragment = AllocatePool (FragmentCount * sizeof (NET_FRAGMENT));
> + if (Fragment == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Build the fragment table.
> + //
> + NetbufBuildExt (Packet, Fragment, &FragmentCount);
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + Tcp4RxData = HttpInstance->Tcp4TlsRxToken.Packet.RxData;
> + if (Tcp4RxData == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + Tcp4RxData->FragmentCount = 1;
> + } else {
> + Tcp6RxData = HttpInstance->Tcp6TlsRxToken.Packet.RxData;
> + if (Tcp6RxData == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> + Tcp6RxData->FragmentCount = 1;
> + }
> +
> + CurrentFragment = 0;
> + Status = EFI_SUCCESS;
> +
> + while (CurrentFragment < FragmentCount) {
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + Tcp4RxData->DataLength = Fragment[CurrentFragment].Len;
> + Tcp4RxData->FragmentTable[0].FragmentLength =
> Fragment[CurrentFragment].Len;
> + Tcp4RxData->FragmentTable[0].FragmentBuffer =
> Fragment[CurrentFragment].Bulk;
> + Status = HttpInstance->Tcp4->Receive (HttpInstance->Tcp4,
> &HttpInstance->Tcp4TlsRxToken);
> + } else {
> + Tcp6RxData->DataLength = Fragment[CurrentFragment].Len;
> + Tcp6RxData->FragmentTable[0].FragmentLength =
> Fragment[CurrentFragment].Len;
> + Tcp6RxData->FragmentTable[0].FragmentBuffer =
> Fragment[CurrentFragment].Bulk;
> + Status = HttpInstance->Tcp6->Receive (HttpInstance->Tcp6,
> &HttpInstance->Tcp6TlsRxToken);
> + }
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + while (!HttpInstance->TlsIsRxDone && ((Timeout == NULL) || EFI_ERROR
> (gBS->CheckEvent (Timeout)))) {
> + //
> + // Poll until some data is received or an error occurs.
> + //
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + HttpInstance->Tcp4->Poll (HttpInstance->Tcp4);
> + } else {
> + HttpInstance->Tcp6->Poll (HttpInstance->Tcp6);
> + }
> + }
> +
> + if (!HttpInstance->TlsIsRxDone) {
> + //
> + // Timeout occurs, cancel the receive request.
> + //
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + HttpInstance->Tcp4->Cancel (HttpInstance->Tcp4, &HttpInstance-
> >Tcp4TlsRxToken.CompletionToken);
> + } else {
> + HttpInstance->Tcp6->Cancel (HttpInstance->Tcp6, &HttpInstance-
> >Tcp6TlsRxToken.CompletionToken);
> + }
> +
> + Status = EFI_TIMEOUT;
> + goto ON_EXIT;
> + } else {
> + HttpInstance->TlsIsRxDone = FALSE;
> + }
> +
> + if (!HttpInstance->LocalAddressIsIPv6) {
> + Status = HttpInstance->Tcp4TlsRxToken.CompletionToken.Status;
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + Fragment[CurrentFragment].Len -= Tcp4RxData-
> >FragmentTable[0].FragmentLength;
> + if (Fragment[CurrentFragment].Len == 0) {
> + CurrentFragment++;
> + } else {
> + Fragment[CurrentFragment].Bulk += Tcp4RxData-
> >FragmentTable[0].FragmentLength;
> + }
> + } else {
> + Status = HttpInstance->Tcp6TlsRxToken.CompletionToken.Status;
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + Fragment[CurrentFragment].Len -= Tcp6RxData-
> >FragmentTable[0].FragmentLength;
> + if (Fragment[CurrentFragment].Len == 0) {
> + CurrentFragment++;
> + } else {
> + Fragment[CurrentFragment].Bulk += Tcp6RxData-
> >FragmentTable[0].FragmentLength;
> + }
> + }
> + }
> +
> +ON_EXIT:
> +
> + if (Fragment != NULL) {
> + FreePool (Fragment);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
> + corresponding record data. This two parts will be put into two blocks of
> buffers in the
> + net buffer.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[out] Pdu The received TLS PDU.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS An TLS PDU is received.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsReceiveOnePdu (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + OUT NET_BUF **Pdu,
> + IN EFI_EVENT Timeout
> + )
> +{
> + EFI_STATUS Status;
> +
> + LIST_ENTRY *NbufList;
> +
> + UINT32 Len;
> +
> + NET_BUF *PduHdr;
> + UINT8 *Header;
> + TLS_RECORD_HEADER RecordHeader;
> +
> + NET_BUF *DataSeg;
> +
> + NbufList = NULL;
> + PduHdr = NULL;
> + Header = NULL;
> + DataSeg = NULL;
> +
> + NbufList = AllocatePool (sizeof (LIST_ENTRY));
> + if (NbufList == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + InitializeListHead (NbufList);
> +
> + //
> + // Allocate buffer to receive one TLS header.
> + //
> + Len = sizeof (TLS_RECORD_HEADER);
> + PduHdr = NetbufAlloc (Len);
> + if (PduHdr == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + Header = NetbufAllocSpace (PduHdr, Len, NET_BUF_TAIL);
> + if (Header == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // First step, receive one TLS header.
> + //
> + Status = TlsCommonReceive (HttpInstance, PduHdr, Timeout);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + RecordHeader = *(TLS_RECORD_HEADER *) Header;
> + if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_HANDSHAKE ||
> + RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT ||
> + RecordHeader.ContentType ==
> TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC ||
> + RecordHeader.ContentType ==
> TLS_CONTENT_TYPE_APPLICATION_DATA) &&
> + (RecordHeader.Version.Major == 0x03) && /// Major versions are same.
> + (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor ==TLS11_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
> + ) {
> + InsertTailList (NbufList, &PduHdr->List);
> + } else {
> + Status = EFI_PROTOCOL_ERROR;
> + goto ON_EXIT;
> + }
> +
> + Len = SwapBytes16(RecordHeader.Length);
> + if (Len == 0) {
> + //
> + // No TLS payload.
> + //
> + goto FORM_PDU;
> + }
> +
> + //
> + // Allocate buffer to receive one TLS payload.
> + //
> + DataSeg = NetbufAlloc (Len);
> + if (DataSeg == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + NetbufAllocSpace (DataSeg, Len, NET_BUF_TAIL);
> +
> + //
> + // Second step, receive one TLS payload.
> + //
> + Status = TlsCommonReceive (HttpInstance, DataSeg, Timeout);
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + InsertTailList (NbufList, &DataSeg->List);
> +
> +FORM_PDU:
> + //
> + // Form the PDU from a list of PDU.
> + //
> + *Pdu = NetbufFromBufList (NbufList, 0, 0, FreeNbufList, NbufList);
> + if (*Pdu == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + }
> +
> +ON_EXIT:
> +
> + if (EFI_ERROR (Status)) {
> + //
> + // Free the Nbufs in this NbufList and the NbufList itself.
> + //
> + FreeNbufList (NbufList);
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Connect one TLS session by finishing the TLS handshake process.
> +
> + @param[in] HttpInstance The HTTP instance private data.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS The TLS session is established.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConnectSession (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN EFI_EVENT Timeout
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 *BufferOut;
> + UINTN BufferOutSize;
> + NET_BUF *PacketOut;
> + UINT8 *DataOut;
> + NET_BUF *Pdu;
> + UINT8 *BufferIn;
> + UINTN BufferInSize;
> + UINT8 *GetSessionDataBuffer;
> + UINTN GetSessionDataBufferSize;
> +
> + BufferOut = NULL;
> + PacketOut = NULL;
> + DataOut = NULL;
> + Pdu = NULL;
> + BufferIn = NULL;
> +
> + //
> + // Initialize TLS state.
> + //
> + HttpInstance->TlsSessionState = EfiTlsSessionNotStarted;
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + &(HttpInstance->TlsSessionState),
> + sizeof (EFI_TLS_SESSION_STATE)
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + //
> + // Create ClientHello
> + //
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + FreePool (BufferOut);
> + return Status;
> + }
> +
> + //
> + // Transmit ClientHello
> + //
> + PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + FreePool (BufferOut);
> + NetbufFree (PacketOut);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + while(HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring && \
> + ((Timeout == NULL) || EFI_ERROR (gBS->CheckEvent (Timeout)))) {
> + //
> + // Receive one TLS record.
> + //
> + Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + BufferInSize = Pdu->TotalSize;
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + NetbufFree (Pdu);
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + NetbufCopy (Pdu, 0, (UINT32)BufferInSize, BufferIn);
> +
> + NetbufFree (Pdu);
> +
> + //
> + // Handle Receive data.
> + //
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + BufferIn,
> + BufferInSize,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + BufferIn,
> + BufferInSize,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> +
> + FreePool (BufferIn);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + if (BufferOutSize != 0) {
> + //
> + // Transmit the response packet.
> + //
> + PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> +
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + NetbufFree (PacketOut);
> +
> + if (EFI_ERROR (Status)) {
> + FreePool (BufferOut);
> + return Status;
> + }
> + }
> +
> + FreePool (BufferOut);
> +
> + //
> + // Get the session state, then decide whether need to continue handle
> received packet.
> + //
> + GetSessionDataBufferSize = DEF_BUF_LEN;
> + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
> + if (GetSessionDataBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->GetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + GetSessionDataBuffer,
> + &GetSessionDataBufferSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (GetSessionDataBuffer);
> + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
> + if (GetSessionDataBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->GetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + GetSessionDataBuffer,
> + &GetSessionDataBufferSize
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + FreePool(GetSessionDataBuffer);
> + return Status;
> + }
> +
> + ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
> + HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *)
> GetSessionDataBuffer;
> +
> + FreePool (GetSessionDataBuffer);
> +
> + if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
> + return EFI_ABORTED;
> + }
> + }
> +
> + if (HttpInstance->TlsSessionState != EfiTlsSessionDataTransferring) {
> + Status = EFI_ABORTED;
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Close the TLS session and send out the close notification message.
> +
> + @param[in] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS The TLS session is closed.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCloseSession (
> + IN HTTP_PROTOCOL *HttpInstance
> + )
> +{
> + EFI_STATUS Status;
> +
> + UINT8 *BufferOut;
> + UINTN BufferOutSize;
> +
> + NET_BUF *PacketOut;
> + UINT8 *DataOut;
> +
> + Status = EFI_SUCCESS;
> + BufferOut = NULL;
> + PacketOut = NULL;
> + DataOut = NULL;
> +
> + if (HttpInstance == NULL) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + HttpInstance->TlsSessionState = EfiTlsSessionClosing;
> +
> + Status = HttpInstance->Tls->SetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + &(HttpInstance->TlsSessionState),
> + sizeof (EFI_TLS_SESSION_STATE)
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> +
> + if (EFI_ERROR (Status)) {
> + FreePool (BufferOut);
> + return Status;
> + }
> +
> + PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> +
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + FreePool (BufferOut);
> + NetbufFree (PacketOut);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Process one message according to the CryptMode.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Message Pointer to the message buffer needed to
> processed.
> + @param[in] MessageSize Pointer to the message buffer size.
> + @param[in] ProcessMode Process mode.
> + @param[in, out] Fragment Only one Fragment returned after the
> Message is
> + processed successfully.
> +
> + @retval EFI_SUCCESS Message is processed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessMessage (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN UINT8 *Message,
> + IN UINTN MessageSize,
> + IN EFI_TLS_CRYPT_MODE ProcessMode,
> + IN OUT NET_FRAGMENT *Fragment
> + )
> +{
> + EFI_STATUS Status;
> + UINT8 *Buffer;
> + UINT32 BufferSize;
> + UINT32 BytesCopied;
> + EFI_TLS_FRAGMENT_DATA *FragmentTable;
> + UINT32 FragmentCount;
> + EFI_TLS_FRAGMENT_DATA *OriginalFragmentTable;
> + UINTN Index;
> +
> + Status = EFI_SUCCESS;
> + Buffer = NULL;
> + BufferSize = 0;
> + BytesCopied = 0;
> + FragmentTable = NULL;
> + OriginalFragmentTable = NULL;
> +
> + //
> + // Rebuild fragment table from BufferIn.
> + //
> + FragmentCount = 1;
> + FragmentTable = AllocateZeroPool (FragmentCount * sizeof
> (EFI_TLS_FRAGMENT_DATA));
> + if (FragmentTable == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + FragmentTable->FragmentLength = (UINT32) MessageSize;
> + FragmentTable->FragmentBuffer = Message;
> +
> + //
> + // Record the original FragmentTable.
> + //
> + OriginalFragmentTable = FragmentTable;
> +
> + //
> + // Process the Message.
> + //
> + Status = HttpInstance->Tls->ProcessPacket (
> + HttpInstance->Tls,
> + &FragmentTable,
> + &FragmentCount,
> + ProcessMode
> + );
> + if (EFI_ERROR (Status)) {
> + goto ON_EXIT;
> + }
> +
> + //
> + // Calculate the size according to FragmentTable.
> + //
> + for (Index = 0; Index < FragmentCount; Index++) {
> + BufferSize += FragmentTable[Index].FragmentLength;
> + }
> +
> + //
> + // Allocate buffer for processed data.
> + //
> + Buffer = AllocateZeroPool (BufferSize);
> + if (Buffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + goto ON_EXIT;
> + }
> +
> + //
> + // Copy the new FragmentTable buffer into Buffer.
> + //
> + for (Index = 0; Index < FragmentCount; Index++) {
> + CopyMem (
> + (Buffer + BytesCopied),
> + FragmentTable[Index].FragmentBuffer,
> + FragmentTable[Index].FragmentLength
> + );
> + BytesCopied += FragmentTable[Index].FragmentLength;
> +
> + //
> + // Free the FragmentBuffer since it has been copied.
> + //
> + FreePool (FragmentTable[Index].FragmentBuffer);
> + }
> +
> + Fragment->Len = BufferSize;
> + Fragment->Bulk = Buffer;
> +
> +ON_EXIT:
> +
> + if (OriginalFragmentTable != NULL) {
> + FreePool (OriginalFragmentTable);
> + OriginalFragmentTable = NULL;
> + }
> +
> + //
> + // Caller has the responsibility to free the FragmentTable.
> + //
> + if (FragmentTable != NULL) {
> + FreePool (FragmentTable);
> + FragmentTable = NULL;
> + }
> +
> + return Status;
> +}
> +
> +/**
> + Receive one fragment decrypted from one TLS record.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in, out] Fragment The received Fragment.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS One fragment is received.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED Something wrong decryption the message.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +HttpsReceive (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN OUT NET_FRAGMENT *Fragment,
> + IN EFI_EVENT Timeout
> + )
> +{
> + EFI_STATUS Status;
> + NET_BUF *Pdu;
> + TLS_RECORD_HEADER RecordHeader;
> + UINT8 *BufferIn;
> + UINTN BufferInSize;
> + NET_FRAGMENT TempFragment;
> + UINT8 *BufferOut;
> + UINTN BufferOutSize;
> + NET_BUF *PacketOut;
> + UINT8 *DataOut;
> + UINT8 *GetSessionDataBuffer;
> + UINTN GetSessionDataBufferSize;
> +
> + Status = EFI_SUCCESS;
> + Pdu = NULL;
> + BufferIn = NULL;
> + BufferInSize = 0;
> + BufferOut = NULL;
> + BufferOutSize = 0;
> + PacketOut = NULL;
> + DataOut = NULL;
> + GetSessionDataBuffer = NULL;
> + GetSessionDataBufferSize = 0;
> +
> + //
> + // Receive only one TLS record
> + //
> + Status = TlsReceiveOnePdu (HttpInstance, &Pdu, Timeout);
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + BufferInSize = Pdu->TotalSize;
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + NetbufFree (Pdu);
> + return Status;
> + }
> +
> + NetbufCopy (Pdu, 0, (UINT32) BufferInSize, BufferIn);
> +
> + NetbufFree (Pdu);
> +
> + //
> + // Handle Receive data.
> + //
> + RecordHeader = *(TLS_RECORD_HEADER *) BufferIn;
> +
> + if ((RecordHeader.ContentType ==
> TLS_CONTENT_TYPE_APPLICATION_DATA) &&
> + (RecordHeader.Version.Major == 0x03) &&
> + (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
> + ) {
> + //
> + // Decrypt Packet.
> + //
> + Status = TlsProcessMessage (
> + HttpInstance,
> + BufferIn,
> + BufferInSize,
> + EfiTlsDecrypt,
> + &TempFragment
> + );
> +
> + FreePool (BufferIn);
> +
> + if (EFI_ERROR (Status)) {
> + if (Status == EFI_ABORTED) {
> + //
> + // Something wrong decryption the message.
> + // BuildResponsePacket() will be called to generate Error Alert message
> and send it out.
> + //
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + NULL,
> + 0,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + FreePool(BufferOut);
> + return Status;
> + }
> +
> + if (BufferOutSize != 0) {
> + PacketOut = NetbufAlloc ((UINT32)BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> +
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + NetbufFree (PacketOut);
> + }
> +
> + FreePool(BufferOut);
> +
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + return EFI_ABORTED;
> + }
> +
> + return Status;
> + }
> +
> + //
> + // Parsing buffer.
> + //
> + ASSERT (((TLS_RECORD_HEADER *) (TempFragment.Bulk))->ContentType
> == TLS_CONTENT_TYPE_APPLICATION_DATA);
> +
> + BufferInSize = ((TLS_RECORD_HEADER *) (TempFragment.Bulk))->Length;
> + BufferIn = AllocateZeroPool (BufferInSize);
> + if (BufferIn == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + CopyMem (BufferIn, TempFragment.Bulk + sizeof
> (TLS_RECORD_HEADER), BufferInSize);
> +
> + //
> + // Free the buffer in TempFragment.
> + //
> + FreePool (TempFragment.Bulk);
> +
> + } else if ((RecordHeader.ContentType == TLS_CONTENT_TYPE_ALERT) &&
> + (RecordHeader.Version.Major == 0x03) &&
> + (RecordHeader.Version.Minor == TLS10_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS11_PROTOCOL_VERSION_MINOR ||
> + RecordHeader.Version.Minor == TLS12_PROTOCOL_VERSION_MINOR)
> + ) {
> + BufferOutSize = DEF_BUF_LEN;
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + BufferIn,
> + BufferInSize,
> + BufferOut,
> + &BufferOutSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (BufferOut);
> + BufferOut = AllocateZeroPool (BufferOutSize);
> + if (BufferOut == NULL) {
> + FreePool (BufferIn);
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->BuildResponsePacket (
> + HttpInstance->Tls,
> + BufferIn,
> + BufferInSize,
> + BufferOut,
> + &BufferOutSize
> + );
> + }
> +
> + FreePool (BufferIn);
> +
> + if (EFI_ERROR (Status)) {
> + FreePool (BufferOut);
> + return Status;
> + }
> +
> + if (BufferOutSize != 0) {
> + PacketOut = NetbufAlloc ((UINT32) BufferOutSize);
> + DataOut = NetbufAllocSpace (PacketOut, (UINT32) BufferOutSize,
> NET_BUF_TAIL);
> + CopyMem (DataOut, BufferOut, BufferOutSize);
> +
> + Status = TlsCommonTransmit (HttpInstance, PacketOut);
> +
> + NetbufFree (PacketOut);
> + }
> +
> + FreePool (BufferOut);
> +
> + //
> + // Get the session state.
> + //
> + GetSessionDataBufferSize = DEF_BUF_LEN;
> + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
> + if (GetSessionDataBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->GetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + GetSessionDataBuffer,
> + &GetSessionDataBufferSize
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + FreePool (GetSessionDataBuffer);
> + GetSessionDataBuffer = AllocateZeroPool (GetSessionDataBufferSize);
> + if (GetSessionDataBuffer == NULL) {
> + Status = EFI_OUT_OF_RESOURCES;
> + return Status;
> + }
> +
> + Status = HttpInstance->Tls->GetSessionData (
> + HttpInstance->Tls,
> + EfiTlsSessionState,
> + GetSessionDataBuffer,
> + &GetSessionDataBufferSize
> + );
> + }
> + if (EFI_ERROR (Status)) {
> + FreePool (GetSessionDataBuffer);
> + return Status;
> + }
> +
> + ASSERT(GetSessionDataBufferSize == sizeof (EFI_TLS_SESSION_STATE));
> + HttpInstance->TlsSessionState = *(EFI_TLS_SESSION_STATE *)
> GetSessionDataBuffer;
> +
> + FreePool (GetSessionDataBuffer);
> +
> + if(HttpInstance->TlsSessionState == EfiTlsSessionError) {
> + DEBUG ((EFI_D_ERROR, "TLS Session State Error!\n"));
> + return EFI_ABORTED;
> + }
> +
> + BufferIn = NULL;
> + BufferInSize = 0;
> + }
> +
> + Fragment->Bulk = BufferIn;
> + Fragment->Len = (UINT32) BufferInSize;
> +
> + return Status;
> +}
> diff --git a/NetworkPkg/HttpDxe/HttpsSupport.h
> b/NetworkPkg/HttpDxe/HttpsSupport.h
> new file mode 100644
> index 0000000..d846b76
> --- /dev/null
> +++ b/NetworkPkg/HttpDxe/HttpsSupport.h
> @@ -0,0 +1,260 @@
> +/** @file
> + The header files of miscellaneous routines specific to Https for HttpDxe
> driver.
> +
> +Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
> +This program and the accompanying materials
> +are licensed and made available under the terms and conditions of the BSD
> License
> +which accompanies this distribution. The full text of the license may be
> found at
> +http://opensource.org/licenses/bsd-license.php
> +
> +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> +
> +**/
> +
> +#ifndef __EFI_HTTPS_SUPPORT_H__
> +#define __EFI_HTTPS_SUPPORT_H__
> +
> +#define HTTPS_DEFAULT_PORT 443
> +
> +#define HTTPS_FLAG "https"
> +
> +/**
> + Check whether the Url is from Https.
> +
> + @param[in] Url The pointer to a HTTP or HTTPS URL string.
> +
> + @retval TRUE The Url is from HTTPS.
> + @retval FALSE The Url is from HTTP.
> +
> +**/
> +BOOLEAN
> +IsHttpsUrl (
> + IN CHAR8 *Url
> + );
> +
> +/**
> + Creates a Tls child handle, open EFI_TLS_PROTOCOL and
> EFI_TLS_CONFIGURATION_PROTOCOL.
> +
> + @param[in] ImageHandle The firmware allocated handle for the UEFI
> image.
> + @param[out] TlsProto Pointer to the EFI_TLS_PROTOCOL instance.
> + @param[out] TlsConfiguration Pointer to the
> EFI_TLS_CONFIGURATION_PROTOCOL instance.
> +
> + @return The child handle with opened EFI_TLS_PROTOCOL and
> EFI_TLS_CONFIGURATION_PROTOCOL.
> +
> +**/
> +EFI_HANDLE
> +EFIAPI
> +TlsCreateChild (
> + IN EFI_HANDLE ImageHandle,
> + OUT EFI_TLS_PROTOCOL **TlsProto,
> + OUT EFI_TLS_CONFIGURATION_PROTOCOL **TlsConfiguration
> + );
> +
> +/**
> + Create event for the TLS receive and transmit tokens which are used to
> receive and
> + transmit TLS related messages.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> +
> + @retval EFI_SUCCESS The events are created successfully.
> + @retval others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCreateTxRxEvent (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Close events in the TlsTxToken and TlsRxToken.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> +
> +**/
> +VOID
> +EFIAPI
> +TlsCloseTxRxEvent (
> + IN HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Read the TlsCaCertificate variable and configure it.
> +
> + @param[in, out] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS TlsCaCertificate is configured.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_NOT_FOUND Fail to get "TlsCaCertificate" variable.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +TlsConfigCertificate (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Configure TLS session data.
> +
> + @param[in, out] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS TLS session data is configured.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConfigureSession (
> + IN OUT HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Transmit the Packet by processing the associated HTTPS token.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Packet The packet to transmit.
> +
> + @retval EFI_SUCCESS The packet is transmitted.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_DEVICE_ERROR An unexpected system or network error
> occurred.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCommonTransmit (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + IN NET_BUF *Packet
> + );
> +
> +/**
> + Receive the Packet by processing the associated HTTPS token.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Packet The packet to transmit.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS The Packet is received.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_TIMEOUT The operation is time out.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCommonReceive (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + IN NET_BUF *Packet,
> + IN EFI_EVENT Timeout
> + );
> +
> +/**
> + Receive one TLS PDU. An TLS PDU contains an TLS record header and it's
> + corresponding record data. The two parts will be put into two blocks of
> buffers in the
> + net buffer.
> +
> + @param[in, out] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[out] Pdu The received TLS PDU.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS An TLS PDU is received.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_PROTOCOL_ERROR An unexpected TLS packet was received.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsReceiveOnePdu (
> + IN OUT HTTP_PROTOCOL *HttpInstance,
> + OUT NET_BUF **Pdu,
> + IN EFI_EVENT Timeout
> + );
> +
> +/**
> + Connect one TLS session by finishing the TLS handshake process.
> +
> + @param[in] HttpInstance The HTTP instance private data.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS The TLS session is established.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED TLS session state is incorrect.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsConnectSession (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN EFI_EVENT Timeout
> + );
> +
> +/**
> + Close the TLS session and send out the close notification message.
> +
> + @param[in] HttpInstance The HTTP instance private data.
> +
> + @retval EFI_SUCCESS The TLS session is closed.
> + @retval EFI_INVALID_PARAMETER HttpInstance is NULL or Packet is NULL.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval Others Other error as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsCloseSession (
> + IN HTTP_PROTOCOL *HttpInstance
> + );
> +
> +/**
> + Process one message according to the CryptMode.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in] Message Pointer to the message buffer needed to
> processed.
> + @param[in] MessageSize Pointer to the message buffer size.
> + @param[in] ProcessMode Process mode.
> + @param[in, out] Fragment Only one Fragment returned after the
> Message is
> + processed successfully.
> +
> + @retval EFI_SUCCESS Message is processed successfully.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +TlsProcessMessage (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN UINT8 *Message,
> + IN UINTN MessageSize,
> + IN EFI_TLS_CRYPT_MODE ProcessMode,
> + IN OUT NET_FRAGMENT *Fragment
> + );
> +
> +/**
> + Receive one fragment decrypted from one TLS record.
> +
> + @param[in] HttpInstance Pointer to HTTP_PROTOCOL structure.
> + @param[in, out] Fragment The received Fragment.
> + @param[in] Timeout The time to wait for connection done.
> +
> + @retval EFI_SUCCESS One fragment is received.
> + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resources.
> + @retval EFI_ABORTED Something wrong decryption the message.
> + @retval Others Other errors as indicated.
> +
> +**/
> +EFI_STATUS
> +EFIAPI
> +HttpsReceive (
> + IN HTTP_PROTOCOL *HttpInstance,
> + IN OUT NET_FRAGMENT *Fragment,
> + IN EFI_EVENT Timeout
> + );
> +
> +#endif
> --
> 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
` (6 preceding siblings ...)
2016-12-14 7:34 ` [Patch 07/10] NetworkPkg/HttpDxe: HTTPS support over IPv4 and IPv6 Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-15 2:39 ` Fu, Siyuan
2016-12-22 7:37 ` Ye, Ting
2016-12-14 7:34 ` [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib Jiaxin Wu
2016-12-14 7:34 ` [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for Nt32 platform Jiaxin Wu
9 siblings, 2 replies; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Ye Ting, Fu Siyuan, Zhang Lubo, Long Qin, Thomas Palmer,
Wu Jiaxin
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/NetworkPkg.dsc | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc
index 1ef353e..3d881e9 100644
--- a/NetworkPkg/NetworkPkg.dsc
+++ b/NetworkPkg/NetworkPkg.dsc
@@ -53,12 +53,14 @@
TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
[LibraryClasses.common.UEFI_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -111,10 +113,12 @@
NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
NetworkPkg/DnsDxe/DnsDxe.inf
NetworkPkg/HttpDxe/HttpDxe.inf
NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
NetworkPkg/HttpBootDxe/HttpBootDxe.inf
+ NetworkPkg/TlsDxe/TlsDxe.inf
+ NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
NetworkPkg/Application/IfConfig6/IfConfig6.inf
NetworkPkg/Application/IpsecConfig/IpSecConfig.inf
NetworkPkg/Application/VConfig/VConfig.inf
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module
2016-12-14 7:34 ` [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module Jiaxin Wu
@ 2016-12-15 2:39 ` Fu, Siyuan
2016-12-22 7:37 ` Ye, Ting
1 sibling, 0 replies; 37+ messages in thread
From: Fu, Siyuan @ 2016-12-15 2:39 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Ye, Ting, Zhang, Lubo, Long, Qin, Thomas Palmer
Reviewed-by: Fu Siyuan <siyuan.fu@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: 2016年12月14日 15:34
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/NetworkPkg.dsc | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index 1ef353e..3d881e9 100644
--- a/NetworkPkg/NetworkPkg.dsc
+++ b/NetworkPkg/NetworkPkg.dsc
@@ -53,12 +53,14 @@
TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.i
+ nf
SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
[LibraryClasses.common.UEFI_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -111,10 +113,12 @@
NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
NetworkPkg/DnsDxe/DnsDxe.inf
NetworkPkg/HttpDxe/HttpDxe.inf
NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
NetworkPkg/HttpBootDxe/HttpBootDxe.inf
+ NetworkPkg/TlsDxe/TlsDxe.inf
+ NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
NetworkPkg/Application/IfConfig6/IfConfig6.inf
NetworkPkg/Application/IpsecConfig/IpSecConfig.inf
NetworkPkg/Application/VConfig/VConfig.inf
--
1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module
2016-12-14 7:34 ` [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module Jiaxin Wu
2016-12-15 2:39 ` Fu, Siyuan
@ 2016-12-22 7:37 ` Ye, Ting
1 sibling, 0 replies; 37+ messages in thread
From: Ye, Ting @ 2016-12-22 7:37 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Fu, Siyuan, Zhang, Lubo, Long, Qin, Thomas Palmer
Reviewed-by: Ye Ting <ting.ye@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: Wednesday, December 14, 2016 3:34 PM
To: edk2-devel@lists.01.org
Cc: Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Long, Qin <qin.long@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Long Qin <qin.long@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
NetworkPkg/NetworkPkg.dsc | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/NetworkPkg/NetworkPkg.dsc b/NetworkPkg/NetworkPkg.dsc index 1ef353e..3d881e9 100644
--- a/NetworkPkg/NetworkPkg.dsc
+++ b/NetworkPkg/NetworkPkg.dsc
@@ -53,12 +53,14 @@
TcpIoLib|MdeModulePkg/Library/DxeTcpIoLib/DxeTcpIoLib.inf
HttpLib|MdeModulePkg/Library/DxeHttpLib/DxeHttpLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
+
+ FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.i
+ nf
SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
[LibraryClasses.common.UEFI_DRIVER]
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
@@ -111,10 +113,12 @@
NetworkPkg/Mtftp6Dxe/Mtftp6Dxe.inf
NetworkPkg/DnsDxe/DnsDxe.inf
NetworkPkg/HttpDxe/HttpDxe.inf
NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
NetworkPkg/HttpBootDxe/HttpBootDxe.inf
+ NetworkPkg/TlsDxe/TlsDxe.inf
+ NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
NetworkPkg/Application/IfConfig6/IfConfig6.inf
NetworkPkg/Application/IpsecConfig/IpSecConfig.inf
NetworkPkg/Application/VConfig/VConfig.inf
--
1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
` (7 preceding siblings ...)
2016-12-14 7:34 ` [Patch 08/10] NetworkPkg/NetworkPkg.dsc: Enable TlsDxe and TlsAuthConfigDxe module Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-14 7:56 ` Ni, Ruiyu
` (2 more replies)
2016-12-14 7:34 ` [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for Nt32 platform Jiaxin Wu
9 siblings, 3 replies; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Long Qin, Ni Ruiyu, Ye Ting, Fu Siyuan, Zhang Lubo, Thomas Palmer,
Wu Jiaxin
This patch is used to remove the 'SECURE_BOOT_ENABLE' flag for OpensslLib
and BaseCryptLib modules.
Cc: Long Qin <qin.long@intel.com>
Cc: Ni Ruiyu <ruiyu.ni@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
Nt32Pkg/Nt32Pkg.dsc | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc
index 4458c02..79ab2f7 100644
--- a/Nt32Pkg/Nt32Pkg.dsc
+++ b/Nt32Pkg/Nt32Pkg.dsc
@@ -131,15 +131,15 @@
DebugPrintErrorLevelLib|MdeModulePkg/Library/DxeDebugPrintErrorLevelLib/DxeDebugPrintErrorLevelLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
PlatformSecureLib|Nt32Pkg/Library/PlatformSecureLib/PlatformSecureLib.inf
- IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
- OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
!else
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
@@ -173,13 +173,11 @@
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
[LibraryClasses.common.PEIM]
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
OemHookStatusCodeLib|Nt32Pkg/Library/PeiNt32OemHookStatusCodeLib/PeiNt32OemHookStatusCodeLib.inf
-!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
-!endif
[LibraryClasses.common]
#
# DXE phase common
#
@@ -190,13 +188,11 @@
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
OemHookStatusCodeLib|Nt32Pkg/Library/DxeNt32OemHookStatusCodeLib/DxeNt32OemHookStatusCodeLib.inf
PeCoffExtraActionLib|Nt32Pkg/Library/DxeNt32PeCoffExtraActionLib/DxeNt32PeCoffExtraActionLib.inf
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
WinNtLib|Nt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.inf
-!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
-!endif
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@@ -213,13 +209,11 @@
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
#
# Runtime
#
-!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
-!endif
################################################################################
#
# Pcd Section - list of all EDK II PCD Entries defined by this Platform
#
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib
2016-12-14 7:34 ` [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib Jiaxin Wu
@ 2016-12-14 7:56 ` Ni, Ruiyu
2016-12-15 8:25 ` Long, Qin
2016-12-22 7:39 ` Ye, Ting
2 siblings, 0 replies; 37+ messages in thread
From: Ni, Ruiyu @ 2016-12-14 7:56 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Long, Qin, Ye, Ting, Fu, Siyuan, Zhang, Lubo, Thomas Palmer
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
Thanks/Ray
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: Wednesday, December 14, 2016 3:34 PM
> To: edk2-devel@lists.01.org
> Cc: Long, Qin <qin.long@intel.com>; Ni, Ruiyu <ruiyu.ni@intel.com>; Ye, Ting
> <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo
> <lubo.zhang@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu,
> Jiaxin <jiaxin.wu@intel.com>
> Subject: [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib
> and BaseCryptLib
>
> This patch is used to remove the 'SECURE_BOOT_ENABLE' flag for OpensslLib
> and BaseCryptLib modules.
>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Ni Ruiyu <ruiyu.ni@intel.com>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> Nt32Pkg/Nt32Pkg.dsc | 10 ++--------
> 1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc index
> 4458c02..79ab2f7 100644
> --- a/Nt32Pkg/Nt32Pkg.dsc
> +++ b/Nt32Pkg/Nt32Pkg.dsc
> @@ -131,15 +131,15 @@
>
> DebugPrintErrorLevelLib|MdeModulePkg/Library/DxeDebugPrintErrorLevelL
> ib/DxeDebugPrintErrorLevelLib.inf
>
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
>
> DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLi
> bNull.inf
>
> CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibN
> ull/CpuExceptionHandlerLibNull.inf
> LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
> + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
>
> !if $(SECURE_BOOT_ENABLE) == TRUE
>
> PlatformSecureLib|Nt32Pkg/Library/PlatformSecureLib/PlatformSecureLib.in
> f
> - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> - OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
>
> TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTp
> mMeasurementLib.inf
> AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> !else
>
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
> mMeasurementLibNull.inf
>
> AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableL
> ibNull.inf
> @@ -173,13 +173,11 @@
>
> OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibN
> ull/OemHookStatusCodeLibNull.inf
>
> [LibraryClasses.common.PEIM]
> PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
>
> OemHookStatusCodeLib|Nt32Pkg/Library/PeiNt32OemHookStatusCodeLib/
> PeiNt32OemHookStatusCodeLib.inf
> -!if $(SECURE_BOOT_ENABLE) == TRUE
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
> -!endif
>
> [LibraryClasses.common]
> #
> # DXE phase common
> #
> @@ -190,13 +188,11 @@
>
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/Dx
> eReportStatusCodeLib.inf
>
> OemHookStatusCodeLib|Nt32Pkg/Library/DxeNt32OemHookStatusCodeLib/
> DxeNt32OemHookStatusCodeLib.inf
>
> PeCoffExtraActionLib|Nt32Pkg/Library/DxeNt32PeCoffExtraActionLib/DxeNt
> 32PeCoffExtraActionLib.inf
>
> ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeE
> xtractGuidedSectionLib.inf
> WinNtLib|Nt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.inf
> -!if $(SECURE_BOOT_ENABLE) == TRUE
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> -!endif
>
> [LibraryClasses.common.DXE_CORE]
> HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
>
> MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLi
> b/DxeCoreMemoryAllocationLib.inf
> PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> @@ -213,13 +209,11 @@
>
> [LibraryClasses.common.DXE_RUNTIME_DRIVER]
> #
> # Runtime
> #
> -!if $(SECURE_BOOT_ENABLE) == TRUE
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> -!endif
>
>
> ##########################################################
> ######################
> #
> # Pcd Section - list of all EDK II PCD Entries defined by this Platform #
> --
> 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib
2016-12-14 7:34 ` [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib Jiaxin Wu
2016-12-14 7:56 ` Ni, Ruiyu
@ 2016-12-15 8:25 ` Long, Qin
2016-12-22 7:39 ` Ye, Ting
2 siblings, 0 replies; 37+ messages in thread
From: Long, Qin @ 2016-12-15 8:25 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Ni, Ruiyu, Ye, Ting, Fu, Siyuan, Zhang, Lubo, Thomas Palmer
Reviewed-by: Qin Long <qin.long@intel.com>
Best Regards & Thanks,
LONG, Qin
> -----Original Message-----
> From: Wu, Jiaxin
> Sent: Wednesday, December 14, 2016 3:34 PM
> To: edk2-devel@lists.01.org
> Cc: Long, Qin; Ni, Ruiyu; Ye, Ting; Fu, Siyuan; Zhang, Lubo; Thomas Palmer;
> Wu, Jiaxin
> Subject: [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib
> and BaseCryptLib
>
> This patch is used to remove the 'SECURE_BOOT_ENABLE' flag for OpensslLib
> and BaseCryptLib modules.
>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Ni Ruiyu <ruiyu.ni@intel.com>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> Nt32Pkg/Nt32Pkg.dsc | 10 ++--------
> 1 file changed, 2 insertions(+), 8 deletions(-)
>
> diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc index
> 4458c02..79ab2f7 100644
> --- a/Nt32Pkg/Nt32Pkg.dsc
> +++ b/Nt32Pkg/Nt32Pkg.dsc
> @@ -131,15 +131,15 @@
>
> DebugPrintErrorLevelLib|MdeModulePkg/Library/DxeDebugPrintErrorLevelL
> ib/DxeDebugPrintErrorLevelLib.inf
>
> PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanc
> eLibNull.inf
>
> DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLi
> bNull.inf
>
> CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibN
> ull/CpuExceptionHandlerLibNull.inf
> LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
> + IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> + OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
>
> !if $(SECURE_BOOT_ENABLE) == TRUE
>
> PlatformSecureLib|Nt32Pkg/Library/PlatformSecureLib/PlatformSecureLib.in
> f
> - IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
> - OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
>
> TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTp
> mMeasurementLib.inf
> AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
> !else
>
> TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/Tp
> mMeasurementLibNull.inf
>
> AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableL
> ibNull.inf
> @@ -173,13 +173,11 @@
>
> OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibN
> ull/OemHookStatusCodeLibNull.inf
>
> [LibraryClasses.common.PEIM]
> PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
>
> OemHookStatusCodeLib|Nt32Pkg/Library/PeiNt32OemHookStatusCodeLib/
> PeiNt32OemHookStatusCodeLib.inf
> -!if $(SECURE_BOOT_ENABLE) == TRUE
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
> -!endif
>
> [LibraryClasses.common]
> #
> # DXE phase common
> #
> @@ -190,13 +188,11 @@
>
> ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/Dx
> eReportStatusCodeLib.inf
>
> OemHookStatusCodeLib|Nt32Pkg/Library/DxeNt32OemHookStatusCodeLib/
> DxeNt32OemHookStatusCodeLib.inf
>
> PeCoffExtraActionLib|Nt32Pkg/Library/DxeNt32PeCoffExtraActionLib/DxeNt
> 32PeCoffExtraActionLib.inf
>
> ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeE
> xtractGuidedSectionLib.inf
> WinNtLib|Nt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.inf
> -!if $(SECURE_BOOT_ENABLE) == TRUE
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> -!endif
>
> [LibraryClasses.common.DXE_CORE]
> HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
>
> MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLi
> b/DxeCoreMemoryAllocationLib.inf
> PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> @@ -213,13 +209,11 @@
>
> [LibraryClasses.common.DXE_RUNTIME_DRIVER]
> #
> # Runtime
> #
> -!if $(SECURE_BOOT_ENABLE) == TRUE
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
> -!endif
>
>
> ##########################################################
> ######################
> #
> # Pcd Section - list of all EDK II PCD Entries defined by this Platform #
> --
> 1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib
2016-12-14 7:34 ` [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib Jiaxin Wu
2016-12-14 7:56 ` Ni, Ruiyu
2016-12-15 8:25 ` Long, Qin
@ 2016-12-22 7:39 ` Ye, Ting
2 siblings, 0 replies; 37+ messages in thread
From: Ye, Ting @ 2016-12-22 7:39 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Long, Qin, Ni, Ruiyu, Fu, Siyuan, Zhang, Lubo, Thomas Palmer
Reviewed-by: Ye Ting <ting.ye@intel.com>
-----Original Message-----
From: Wu, Jiaxin
Sent: Wednesday, December 14, 2016 3:34 PM
To: edk2-devel@lists.01.org
Cc: Long, Qin <qin.long@intel.com>; Ni, Ruiyu <ruiyu.ni@intel.com>; Ye, Ting <ting.ye@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>; Zhang, Lubo <lubo.zhang@intel.com>; Thomas Palmer <thomas.palmer@hpe.com>; Wu, Jiaxin <jiaxin.wu@intel.com>
Subject: [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib
This patch is used to remove the 'SECURE_BOOT_ENABLE' flag for OpensslLib and BaseCryptLib modules.
Cc: Long Qin <qin.long@intel.com>
Cc: Ni Ruiyu <ruiyu.ni@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
Nt32Pkg/Nt32Pkg.dsc | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc index 4458c02..79ab2f7 100644
--- a/Nt32Pkg/Nt32Pkg.dsc
+++ b/Nt32Pkg/Nt32Pkg.dsc
@@ -131,15 +131,15 @@
DebugPrintErrorLevelLib|MdeModulePkg/Library/DxeDebugPrintErrorLevelLib/DxeDebugPrintErrorLevelLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
CpuExceptionHandlerLib|MdeModulePkg/Library/CpuExceptionHandlerLibNull/CpuExceptionHandlerLibNull.inf
LockBoxLib|MdeModulePkg/Library/LockBoxNullLib/LockBoxNullLib.inf
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+ OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
!if $(SECURE_BOOT_ENABLE) == TRUE
PlatformSecureLib|Nt32Pkg/Library/PlatformSecureLib/PlatformSecureLib.inf
- IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
- OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
AuthVariableLib|SecurityPkg/Library/AuthVariableLib/AuthVariableLib.inf
!else
TpmMeasurementLib|MdeModulePkg/Library/TpmMeasurementLibNull/TpmMeasurementLibNull.inf
AuthVariableLib|MdeModulePkg/Library/AuthVariableLibNull/AuthVariableLibNull.inf
@@ -173,13 +173,11 @@
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
[LibraryClasses.common.PEIM]
PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
OemHookStatusCodeLib|Nt32Pkg/Library/PeiNt32OemHookStatusCodeLib/PeiNt32OemHookStatusCodeLib.inf
-!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/PeiCryptLib.inf
-!endif
[LibraryClasses.common]
#
# DXE phase common
#
@@ -190,13 +188,11 @@
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
OemHookStatusCodeLib|Nt32Pkg/Library/DxeNt32OemHookStatusCodeLib/DxeNt32OemHookStatusCodeLib.inf
PeCoffExtraActionLib|Nt32Pkg/Library/DxeNt32PeCoffExtraActionLib/DxeNt32PeCoffExtraActionLib.inf
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
WinNtLib|Nt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.inf
-!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
-!endif
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@@ -213,13 +209,11 @@
[LibraryClasses.common.DXE_RUNTIME_DRIVER]
#
# Runtime
#
-!if $(SECURE_BOOT_ENABLE) == TRUE
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/RuntimeCryptLib.inf
-!endif
################################################################################
#
# Pcd Section - list of all EDK II PCD Entries defined by this Platform #
--
1.9.5.msysgit.1
^ permalink raw reply [flat|nested] 37+ messages in thread
* [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for Nt32 platform
2016-12-14 7:34 [Patch 00/10] Sync staging/HTTPS-TLS feature into edk2 master Jiaxin Wu
` (8 preceding siblings ...)
2016-12-14 7:34 ` [Patch 09/10] Nt32Pkg/Nt32Pkg.dsc: Remove the flag for OpensslLib and BaseCryptLib Jiaxin Wu
@ 2016-12-14 7:34 ` Jiaxin Wu
2016-12-14 7:44 ` Yao, Jiewen
9 siblings, 1 reply; 37+ messages in thread
From: Jiaxin Wu @ 2016-12-14 7:34 UTC (permalink / raw)
To: edk2-devel
Cc: Long Qin, Ni Ruiyu, Ye Ting, Fu Siyuan, Zhang Lubo, Thomas Palmer,
Wu Jiaxin
This path is used to enable HTTPS boot feature for Nt32 platform.
Cc: Long Qin <qin.long@intel.com>
Cc: Ni Ruiyu <ruiyu.ni@intel.com>
Cc: Ye Ting <ting.ye@intel.com>
Cc: Fu Siyuan <siyuan.fu@intel.com>
Cc: Zhang Lubo <lubo.zhang@intel.com>
Cc: Thomas Palmer <thomas.palmer@hpe.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
---
Nt32Pkg/Nt32Pkg.dsc | 15 ++++++++++++++-
Nt32Pkg/Nt32Pkg.fdf | 4 ++++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc
index 79ab2f7..07703a3 100644
--- a/Nt32Pkg/Nt32Pkg.dsc
+++ b/Nt32Pkg/Nt32Pkg.dsc
@@ -43,10 +43,17 @@
#
# Defines for default states. These can be changed on the command line.
# -D FLAG=VALUE
#
DEFINE SECURE_BOOT_ENABLE = FALSE
+
+ #
+ # This flag is to enable or disable HTTPS boot feature.
+ # These can be changed on the command line.
+ # -D FLAG=VALUE
+ #
+ DEFINE HTTPS_BOOT_ENABLE = TRUE
################################################################################
#
# SKU Identification section - list of all SKU IDs supported by this
# Platform.
@@ -189,10 +196,11 @@
OemHookStatusCodeLib|Nt32Pkg/Library/DxeNt32OemHookStatusCodeLib/DxeNt32OemHookStatusCodeLib.inf
PeCoffExtraActionLib|Nt32Pkg/Library/DxeNt32PeCoffExtraActionLib/DxeNt32PeCoffExtraActionLib.inf
ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
WinNtLib|Nt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.inf
BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+ TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
[LibraryClasses.common.DXE_CORE]
HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
@@ -232,11 +240,11 @@
gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f
gEfiNt32PkgTokenSpaceGuid.PcdWinNtFirmwareVolume|L"..\\Fv\\Nt32.fd"
gEfiNt32PkgTokenSpaceGuid.PcdWinNtFirmwareBlockSize|0x10000
gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f
gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
-!if $(SECURE_BOOT_ENABLE) == TRUE
+!if $(SECURE_BOOT_ENABLE) == TRUE || $(HTTPS_BOOT_ENABLE) == TRUE
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
!endif
!ifndef $(USE_OLD_SHELL)
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
@@ -437,10 +445,15 @@
NetworkPkg/HttpBootDxe/HttpBootDxe.inf
NetworkPkg/DnsDxe/DnsDxe.inf
NetworkPkg/HttpDxe/HttpDxe.inf
NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
+
+!if $(HTTPS_BOOT_ENABLE) == TRUE
+ NetworkPkg/TlsDxe/TlsDxe.inf
+ NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
+!endif
MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
MdeModulePkg/Application/UiApp/UiApp.inf{
<LibraryClasses>
NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
diff --git a/Nt32Pkg/Nt32Pkg.fdf b/Nt32Pkg/Nt32Pkg.fdf
index cf00a13..094ed91 100644
--- a/Nt32Pkg/Nt32Pkg.fdf
+++ b/Nt32Pkg/Nt32Pkg.fdf
@@ -260,10 +260,14 @@ INF MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
INF NetworkPkg/HttpBootDxe/HttpBootDxe.inf
INF NetworkPkg/DnsDxe/DnsDxe.inf
INF NetworkPkg/HttpDxe/HttpDxe.inf
INF NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
+!if $(HTTPS_BOOT_ENABLE) == TRUE
+INF NetworkPkg/TlsDxe/TlsDxe.inf
+INF NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
+!endif
INF MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.inf
################################################################################
#
# FILE statements are provided so that a platform integrator can include
# complete EFI FFS files, as well as a method for constructing FFS files
--
1.9.5.msysgit.1
^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for Nt32 platform
2016-12-14 7:34 ` [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for Nt32 platform Jiaxin Wu
@ 2016-12-14 7:44 ` Yao, Jiewen
2016-12-14 7:46 ` Wu, Jiaxin
0 siblings, 1 reply; 37+ messages in thread
From: Yao, Jiewen @ 2016-12-14 7:44 UTC (permalink / raw)
To: Wu, Jiaxin, edk2-devel@lists.01.org
Cc: Ni, Ruiyu, Ye, Ting, Zhang, Lubo, Wu, Jiaxin, Long, Qin,
Fu, Siyuan
Hi Jiaxin
Thanks to contribute this.
I found below update is NOT related to HTTPS.
Can we use a better name, such as TLS_ENABLE ?
+!if $(HTTPS_BOOT_ENABLE) == TRUE
+ NetworkPkg/TlsDxe/TlsDxe.inf
+ NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
+!endif
Thank you
Yao Jiewen
> -----Original Message-----
> From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Jiaxin
> Wu
> Sent: Wednesday, December 14, 2016 3:34 PM
> To: edk2-devel@lists.01.org
> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Ye, Ting <ting.ye@intel.com>; Zhang, Lubo
> <lubo.zhang@intel.com>; Wu, Jiaxin <jiaxin.wu@intel.com>; Long, Qin
> <qin.long@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> Subject: [edk2] [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for Nt32
> platform
>
> This path is used to enable HTTPS boot feature for Nt32 platform.
>
> Cc: Long Qin <qin.long@intel.com>
> Cc: Ni Ruiyu <ruiyu.ni@intel.com>
> Cc: Ye Ting <ting.ye@intel.com>
> Cc: Fu Siyuan <siyuan.fu@intel.com>
> Cc: Zhang Lubo <lubo.zhang@intel.com>
> Cc: Thomas Palmer <thomas.palmer@hpe.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> ---
> Nt32Pkg/Nt32Pkg.dsc | 15 ++++++++++++++-
> Nt32Pkg/Nt32Pkg.fdf | 4 ++++
> 2 files changed, 18 insertions(+), 1 deletion(-)
>
> diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc
> index 79ab2f7..07703a3 100644
> --- a/Nt32Pkg/Nt32Pkg.dsc
> +++ b/Nt32Pkg/Nt32Pkg.dsc
> @@ -43,10 +43,17 @@
> #
> # Defines for default states. These can be changed on the command line.
> # -D FLAG=VALUE
> #
> DEFINE SECURE_BOOT_ENABLE = FALSE
> +
> + #
> + # This flag is to enable or disable HTTPS boot feature.
> + # These can be changed on the command line.
> + # -D FLAG=VALUE
> + #
> + DEFINE HTTPS_BOOT_ENABLE = TRUE
>
>
> #############################################################
> ###################
> #
> # SKU Identification section - list of all SKU IDs supported by this
> # Platform.
> @@ -189,10 +196,11 @@
>
> OemHookStatusCodeLib|Nt32Pkg/Library/DxeNt32OemHookStatusCodeLib/Dxe
> Nt32OemHookStatusCodeLib.inf
>
> PeCoffExtraActionLib|Nt32Pkg/Library/DxeNt32PeCoffExtraActionLib/DxeNt32P
> eCoffExtraActionLib.inf
>
> ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtra
> ctGuidedSectionLib.inf
> WinNtLib|Nt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.inf
> BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> + TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
>
> [LibraryClasses.common.DXE_CORE]
> HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
>
> MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/Dx
> eCoreMemoryAllocationLib.inf
> PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> @@ -232,11 +240,11 @@
> gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f
> gEfiNt32PkgTokenSpaceGuid.PcdWinNtFirmwareVolume|L"..\\Fv\\Nt32.fd"
> gEfiNt32PkgTokenSpaceGuid.PcdWinNtFirmwareBlockSize|0x10000
> gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f
>
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChang
> e|FALSE
> -!if $(SECURE_BOOT_ENABLE) == TRUE
> +!if $(SECURE_BOOT_ENABLE) == TRUE || $(HTTPS_BOOT_ENABLE) == TRUE
> gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
> !endif
>
> !ifndef $(USE_OLD_SHELL)
> gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5,
> 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4,
> 0xD1 }
> @@ -437,10 +445,15 @@
>
> NetworkPkg/HttpBootDxe/HttpBootDxe.inf
> NetworkPkg/DnsDxe/DnsDxe.inf
> NetworkPkg/HttpDxe/HttpDxe.inf
> NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
> +
> +!if $(HTTPS_BOOT_ENABLE) == TRUE
> + NetworkPkg/TlsDxe/TlsDxe.inf
> + NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> +!endif
>
> MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
> MdeModulePkg/Application/UiApp/UiApp.inf{
> <LibraryClasses>
>
> NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
> diff --git a/Nt32Pkg/Nt32Pkg.fdf b/Nt32Pkg/Nt32Pkg.fdf
> index cf00a13..094ed91 100644
> --- a/Nt32Pkg/Nt32Pkg.fdf
> +++ b/Nt32Pkg/Nt32Pkg.fdf
> @@ -260,10 +260,14 @@ INF
> MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
> INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
> INF NetworkPkg/HttpBootDxe/HttpBootDxe.inf
> INF NetworkPkg/DnsDxe/DnsDxe.inf
> INF NetworkPkg/HttpDxe/HttpDxe.inf
> INF NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
> +!if $(HTTPS_BOOT_ENABLE) == TRUE
> +INF NetworkPkg/TlsDxe/TlsDxe.inf
> +INF NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> +!endif
> INF
> MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuApp.in
> f
>
> #############################################################
> ###################
> #
> # FILE statements are provided so that a platform integrator can include
> # complete EFI FFS files, as well as a method for constructing FFS files
> --
> 1.9.5.msysgit.1
>
> _______________________________________________
> edk2-devel mailing list
> edk2-devel@lists.01.org
> https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for Nt32 platform
2016-12-14 7:44 ` Yao, Jiewen
@ 2016-12-14 7:46 ` Wu, Jiaxin
0 siblings, 0 replies; 37+ messages in thread
From: Wu, Jiaxin @ 2016-12-14 7:46 UTC (permalink / raw)
To: Yao, Jiewen, edk2-devel@lists.01.org
Cc: Ni, Ruiyu, Ye, Ting, Zhang, Lubo, Long, Qin, Fu, Siyuan
Thanks Jiewen, I'm fine with the flag rename:).
Best Regards!
Jiaxin
> -----Original Message-----
> From: Yao, Jiewen
> Sent: Wednesday, December 14, 2016 3:45 PM
> To: Wu, Jiaxin <jiaxin.wu@intel.com>; edk2-devel@lists.01.org
> Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Ye, Ting <ting.ye@intel.com>; Zhang,
> Lubo <lubo.zhang@intel.com>; Wu, Jiaxin <jiaxin.wu@intel.com>; Long, Qin
> <qin.long@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> Subject: RE: [edk2] [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for
> Nt32 platform
>
> Hi Jiaxin
> Thanks to contribute this.
>
> I found below update is NOT related to HTTPS.
>
> Can we use a better name, such as TLS_ENABLE ?
>
> +!if $(HTTPS_BOOT_ENABLE) == TRUE
> + NetworkPkg/TlsDxe/TlsDxe.inf
> + NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> +!endif
>
> Thank you
> Yao Jiewen
>
> > -----Original Message-----
> > From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of
> > Jiaxin Wu
> > Sent: Wednesday, December 14, 2016 3:34 PM
> > To: edk2-devel@lists.01.org
> > Cc: Ni, Ruiyu <ruiyu.ni@intel.com>; Ye, Ting <ting.ye@intel.com>;
> > Zhang, Lubo <lubo.zhang@intel.com>; Wu, Jiaxin <jiaxin.wu@intel.com>;
> > Long, Qin <qin.long@intel.com>; Fu, Siyuan <siyuan.fu@intel.com>
> > Subject: [edk2] [Patch 10/10] Nt32Pkg: Enable HTTPS boot feature for
> > Nt32 platform
> >
> > This path is used to enable HTTPS boot feature for Nt32 platform.
> >
> > Cc: Long Qin <qin.long@intel.com>
> > Cc: Ni Ruiyu <ruiyu.ni@intel.com>
> > Cc: Ye Ting <ting.ye@intel.com>
> > Cc: Fu Siyuan <siyuan.fu@intel.com>
> > Cc: Zhang Lubo <lubo.zhang@intel.com>
> > Cc: Thomas Palmer <thomas.palmer@hpe.com>
> > Contributed-under: TianoCore Contribution Agreement 1.0
> > Signed-off-by: Wu Jiaxin <jiaxin.wu@intel.com>
> > ---
> > Nt32Pkg/Nt32Pkg.dsc | 15 ++++++++++++++- Nt32Pkg/Nt32Pkg.fdf | 4
> > ++++
> > 2 files changed, 18 insertions(+), 1 deletion(-)
> >
> > diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc index
> > 79ab2f7..07703a3 100644
> > --- a/Nt32Pkg/Nt32Pkg.dsc
> > +++ b/Nt32Pkg/Nt32Pkg.dsc
> > @@ -43,10 +43,17 @@
> > #
> > # Defines for default states. These can be changed on the command line.
> > # -D FLAG=VALUE
> > #
> > DEFINE SECURE_BOOT_ENABLE = FALSE
> > +
> > + #
> > + # This flag is to enable or disable HTTPS boot feature.
> > + # These can be changed on the command line.
> > + # -D FLAG=VALUE
> > + #
> > + DEFINE HTTPS_BOOT_ENABLE = TRUE
> >
> >
> >
> ##########################################################
> ###
> > ###################
> > #
> > # SKU Identification section - list of all SKU IDs supported by this
> > # Platform.
> > @@ -189,10 +196,11 @@
> >
> >
> OemHookStatusCodeLib|Nt32Pkg/Library/DxeNt32OemHookStatusCodeLib/
> Dxe
> > Nt32OemHookStatusCodeLib.inf
> >
> >
> PeCoffExtraActionLib|Nt32Pkg/Library/DxeNt32PeCoffExtraActionLib/DxeNt
> > PeCoffExtraActionLib|32P
> > eCoffExtraActionLib.inf
> >
> >
> ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeE
> > ExtractGuidedSectionLib|xtra
> > ctGuidedSectionLib.inf
> > WinNtLib|Nt32Pkg/Library/DxeWinNtLib/DxeWinNtLib.inf
> > BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
> > + TlsLib|CryptoPkg/Library/TlsLib/TlsLib.inf
> >
> > [LibraryClasses.common.DXE_CORE]
> > HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
> >
> >
> MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLi
> b/Dx
> > eCoreMemoryAllocationLib.inf
> > PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
> > @@ -232,11 +240,11 @@
> > gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x1f
> >
> gEfiNt32PkgTokenSpaceGuid.PcdWinNtFirmwareVolume|L"..\\Fv\\Nt32.fd"
> > gEfiNt32PkgTokenSpaceGuid.PcdWinNtFirmwareBlockSize|0x10000
> > gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x0f
> >
> >
> gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationC
> hang
> > e|FALSE
> > -!if $(SECURE_BOOT_ENABLE) == TRUE
> > +!if $(SECURE_BOOT_ENABLE) == TRUE || $(HTTPS_BOOT_ENABLE) ==
> TRUE
> > gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
> > !endif
> >
> > !ifndef $(USE_OLD_SHELL)
> > gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83,
> > 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52,
> > 0x68, 0xD0, 0xB4,
> > 0xD1 }
> > @@ -437,10 +445,15 @@
> >
> > NetworkPkg/HttpBootDxe/HttpBootDxe.inf
> > NetworkPkg/DnsDxe/DnsDxe.inf
> > NetworkPkg/HttpDxe/HttpDxe.inf
> > NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
> > +
> > +!if $(HTTPS_BOOT_ENABLE) == TRUE
> > + NetworkPkg/TlsDxe/TlsDxe.inf
> > + NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> > +!endif
> >
> > MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
> > MdeModulePkg/Application/UiApp/UiApp.inf{
> > <LibraryClasses>
> >
> >
> NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
> > diff --git a/Nt32Pkg/Nt32Pkg.fdf b/Nt32Pkg/Nt32Pkg.fdf index
> > cf00a13..094ed91 100644
> > --- a/Nt32Pkg/Nt32Pkg.fdf
> > +++ b/Nt32Pkg/Nt32Pkg.fdf
> > @@ -260,10 +260,14 @@ INF
> > MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf
> > INF MdeModulePkg/Universal/Network/IScsiDxe/IScsiDxe.inf
> > INF NetworkPkg/HttpBootDxe/HttpBootDxe.inf
> > INF NetworkPkg/DnsDxe/DnsDxe.inf
> > INF NetworkPkg/HttpDxe/HttpDxe.inf
> > INF NetworkPkg/HttpUtilitiesDxe/HttpUtilitiesDxe.inf
> > +!if $(HTTPS_BOOT_ENABLE) == TRUE
> > +INF NetworkPkg/TlsDxe/TlsDxe.inf
> > +INF NetworkPkg/TlsAuthConfigDxe/TlsAuthConfigDxe.inf
> > +!endif
> > INF
> >
> MdeModulePkg/Application/BootManagerMenuApp/BootManagerMenuAp
> p.in
> > f
> >
> >
> ##########################################################
> ###
> > ###################
> > #
> > # FILE statements are provided so that a platform integrator can
> > include # complete EFI FFS files, as well as a method for
> > constructing FFS files
> > --
> > 1.9.5.msysgit.1
> >
> > _______________________________________________
> > edk2-devel mailing list
> > edk2-devel@lists.01.org
> > https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply [flat|nested] 37+ messages in thread