TLS work continues...
This commit is contained in:
238
lib/TLS/src/TLS.cpp
Normal file
238
lib/TLS/src/TLS.cpp
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
Copyright 2015-2016 Amebis
|
||||
Copyright 2016 G<>ANT
|
||||
|
||||
This file is part of G<>ANTLink.
|
||||
|
||||
G<>ANTLink is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
G<>ANTLink is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with G<>ANTLink. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace winstd;
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// eap::tls_random
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
eap::tls_random::tls_random()
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_random::tls_random(_In_ const tls_random &other)
|
||||
{
|
||||
memcpy(data, other.data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_random::~tls_random()
|
||||
{
|
||||
SecureZeroMemory(data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_random& eap::tls_random::operator=(_In_ const tls_random &other)
|
||||
{
|
||||
if (this != std::addressof(other))
|
||||
memcpy(data, other.data, sizeof(data));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void eap::tls_random::clear()
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
void eap::tls_random::reset(_In_ HCRYPTPROV cp)
|
||||
{
|
||||
_time32((__time32_t*)&time);
|
||||
if (!CryptGenRandom(cp, sizeof(data) - sizeof(__time32_t), data + sizeof(__time32_t)))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating randomness.");
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// eap::tls_master_secret
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
eap::tls_master_secret::tls_master_secret()
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_master_secret::tls_master_secret(_In_ HCRYPTPROV cp)
|
||||
{
|
||||
data[0] = 3;
|
||||
data[1] = 1;
|
||||
|
||||
if (!CryptGenRandom(cp, sizeof(data) - 2, data + 2))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating PMS randomness.");
|
||||
}
|
||||
|
||||
|
||||
eap::tls_master_secret::tls_master_secret(_In_ const tls_master_secret &other)
|
||||
{
|
||||
memcpy(data, other.data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_master_secret::~tls_master_secret()
|
||||
{
|
||||
SecureZeroMemory(data, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
eap::tls_master_secret& eap::tls_master_secret::operator=(_In_ const tls_master_secret &other)
|
||||
{
|
||||
if (this != std::addressof(other))
|
||||
memcpy(data, other.data, sizeof(data));
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
void eap::tls_master_secret::clear()
|
||||
{
|
||||
memset(data, 0, sizeof(data));
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// eap::tls_conn_state
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
eap::tls_conn_state::tls_conn_state()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
eap::tls_conn_state::tls_conn_state(_In_ const tls_conn_state &other) :
|
||||
m_master_secret(other.m_master_secret),
|
||||
m_random_client(other.m_random_client),
|
||||
m_random_server(other.m_random_server)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
eap::tls_conn_state::tls_conn_state(_Inout_ tls_conn_state &&other) :
|
||||
m_master_secret(std::move(other.m_master_secret)),
|
||||
m_random_client(std::move(other.m_random_client)),
|
||||
m_random_server(std::move(other.m_random_server))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
eap::tls_conn_state& eap::tls_conn_state::operator=(_In_ const tls_conn_state &other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
m_master_secret = other.m_master_secret;
|
||||
m_random_client = other.m_random_client;
|
||||
m_random_server = other.m_random_server;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
eap::tls_conn_state& eap::tls_conn_state::operator=(_Inout_ tls_conn_state &&other)
|
||||
{
|
||||
if (this != std::addressof(other)) {
|
||||
m_master_secret = std::move(other.m_master_secret);
|
||||
m_random_client = std::move(other.m_random_client);
|
||||
m_random_server = std::move(other.m_random_server);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// eap::hash_hmac
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
eap::hash_hmac::hash_hmac(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
_In_ size_t size_secret)
|
||||
{
|
||||
// Prepare padding.
|
||||
sanitizing_blob padding(sizeof(padding_t));
|
||||
inner_padding(cp, alg, secret, size_secret, padding.data());
|
||||
|
||||
// Continue with the other constructor.
|
||||
this->hash_hmac::hash_hmac(cp, alg, padding.data());
|
||||
}
|
||||
|
||||
|
||||
eap::hash_hmac::hash_hmac(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_ const padding_t padding)
|
||||
{
|
||||
// Create inner hash.
|
||||
if (!m_hash_inner.create(cp, alg))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating inner hash.");
|
||||
|
||||
// Initialize it with the inner padding.
|
||||
if (!CryptHashData(m_hash_inner, padding, sizeof(padding_t), 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error hashing secret XOR inner padding.");
|
||||
|
||||
// Convert inner padding to outer padding for final calculation.
|
||||
padding_t padding_out;
|
||||
for (size_t i = 0; i < sizeof(padding_t); i++)
|
||||
padding_out[i] = padding[i] ^ (0x36 ^ 0x5c);
|
||||
|
||||
// Create outer hash.
|
||||
if (!m_hash_outer.create(cp, alg))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating outer hash.");
|
||||
|
||||
// Initialize it with the outer padding.
|
||||
if (!CryptHashData(m_hash_outer, padding_out, sizeof(padding_t), 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error hashing secret XOR inner padding.");
|
||||
}
|
||||
|
||||
|
||||
void eap::hash_hmac::inner_padding(
|
||||
_In_ HCRYPTPROV cp,
|
||||
_In_ ALG_ID alg,
|
||||
_In_bytecount_(size_secret ) const void *secret,
|
||||
_In_ size_t size_secret,
|
||||
_Out_ padding_t padding)
|
||||
{
|
||||
if (size_secret > sizeof(padding_t)) {
|
||||
// If the secret is longer than padding, use secret's hash instead.
|
||||
crypt_hash hash;
|
||||
if (!hash.create(cp, alg))
|
||||
throw win_runtime_error(__FUNCTION__ " Error creating hash.");
|
||||
if (!CryptHashData(hash, (const BYTE*)secret, (DWORD)size_secret, 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error hashing.");
|
||||
DWORD size_hash = sizeof(padding_t);
|
||||
if (!CryptGetHashParam(hash, HP_HASHVAL, padding, &size_hash, 0))
|
||||
throw win_runtime_error(__FUNCTION__ " Error finishing hash.");
|
||||
size_secret = size_hash;
|
||||
} else
|
||||
memcpy(padding, secret, size_secret);
|
||||
for (size_t i = 0; i < size_secret; i++)
|
||||
padding[i] ^= 0x36;
|
||||
memset(padding + size_secret, 0x36, sizeof(padding_t) - size_secret);
|
||||
}
|
Reference in New Issue
Block a user