X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=CryptoPkg%2FLibrary%2FTlsLib%2FTlsConfig.c;h=0673c9d5322e87ce85649bf953cc98da660fd012;hp=74b577d60ee390b52a36578a7db31aea72ca9a2f;hb=HEAD;hpb=2009f6b4c5cbd7dda95a2594288405224173d239
diff --git a/CryptoPkg/Library/TlsLib/TlsConfig.c b/CryptoPkg/Library/TlsLib/TlsConfig.c
index 74b577d60e..60559de4a7 100644
--- a/CryptoPkg/Library/TlsLib/TlsConfig.c
+++ b/CryptoPkg/Library/TlsLib/TlsConfig.c
@@ -1,7 +1,7 @@
/** @file
SSL/TLS Configuration Library Wrapper Implementation over OpenSSL.
-Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.
(C) Copyright 2016 Hewlett Packard Enterprise Development LP
SPDX-License-Identifier: BSD-2-Clause-Patent
@@ -13,15 +13,15 @@ typedef struct {
//
// IANA/IETF defined Cipher Suite ID
//
- UINT16 IanaCipher;
+ UINT16 IanaCipher;
//
// OpenSSL-used Cipher Suite String
//
- CONST CHAR8 *OpensslCipher;
+ CONST CHAR8 *OpensslCipher;
//
// Length of OpensslCipher
//
- UINTN OpensslCipherLength;
+ UINTN OpensslCipherLength;
} TLS_CIPHER_MAPPING;
//
@@ -38,30 +38,62 @@ typedef struct {
//
// Keep the table uniquely sorted by the IanaCipher field, in increasing order.
//
-STATIC CONST TLS_CIPHER_MAPPING TlsCipherMappingTable[] = {
- MAP ( 0x0001, "NULL-MD5" ), /// TLS_RSA_WITH_NULL_MD5
- MAP ( 0x0002, "NULL-SHA" ), /// TLS_RSA_WITH_NULL_SHA
- MAP ( 0x0004, "RC4-MD5" ), /// TLS_RSA_WITH_RC4_128_MD5
- MAP ( 0x0005, "RC4-SHA" ), /// TLS_RSA_WITH_RC4_128_SHA
- MAP ( 0x000A, "DES-CBC3-SHA" ), /// TLS_RSA_WITH_3DES_EDE_CBC_SHA, mandatory TLS 1.1
- MAP ( 0x0016, "DHE-RSA-DES-CBC3-SHA" ), /// TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
- MAP ( 0x002F, "AES128-SHA" ), /// TLS_RSA_WITH_AES_128_CBC_SHA, mandatory TLS 1.2
- MAP ( 0x0030, "DH-DSS-AES128-SHA" ), /// TLS_DH_DSS_WITH_AES_128_CBC_SHA
- MAP ( 0x0031, "DH-RSA-AES128-SHA" ), /// TLS_DH_RSA_WITH_AES_128_CBC_SHA
- MAP ( 0x0033, "DHE-RSA-AES128-SHA" ), /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA
- MAP ( 0x0035, "AES256-SHA" ), /// TLS_RSA_WITH_AES_256_CBC_SHA
- MAP ( 0x0036, "DH-DSS-AES256-SHA" ), /// TLS_DH_DSS_WITH_AES_256_CBC_SHA
- MAP ( 0x0037, "DH-RSA-AES256-SHA" ), /// TLS_DH_RSA_WITH_AES_256_CBC_SHA
- MAP ( 0x0039, "DHE-RSA-AES256-SHA" ), /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA
- MAP ( 0x003B, "NULL-SHA256" ), /// TLS_RSA_WITH_NULL_SHA256
- MAP ( 0x003C, "AES128-SHA256" ), /// TLS_RSA_WITH_AES_128_CBC_SHA256
- MAP ( 0x003D, "AES256-SHA256" ), /// TLS_RSA_WITH_AES_256_CBC_SHA256
- MAP ( 0x003E, "DH-DSS-AES128-SHA256" ), /// TLS_DH_DSS_WITH_AES_128_CBC_SHA256
- MAP ( 0x003F, "DH-RSA-AES128-SHA256" ), /// TLS_DH_RSA_WITH_AES_128_CBC_SHA256
- MAP ( 0x0067, "DHE-RSA-AES128-SHA256" ), /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
- MAP ( 0x0068, "DH-DSS-AES256-SHA256" ), /// TLS_DH_DSS_WITH_AES_256_CBC_SHA256
- MAP ( 0x0069, "DH-RSA-AES256-SHA256" ), /// TLS_DH_RSA_WITH_AES_256_CBC_SHA256
- MAP ( 0x006B, "DHE-RSA-AES256-SHA256" ), /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+STATIC CONST TLS_CIPHER_MAPPING TlsCipherMappingTable[] = {
+ MAP (0x0001, "NULL-MD5"), /// TLS_RSA_WITH_NULL_MD5
+ MAP (0x0002, "NULL-SHA"), /// TLS_RSA_WITH_NULL_SHA
+ MAP (0x0004, "RC4-MD5"), /// TLS_RSA_WITH_RC4_128_MD5
+ MAP (0x0005, "RC4-SHA"), /// TLS_RSA_WITH_RC4_128_SHA
+ MAP (0x000A, "DES-CBC3-SHA"), /// TLS_RSA_WITH_3DES_EDE_CBC_SHA, mandatory TLS 1.1
+ MAP (0x0016, "DHE-RSA-DES-CBC3-SHA"), /// TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
+ MAP (0x002F, "AES128-SHA"), /// TLS_RSA_WITH_AES_128_CBC_SHA, mandatory TLS 1.2
+ MAP (0x0030, "DH-DSS-AES128-SHA"), /// TLS_DH_DSS_WITH_AES_128_CBC_SHA
+ MAP (0x0031, "DH-RSA-AES128-SHA"), /// TLS_DH_RSA_WITH_AES_128_CBC_SHA
+ MAP (0x0033, "DHE-RSA-AES128-SHA"), /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA
+ MAP (0x0035, "AES256-SHA"), /// TLS_RSA_WITH_AES_256_CBC_SHA
+ MAP (0x0036, "DH-DSS-AES256-SHA"), /// TLS_DH_DSS_WITH_AES_256_CBC_SHA
+ MAP (0x0037, "DH-RSA-AES256-SHA"), /// TLS_DH_RSA_WITH_AES_256_CBC_SHA
+ MAP (0x0039, "DHE-RSA-AES256-SHA"), /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA
+ MAP (0x003B, "NULL-SHA256"), /// TLS_RSA_WITH_NULL_SHA256
+ MAP (0x003C, "AES128-SHA256"), /// TLS_RSA_WITH_AES_128_CBC_SHA256
+ MAP (0x003D, "AES256-SHA256"), /// TLS_RSA_WITH_AES_256_CBC_SHA256
+ MAP (0x003E, "DH-DSS-AES128-SHA256"), /// TLS_DH_DSS_WITH_AES_128_CBC_SHA256
+ MAP (0x003F, "DH-RSA-AES128-SHA256"), /// TLS_DH_RSA_WITH_AES_128_CBC_SHA256
+ MAP (0x0067, "DHE-RSA-AES128-SHA256"), /// TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
+ MAP (0x0068, "DH-DSS-AES256-SHA256"), /// TLS_DH_DSS_WITH_AES_256_CBC_SHA256
+ MAP (0x0069, "DH-RSA-AES256-SHA256"), /// TLS_DH_RSA_WITH_AES_256_CBC_SHA256
+ MAP (0x006B, "DHE-RSA-AES256-SHA256"), /// TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
+ MAP (0x009F, "DHE-RSA-AES256-GCM-SHA384"), /// TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
+ MAP (0xC02B, "ECDHE-ECDSA-AES128-GCM-SHA256"), /// TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
+ MAP (0xC02C, "ECDHE-ECDSA-AES256-GCM-SHA384"), /// TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
+ MAP (0xC030, "ECDHE-RSA-AES256-GCM-SHA384"), /// TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
+};
+
+typedef struct {
+ //
+ // TLS Algorithm
+ //
+ UINT8 Algo;
+ //
+ // TLS Algorithm name
+ //
+ CONST CHAR8 *Name;
+} TLS_ALGO_TO_NAME;
+
+STATIC CONST TLS_ALGO_TO_NAME TlsHashAlgoToName[] = {
+ { TlsHashAlgoNone, NULL },
+ { TlsHashAlgoMd5, "MD5" },
+ { TlsHashAlgoSha1, "SHA1" },
+ { TlsHashAlgoSha224, "SHA224" },
+ { TlsHashAlgoSha256, "SHA256" },
+ { TlsHashAlgoSha384, "SHA384" },
+ { TlsHashAlgoSha512, "SHA512" },
+};
+
+STATIC CONST TLS_ALGO_TO_NAME TlsSignatureAlgoToName[] = {
+ { TlsSignatureAlgoAnonymous, NULL },
+ { TlsSignatureAlgoRsa, "RSA" },
+ { TlsSignatureAlgoDsa, "DSA" },
+ { TlsSignatureAlgoEcdsa, "ECDSA" },
};
/**
@@ -76,12 +108,12 @@ STATIC CONST TLS_CIPHER_MAPPING TlsCipherMappingTable[] = {
STATIC
CONST TLS_CIPHER_MAPPING *
TlsGetCipherMapping (
- IN UINT16 CipherId
+ IN UINT16 CipherId
)
{
- INTN Left;
- INTN Right;
- INTN Middle;
+ INTN Left;
+ INTN Right;
+ INTN Middle;
//
// Binary Search Cipher Mapping Table for IANA-OpenSSL Cipher Translation
@@ -102,7 +134,7 @@ TlsGetCipherMapping (
if (CipherId < TlsCipherMappingTable[Middle].IanaCipher) {
Right = Middle - 1;
} else {
- Left = Middle + 1;
+ Left = Middle + 1;
}
}
@@ -129,16 +161,16 @@ TlsGetCipherMapping (
EFI_STATUS
EFIAPI
TlsSetVersion (
- IN VOID *Tls,
- IN UINT8 MajorVer,
- IN UINT8 MinorVer
+ IN VOID *Tls,
+ IN UINT8 MajorVer,
+ IN UINT8 MinorVer
)
{
TLS_CONNECTION *TlsConn;
UINT16 ProtoVersion;
TlsConn = (TLS_CONNECTION *)Tls;
- if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -148,35 +180,35 @@ TlsSetVersion (
// Bound TLS method to the particular specified version.
//
switch (ProtoVersion) {
- case TLS1_VERSION:
- //
- // TLS 1.0
- //
- SSL_set_min_proto_version (TlsConn->Ssl, TLS1_VERSION);
- SSL_set_max_proto_version (TlsConn->Ssl, TLS1_VERSION);
- break;
- case TLS1_1_VERSION:
- //
- // TLS 1.1
- //
- SSL_set_min_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
- SSL_set_max_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
- break;
- case TLS1_2_VERSION:
- //
- // TLS 1.2
- //
- SSL_set_min_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
- SSL_set_max_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
- break;
- default:
- //
- // Unsupported Protocol Version
- //
- return EFI_UNSUPPORTED;
+ case TLS1_VERSION:
+ //
+ // TLS 1.0
+ //
+ SSL_set_min_proto_version (TlsConn->Ssl, TLS1_VERSION);
+ SSL_set_max_proto_version (TlsConn->Ssl, TLS1_VERSION);
+ break;
+ case TLS1_1_VERSION:
+ //
+ // TLS 1.1
+ //
+ SSL_set_min_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
+ SSL_set_max_proto_version (TlsConn->Ssl, TLS1_1_VERSION);
+ break;
+ case TLS1_2_VERSION:
+ //
+ // TLS 1.2
+ //
+ SSL_set_min_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
+ SSL_set_max_proto_version (TlsConn->Ssl, TLS1_2_VERSION);
+ break;
+ default:
+ //
+ // Unsupported Protocol Version
+ //
+ return EFI_UNSUPPORTED;
}
- return EFI_SUCCESS;;
+ return EFI_SUCCESS;
}
/**
@@ -195,14 +227,14 @@ TlsSetVersion (
EFI_STATUS
EFIAPI
TlsSetConnectionEnd (
- IN VOID *Tls,
- IN BOOLEAN IsServer
+ IN VOID *Tls,
+ IN BOOLEAN IsServer
)
{
TLS_CONNECTION *TlsConn;
- TlsConn = (TLS_CONNECTION *) Tls;
- if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ TlsConn = (TLS_CONNECTION *)Tls;
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -216,7 +248,7 @@ TlsSetConnectionEnd (
// Set TLS to work in Server mode.
// It is unsupported for UEFI version currently.
//
- //SSL_set_accept_state (TlsConn->Ssl);
+ // SSL_set_accept_state (TlsConn->Ssl);
return EFI_UNSUPPORTED;
}
@@ -244,24 +276,24 @@ TlsSetConnectionEnd (
EFI_STATUS
EFIAPI
TlsSetCipherList (
- IN VOID *Tls,
- IN UINT16 *CipherId,
- IN UINTN CipherNum
+ IN VOID *Tls,
+ IN UINT16 *CipherId,
+ IN UINTN CipherNum
)
{
- TLS_CONNECTION *TlsConn;
- EFI_STATUS Status;
- CONST TLS_CIPHER_MAPPING **MappedCipher;
- UINTN MappedCipherBytes;
- UINTN MappedCipherCount;
- UINTN CipherStringSize;
- UINTN Index;
- CONST TLS_CIPHER_MAPPING *Mapping;
- CHAR8 *CipherString;
- CHAR8 *CipherStringPosition;
-
- TlsConn = (TLS_CONNECTION *) Tls;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
+ TLS_CONNECTION *TlsConn;
+ EFI_STATUS Status;
+ CONST TLS_CIPHER_MAPPING **MappedCipher;
+ UINTN MappedCipherBytes;
+ UINTN MappedCipherCount;
+ UINTN CipherStringSize;
+ UINTN Index;
+ CONST TLS_CIPHER_MAPPING *Mapping;
+ CHAR8 *CipherString;
+ CHAR8 *CipherStringPosition;
+
+ TlsConn = (TLS_CONNECTION *)Tls;
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (CipherId == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -269,11 +301,15 @@ TlsSetCipherList (
// Allocate the MappedCipher array for recording the mappings that we find
// for the input IANA identifiers in CipherId.
//
- Status = SafeUintnMult (CipherNum, sizeof (*MappedCipher),
- &MappedCipherBytes);
+ Status = SafeUintnMult (
+ CipherNum,
+ sizeof (*MappedCipher),
+ &MappedCipherBytes
+ );
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
+
MappedCipher = AllocatePool (MappedCipherBytes);
if (MappedCipher == NULL) {
return EFI_OUT_OF_RESOURCES;
@@ -284,15 +320,20 @@ TlsSetCipherList (
// CipherString.
//
MappedCipherCount = 0;
- CipherStringSize = 0;
+ CipherStringSize = 0;
for (Index = 0; Index < CipherNum; Index++) {
//
// Look up the IANA-to-OpenSSL mapping.
//
Mapping = TlsGetCipherMapping (CipherId[Index]);
if (Mapping == NULL) {
- DEBUG ((DEBUG_VERBOSE, "%a:%a: skipping CipherId=0x%04x\n",
- gEfiCallerBaseName, __FUNCTION__, CipherId[Index]));
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a:%a: skipping CipherId=0x%04x\n",
+ gEfiCallerBaseName,
+ __FUNCTION__,
+ CipherId[Index]
+ ));
//
// Skipping the cipher is valid because CipherId is an ordered
// preference list of ciphers, thus we can filter it as long as we
@@ -300,6 +341,7 @@ TlsSetCipherList (
//
continue;
}
+
//
// Accumulate Mapping->OpensslCipherLength into CipherStringSize. If this
// is not the first successful mapping, account for a colon (":") prefix
@@ -312,12 +354,17 @@ TlsSetCipherList (
goto FreeMappedCipher;
}
}
- Status = SafeUintnAdd (CipherStringSize, Mapping->OpensslCipherLength,
- &CipherStringSize);
+
+ Status = SafeUintnAdd (
+ CipherStringSize,
+ Mapping->OpensslCipherLength,
+ &CipherStringSize
+ );
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto FreeMappedCipher;
}
+
//
// Record the mapping.
//
@@ -329,16 +376,22 @@ TlsSetCipherList (
// terminating NUL character in CipherStringSize; allocate CipherString.
//
if (MappedCipherCount == 0) {
- DEBUG ((DEBUG_ERROR, "%a:%a: no CipherId could be mapped\n",
- gEfiCallerBaseName, __FUNCTION__));
+ DEBUG ((
+ DEBUG_ERROR,
+ "%a:%a: no CipherId could be mapped\n",
+ gEfiCallerBaseName,
+ __FUNCTION__
+ ));
Status = EFI_UNSUPPORTED;
goto FreeMappedCipher;
}
+
Status = SafeUintnAdd (CipherStringSize, 1, &CipherStringSize);
if (EFI_ERROR (Status)) {
Status = EFI_OUT_OF_RESOURCES;
goto FreeMappedCipher;
}
+
CipherString = AllocatePool (CipherStringSize);
if (CipherString == NULL) {
Status = EFI_OUT_OF_RESOURCES;
@@ -358,8 +411,12 @@ TlsSetCipherList (
if (Index > 0) {
*(CipherStringPosition++) = ':';
}
- CopyMem (CipherStringPosition, Mapping->OpensslCipher,
- Mapping->OpensslCipherLength);
+
+ CopyMem (
+ CipherStringPosition,
+ Mapping->OpensslCipher,
+ Mapping->OpensslCipherLength
+ );
CipherStringPosition += Mapping->OpensslCipherLength;
}
@@ -375,30 +432,37 @@ TlsSetCipherList (
// 79 non-newline characters. (MAX_DEBUG_MESSAGE_LENGTH is usually 0x100 in
// DebugLib instances.)
//
- DEBUG_CODE (
- UINTN FullLength;
- UINTN SegmentLength;
-
- FullLength = CipherStringSize - 1;
- DEBUG ((DEBUG_VERBOSE, "%a:%a: CipherString={\n", gEfiCallerBaseName,
- __FUNCTION__));
- for (CipherStringPosition = CipherString;
- CipherStringPosition < CipherString + FullLength;
- CipherStringPosition += SegmentLength) {
- SegmentLength = FullLength - (CipherStringPosition - CipherString);
- if (SegmentLength > 79) {
- SegmentLength = 79;
- }
- DEBUG ((DEBUG_VERBOSE, "%.*a\n", SegmentLength, CipherStringPosition));
+ DEBUG_CODE_BEGIN ();
+ UINTN FullLength;
+ UINTN SegmentLength;
+
+ FullLength = CipherStringSize - 1;
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a:%a: CipherString={\n",
+ gEfiCallerBaseName,
+ __FUNCTION__
+ ));
+ for (CipherStringPosition = CipherString;
+ CipherStringPosition < CipherString + FullLength;
+ CipherStringPosition += SegmentLength)
+ {
+ SegmentLength = FullLength - (CipherStringPosition - CipherString);
+ if (SegmentLength > 79) {
+ SegmentLength = 79;
}
- DEBUG ((DEBUG_VERBOSE, "}\n"));
- //
- // Restore the pre-debug value of CipherStringPosition by skipping over the
- // trailing NUL.
- //
- CipherStringPosition++;
- ASSERT (CipherStringPosition == CipherString + CipherStringSize);
- );
+
+ DEBUG ((DEBUG_VERBOSE, "%.*a\n", SegmentLength, CipherStringPosition));
+ }
+
+ DEBUG ((DEBUG_VERBOSE, "}\n"));
+ //
+ // Restore the pre-debug value of CipherStringPosition by skipping over the
+ // trailing NUL.
+ //
+ CipherStringPosition++;
+ ASSERT (CipherStringPosition == CipherString + CipherStringSize);
+ DEBUG_CODE_END ();
//
// Sets the ciphers for use by the Tls object.
@@ -414,7 +478,7 @@ FreeCipherString:
FreePool (CipherString);
FreeMappedCipher:
- FreePool (MappedCipher);
+ FreePool ((VOID *)MappedCipher);
return Status;
}
@@ -434,7 +498,7 @@ FreeMappedCipher:
EFI_STATUS
EFIAPI
TlsSetCompressionMethod (
- IN UINT8 CompMethod
+ IN UINT8 CompMethod
)
{
COMP_METHOD *Cm;
@@ -451,7 +515,7 @@ TlsSetCompressionMethod (
//
return EFI_SUCCESS;
} else if (CompMethod == 1) {
- Cm = COMP_zlib();
+ Cm = COMP_zlib ();
} else {
return EFI_UNSUPPORTED;
}
@@ -480,14 +544,14 @@ TlsSetCompressionMethod (
VOID
EFIAPI
TlsSetVerify (
- IN VOID *Tls,
- IN UINT32 VerifyMode
+ IN VOID *Tls,
+ IN UINT32 VerifyMode
)
{
TLS_CONNECTION *TlsConn;
- TlsConn = (TLS_CONNECTION *) Tls;
- if (TlsConn == NULL || TlsConn->Ssl == NULL) {
+ TlsConn = (TLS_CONNECTION *)Tls;
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
return;
}
@@ -497,6 +561,71 @@ TlsSetVerify (
SSL_set_verify (TlsConn->Ssl, VerifyMode, NULL);
}
+/**
+ Set the specified host name to be verified.
+
+ @param[in] Tls Pointer to the TLS object.
+ @param[in] Flags The setting flags during the validation.
+ @param[in] HostName The specified host name to be verified.
+
+ @retval EFI_SUCCESS The HostName setting was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameter is invalid.
+ @retval EFI_ABORTED Invalid HostName setting.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetVerifyHost (
+ IN VOID *Tls,
+ IN UINT32 Flags,
+ IN CHAR8 *HostName
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ X509_VERIFY_PARAM *VerifyParam;
+ UINTN BinaryAddressSize;
+ UINT8 BinaryAddress[MAX (NS_INADDRSZ, NS_IN6ADDRSZ)];
+ INTN ParamStatus;
+
+ TlsConn = (TLS_CONNECTION *)Tls;
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (HostName == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SSL_set_hostflags (TlsConn->Ssl, Flags);
+
+ VerifyParam = SSL_get0_param (TlsConn->Ssl);
+ ASSERT (VerifyParam != NULL);
+
+ BinaryAddressSize = 0;
+ if (inet_pton (AF_INET6, HostName, BinaryAddress) == 1) {
+ BinaryAddressSize = NS_IN6ADDRSZ;
+ } else if (inet_pton (AF_INET, HostName, BinaryAddress) == 1) {
+ BinaryAddressSize = NS_INADDRSZ;
+ }
+
+ if (BinaryAddressSize > 0) {
+ DEBUG ((
+ DEBUG_VERBOSE,
+ "%a:%a: parsed \"%a\" as an IPv%c address "
+ "literal\n",
+ gEfiCallerBaseName,
+ __FUNCTION__,
+ HostName,
+ (UINTN)((BinaryAddressSize == NS_IN6ADDRSZ) ? '6' : '4')
+ ));
+ ParamStatus = X509_VERIFY_PARAM_set1_ip (
+ VerifyParam,
+ BinaryAddress,
+ BinaryAddressSize
+ );
+ } else {
+ ParamStatus = X509_VERIFY_PARAM_set1_host (VerifyParam, HostName, 0);
+ }
+
+ return (ParamStatus == 1) ? EFI_SUCCESS : EFI_ABORTED;
+}
+
/**
Sets a TLS/SSL session ID to be used during TLS/SSL connect.
@@ -515,18 +644,18 @@ TlsSetVerify (
EFI_STATUS
EFIAPI
TlsSetSessionId (
- IN VOID *Tls,
- IN UINT8 *SessionId,
- IN UINT16 SessionIdLen
+ IN VOID *Tls,
+ IN UINT8 *SessionId,
+ IN UINT16 SessionIdLen
)
{
TLS_CONNECTION *TlsConn;
SSL_SESSION *Session;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
Session = NULL;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (SessionId == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -560,9 +689,9 @@ TlsSetSessionId (
EFI_STATUS
EFIAPI
TlsSetCaCertificate (
- IN VOID *Tls,
- IN VOID *Data,
- IN UINTN DataSize
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
)
{
BIO *BioCert;
@@ -578,10 +707,10 @@ TlsSetCaCertificate (
Cert = NULL;
X509Store = NULL;
Status = EFI_SUCCESS;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
Ret = 0;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize == 0)) {
return EFI_INVALID_PARAMETER;
}
@@ -589,7 +718,7 @@ TlsSetCaCertificate (
// 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);
+ Cert = d2i_X509 (NULL, (const unsigned char **)&Data, (long)DataSize);
if (Cert == NULL) {
//
// Certificate is from PEM encoding.
@@ -600,7 +729,7 @@ TlsSetCaCertificate (
goto ON_EXIT;
}
- if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
+ if (BIO_write (BioCert, Data, (UINT32)DataSize) <= 0) {
Status = EFI_ABORTED;
goto ON_EXIT;
}
@@ -615,8 +744,8 @@ TlsSetCaCertificate (
SslCtx = SSL_get_SSL_CTX (TlsConn->Ssl);
X509Store = SSL_CTX_get_cert_store (SslCtx);
if (X509Store == NULL) {
- Status = EFI_ABORTED;
- goto ON_EXIT;
+ Status = EFI_ABORTED;
+ goto ON_EXIT;
}
//
@@ -628,8 +757,9 @@ TlsSetCaCertificate (
//
// 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)) {
+ 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;
}
@@ -667,9 +797,9 @@ ON_EXIT:
EFI_STATUS
EFIAPI
TlsSetHostPublicCert (
- IN VOID *Tls,
- IN VOID *Data,
- IN UINTN DataSize
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
)
{
BIO *BioCert;
@@ -680,9 +810,9 @@ TlsSetHostPublicCert (
BioCert = NULL;
Cert = NULL;
Status = EFI_SUCCESS;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || Data == NULL || DataSize == 0) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize == 0)) {
return EFI_INVALID_PARAMETER;
}
@@ -690,7 +820,7 @@ TlsSetHostPublicCert (
// 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);
+ Cert = d2i_X509 (NULL, (const unsigned char **)&Data, (long)DataSize);
if (Cert == NULL) {
//
// Certificate is from PEM encoding.
@@ -701,7 +831,7 @@ TlsSetHostPublicCert (
goto ON_EXIT;
}
- if (BIO_write (BioCert, Data, (UINT32) DataSize) <= 0) {
+ if (BIO_write (BioCert, Data, (UINT32)DataSize) <= 0) {
Status = EFI_ABORTED;
goto ON_EXIT;
}
@@ -733,11 +863,107 @@ ON_EXIT:
/**
Adds the local private key to the specified TLS object.
- This function adds the local private key (PEM-encoded RSA or PKCS#8 private
+ This function adds the local private key (DER-encoded or PEM-encoded 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
+ @param[in] Data Pointer to the data buffer of a DER-encoded or PEM-encoded
+ or PKCS#8 private key.
+ @param[in] DataSize The size of data buffer in bytes.
+ @param[in] Password Pointer to NULL-terminated private key password, set it to NULL
+ if private key not encrypted.
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_UNSUPPORTED This function is not supported.
+ @retval EFI_ABORTED Invalid private key data.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetHostPrivateKeyEx (
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize,
+ IN VOID *Password OPTIONAL
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ BIO *Bio;
+ EVP_PKEY *Pkey;
+ BOOLEAN Verify;
+
+ TlsConn = (TLS_CONNECTION *)Tls;
+
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize == 0)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Try to parse the private key in DER format or un-encrypted PKC#8
+ if (SSL_use_PrivateKey_ASN1 (
+ EVP_PKEY_RSA,
+ TlsConn->Ssl,
+ Data,
+ (long)DataSize
+ ) == 1)
+ {
+ goto verify;
+ }
+
+ if (SSL_use_PrivateKey_ASN1 (
+ EVP_PKEY_DSA,
+ TlsConn->Ssl,
+ Data,
+ (long)DataSize
+ ) == 1)
+ {
+ goto verify;
+ }
+
+ if (SSL_use_PrivateKey_ASN1 (
+ EVP_PKEY_EC,
+ TlsConn->Ssl,
+ Data,
+ (long)DataSize
+ ) == 1)
+ {
+ goto verify;
+ }
+
+ // Try to parse the private key in PEM format or encrypted PKC#8
+ Bio = BIO_new_mem_buf (Data, (int)DataSize);
+ if (Bio != NULL) {
+ Verify = FALSE;
+ Pkey = PEM_read_bio_PrivateKey (Bio, NULL, NULL, Password);
+ if ((Pkey != NULL) && (SSL_use_PrivateKey (TlsConn->Ssl, Pkey) == 1)) {
+ Verify = TRUE;
+ }
+
+ EVP_PKEY_free (Pkey);
+ BIO_free (Bio);
+
+ if (Verify) {
+ goto verify;
+ }
+ }
+
+ return EFI_ABORTED;
+
+verify:
+ if (SSL_check_private_key (TlsConn->Ssl) == 1) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_ABORTED;
+}
+
+/**
+ Adds the local private key to the specified TLS object.
+
+ This function adds the local private key (DER-encoded or PEM-encoded 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 DER-encoded or PEM-encoded
or PKCS#8 private key.
@param[in] DataSize The size of data buffer in bytes.
@@ -749,12 +975,12 @@ ON_EXIT:
EFI_STATUS
EFIAPI
TlsSetHostPrivateKey (
- IN VOID *Tls,
- IN VOID *Data,
- IN UINTN DataSize
+ IN VOID *Tls,
+ IN VOID *Data,
+ IN UINTN DataSize
)
{
- return EFI_UNSUPPORTED;
+ return TlsSetHostPrivateKeyEx (Tls, Data, DataSize, NULL);
}
/**
@@ -774,13 +1000,191 @@ TlsSetHostPrivateKey (
EFI_STATUS
EFIAPI
TlsSetCertRevocationList (
- IN VOID *Data,
- IN UINTN DataSize
+ IN VOID *Data,
+ IN UINTN DataSize
)
{
return EFI_UNSUPPORTED;
}
+/**
+ Set the signature algorithm list to used by the TLS object.
+
+ This function sets the signature algorithms for use by a specified TLS object.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] Data Array of UINT8 of signature algorithms. The array consists of
+ pairs of the hash algorithm and the signature algorithm as defined
+ in RFC 5246
+ @param[in] DataSize The length the SignatureAlgoList. Must be divisible by 2.
+
+ @retval EFI_SUCCESS The signature algorithm list was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameters are invalid.
+ @retval EFI_UNSUPPORTED No supported TLS signature algorithm was found in SignatureAlgoList
+ @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetSignatureAlgoList (
+ IN VOID *Tls,
+ IN UINT8 *Data,
+ IN UINTN DataSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ UINTN Index;
+ UINTN SignAlgoStrSize;
+ CHAR8 *SignAlgoStr;
+ CHAR8 *Pos;
+ UINT8 *SignatureAlgoList;
+ EFI_STATUS Status;
+
+ TlsConn = (TLS_CONNECTION *)Tls;
+
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize < 3) ||
+ ((DataSize % 2) == 0) || (Data[0] != DataSize - 1))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ SignatureAlgoList = Data + 1;
+ SignAlgoStrSize = 0;
+ for (Index = 0; Index < Data[0]; Index += 2) {
+ CONST CHAR8 *Tmp;
+
+ if (SignatureAlgoList[Index] >= ARRAY_SIZE (TlsHashAlgoToName)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Tmp = TlsHashAlgoToName[SignatureAlgoList[Index]].Name;
+ if (!Tmp) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Add 1 for the '+'
+ SignAlgoStrSize += AsciiStrLen (Tmp) + 1;
+
+ if (SignatureAlgoList[Index + 1] >= ARRAY_SIZE (TlsSignatureAlgoToName)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Tmp = TlsSignatureAlgoToName[SignatureAlgoList[Index + 1]].Name;
+ if (!Tmp) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Add 1 for the ':' or for the NULL terminator
+ SignAlgoStrSize += AsciiStrLen (Tmp) + 1;
+ }
+
+ if (!SignAlgoStrSize) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SignAlgoStr = AllocatePool (SignAlgoStrSize);
+ if (SignAlgoStr == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Pos = SignAlgoStr;
+ for (Index = 0; Index < Data[0]; Index += 2) {
+ CONST CHAR8 *Tmp;
+
+ Tmp = TlsHashAlgoToName[SignatureAlgoList[Index]].Name;
+ CopyMem (Pos, Tmp, AsciiStrLen (Tmp));
+ Pos += AsciiStrLen (Tmp);
+ *Pos++ = '+';
+
+ Tmp = TlsSignatureAlgoToName[SignatureAlgoList[Index + 1]].Name;
+ CopyMem (Pos, Tmp, AsciiStrLen (Tmp));
+ Pos += AsciiStrLen (Tmp);
+ *Pos++ = ':';
+ }
+
+ *(Pos - 1) = '\0';
+
+ if (SSL_set1_sigalgs_list (TlsConn->Ssl, SignAlgoStr) < 1) {
+ Status = EFI_INVALID_PARAMETER;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+ FreePool (SignAlgoStr);
+ return Status;
+}
+
+/**
+ Set the EC curve to be used for TLS flows
+
+ This function sets the EC curve to be used for TLS flows.
+
+ @param[in] Tls Pointer to a TLS object.
+ @param[in] Data An EC named curve as defined in section 5.1.1 of RFC 4492.
+ @param[in] DataSize Size of Data, it should be sizeof (UINT32)
+
+ @retval EFI_SUCCESS The EC curve was set successfully.
+ @retval EFI_INVALID_PARAMETER The parameters are invalid.
+ @retval EFI_UNSUPPORTED The requested TLS EC curve is not supported
+
+**/
+EFI_STATUS
+EFIAPI
+TlsSetEcCurve (
+ IN VOID *Tls,
+ IN UINT8 *Data,
+ IN UINTN DataSize
+ )
+{
+ TLS_CONNECTION *TlsConn;
+ EC_KEY *EcKey;
+ INT32 Nid;
+ INT32 Ret;
+
+ TlsConn = (TLS_CONNECTION *)Tls;
+
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (Data == NULL) || (DataSize != sizeof (UINT32))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (*((UINT32 *)Data)) {
+ case TlsEcNamedCurveSecp256r1:
+ return EFI_UNSUPPORTED;
+ case TlsEcNamedCurveSecp384r1:
+ Nid = NID_secp384r1;
+ break;
+ case TlsEcNamedCurveSecp521r1:
+ Nid = NID_secp521r1;
+ break;
+ case TlsEcNamedCurveX25519:
+ Nid = NID_X25519;
+ break;
+ case TlsEcNamedCurveX448:
+ Nid = NID_X448;
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ if (SSL_set1_curves (TlsConn->Ssl, &Nid, 1) != 1) {
+ return EFI_UNSUPPORTED;
+ }
+
+ EcKey = EC_KEY_new_by_curve_name (Nid);
+ if (EcKey == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Ret = SSL_set_tmp_ecdh (TlsConn->Ssl, EcKey);
+ EC_KEY_free (EcKey);
+
+ if (Ret != 1) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
/**
Gets the protocol version used by the specified TLS connection.
@@ -797,12 +1201,12 @@ TlsSetCertRevocationList (
UINT16
EFIAPI
TlsGetVersion (
- IN VOID *Tls
+ IN VOID *Tls
)
{
TLS_CONNECTION *TlsConn;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
ASSERT (TlsConn != NULL);
@@ -825,12 +1229,12 @@ TlsGetVersion (
UINT8
EFIAPI
TlsGetConnectionEnd (
- IN VOID *Tls
+ IN VOID *Tls
)
{
TLS_CONNECTION *TlsConn;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
ASSERT (TlsConn != NULL);
@@ -854,17 +1258,17 @@ TlsGetConnectionEnd (
EFI_STATUS
EFIAPI
TlsGetCurrentCipher (
- IN VOID *Tls,
- IN OUT UINT16 *CipherId
+ IN VOID *Tls,
+ IN OUT UINT16 *CipherId
)
{
TLS_CONNECTION *TlsConn;
CONST SSL_CIPHER *Cipher;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
Cipher = NULL;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || CipherId == NULL) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (CipherId == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -897,8 +1301,8 @@ TlsGetCurrentCipher (
EFI_STATUS
EFIAPI
TlsGetCurrentCompressionId (
- IN VOID *Tls,
- IN OUT UINT8 *CompressionId
+ IN VOID *Tls,
+ IN OUT UINT8 *CompressionId
)
{
return EFI_UNSUPPORTED;
@@ -920,12 +1324,12 @@ TlsGetCurrentCompressionId (
UINT32
EFIAPI
TlsGetVerify (
- IN VOID *Tls
+ IN VOID *Tls
)
{
TLS_CONNECTION *TlsConn;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
ASSERT (TlsConn != NULL);
@@ -950,19 +1354,19 @@ TlsGetVerify (
EFI_STATUS
EFIAPI
TlsGetSessionId (
- IN VOID *Tls,
- IN OUT UINT8 *SessionId,
- IN OUT UINT16 *SessionIdLen
+ IN VOID *Tls,
+ IN OUT UINT8 *SessionId,
+ IN OUT UINT16 *SessionIdLen
)
{
TLS_CONNECTION *TlsConn;
SSL_SESSION *Session;
CONST UINT8 *SslSessionId;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
Session = NULL;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || SessionId == NULL || SessionIdLen == NULL) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (SessionId == NULL) || (SessionIdLen == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -991,15 +1395,15 @@ TlsGetSessionId (
VOID
EFIAPI
TlsGetClientRandom (
- IN VOID *Tls,
- IN OUT UINT8 *ClientRandom
+ IN VOID *Tls,
+ IN OUT UINT8 *ClientRandom
)
{
TLS_CONNECTION *TlsConn;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || ClientRandom == NULL) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (ClientRandom == NULL)) {
return;
}
@@ -1020,15 +1424,15 @@ TlsGetClientRandom (
VOID
EFIAPI
TlsGetServerRandom (
- IN VOID *Tls,
- IN OUT UINT8 *ServerRandom
+ IN VOID *Tls,
+ IN OUT UINT8 *ServerRandom
)
{
TLS_CONNECTION *TlsConn;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || ServerRandom == NULL) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (ServerRandom == NULL)) {
return;
}
@@ -1052,17 +1456,17 @@ TlsGetServerRandom (
EFI_STATUS
EFIAPI
TlsGetKeyMaterial (
- IN VOID *Tls,
- IN OUT UINT8 *KeyMaterial
+ IN VOID *Tls,
+ IN OUT UINT8 *KeyMaterial
)
{
TLS_CONNECTION *TlsConn;
SSL_SESSION *Session;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
Session = NULL;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || KeyMaterial == NULL) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (KeyMaterial == NULL)) {
return EFI_INVALID_PARAMETER;
}
@@ -1096,9 +1500,9 @@ TlsGetKeyMaterial (
EFI_STATUS
EFIAPI
TlsGetCaCertificate (
- IN VOID *Tls,
- OUT VOID *Data,
- IN OUT UINTN *DataSize
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
)
{
return EFI_UNSUPPORTED;
@@ -1124,22 +1528,22 @@ TlsGetCaCertificate (
EFI_STATUS
EFIAPI
TlsGetHostPublicCert (
- IN VOID *Tls,
- OUT VOID *Data,
- IN OUT UINTN *DataSize
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
)
{
X509 *Cert;
TLS_CONNECTION *TlsConn;
Cert = NULL;
- TlsConn = (TLS_CONNECTION *) Tls;
+ TlsConn = (TLS_CONNECTION *)Tls;
- if (TlsConn == NULL || TlsConn->Ssl == NULL || DataSize == NULL || (*DataSize != 0 && Data == NULL)) {
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL) || (DataSize == NULL) || ((*DataSize != 0) && (Data == NULL))) {
return EFI_INVALID_PARAMETER;
}
- Cert = SSL_get_certificate(TlsConn->Ssl);
+ Cert = SSL_get_certificate (TlsConn->Ssl);
if (Cert == NULL) {
return EFI_NOT_FOUND;
}
@@ -1147,12 +1551,12 @@ TlsGetHostPublicCert (
//
// Only DER encoding is supported currently.
//
- if (*DataSize < (UINTN) i2d_X509 (Cert, NULL)) {
- *DataSize = (UINTN) i2d_X509 (Cert, NULL);
+ 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);
+ *DataSize = (UINTN)i2d_X509 (Cert, (unsigned char **)&Data);
return EFI_SUCCESS;
}
@@ -1176,9 +1580,9 @@ TlsGetHostPublicCert (
EFI_STATUS
EFIAPI
TlsGetHostPrivateKey (
- IN VOID *Tls,
- OUT VOID *Data,
- IN OUT UINTN *DataSize
+ IN VOID *Tls,
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
)
{
return EFI_UNSUPPORTED;
@@ -1202,10 +1606,59 @@ TlsGetHostPrivateKey (
EFI_STATUS
EFIAPI
TlsGetCertRevocationList (
- OUT VOID *Data,
- IN OUT UINTN *DataSize
+ OUT VOID *Data,
+ IN OUT UINTN *DataSize
)
{
return EFI_UNSUPPORTED;
}
+/**
+ Derive keying material from a TLS connection.
+
+ This function exports keying material using the mechanism described in RFC
+ 5705.
+
+ @param[in] Tls Pointer to the TLS object
+ @param[in] Label Description of the key for the PRF function
+ @param[in] Context Optional context
+ @param[in] ContextLen The length of the context value in bytes
+ @param[out] KeyBuffer Buffer to hold the output of the TLS-PRF
+ @param[in] KeyBufferLen The length of the KeyBuffer
+
+ @retval EFI_SUCCESS The operation succeeded.
+ @retval EFI_INVALID_PARAMETER The TLS object is invalid.
+ @retval EFI_PROTOCOL_ERROR Some other error occurred.
+
+**/
+EFI_STATUS
+EFIAPI
+TlsGetExportKey (
+ IN VOID *Tls,
+ IN CONST VOID *Label,
+ IN CONST VOID *Context,
+ IN UINTN ContextLen,
+ OUT VOID *KeyBuffer,
+ IN UINTN KeyBufferLen
+ )
+{
+ TLS_CONNECTION *TlsConn;
+
+ TlsConn = (TLS_CONNECTION *)Tls;
+
+ if ((TlsConn == NULL) || (TlsConn->Ssl == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SSL_export_keying_material (
+ TlsConn->Ssl,
+ KeyBuffer,
+ KeyBufferLen,
+ Label,
+ AsciiStrLen (Label),
+ Context,
+ ContextLen,
+ Context != NULL
+ ) == 1 ?
+ EFI_SUCCESS : EFI_PROTOCOL_ERROR;
+}