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

More functions to simplify wawaka contract development #348

Merged
merged 5 commits into from
Feb 1, 2022
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
346 changes: 97 additions & 249 deletions contracts/wawaka/attestation-test/attestation-test.cpp

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions contracts/wawaka/attestation-test/plugins/attestation-test.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,12 @@ def __command_attestation__(state, bindings, pargs) :
subparser.add_argument('-m', '--contract-metadata',
help='contract metadata', type=invocation_parameter, required=True)

subparser = subparsers.add_parser('generate_secret')
subparser.add_argument('-s', '--symbol', help='binding symbol for result', type=str)

subparser = subparsers.add_parser('send_secret')
subparser.add_argument('-i', '--contract-id', help='contract identifier', type=str, required=True)
subparser.add_argument('-s', '--symbol', help='binding symbol for result', type=str)

subparser = subparsers.add_parser('recv_secret')
subparser.add_argument('--secret', help='contract secret', type=invocation_parameter, required=True)
subparser.add_argument('-s', '--symbol', help='binding symbol for result', type=str)

subparser = subparsers.add_parser('reveal_secret')
Expand Down Expand Up @@ -120,10 +119,18 @@ def __command_attestation__(state, bindings, pargs) :

# -------------------------------------------------------
if options.command == 'send_secret' :
message = invocation_request('send_secret', contract_id=options.contract_id)
result = send_to_contract(state, options.save_file, message, eservice_url=options.enclave, **extraparams)
if result and options.symbol :
bindings.bind(options.symbol, result)

return

# -------------------------------------------------------
if options.command == 'recv_secret' :
message = invocation_request('recv_secret', **options.secret)
send_to_contract(state, options.save_file, message, eservice_url=options.enclave, **extraparams)

return

# -------------------------------------------------------
Expand Down
25 changes: 20 additions & 5 deletions contracts/wawaka/attestation-test/scripts/attestation-test.psh
Original file line number Diff line number Diff line change
Expand Up @@ -86,21 +86,36 @@ identity -n user2
attestation -q -f ${save}/contract1.pdo add_endpoint -i ${_id2_} -c "${_mdc2_}" -m "${_md2_}" -l "${_info2_}"

## =================================================================
echo ${INFO} create a signature ${ENDC}
echo ${INFO} create a secret and share it with the other contracts ${ENDC}
identity -n user1
attestation -w -q -f ${save}/contract1.pdo generate_secret
attestation -w -q -f ${save}/contract1.pdo send_secret -i ${_id2_} -s _secret_
attestation -w -q -f ${save}/contract2.pdo recv_secret --secret "${_secret_}"

## wait for the generate_secret operation to commit otherwise the
## current_state command will return an old version of state, or
## at least might return an old version of state
sleep -q -t 1

ledger -q -s _sig_ current-state -i ${_id1_} -p signature
attestation -q -f ${save}/contract1.pdo reveal_secret -s _secret_ -a ${_sig_}
echo ${HEADER} secret is ${_secret_} ${ENDC}
identity -n user1
ledger -q -s _sig1_ current-state -i ${_id1_} -p signature
attestation -q -f ${save}/contract1.pdo reveal_secret -s _secret1_ -a ${_sig1_}
##echo ${HEADER} secret stored in contract 1 is ${_secret1_} ${ENDC}

identity -n user2
ledger -q -s _sig2_ current-state -i ${_id2_} -p signature
attestation -q -f ${save}/contract2.pdo reveal_secret -s _secret2_ -a ${_sig2_}
##echo ${HEADER} secret stored in contract 2 is ${_secret2_} ${ENDC}

if --not -e ${_secret1_} ${_secret2_}
echo Secrets did not match
exit -v 1
fi

echo ${HEADER} secrets matched ${ENDC}

## =================================================================
echo ${INFO} test sgx report verification ${ENDC}
identity -n user1

