/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this file ,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <memory>
#include "nss.h"
#include "pk11pub.h"
#include "cpputil.h"
#include "gtest/gtest.h"
namespace nss_test {
const size_t kPmsSize =
48 ;
const size_t kMasterSecretSize =
48 ;
const size_t kPrfSeedSizeSha256 =
32 ;
const size_t kPrfSeedSizeTlsPrf =
36 ;
// This is not the right size for anything
const size_t kIncorrectSize =
17 ;
const uint8_t kPmsData[] = {
0 x00,
0 x01,
0 x02,
0 x03,
0 x04,
0 x05,
0 x06,
0 x07,
0 x08,
0 x09,
0 x0a,
0 x0b,
0 x0c,
0 x0d,
0 x0e,
0 x0f,
0 x10,
0 x11,
0 x12,
0 x13,
0 x14,
0 x15,
0 x16,
0 x17,
0 x18,
0 x19,
0 x1a,
0 x1b,
0 x1c,
0 x1d,
0 x1e,
0 x1f,
0 x20,
0 x21,
0 x22,
0 x23,
0 x24,
0 x25,
0 x26,
0 x27,
0 x28,
0 x29,
0 x2a,
0 x2b,
0 x2c,
0 x2d,
0 x2e,
0 x2f};
const uint8_t kPrfSeed[] = {
0 xf0,
0 xf1,
0 xf2,
0 xf3,
0 xf4,
0 xf5,
0 xf6,
0 xf7,
0 xf8,
0 xf9,
0 xfa,
0 xfb,
0 xfc,
0 xfd,
0 xfe,
0 xff,
0 xe0,
0 xe1,
0 xe2,
0 xe3,
0 xe4,
0 xe5,
0 xe6,
0 xe7,
0 xe8,
0 xe9,
0 xea,
0 xeb,
0 xec,
0 xed,
0 xee,
0 xef,
0 xd0,
0 xd1,
0 xd2,
0 xd3};
const uint8_t kExpectedOutputEmsSha256[] = {
0 x75,
0 xa7,
0 xa5,
0 x98,
0 xef,
0 xab,
0 x90,
0 xe7,
0 x7c,
0 x67,
0 x80,
0 xde,
0 xab,
0 x3a,
0 x11,
0 xf3,
0 x5d,
0 xb2,
0 xf8,
0 x47,
0 xff,
0 x09,
0 x01,
0 xec,
0 xf8,
0 x93,
0 x89,
0 xfc,
0 x98,
0 x2e,
0 x6e,
0 xf9,
0 x2c,
0 xf5,
0 x9b,
0 x04,
0 x04,
0 x6f,
0 xd7,
0 x28,
0 x6e,
0 xea,
0 xe3,
0 x83,
0 xc4,
0 x4a,
0 xff,
0 x03};
const uint8_t kExpectedOutputEmsTlsPrf[] = {
0 x06,
0 xbf,
0 x29,
0 x86,
0 x5d,
0 xf3,
0 x3e,
0 x38,
0 xfd,
0 xfa,
0 x91,
0 x10,
0 x2a,
0 x20,
0 xff,
0 xd6,
0 xb9,
0 xd5,
0 x72,
0 x5a,
0 x6d,
0 x42,
0 x20,
0 x16,
0 xde,
0 xa4,
0 xa0,
0 x51,
0 xe5,
0 x53,
0 xc1,
0 x28,
0 x04,
0 x99,
0 xbc,
0 xb1,
0 x2c,
0 x9d,
0 xe8,
0 x0b,
0 x18,
0 xa2,
0 x0e,
0 x48,
0 x52,
0 x8d,
0 x61,
0 x13};
class TlsPrfTest :
public ::testing::Test {
public :
TlsPrfTest()
: params_({siBuffer, nullptr,
0 }),
pms_item_({siBuffer, toUcharPtr(kPmsData), kPmsSize}),
key_mech_(
0 ),
slot_(nullptr),
pms_(nullptr),
ms_(nullptr),
pms_version_({
0 ,
0 }) {}
~TlsPrfTest() {
if (slot_) {
PK11_FreeSlot(slot_);
}
ClearTempVars();
}
void ClearTempVars() {
if (pms_) {
PK11_FreeSymKey(pms_);
}
if (ms_) {
PK11_FreeSymKey(ms_);
}
}
void Init() {
params_.type = siBuffer;
pms_item_.type = siBuffer;
pms_item_.data =
const_cast <
unsigned char *>(
static_cast <
const unsigned char *>(kPmsData));
slot_ = PK11_GetInternalSlot();
ASSERT_NE(nullptr, slot_);
}
void CheckForError(CK_MECHANISM_TYPE hash_mech, size_t seed_len,
size_t pms_len, size_t output_len) {
// Error tests don't depend on the derivation mechansim
Inner(CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE, hash_mech, seed_len, pms_len,
output_len, nullptr, nullptr);
}
void ComputeAndVerifyMs(CK_MECHANISM_TYPE derive_mech,
CK_MECHANISM_TYPE hash_mech, CK_VERSION* version,
const uint8_t* expected) {
// Infer seed length from mechanism
int seed_len =
0 ;
switch (hash_mech) {
case CKM_TLS_PRF:
seed_len = kPrfSeedSizeTlsPrf;
break ;
case CKM_SHA256:
seed_len = kPrfSeedSizeSha256;
break ;
default :
ASSERT_TRUE(
false );
}
Inner(derive_mech, hash_mech, seed_len, kPmsSize,
0 , version, expected);
}
// Set output == nullptr to test when errors occur
void Inner(CK_MECHANISM_TYPE derive_mech, CK_MECHANISM_TYPE hash_mech,
size_t seed_len, size_t pms_len, size_t output_len,
CK_VERSION* version,
const uint8_t* expected) {
ClearTempVars();
// Infer the key mechanism from the hash type
switch (hash_mech) {
case CKM_TLS_PRF:
key_mech_ = CKM_TLS_KEY_AND_MAC_DERIVE;
break ;
case CKM_SHA256:
key_mech_ = CKM_NSS_TLS_KEY_AND_MAC_DERIVE_SHA256;
break ;
default :
ASSERT_TRUE(
false );
}
// Import the params
CK_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_PARAMS master_params = {
hash_mech, toUcharPtr(kPrfSeed),
static_cast <CK_ULONG>(seed_len),
version};
params_.data =
reinterpret_cast <
unsigned char *>(&master_params);
params_.len =
sizeof (master_params);
// Import the PMS
pms_item_.len = pms_len;
pms_ = PK11_ImportSymKey(slot_, derive_mech, PK11_OriginUnwrap, CKA_DERIVE,
&pms_item_, NULL);
ASSERT_NE(nullptr, pms_);
// Compute the EMS
ms_ = PK11_DeriveWithFlags(pms_, derive_mech, ¶ms_, key_mech_,
CKA_DERIVE, output_len, CKF_SIGN | CKF_VERIFY);
// Verify the EMS has the expected value (null or otherwise)
if (!expected) {
EXPECT_EQ(nullptr, ms_);
}
else {
ASSERT_NE(nullptr, ms_);
SECStatus rv = PK11_ExtractKeyValue(ms_);
ASSERT_EQ(SECSuccess, rv);
SECItem* msData = PK11_GetKeyData(ms_);
ASSERT_NE(nullptr, msData);
ASSERT_EQ(kMasterSecretSize, msData->len);
EXPECT_EQ(
0 , memcmp(msData->data, expected, kMasterSecretSize));
}
}
protected :
SECItem params_;
SECItem pms_item_;
CK_MECHANISM_TYPE key_mech_;
PK11SlotInfo* slot_;
PK11SymKey* pms_;
PK11SymKey* ms_;
CK_VERSION pms_version_;
};
TEST_F(TlsPrfTest, ExtendedMsParamErr) {
Init();
// This should fail; it's the correct set from which the below are derived
// CheckForError(CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE, CKM_TLS_PRF,
// kPrfSeedSizeTlsPrf, kPmsSize, 0);
// Output key size != 0, SSL3_MASTER_SECRET_LENGTH
CheckForError(CKM_TLS_PRF, kPrfSeedSizeTlsPrf, kPmsSize, kIncorrectSize);
// not-DH && pms size != SSL3_PMS_LENGTH
CheckForError(CKM_TLS_PRF, kPrfSeedSizeTlsPrf, kIncorrectSize,
0 );
// CKM_TLS_PRF && seed length != MD5_LENGTH + SHA1_LENGTH
CheckForError(CKM_TLS_PRF, kIncorrectSize, kPmsSize,
0 );
// !CKM_TLS_PRF && seed length != hash output length
CheckForError(CKM_SHA256, kIncorrectSize, kPmsSize,
0 );
}
// Test matrix:
//
// DH RSA
// TLS_PRF 1 2
// SHA256 3 4
TEST_F(TlsPrfTest, ExtendedMsDhTlsPrf) {
Init();
ComputeAndVerifyMs(CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH, CKM_TLS_PRF,
nullptr, kExpectedOutputEmsTlsPrf);
}
TEST_F(TlsPrfTest, ExtendedMsRsaTlsPrf) {
Init();
ComputeAndVerifyMs(CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE, CKM_TLS_PRF,
&pms_version_, kExpectedOutputEmsTlsPrf);
EXPECT_EQ(
0 , pms_version_.major);
EXPECT_EQ(
1 , pms_version_.minor);
}
TEST_F(TlsPrfTest, ExtendedMsDhSha256) {
Init();
ComputeAndVerifyMs(CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE_DH, CKM_SHA256,
nullptr, kExpectedOutputEmsSha256);
}
TEST_F(TlsPrfTest, ExtendedMsRsaSha256) {
Init();
ComputeAndVerifyMs(CKM_NSS_TLS_EXTENDED_MASTER_KEY_DERIVE, CKM_SHA256,
&pms_version_, kExpectedOutputEmsSha256);
EXPECT_EQ(
0 , pms_version_.major);
EXPECT_EQ(
1 , pms_version_.minor);
}
}
// namespace nss_test
Messung V0.5 in Prozent C=92 H=100 G=95
¤ Dauer der Verarbeitung: 0.3 Sekunden
¤
*© Formatika GbR, Deutschland