Skip to content

Commit 22f36b3

Browse files
authored
Split keypair.h (#828)
1 parent 360abf5 commit 22f36b3

File tree

11 files changed

+480
-444
lines changed

11 files changed

+480
-444
lines changed

src/consensus/pbft/libbyz/parameters.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#pragma once
77

88
#include "tls/keypair.h"
9+
#include "tls/verifier.h"
910

1011
#include <cstddef>
1112

src/enclave/httpsig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
#include "httpparser.h"
66
#include "node/clientsignatures.h"
77
#include "tls/base64.h"
8-
#include "tls/keypair.h"
8+
#include "tls/hash.h"
99

1010
#include <fmt/format_header_only.h>
1111
#include <optional>

src/node/genesisgen.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include "rpc/consts.h"
1313
#include "rpc/jsonrpc.h"
1414
#include "runtime_config/default_whitelists.h"
15-
#include "tls/keypair.h"
15+
#include "tls/verifier.h"
1616
#include "values.h"
1717

1818
#include <algorithm>

src/node/history.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,15 @@
22
// Licensed under the Apache 2.0 License.
33
#pragma once
44

5-
#include "../consensus/pbft/pbfttypes.h"
6-
#include "../crypto/hash.h"
7-
#include "../ds/logger.h"
8-
#include "../kv/kvtypes.h"
9-
#include "../tls/keypair.h"
10-
#include "../tls/tls.h"
5+
#include "consensus/pbft/pbfttypes.h"
6+
#include "crypto/hash.h"
7+
#include "ds/logger.h"
118
#include "entities.h"
9+
#include "kv/kvtypes.h"
1210
#include "nodes.h"
1311
#include "signatures.h"
12+
#include "tls/tls.h"
13+
#include "tls/verifier.h"
1414

1515
#include <array>
1616
#include <deque>

src/node/rpc/frontend.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "node/nodes.h"
1313
#include "nodeinterface.h"
1414
#include "rpcexception.h"
15+
#include "tls/verifier.h"
1516

1617
#include <fmt/format_header_only.h>
1718
#include <mutex>

src/node/rpc/test/nodefrontend_test.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "node/rpc/nodefrontend.h"
1111
#include "node_stub.h"
1212
#include "tls/pem.h"
13+
#include "tls/verifier.h"
1314

1415
using namespace ccf;
1516
using namespace nlohmann;

src/tls/curve.h

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the Apache 2.0 License.
3+
#pragma once
4+
5+
#include "ds/logger.h"
6+
#include "tls.h"
7+
8+
#include <secp256k1/include/secp256k1.h>
9+
#include <secp256k1/include/secp256k1_recovery.h>
10+
#include <stdexcept>
11+
#include <string>
12+
13+
namespace tls
14+
{
15+
enum class CurveImpl
16+
{
17+
secp384r1 = 1,
18+
#ifdef MOD_MBEDTLS
19+
ed25519 = 2,
20+
#endif
21+
secp256k1_mbedtls = 3,
22+
secp256k1_bitcoin = 4,
23+
24+
#if SERVICE_IDENTITY_CURVE_CHOICE_SECP384R1
25+
service_identity_curve_choice = secp384r1,
26+
#elif SERVICE_IDENTITY_CURVE_CHOICE_ED25519
27+
service_identity_curve_choice = ed25519,
28+
#elif SERVICE_IDENTITY_CURVE_CHOICE_SECP256K1_MBEDTLS
29+
service_identity_curve_choice = secp256k1_mbedtls,
30+
#elif SERVICE_IDENTITY_CURVE_CHOICE_SECP256K1_BITCOIN
31+
service_identity_curve_choice = secp256k1_bitcoin,
32+
#else
33+
# pragma message( \
34+
"No service identity curve specified - defaulting to secp384r1")
35+
service_identity_curve_choice = secp384r1,
36+
#endif
37+
};
38+
39+
// 2 implementations of secp256k1 are available - mbedtls and bitcoin. Either
40+
// can be asked for explicitly via the CurveImpl enum. For cases where we
41+
// receive a raw 256k1 key/signature/cert only, this flag determines which
42+
// implementation is used
43+
static constexpr bool prefer_bitcoin_secp256k1 = true;
44+
45+
// Helper to access elliptic curve id from context
46+
inline mbedtls_ecp_group_id get_ec_from_context(const mbedtls_pk_context& ctx)
47+
{
48+
return mbedtls_pk_ec(ctx)->grp.id;
49+
}
50+
51+
// Get mbedtls elliptic curve for given CCF curve implementation
52+
inline mbedtls_ecp_group_id get_ec_for_curve_impl(CurveImpl curve)
53+
{
54+
switch (curve)
55+
{
56+
case CurveImpl::secp384r1:
57+
{
58+
return MBEDTLS_ECP_DP_SECP384R1;
59+
}
60+
#ifdef MOD_MBEDTLS
61+
case CurveImpl::ed25519:
62+
{
63+
return MBEDTLS_ECP_DP_CURVE25519;
64+
}
65+
#endif
66+
case CurveImpl::secp256k1_mbedtls:
67+
case CurveImpl::secp256k1_bitcoin:
68+
{
69+
return MBEDTLS_ECP_DP_SECP256K1;
70+
}
71+
default:
72+
{
73+
throw std::logic_error(
74+
"Unhandled curve type: " +
75+
std::to_string(static_cast<size_t>(curve)));
76+
}
77+
}
78+
}
79+
80+
// Get message digest algorithm to use for given elliptic curve
81+
inline mbedtls_md_type_t get_md_for_ec(mbedtls_ecp_group_id ec)
82+
{
83+
switch (ec)
84+
{
85+
case MBEDTLS_ECP_DP_SECP384R1:
86+
{
87+
return MBEDTLS_MD_SHA384;
88+
}
89+
#ifdef MOD_MBEDTLS
90+
case MBEDTLS_ECP_DP_CURVE25519:
91+
{
92+
return MBEDTLS_MD_SHA512;
93+
}
94+
#endif
95+
case MBEDTLS_ECP_DP_SECP256K1:
96+
{
97+
return MBEDTLS_MD_SHA256;
98+
}
99+
default:
100+
{
101+
throw std::logic_error(
102+
std::string("Unhandled ecp group id: ") +
103+
mbedtls_ecp_curve_info_from_grp_id(ec)->name);
104+
}
105+
}
106+
}
107+
108+
inline bool verify_secp256k_bc(
109+
secp256k1_context* ctx,
110+
const uint8_t* signature,
111+
size_t signature_size,
112+
const uint8_t* hash,
113+
size_t hash_size,
114+
const secp256k1_pubkey* public_key)
115+
{
116+
if (hash_size != 32)
117+
return false;
118+
119+
secp256k1_ecdsa_signature sig;
120+
if (
121+
secp256k1_ecdsa_signature_parse_der(
122+
ctx, &sig, signature, signature_size) != 1)
123+
return false;
124+
125+
secp256k1_ecdsa_signature norm_sig;
126+
if (secp256k1_ecdsa_signature_normalize(ctx, &norm_sig, &sig) == 1)
127+
{
128+
LOG_TRACE_FMT("secp256k1 normalized a signature to lower-S form");
129+
}
130+
131+
return secp256k1_ecdsa_verify(ctx, &norm_sig, hash, public_key) == 1;
132+
}
133+
134+
static void secp256k1_illegal_callback(const char* str, void*)
135+
{
136+
throw std::logic_error(
137+
fmt::format("[libsecp256k1] illegal argument: {}", str));
138+
}
139+
140+
// Wrap calls to secp256k1_context_create, setting illegal callback to throw
141+
// catchable errors rather than aborting, and ensuring destroy is called when
142+
// this goes out of scope
143+
class BCk1Context
144+
{
145+
public:
146+
secp256k1_context* p = nullptr;
147+
148+
BCk1Context(unsigned int flags)
149+
{
150+
p = secp256k1_context_create(flags);
151+
152+
secp256k1_context_set_illegal_callback(
153+
p, secp256k1_illegal_callback, nullptr);
154+
}
155+
156+
~BCk1Context()
157+
{
158+
secp256k1_context_destroy(p);
159+
}
160+
};
161+
162+
using BCk1ContextPtr = std::unique_ptr<BCk1Context>;
163+
164+
inline BCk1ContextPtr make_bc_context(unsigned int flags)
165+
{
166+
return std::make_unique<BCk1Context>(flags);
167+
}
168+
}

