Skip to content

Commit 4cac5c5

Browse files
committed
Fix for bug in git issue 260 & addressing some revie comments
Signed-off-by: prakashngit <[email protected]>
1 parent 4ba4cc1 commit 4cac5c5

File tree

5 files changed

+30
-54
lines changed

5 files changed

+30
-54
lines changed

ccf_transaction_processor/Readme.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,7 @@ only under the virtual enclave mode for both PDO and CCF. (set env variable SGX_
1717
set cmake flag TARGET=virtual for ccf). Support for HW mode for both PDO and CCF will be added soon. Further,
1818
the current implementation of PDO TP hasn't been tested under multi-threaded CCF enclaves.(CCF 0.7.1 offers initial support for multi-threading). It is recommended that the application is deployed with single worker thread per enclave. Please see https://microsoft.github.io/CCF/developers/threading.html for instructions.
1919

20-
CCF uses mutually authenticated TLS channels for transactions. Given that in PDO client authentication is implemented within the transaction processor itself, we do not utilize the client authentication feature provided by CCF. Once CCF is deployed, CCF's network certificate (networkcert.pem) and one set of user keys (userccf_cert.pem & userccf_privk.pem)
21-
must be made available to all PDO processes that want to submit a CCF transaction. In this case, every
22-
PDO process behaves as though it is a CCF user corresponding to the private key userccf_privk.pem.
20+
CCF uses mutually authenticated TLS channels for transactions. Given that in PDO client authentication is implemented within the transaction processor itself, we do not utilize the client authentication feature provided by CCF. Once CCF is deployed, CCF's network certificate (networkcert.pem) and one set of user keys (userccf_cert.pem & userccf_privk.pem) must be made available to all PDO processes that want to submit a CCF transaction. In this case, every PDO process behaves as though it is a CCF user corresponding to the private key userccf_privk.pem.
2321
These keys must be stored under $PDO_LEDGER_KEY_ROOT as part of PDO deployment.
2422

2523
It may be noted that PDO also supports TP based on the Hyperledger Sawtooth blockchain.
@@ -33,10 +31,12 @@ A feature of the CCF based TP that is not supported by Sawtooth based TP is the
3331
responses to read-transactions include a payload signature, where the signature is generated by the CCF enclave
3432
serving the read request. The (signing key, verifying key) pair is created within the TP,
3533
and is globally persisted among all CCF enclaves. The verifying_key can be obtained from CCF using
36-
the "get_ledger_verifying_key" transaction. In fact, the very first invocation of "get_ledger_verifying_key" rpc
37-
after the service is started is used to create the key pair, which will then be globally committed.
38-
This feature may be used by PDO clients to establish offline verifiable proof of transaction commits as
39-
desired by the PDO smart contract application. Note that for trust purposes, it is recommended that
40-
any entity that uses the above verifying_key gets it directly from the CCF service using the
34+
the "get_ledger_verifying_key" transaction. This feature may be used by PDO clients to establish offline verifiable proof of transaction commits as desired by the PDO smart contract application. Note that for trust purposes, it is recommended that any entity that uses the above verifying_key gets it directly from the CCF service using the
4135
"get_ledger_verifying_key" transaction.
4236

37+
We note that the very first invocation of "get_ledger_verifying_key" rpc
38+
after the service is started is used to create the key pair, which will then be globally committed.
39+
The system admin who deploys the CCF ledger is expected to invoke the "get_ledger_verifying_key"
40+
rpc after deployment to generate these keys. Further, the admin must ensure that this key pair is globally committed
41+
before making the ledger available for PDO usage. This can checked by issuing the rpc again & ensuring that a verifying key gets returned. See https://microsoft.github.io/CCF/users/issue_commands.html for instructions on
42+
how an rpc can be issued via command line.

ccf_transaction_processor/transaction_processor/pdo_tp.cpp

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ namespace ccfapp
143143