set -q -s _report_ -f ${test_data}/report.json
set -q -s _certificate_ -f ${test_data}/certificate.pem
Expand Down
1 change: 1 addition & 0 deletions contracts/wawaka/common/Dispatch.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,4 @@ extern bool initialize_contract(const Environment& env, Response& rsp);
extern contract_method_reference_t contract_method_dispatch_table[];

#define CONTRACT_METHOD(m) { #m, m }
#define CONTRACT_METHOD2(n, m) { #n, m }
190 changes: 190 additions & 0 deletions contracts/wawaka/common/Secret.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
/* Copyright 2019 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

//#include <malloc.h>
#include <algorithm>
#include <stdint.h>
#include <string>

#include "Cryptography.h"
#include "Secret.h"
#include "Util.h"
#include "Value.h"

#include "WasmExtensions.h"

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// NAME: send_secret
//
// returns a JSON encoded object:
//
// {
// "encrypted_session_key": <base64 encoded encrypted session key>
// "session_key_iv": <base64 encoded AES IV>
// "encrypted_message": <base64 encode encrypted message>
// }
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
bool ww::secret::send_secret(
const std::string& encryption_key,
const std::string& message_string,
std::string& encrypted_message_string)
{
ww::value::Object secret_object;
if (! send_secret(encryption_key, message_string, secret_object))
{
CONTRACT_SAFE_LOG(3, "failed to encrypt secret");
return false;
}

if (! secret_object.serialize(encrypted_message_string))
{
CONTRACT_SAFE_LOG(3, "failed to serialize message");
return false;
}

return true;
}

bool ww::secret::send_secret(
const std::string& encryption_key,
const std::string& message_string,
ww::value::Object& secret_object)
{
// ---------- encrypt message ----------
ww::types::ByteArray iv;
ww::types::ByteArray session_key;
if (! ww::crypto::aes::generate_key(session_key) || ! ww::crypto::aes::generate_iv(iv))
{
CONTRACT_SAFE_LOG(3, "failed to generate session key");
return false;
}

ww::types::ByteArray message(message_string.begin(), message_string.end());
ww::types::ByteArray cipher;
if (! ww::crypto::aes::encrypt_message(message, session_key, iv, cipher))
{
CONTRACT_SAFE_LOG(3, "failed to encrypt the secret");
return false;
}

std::string encoded_cipher;
if (! ww::crypto::b64_encode(cipher, encoded_cipher))
{
CONTRACT_SAFE_LOG(3, "failed to encode cipher text");
return false;
}

// ---------- encrypt the session key ----------
ww::types::ByteArray encrypted_session_key;
if (! ww::crypto::rsa::encrypt_message(session_key, encryption_key, encrypted_session_key))
{
CONTRACT_SAFE_LOG(3, "failed to encrypt session key");
return false;
}

std::string encoded_session_key;
if (! ww::crypto::b64_encode(encrypted_session_key, encoded_session_key))
{
CONTRACT_SAFE_LOG(3, "failed to encode session key");
return false;
}

// ---------- encode the IV ----------
std::string encoded_iv;
if (! ww::crypto::b64_encode(iv, encoded_iv))
{
CONTRACT_SAFE_LOG(3, "failed to encode iv");
return false;
}

// ---------- build the object ----------
secret_object.set_string("encrypted_session_key", encoded_session_key.c_str());
secret_object.set_string("session_key_iv", encoded_iv.c_str());
secret_object.set_string("encrypted_message", encoded_cipher.c_str());

return true;
}

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// NAME: recv_secret
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
bool ww::secret::recv_secret(
const std::string& decryption_key,
const std::string& encrypted_message_string,
std::string& message_string)
{
ww::value::Object secret_object;
if (! secret_object.deserialize(encrypted_message_string.c_str()))
{
CONTRACT_SAFE_LOG(3, "failed to deserialize secret");
return false;
}

return ww::secret::recv_secret(decryption_key, secret_object, message_string);
}

bool ww::secret::recv_secret(
const std::string& decryption_key,
const ww::value::Object& secret_object,
std::string& message_string)
{
if (! secret_object.validate_schema(CONTRACT_SECRET_SCHEMA))
{
CONTRACT_SAFE_LOG(3, "invalid secret");
return false;
}

const std::string encoded_session_key(secret_object.get_string("encrypted_session_key"));
const std::string encoded_iv(secret_object.get_string("session_key_iv"));
const std::string encoded_cipher(secret_object.get_string("encrypted_message"));

ww::types::ByteArray iv;
if (! ww::crypto::b64_decode(encoded_iv, iv))
{
CONTRACT_SAFE_LOG(3, "failed to decode session iv");
return false;
}

ww::types::ByteArray encrypted_session_key;
if (! ww::crypto::b64_decode(encoded_session_key, encrypted_session_key))
{
CONTRACT_SAFE_LOG(3, "failed to decode session key");
return false;
}

ww::types::ByteArray session_key;
if (! ww::crypto::rsa::decrypt_message(encrypted_session_key, decryption_key, session_key))
{
CONTRACT_SAFE_LOG(3, "failed to decrypt session key");
return false;
}

ww::types::ByteArray cipher;
if (! ww::crypto::b64_decode(encoded_cipher, cipher))
{
CONTRACT_SAFE_LOG(3, "failed to decode cipher");
return false;
}

ww::types::ByteArray message;
if (! ww::crypto::aes::decrypt_message(cipher, session_key, iv, message))
{
CONTRACT_SAFE_LOG(3, "failed to decrypt cipher");
return false;
}

message_string = ww::types::ByteArrayToString(message);
return true;
}
55 changes: 55 additions & 0 deletions contracts/wawaka/common/Secret.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* Copyright 2019 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <stdint.h>
#include <string>

#include "Util.h"
#include "Value.h"

#define CONTRACT_SECRET_SCHEMA \
"{" \
SCHEMA_KW(encrypted_session_key,"") "," \
SCHEMA_KW(session_key_iv,"") "," \
SCHEMA_KW(encrypted_message,"") \
"}"

namespace ww
{
namespace secret
{
bool send_secret(
cmickeyb marked this conversation as resolved.
Show resolved Hide resolved
const std::string& encryption_key,
const std::string& message_string,
std::string& encrypted_message_string);

bool send_secret(
const std::string& encryption_key,
const std::string& message_string,
ww::value::Object& secret_object);

bool recv_secret(
cmickeyb marked this conversation as resolved.
Show resolved Hide resolved
const std::string& decryption_key,
const std::string& encrypted_message_string,
std::string& message_string);

bool recv_secret(
const std::string& decryption_key,
const ww::value::Object& secret_object,
std::string& message_string);
}; /* namespace secret */
}; /* namespac ww */
50 changes: 50 additions & 0 deletions contracts/wawaka/common/StateReference.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* Copyright 2019 Intel Corporation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "StateReference.h"

// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
// Class: ww::value::StateReference
// XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

// -----------------------------------------------------------------
bool ww::value::StateReference::deserialize(const ww::value::Object& reference)
{
if (! reference.validate_schema(STATE_REFERENCE_SCHEMA))
return false;

contract_id_ = reference.get_string("contract_id");
state_hash_ = reference.get_string("state_hash");
return true;
}

// -----------------------------------------------------------------
bool ww::value::StateReference::serialize(ww::value::Value& serialized_reference) const
{
ww::value::Structure reference(STATE_REFERENCE_SCHEMA);
if (! reference.set_string("contract_id", contract_id_.c_str()))
return false;
if (! reference.set_string("state_hash", state_hash_.c_str()))
return false;

serialized_reference.set(reference);
return true;
}

// -----------------------------------------------------------------
bool ww::value::StateReference::add_to_response(Response& rsp) const
marcelamelara marked this conversation as resolved.
Show resolved Hide resolved
{
return rsp.add_dependency(contract_id_, state_hash_);
}
Loading