Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to using COSE_Sign for the QueryRequest #185

Merged
merged 3 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions TeepUnitTest/ProtocolTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ static void TestConfigureKeys(teep_signature_kind_t signatureKind)
char agent_public_key_filename[256];
REQUIRE(StartAgentBroker(TEEP_AGENT_DATA_DIRECTORY, TRUE, signatureKind, agent_public_key_filename) == 0);

// Copy Agent keys to TAM
// Copy Agent keys to TAM.
CopyFile(agent_public_key_filename, TAM_DATA_DIRECTORY "/trusted");

// Copy TAM keys to Agent
// Copy TAM keys to Agent.
char tam_public_key_filename[256];
TamGetPublicKey(signatureKind, tam_public_key_filename);
CopyFile(tam_public_key_filename, TEEP_AGENT_DATA_DIRECTORY "/trusted");
Expand Down
7 changes: 4 additions & 3 deletions protocol/TeepAgentLib/AgentKeys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void TeepAgentGetSigningKeyPair(_Out_ struct t_cose_key* keyPair, _Out_ teep_sig
*kind = g_teep_agent_signing_key_kind;
}

vector<struct t_cose_key> g_tam_key_pairs;
map<teep_signature_kind_t,struct t_cose_key> g_tam_key_pairs;

/* TODO: This is just a placeholder for a real implementation.
* Currently we provide untrusted keys into the TAM.
Expand Down Expand Up @@ -64,14 +64,15 @@ teep_error_code_t TeepAgentConfigureTamKeys(_In_z_ const char* directory_name)
if (result != TEEP_ERR_SUCCESS) {
break;
}
g_tam_key_pairs.emplace_back(key_pair);
teep_signature_kind_t kind = (strstr(filename, "es256") != nullptr) ? TEEP_SIGNATURE_ES256 : TEEP_SIGNATURE_EDDSA;
g_tam_key_pairs[kind] = key_pair;
}
closedir(dir);
return result;
}

/* Get the TEEP Agents' public keys to verify an incoming message against. */
vector<struct t_cose_key> TeepAgentGetTamKeys()
map<teep_signature_kind_t, struct t_cose_key> TeepAgentGetTamKeys()
{
return g_tam_key_pairs;
}
Expand Down
4 changes: 2 additions & 2 deletions protocol/TeepAgentLib/AgentKeys.h
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
// Copyright (c) TEEP contributors
// SPDX-License-Identifier: MIT
#pragma once
#include <vector>
#include <map>

teep_error_code_t TeepAgentConfigureTamKeys(_In_z_ const char* directory_name);

std::vector<struct t_cose_key> TeepAgentGetTamKeys();
std::map<teep_signature_kind_t, struct t_cose_key> TeepAgentGetTamKeys();