144144
//create signature verifier for this enclave and cache it
145145
const auto public_key_pem = tls::Pem(CBuffer(in.verifying_key));
146-
this->enclave_pubk_verifier[in.verifying_key] = tls::make_public_key(public_key_pem, true);
146+
this->enclave_pubk_verifier[in.verifying_key] = tls::make_public_key(public_key_pem, false);
147147

148148
return make_success(true);
149149
};
@@ -270,21 +270,7 @@ namespace ccfapp
270270
contract_info.contract_creator_verifying_key_PEM, in.contract_id, enclave_info_temp.provisioning_key_state_secret_pairs, \
271271
enclave_info_temp.encrypted_state_encryption_key)){
272272

273-
// the following code is to aid in debugging the signature verification issue.
274-
string message = in.contract_id;
275-
message += contract_info.contract_creator_verifying_key_PEM;
276-
for (auto prov :enclave_info_temp.provisioning_key_state_secret_pairs ) {
277-
message += prov.pspk;
278-
message += prov.encrypted_secret;
279-
}
280-
vector<uint8_t> contents(message.begin(), message.end());
281-
vector<uint8_t> temp = raw_from_b64(enclave_info_temp.encrypted_state_encryption_key);
282-
contents.insert(contents.end(), temp.begin(), temp.end());
283-
284-
string temp2 = b64_from_raw(contents.data(), contents.size());
285-
return make_error(
286-
jsonrpc::StandardErrorCodes::INVALID_PARAMS, "Invalid enclave signature (doc::sig::key) as follows::"+ \
287-
temp2 + "::"+enclave_info_temp.signature +"::"+enclave_r.value().verifying_key);
273+
return make_error( jsonrpc::StandardErrorCodes::INVALID_PARAMS, "Invalid enclave signature");
288274
}
289275

290276
//all good, add enclave to contract
@@ -409,7 +395,7 @@ namespace ccfapp
409395
}
410396

