From 86dec922c45391762b29c1da1563633cfb02f05a Mon Sep 17 00:00:00 2001 From: Shruti Garg Date: Tue, 27 Oct 2015 19:43:23 +0530 Subject: [PATCH 1/2] Populate DataHash key size in SslConnectionInfo --- .../Interop.Ssl.cs | 3 +- .../Interop/Unix/libssl/SslConnectionInfo.cs | 5 +- .../pal_ssl.cpp | 55 +++++++++++++++++-- .../pal_ssl.h | 7 +-- .../src/System/Net/SslStreamPal.Unix.cs | 16 +----- 5 files changed, 60 insertions(+), 26 deletions(-) diff --git a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs index d2b8b1b791ea..ca0b9bb9d854 100644 --- a/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs +++ b/src/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.Ssl.cs @@ -65,7 +65,8 @@ internal static extern bool GetSslConnectionInfo( out int dataCipherAlg, out int keyExchangeAlg, out int dataHashAlg, - out int dataKeySize); + out int dataKeySize, + out int hashKeySize); [DllImport(Libraries.CryptoNative)] internal static unsafe extern int SslWrite(SafeSslHandle ssl, byte* buf, int num); diff --git a/src/Common/src/Interop/Unix/libssl/SslConnectionInfo.cs b/src/Common/src/Interop/Unix/libssl/SslConnectionInfo.cs index 85ea9aeaf42a..c8ec0aa1dedf 100644 --- a/src/Common/src/Interop/Unix/libssl/SslConnectionInfo.cs +++ b/src/Common/src/Interop/Unix/libssl/SslConnectionInfo.cs @@ -12,7 +12,7 @@ internal class SslConnectionInfo public readonly int DataCipherAlg; public readonly int DataKeySize; public readonly int DataHashAlg; - public readonly int DataHashKeySize = 0; + public readonly int DataHashKeySize; public readonly int KeyExchangeAlg; public readonly int KeyExchKeySize = 0; @@ -26,7 +26,8 @@ internal SslConnectionInfo(SafeSslHandle sslContext) out DataCipherAlg, out KeyExchangeAlg, out DataHashAlg, - out DataKeySize)) + out DataKeySize, + out DataHashKeySize)) { throw Interop.OpenSsl.CreateSslException(SR.net_ssl_get_connection_info_failed); } diff --git a/src/Native/System.Security.Cryptography.Native/pal_ssl.cpp b/src/Native/System.Security.Cryptography.Native/pal_ssl.cpp index e2e7f312a0ad..14c4c1ac620d 100644 --- a/src/Native/System.Security.Cryptography.Native/pal_ssl.cpp +++ b/src/Native/System.Security.Cryptography.Native/pal_ssl.cpp @@ -364,6 +364,16 @@ enum class SSL_DataHashAlgorithm : int64_t #endif }; +class SSL_DataHashSize +{ +public: + static const int32_t MD5_HashKeySize = 128; + static const int32_t SHA1_HashKeySize = 160; + static const int32_t SHA256_HashKeySize = 256; + static const int32_t SHA384_HashKeySize = 384; + static const int32_t GOST_HashKeySize = 256; +}; + static HashAlgorithmType MapHashAlgorithmType(const SSL_CIPHER* cipher) { unsigned long mac; @@ -404,11 +414,45 @@ static HashAlgorithmType MapHashAlgorithmType(const SSL_CIPHER* cipher) return HashAlgorithmType::None; } -extern "C" int32_t GetSslConnectionInfo(SSL* ssl, - CipherAlgorithmType* dataCipherAlg, - ExchangeAlgorithmType* keyExchangeAlg, - HashAlgorithmType* dataHashAlg, - int32_t* dataKeySize) +static int32_t GetHashKeySize(const SSL_CIPHER* cipher) +{ + unsigned long mac; +#if HAVE_SSL_CIPHER_SPLIT_ALGORITHMS + mac = cipher->algorithm_mac; +#else + const unsigned long SSL_MAC_MASK = 0x00c00000L; + mac = cipher->algorithms & SSL_MAC_MASK; +#endif + + SSL_DataHashAlgorithm sslMac = static_cast(mac); + switch (sslMac) + { + case SSL_DataHashAlgorithm::SSL_MD5: + return SSL_DataHashSize::MD5_HashKeySize; + + case SSL_DataHashAlgorithm::SSL_SHA1: + return SSL_DataHashSize::SHA1_HashKeySize; + +#if HAVE_SSL_CIPHER_SPLIT_ALGORITHMS + case SSL_DataHashAlgorithm::SSL_GOST94: + return SSL_DataHashSize::GOST_HashKeySize; + + case SSL_DataHashAlgorithm::SSL_GOST89MAC: + return SSL_DataHashSize::GOST_HashKeySize; + + case SSL_DataHashAlgorithm::SSL_SHA256: + return SSL_DataHashSize::SHA256_HashKeySize; + + case SSL_DataHashAlgorithm::SSL_SHA384: + return SSL_DataHashSize::SHA384_HashKeySize; + + case SSL_DataHashAlgorithm::SSL_AEAD: + return 0; +#endif + } +} + +extern "C" int32_t GetSslConnectionInfo(SSL* ssl, CipherAlgorithmType* dataCipherAlg, ExchangeAlgorithmType* keyExchangeAlg, HashAlgorithmType* dataHashAlg, int32_t* dataKeySize, int32_t* hashKeySize) { const SSL_CIPHER* cipher; @@ -427,6 +471,7 @@ extern "C" int32_t GetSslConnectionInfo(SSL* ssl, *keyExchangeAlg = MapExchangeAlgorithmType(cipher); *dataHashAlg = MapHashAlgorithmType(cipher); *dataKeySize = cipher->alg_bits; + *hashKeySize = GetHashKeySize(cipher); return 1; diff --git a/src/Native/System.Security.Cryptography.Native/pal_ssl.h b/src/Native/System.Security.Cryptography.Native/pal_ssl.h index 09eaf8324c41..f7034ec52663 100644 --- a/src/Native/System.Security.Cryptography.Native/pal_ssl.h +++ b/src/Native/System.Security.Cryptography.Native/pal_ssl.h @@ -214,11 +214,8 @@ Returns the connection information for the SSL instance. Returns 1 upon success, otherwise 0. */ -extern "C" int32_t GetSslConnectionInfo(SSL* ssl, - CipherAlgorithmType* dataCipherAlg, - ExchangeAlgorithmType* keyExchangeAlg, - HashAlgorithmType* dataHashAlg, - int32_t* dataKeySize); + +extern "C" int32_t GetSslConnectionInfo(SSL* ssl, CipherAlgorithmType* dataCipherAlg, ExchangeAlgorithmType* keyExchangeAlg, HashAlgorithmType* dataHashAlg, int32_t* dataKeySize, int32_t* hashKeySize); /* Shims the SSL_write method. diff --git a/src/System.Net.Security/src/System/Net/SslStreamPal.Unix.cs b/src/System.Net.Security/src/System/Net/SslStreamPal.Unix.cs index 2014b6feccd6..b90a825bac9a 100644 --- a/src/System.Net.Security/src/System/Net/SslStreamPal.Unix.cs +++ b/src/System.Net.Security/src/System/Net/SslStreamPal.Unix.cs @@ -66,7 +66,7 @@ public static SecurityStatusPal DecryptMessage(SafeDeleteContext securityContext public static SafeFreeContextBufferChannelBinding QueryContextChannelBinding(SafeDeleteContext phContext, ChannelBindingKind attribute) { - // TODO (Issue #3362) To be implemented + // TODO (Issue #3954) To be implemented throw NotImplemented.ByDesignWithMessage(SR.net_MethodNotImplementedException); } @@ -75,19 +75,9 @@ public static void QueryContextStreamSizes(SafeDeleteContext securityContext, ou streamSizes = new StreamSizes(); } - public static int QueryContextConnectionInfo(SafeDeleteContext securityContext, out SslConnectionInfo connectionInfo) + public static void QueryContextConnectionInfo(SafeDeleteContext securityContext, out SslConnectionInfo connectionInfo) { - connectionInfo = null; - try - { - connectionInfo = new SslConnectionInfo(securityContext.SslContext); - - return 0; - } - catch - { - return -1; - } + connectionInfo = new SslConnectionInfo(securityContext.SslContext); } private static SecurityStatusPal HandshakeInternal(SafeFreeCredentials credential, ref SafeDeleteContext context, From 02e3992cf5f11d7fc50debe4a16c4cb9527461e8 Mon Sep 17 00:00:00 2001 From: Shruti Garg Date: Thu, 29 Oct 2015 14:56:44 +0530 Subject: [PATCH 2/2] Fixed PR Comments and Synced code --- .../Interop/Unix/libssl/SslConnectionInfo.cs | 5 +- .../pal_ssl.cpp | 98 +++++++------------ .../pal_ssl.h | 19 +++- 3 files changed, 58 insertions(+), 64 deletions(-) diff --git a/src/Common/src/Interop/Unix/libssl/SslConnectionInfo.cs b/src/Common/src/Interop/Unix/libssl/SslConnectionInfo.cs index c8ec0aa1dedf..028aedf44cdc 100644 --- a/src/Common/src/Interop/Unix/libssl/SslConnectionInfo.cs +++ b/src/Common/src/Interop/Unix/libssl/SslConnectionInfo.cs @@ -31,7 +31,10 @@ internal SslConnectionInfo(SafeSslHandle sslContext) { throw Interop.OpenSsl.CreateSslException(SR.net_ssl_get_connection_info_failed); } - // TODO (Issue #3362) map key sizes + + //Openssl does not provide a way to return a exchange key size. + //It internally does calculate the key size before generating key to exchange + //It is not a constant (Algorthim specific) either that we can hardcode and return. } private SslProtocols MapProtocolVersion(string protocolVersion) diff --git a/src/Native/System.Security.Cryptography.Native/pal_ssl.cpp b/src/Native/System.Security.Cryptography.Native/pal_ssl.cpp index 14c4c1ac620d..0dfe4e75a156 100644 --- a/src/Native/System.Security.Cryptography.Native/pal_ssl.cpp +++ b/src/Native/System.Security.Cryptography.Native/pal_ssl.cpp @@ -364,57 +364,7 @@ enum class SSL_DataHashAlgorithm : int64_t #endif }; -class SSL_DataHashSize -{ -public: - static const int32_t MD5_HashKeySize = 128; - static const int32_t SHA1_HashKeySize = 160; - static const int32_t SHA256_HashKeySize = 256; - static const int32_t SHA384_HashKeySize = 384; - static const int32_t GOST_HashKeySize = 256; -}; - -static HashAlgorithmType MapHashAlgorithmType(const SSL_CIPHER* cipher) -{ - unsigned long mac; -#if HAVE_SSL_CIPHER_SPLIT_ALGORITHMS - mac = cipher->algorithm_mac; -#else - const unsigned long SSL_MAC_MASK = 0x00c00000L; - mac = cipher->algorithms & SSL_MAC_MASK; -#endif - - SSL_DataHashAlgorithm sslMac = static_cast(mac); - switch (sslMac) - { - case SSL_DataHashAlgorithm::SSL_MD5: - return HashAlgorithmType::Md5; - - case SSL_DataHashAlgorithm::SSL_SHA1: - return HashAlgorithmType::Sha1; - -#if HAVE_SSL_CIPHER_SPLIT_ALGORITHMS - case SSL_DataHashAlgorithm::SSL_GOST94: - return HashAlgorithmType::SSL_GOST94; - - case SSL_DataHashAlgorithm::SSL_GOST89MAC: - return HashAlgorithmType::SSL_GOST89; - - case SSL_DataHashAlgorithm::SSL_SHA256: - return HashAlgorithmType::SSL_SHA256; - - case SSL_DataHashAlgorithm::SSL_SHA384: - return HashAlgorithmType::SSL_SHA384; - - case SSL_DataHashAlgorithm::SSL_AEAD: - return HashAlgorithmType::SSL_AEAD; -#endif - } - - return HashAlgorithmType::None; -} - -static int32_t GetHashKeySize(const SSL_CIPHER* cipher) +static void GetHashAlgorithmTypeAndSize(const SSL_CIPHER* cipher, HashAlgorithmType* dataHashAlg, DataHashSize* hashKeySize) { unsigned long mac; #if HAVE_SSL_CIPHER_SPLIT_ALGORITHMS @@ -428,35 +378,58 @@ static int32_t GetHashKeySize(const SSL_CIPHER* cipher) switch (sslMac) { case SSL_DataHashAlgorithm::SSL_MD5: - return SSL_DataHashSize::MD5_HashKeySize; + *dataHashAlg = HashAlgorithmType::Md5; + *hashKeySize = DataHashSize::MD5_HashKeySize; + return; case SSL_DataHashAlgorithm::SSL_SHA1: - return SSL_DataHashSize::SHA1_HashKeySize; + *dataHashAlg = HashAlgorithmType::Sha1; + *hashKeySize = DataHashSize::SHA1_HashKeySize; + return; #if HAVE_SSL_CIPHER_SPLIT_ALGORITHMS case SSL_DataHashAlgorithm::SSL_GOST94: - return SSL_DataHashSize::GOST_HashKeySize; + *dataHashAlg = HashAlgorithmType::SSL_GOST94; + *hashKeySize = DataHashSize::GOST_HashKeySize; + return; case SSL_DataHashAlgorithm::SSL_GOST89MAC: - return SSL_DataHashSize::GOST_HashKeySize; + *dataHashAlg = HashAlgorithmType::SSL_GOST89; + *hashKeySize = DataHashSize::GOST_HashKeySize; + return; case SSL_DataHashAlgorithm::SSL_SHA256: - return SSL_DataHashSize::SHA256_HashKeySize; + *dataHashAlg = HashAlgorithmType::SSL_SHA256; + *hashKeySize = DataHashSize::SHA256_HashKeySize; + return; case SSL_DataHashAlgorithm::SSL_SHA384: - return SSL_DataHashSize::SHA384_HashKeySize; + *dataHashAlg = HashAlgorithmType::SSL_SHA384; + *hashKeySize = DataHashSize::SHA384_HashKeySize; + return; case SSL_DataHashAlgorithm::SSL_AEAD: - return 0; + *dataHashAlg = HashAlgorithmType::SSL_AEAD; + *hashKeySize = DataHashSize::Default; + return; #endif } + + *dataHashAlg = HashAlgorithmType::None; + *hashKeySize = DataHashSize::Default; + return; } -extern "C" int32_t GetSslConnectionInfo(SSL* ssl, CipherAlgorithmType* dataCipherAlg, ExchangeAlgorithmType* keyExchangeAlg, HashAlgorithmType* dataHashAlg, int32_t* dataKeySize, int32_t* hashKeySize) +extern "C" int32_t GetSslConnectionInfo(SSL* ssl, + CipherAlgorithmType* dataCipherAlg, + ExchangeAlgorithmType* keyExchangeAlg, + HashAlgorithmType* dataHashAlg, + int32_t* dataKeySize, + DataHashSize* hashKeySize) { const SSL_CIPHER* cipher; - if (!ssl || !dataCipherAlg || !keyExchangeAlg || !dataHashAlg || !dataKeySize) + if (!ssl || !dataCipherAlg || !keyExchangeAlg || !dataHashAlg || !dataKeySize || !hashKeySize) { goto err; } @@ -469,9 +442,8 @@ extern "C" int32_t GetSslConnectionInfo(SSL* ssl, CipherAlgorithmType* dataCiphe *dataCipherAlg = MapCipherAlgorithmType(cipher); *keyExchangeAlg = MapExchangeAlgorithmType(cipher); - *dataHashAlg = MapHashAlgorithmType(cipher); *dataKeySize = cipher->alg_bits; - *hashKeySize = GetHashKeySize(cipher); + GetHashAlgorithmTypeAndSize(cipher, dataHashAlg, hashKeySize); return 1; @@ -486,6 +458,8 @@ extern "C" int32_t GetSslConnectionInfo(SSL* ssl, CipherAlgorithmType* dataCiphe *dataHashAlg = HashAlgorithmType::None; if (dataKeySize) *dataKeySize = 0; + if (hashKeySize) + *hashKeySize = DataHashSize::Default; return 0; } diff --git a/src/Native/System.Security.Cryptography.Native/pal_ssl.h b/src/Native/System.Security.Cryptography.Native/pal_ssl.h index f7034ec52663..cf58cb2c8eff 100644 --- a/src/Native/System.Security.Cryptography.Native/pal_ssl.h +++ b/src/Native/System.Security.Cryptography.Native/pal_ssl.h @@ -4,6 +4,8 @@ #include "pal_crypto_types.h" #include +#include +#include /* These values should be kept in sync with System.Security.Authentication.SslProtocols. @@ -88,6 +90,16 @@ enum class HashAlgorithmType : int32_t SSL_AEAD = 229412, }; +enum class DataHashSize : int32_t +{ + MD5_HashKeySize = 8 * MD5_DIGEST_LENGTH, + SHA1_HashKeySize = 8 * SHA_DIGEST_LENGTH, + SHA256_HashKeySize = 8 * SHA256_DIGEST_LENGTH, + SHA384_HashKeySize = 8 * SHA384_DIGEST_LENGTH, + GOST_HashKeySize = 256, + Default = 0, +}; + enum SslErrorCode : int32_t { PAL_SSL_ERROR_NONE = 0, @@ -215,7 +227,12 @@ Returns the connection information for the SSL instance. Returns 1 upon success, otherwise 0. */ -extern "C" int32_t GetSslConnectionInfo(SSL* ssl, CipherAlgorithmType* dataCipherAlg, ExchangeAlgorithmType* keyExchangeAlg, HashAlgorithmType* dataHashAlg, int32_t* dataKeySize, int32_t* hashKeySize); +extern "C" int32_t GetSslConnectionInfo(SSL* ssl, + CipherAlgorithmType* dataCipherAlg, + ExchangeAlgorithmType* keyExchangeAlg, + HashAlgorithmType* dataHashAlg, + int32_t* dataKeySize, + DataHashSize* hashKeySize); /* Shims the SSL_write method.