void TeepAgentGetSigningKeyPair(_Out_ struct t_cose_key* keyPair, _Out_ teep_signature_kind_t* kind);
4 changes: 2 additions & 2 deletions protocol/TeepAgentLib/TeepAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -754,8 +754,8 @@ static teep_error_code_t TeepAgentVerifyMessageSignature(
UsefulBufC signed_cose;
signed_cose.ptr = message;
signed_cose.len = messageLength;
for (auto key_pair : TeepAgentGetTamKeys()) {
teep_error_code_t teeperr = teep_verify_cbor_message(&key_pair, &signed_cose, pencoded);
for (auto [kind, key_pair] : TeepAgentGetTamKeys()) {
teep_error_code_t teeperr = teep_verify_cbor_message(kind, &key_pair, &signed_cose, pencoded);
if (teeperr == TEEP_ERR_SUCCESS) {
// TODO(#114): save key_pair in session
return TEEP_ERR_SUCCESS;
Expand Down
1 change: 1 addition & 0 deletions protocol/TeepCommonLib/TeepCommonLib.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
<WarningLevel>Level3</WarningLevel>
<AdditionalIncludeDirectories>$(ProgramW6432)\openssl\include;$(SolutionDir)external\openssl\include;$(SolutionDir)external\openssl\_build\include;$(SolutionDir)external/t_cose/inc;$(SolutionDir)external/qcbor/inc</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<LanguageStandard>stdcpp17</LanguageStandard>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
Expand Down
215 changes: 205 additions & 10 deletions protocol/TeepCommonLib/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,34 @@ teep_error_code_t TeepInitialize(_In_z_ const char* signing_private_key_pair_fil
return teep_load_signing_key_pair(&key_pair, signing_private_key_pair_filename, signing_public_key_filename, signature_kind);
}

teep_error_code_t
teep_compute_key_id(teep_signature_kind_t signature_kind, _In_ const struct t_cose_key* key_pair, _Out_ UsefulBuf* key_id)
{
#if 1
// TODO: this is not correct or secure, switch to the other code path once we
// can get the public key from a t_cose_key key pair.
*(teep_signature_kind_t*)key_id->ptr = signature_kind;
key_id->len = sizeof(signature_kind);
return TEEP_ERR_SUCCESS;
#else
// Get the public key.
if (signature_kind == TEEP_SIGNATURE_ES256) {
}
else {
}

// Compute SHA-256 hash.
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, public_key.key.buffer.ptr, public_key.key.buffer.len);
SHA256_Final(hash, &sha256);

*key_id = UsefulBuf_FROM_BYTE_ARRAY_LITERAL(hash);
return TEEP_ERR_PERMANENT_ERROR;
#endif
}

teep_error_code_t
teep_sign1_cbor_message(
_In_ const struct t_cose_key* key_pair,
Expand All @@ -234,7 +262,12 @@ teep_sign1_cbor_message(
// Initialize for signing.
struct t_cose_sign1_sign_ctx sign_ctx;
t_cose_sign1_sign_init(&sign_ctx, 0, get_cose_algorithm(signature_kind));
t_cose_sign1_set_signing_key(&sign_ctx, *key_pair, NULL_Q_USEFUL_BUF_C);
UsefulBuf_MAKE_STACK_UB(key_id, SHA256_DIGEST_LENGTH);
teep_error_code_t result = teep_compute_key_id(signature_kind, key_pair, &key_id);
if (result != TEEP_ERR_SUCCESS) {
return result;
}
t_cose_sign1_set_signing_key(&sign_ctx, *key_pair, UsefulBuf_Const(key_id));

// Compute the size of the output and auxiliary buffers.
struct q_useful_buf null_buff { NULL, SIZE_MAX };
Expand Down Expand Up @@ -292,19 +325,86 @@ teep_sign_cbor_message(
teep_signature_kind_t signature_kind,
_Out_ UsefulBufC* signed_message)
{
// TODO(#104): t_cose 2.0 should support Sign.
// Switch to it once it's ready and supports EdDSA.
// In the meantime, we just use Sign1 ES256.
// Initialize for signing.
struct t_cose_sign_sign_ctx sign_ctx;
t_cose_sign_sign_init(&sign_ctx, T_COSE_OPT_MESSAGE_TYPE_SIGN);

struct t_cose_signature_sign_eddsa eddsa_signer;
struct t_cose_signature_sign_main es256_signer;
UsefulBuf_MAKE_STACK_UB(eddsa_key_id, SHA256_DIGEST_LENGTH);
UsefulBuf_MAKE_STACK_UB(es256_key_id, SHA256_DIGEST_LENGTH);
for (const auto& [kind, key_pair] : key_pairs) {
int32_t algorithm_id = (kind == TEEP_SIGNATURE_ES256) ? T_COSE_ALGORITHM_ES256 : T_COSE_ALGORITHM_EDDSA;
if (kind == TEEP_SIGNATURE_ES256) {
t_cose_signature_sign_main_init(&es256_signer, algorithm_id);
teep_error_code_t result = teep_compute_key_id(kind, &key_pair, &es256_key_id);
if (result != TEEP_ERR_SUCCESS) {
return result;
}
t_cose_signature_sign_main_set_signing_key(&es256_signer, key_pair, UsefulBuf_Const(es256_key_id));
t_cose_sign_add_signer(&sign_ctx, t_cose_signature_sign_from_main(&es256_signer));
} else {
t_cose_signature_sign_eddsa_init(&eddsa_signer);
teep_error_code_t result = teep_compute_key_id(kind, &key_pair, &eddsa_key_id);
if (result != TEEP_ERR_SUCCESS) {
return result;
}
t_cose_signature_sign_eddsa_set_signing_key(&eddsa_signer, key_pair, UsefulBuf_Const(eddsa_key_id));
t_cose_sign_add_signer(&sign_ctx, t_cose_signature_sign_from_eddsa(&eddsa_signer));

// Compute the size of the output and auxiliary buffers.
struct q_useful_buf null_buff { NULL, SIZE_MAX };
struct q_useful_buf_c signed_cose;
enum t_cose_err_t return_value = t_cose_sign_sign(&sign_ctx,
NULL_Q_USEFUL_BUF_C, // No externally supplied AAD.
*unsigned_message,
null_buff,
&signed_cose);

// Allocate buffers of the right size.
if (signed_cose.len > signed_message_buffer.len) {
return TEEP_ERR_TEMPORARY_ERROR;
}
struct q_useful_buf auxiliary_buffer = {};
auxiliary_buffer.len = t_cose_signature_sign_eddsa_auxiliary_buffer_size(&eddsa_signer);
if (auxiliary_buffer.len > 0) {
auxiliary_buffer.ptr = malloc(auxiliary_buffer.len);
if (auxiliary_buffer.ptr == NULL) {
return TEEP_ERR_TEMPORARY_ERROR;
}
}

t_cose_signature_sign_eddsa_set_auxiliary_buffer(&eddsa_signer, auxiliary_buffer);
}
}

return teep_sign1_cbor_message(&key_pairs[TEEP_SIGNATURE_ES256],
unsigned_message,
// Sign.
enum t_cose_err_t return_value = t_cose_sign_sign(&sign_ctx,
NULL_Q_USEFUL_BUF_C, // No externally supplied AAD.
*unsigned_message,
/* Non-const pointer and length of the
* buffer where the completed output is
* written to. The length here is that
* of the whole buffer.
*/
signed_message_buffer,
TEEP_SIGNATURE_ES256,
/* Const pointer and actual length of
* the completed, signed and encoded
* COSE_Sign1 message. This points
* into the output buffer and has the
* lifetime of the output buffer.
*/
signed_message);
if (return_value != T_COSE_SUCCESS) {
TeepLogMessage("COSE Sign failed with error %d\n", return_value);
return TEEP_ERR_PERMANENT_ERROR;
}

return TEEP_ERR_SUCCESS;
}

teep_error_code_t
teep_verify_cbor_message(
teep_verify_cbor_message_sign1(
_In_ const struct t_cose_key* key_pair,
_In_ const UsefulBufC* signed_cose,
_Out_ UsefulBufC* encoded)
Expand All @@ -313,7 +413,7 @@ teep_verify_cbor_message(

t_cose_sign1_verify_init(&verify_ctx, T_COSE_OPT_DECODE_ONLY);
UsefulBufC payload = {};
int return_value = t_cose_sign1_verify(&verify_ctx, *signed_cose, &payload, nullptr);
t_cose_err_t return_value = t_cose_sign1_verify(&verify_ctx, *signed_cose, &payload, nullptr);
if (return_value != T_COSE_SUCCESS) {
TeepLogMessage("First t_cose_sign1_verify failed with error %d\n", return_value);
return TEEP_ERR_PERMANENT_ERROR;
Expand All @@ -338,7 +438,7 @@ teep_verify_cbor_message(
return_value = t_cose_sign1_verify(&verify_ctx,
*signed_cose, /* COSE to verify */
encoded, /* Payload from signed_cose */
NULL); /* Don't return parameters */
nullptr); /* Don't return parameters */
free(auxiliary_buffer.ptr);
if (return_value != T_COSE_SUCCESS) {
TeepLogMessage("Second t_cose_sign1_verify failed with error %d\n", return_value);
Expand All @@ -348,6 +448,101 @@ teep_verify_cbor_message(
return TEEP_ERR_SUCCESS;
}

// TODO: Define this once https://github.com/laurencelundblade/t_cose/issues/252
// is fixed.
#undef COMPUTE_AUXILIARY_BUFFER_SIZE

teep_error_code_t
teep_verify_cbor_message_sign(
teep_signature_kind_t signature_kind,
_In_ const struct t_cose_key* key_pair,
_In_ const UsefulBufC* signed_cose,
_Out_ UsefulBufC* encoded)
{
struct t_cose_sign_verify_ctx verify_ctx;

UsefulBuf_MAKE_STACK_UB(key_id, SHA256_DIGEST_LENGTH);
teep_error_code_t result = teep_compute_key_id(signature_kind, key_pair, &key_id);
if (result != TEEP_ERR_SUCCESS) {
return result;
}

// Initialize verifiers.
#ifndef COMPUTE_AUXILIARY_BUFFER_SIZE
t_cose_sign_verify_init(&verify_ctx, 0);
#else
t_cose_sign_verify_init(&verify_ctx, T_COSE_OPT_DECODE_ONLY);
#endif
struct t_cose_signature_verify_main es256_verifier;
struct t_cose_signature_verify_eddsa eddsa_verifier;
if (signature_kind == TEEP_SIGNATURE_ES256) {
// ES256 verifier.
t_cose_signature_verify_main_init(&es256_verifier);
t_cose_signature_verify_main_set_key(&es256_verifier, *key_pair, UsefulBuf_Const(key_id));
t_cose_sign_add_verifier(&verify_ctx, t_cose_signature_verify_from_main(&es256_verifier));
} else {
// EdDSA verifier.
t_cose_signature_verify_eddsa_init(&eddsa_verifier, 0);
t_cose_signature_verify_eddsa_set_key(&eddsa_verifier, *key_pair, UsefulBuf_Const(key_id));
t_cose_sign_add_verifier(&verify_ctx, t_cose_signature_verify_from_eddsa(&eddsa_verifier));
}

t_cose_err_t return_value;
struct q_useful_buf auxiliary_buffer = {};
#ifdef COMPUTE_AUXILIARY_BUFFER_SIZE
// Compute the auxiliary buffer size needed.
UsefulBufC payload = {};
return_value = t_cose_sign_verify(&verify_ctx, *signed_cose, NULL_Q_USEFUL_BUF_C, &payload, nullptr);
if (return_value != T_COSE_SUCCESS) {
TeepLogMessage("First t_cose_sign1_verify failed with error %d\n", return_value);
return TEEP_ERR_PERMANENT_ERROR;
}
t_cose_sign_verify_init(&verify_ctx, 0);

// Allocate an auxiliary buffer of the right size
auxiliary_buffer.len = t_cose_signature_verify_eddsa_auxiliary_buffer_size(&eddsa_verifier);
#else
auxiliary_buffer.len = 1024;
#endif
if (auxiliary_buffer.len > 0) {
auxiliary_buffer.ptr = malloc(auxiliary_buffer.len);
if (auxiliary_buffer.ptr == NULL) {
TeepLogMessage("teep_verify_cbor_message could not allocate %d bytes\n", auxiliary_buffer.len);
return TEEP_ERR_TEMPORARY_ERROR;
}
}
t_cose_signature_verify_eddsa_set_auxiliary_buffer(&eddsa_verifier, auxiliary_buffer);

// Do the actual verification.
return_value = t_cose_sign_verify(&verify_ctx,
*signed_cose, /* COSE to verify */
NULL_Q_USEFUL_BUF_C, /* No AAD */
encoded, /* Payload from signed_cose */
nullptr); /* Don't return parameters */
if (return_value != T_COSE_SUCCESS) {
TeepLogMessage("Second t_cose_sign_verify failed with error %d\n", return_value);
return TEEP_ERR_PERMANENT_ERROR;
}

return TEEP_ERR_SUCCESS;
}

teep_error_code_t
teep_verify_cbor_message(
teep_signature_kind_t signature_kind,
_In_ const struct t_cose_key* key_pair,
_In_ const UsefulBufC* signed_cose,
_Out_ UsefulBufC* encoded)
{
#if 0
teep_error_code_t result = teep_verify_cbor_message_sign1(key_pair, signed_cose, encoded);
if (result == TEEP_ERR_SUCCESS) {
return TEEP_ERR_SUCCESS;
}
#endif
return teep_verify_cbor_message_sign(signature_kind, key_pair, signed_cose, encoded);
}

#ifdef TEEP_USE_CERTIFICATES // Currently unused.
_Ret_writes_bytes_maybenull_(*pCertificateSize)
const unsigned char* GetDerCertificate(
Expand Down
1 change: 1 addition & 0 deletions protocol/TeepCommonLib/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ teep_sign_cbor_message(

teep_error_code_t
teep_verify_cbor_message(
teep_signature_kind_t signature_kind,
_In_ const struct t_cose_key* key_pair,
_In_ const UsefulBufC* signed_cose,
_Out_ UsefulBufC* encoded);
Expand Down
7 changes: 4 additions & 3 deletions protocol/TeepTamLib/TamKeys.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ teep_error_code_t TamGetSigningKeyPairs(_Out_ std::map<teep_signature_kind_t, st
return TEEP_ERR_SUCCESS;
}

vector<struct t_cose_key> g_agent_key_pairs;
map<teep_signature_kind_t, struct t_cose_key> g_agent_key_pairs;

/* TODO: This is just a placeholder for a real implementation.
* Currently we provide untrusted keys into the TAM.
Expand Down Expand Up @@ -63,7 +63,8 @@ teep_error_code_t TamConfigureAgentKeys(_In_z_ const char* directory_name)
if (result != TEEP_ERR_SUCCESS) {
break;
}
g_agent_key_pairs.emplace_back(key_pair);
teep_signature_kind_t kind = (strstr(filename, "es256") != nullptr) ? TEEP_SIGNATURE_ES256 : TEEP_SIGNATURE_EDDSA;
g_agent_key_pairs[kind] = key_pair;

TeepLogMessage("TAM loaded TEEP agent key from %s\n", keyfile.c_str());
}
Expand All @@ -72,7 +73,7 @@ teep_error_code_t TamConfigureAgentKeys(_In_z_ const char* directory_name)
}

/* Get the TEEP Agents' public keys to verify an incoming message against. */
vector<struct t_cose_key> TamGetTeepAgentKeys()
map<teep_signature_kind_t, struct t_cose_key> TamGetTeepAgentKeys()
{
return g_agent_key_pairs;
}
Expand Down
3 changes: 1 addition & 2 deletions protocol/TeepTamLib/TamKeys.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@
// SPDX-License-Identifier: MIT
#pragma once
#include <map>
#include <vector>

teep_error_code_t TamConfigureAgentKeys(_In_z_ const char* directory_name);

std::vector<struct t_cose_key> TamGetTeepAgentKeys();
std::map<teep_signature_kind_t, struct t_cose_key> TamGetTeepAgentKeys();

teep_error_code_t TamGetSigningKeyPairs(_Out_ std::map<teep_signature_kind_t, struct t_cose_key>& key_pairs);

Expand Down
Loading