411397
// verify contract enclave signature. This signature also ensures (via the notion of channel ids) that
412-
// the contraction invocation was performed by the transaction submitter.
398+
// the contract invocation was performed by the transaction submitter.
413399
if (!verify_enclave_signature_update_contract_state(in.contract_enclave_signature, this->enclave_pubk_verifier[enclave_r.value().verifying_key], \
414400
in.nonce, contract_info.contract_creator_verifying_key_PEM, contract_info.contract_code_hash, \
415401
state_update_info)) {

ccf_transaction_processor/transaction_processor/pdo_tp.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,11 @@ namespace ccfapp
7474
bool verify_pdo_transaction_signature_register_enclave(const vector<uint8_t>& signature, const string & verifying_key,
7575
const EnclaveInfo & enclave_info);
7676

77-
bool verify_sig(const vector<uint8_t>& signature, const string & verifying_key, const vector<uint8_t> & contents);
77+
bool verify_sig(vector<uint8_t> signature, const string & verifying_key, const vector<uint8_t> & contents);
7878

79-
bool verify_sig_static(const vector<uint8_t>& signature, const tls::PublicKeyPtr & pubk_verifier, \
79+
bool verify_sig_static(vector<uint8_t> signature, const tls::PublicKeyPtr & pubk_verifier, \
8080
const vector<uint8_t>& contents);
8181

82-
8382
bool verify_pdo_transaction_signature_register_contract(const vector<uint8_t>& signature, const string & verifying_key, \
8483
const vector<uint8_t>& contract_code_hash, const string & nonce, const vector<string> & provisioning_service_ids);
8584

ccf_transaction_processor/transaction_processor/verify_signatures.cpp

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ namespace ccfapp
2424
{
2525

2626

27-
bool TPHandler::verify_sig_static(const vector<uint8_t>& signature, const tls::PublicKeyPtr & pubk_verifier, \
27+
bool TPHandler::verify_sig_static(vector<uint8_t> signature, const tls::PublicKeyPtr & pubk_verifier, \
2828
const vector<uint8_t>& contents) {
2929

3030
// verify & return true or false
3131
return pubk_verifier->verify(contents, signature);
3232

3333
}
3434

35-
bool TPHandler::verify_sig(const vector<uint8_t>& signature, const string & verifying_key, \
35+
bool TPHandler::verify_sig(vector<uint8_t> signature, const string & verifying_key, \
3636
const vector<uint8_t>& contents) {
3737

3838
// format the verifying key as needed by CCF to create the verifier
@@ -42,7 +42,6 @@ namespace ccfapp
4242

4343
}
4444

45-
4645
bool TPHandler::verify_pdo_transaction_signature_register_enclave(const vector<uint8_t>& signature, const string & verifying_key,
4746
const EnclaveInfo & enclave_info){
4847

@@ -94,10 +93,7 @@ namespace ccfapp
9493
const string & contract_creator_key, const string & contract_id, const vector<ProvisioningKeysToSecretMap> & prov_key_maps, \
9594
const string & encrypted_state_encryption_key){
9695

97-
return true;
98-
99-
// the following signature verification code does not work. See git issues for status
100-
/*string message = contract_id;
96+
string message = contract_id;
10197
message += contract_creator_key;
10298
for (auto prov :prov_key_maps ) {
10399
message += prov.pspk;
@@ -108,7 +104,20 @@ namespace ccfapp
108104
vector<uint8_t> temp = raw_from_b64(encrypted_state_encryption_key);
109105
contents.insert(contents.end(), temp.begin(), temp.end());
110106

111-
return verify_sig_static(raw_from_b64(signature), pubk_verifier, contents);*/
107+
auto signature_byte_array = raw_from_b64(signature);
108+
109+
//remove any trailing zeros (null characters) in the signature array
110+
//this seems to be necessary for verifying this sign
111+
while(true){
112+
if (signature_byte_array.back() == 0){
113+
signature_byte_array.pop_back();
114+
}
115+
else{
116+
break;
117+
}
118+
}
119+
120+
return verify_sig_static(signature_byte_array, pubk_verifier, contents);
112121
}
113122

114123

python/pdo/contract/contract.py

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,6 @@ def add_enclave_to_contract(
231231
signature,
232232
**extra_params):
233233

234-
235234
enclave_secret_data_array = []
236235
enclave_secret_data = dict()
237236
enclave_secret_data['contract_id'] = contract_id
@@ -245,23 +244,6 @@ def add_enclave_to_contract(
245244
enclave_secret_data['provisioning_key_state_secret_pairs'] = secret_list
246245
enclave_secret_data_array.append(enclave_secret_data)
247246

248-
#verify enclave signature if enclave_keys is passed as optional input
249-
#code is for debugging the issue where verification does not work at ccf ledger
250-
#see git issues for status.
251-
enclave_keys = extra_params.get('enclave_keys', None)
252-
if enclave_keys is not None:
253-
document = contract_id
254-
document += creator_keys.verifying_key
255-
for secret in secrets:
256-
document += secret['pspk'] + secret['encrypted_secret']
257-
document_ba = crypto.string_to_byte_array(document)
258-
document_ba += crypto.base64_to_byte_array(encrypted_state_encryption_key)
259-
if enclave_keys.verify(document_ba, signature, encoding = 'b64') == 1:
260-
logger.info("Add enclave to contract sign verified. (doc::sig::key) as follows")
261-
logger.info(crypto.byte_array_to_base64(document_ba)+"::"+signature+"::"+enclave_id)
262-
else:
263-
logger.error("Failed to verify add enclave to contract sign")
264-
265247
ss = create_submitter(ledger_config, pdo_signer = creator_keys)
266248
txnsignature = ss.add_enclave_to_contract(
267249
contract_id,

0 commit comments

Comments
 (0)