src/tls/hash.h

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the Apache 2.0 License.
3+
#pragma once
4+
5+
#include "curve.h"
6+
7+
#include <vector>
8+
9+
namespace tls
10+
{
11+
using HashBytes = std::vector<uint8_t>;
12+
13+
/**
14+
* Hash the given data, with the specified digest algorithm
15+
*
16+
* @return 0 on success
17+
*/
18+
inline int do_hash(
19+
const uint8_t* data_ptr,
20+
size_t data_size,
21+
HashBytes& o_hash,
22+
mbedtls_md_type_t md_type)
23+
{
24+
const auto md_info = mbedtls_md_info_from_type(md_type);
25+
const auto hash_size = mbedtls_md_get_size(md_info);
26+
27+
if (o_hash.size() < hash_size)
28+
{
29+
o_hash.resize(hash_size);
30+
}
31+
32+
return mbedtls_md(md_info, data_ptr, data_size, o_hash.data());
33+
}
34+
35+
/**
36+
* Hash the given data, with an algorithm chosen by key type
37+
*
38+
* @return 0 on success
39+
*/
40+
inline int do_hash(
41+
const mbedtls_pk_context& ctx,
42+
const uint8_t* data_ptr,
43+
size_t data_size,
44+
HashBytes& o_hash,
45+
mbedtls_md_type_t md_type_ = MBEDTLS_MD_NONE)
46+
{
47+
const auto ec = get_ec_from_context(ctx);
48+
mbedtls_md_type_t md_type;
49+
if (md_type_ != MBEDTLS_MD_NONE)
50+
{
51+
md_type = md_type_;
52+
}
53+
else
54+
{
55+
md_type = get_md_for_ec(ec);
56+
}
57+
const auto md_info = mbedtls_md_info_from_type(md_type);
58+
const auto hash_size = mbedtls_md_get_size(md_info);
59+
60+
if (o_hash.size() < hash_size)
61+
o_hash.resize(hash_size);
62+
63+
return mbedtls_md(md_info, data_ptr, data_size, o_hash.data());
64+
}
65+
66+
}

0 commit comments

Comments
 (0)