-
Notifications
You must be signed in to change notification settings - Fork 91
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
support for digital signatures + integration tests work (again) #501
Changes from all commits
bc5982d
7ce70f7
26ba7a2
d46f309
4df41e6
92afe5c
4138a9f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright 2020 Intel Corporation | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <string.h> | ||
#include "crypto.h" | ||
#include "logging.h" | ||
#include "error.h" | ||
#include "types.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
bool compute_hash(uint8_t* message, | ||
uint32_t message_len, | ||
uint8_t* hash, | ||
uint32_t max_hash_len, | ||
uint32_t* actual_hash_len) | ||
{ | ||
ByteArray ba; | ||
|
||
COND2ERR(message == NULL); | ||
|
||
ba = pdo::crypto::ComputeMessageHash(ByteArray(message, message + message_len)); | ||
COND2ERR(ba.size() > max_hash_len); | ||
|
||
memcpy(hash, ba.data(), ba.size()); | ||
*actual_hash_len = ba.size(); | ||
return true; | ||
|
||
err: | ||
return false; | ||
} | ||
|
||
bool verify_signature(uint8_t* public_key, uint32_t public_key_len, uint8_t* message, uint32_t message_len, uint8_t* signature, uint32_t signature_len) | ||
{ | ||
try | ||
{ | ||
std::string pk_string((const char*)public_key, public_key_len); | ||
ByteArray msg(message, message + message_len); | ||
ByteArray sig(signature, signature + signature_len); | ||
|
||
//deserialize public key | ||
pdo::crypto::sig::PublicKey pk(pk_string); | ||
|
||
//check signature | ||
int r = pk.VerifySignature(msg, sig); | ||
COND2ERR(r != 1); | ||
} | ||
catch(...) | ||
{ | ||
COND2ERR(true); | ||
} | ||
|
||
// verification successful | ||
return true; | ||
|
||
err: | ||
return false; | ||
} | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif /* __cplusplus */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* Copyright 2020 Intel Corporation | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
bool compute_hash(uint8_t* message, | ||
uint32_t message_len, | ||
uint8_t* hash, | ||
uint32_t max_hash_len, | ||
uint32_t* actual_hash_len); | ||
|
||
bool verify_signature(uint8_t* public_key, uint32_t public_key_len, uint8_t* message, uint32_t message_len, uint8_t* signature, uint32_t signature_len); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -16,7 +16,6 @@ import ( | |
"unsafe" | ||
|
||
"github.com/golang/protobuf/proto" | ||
"github.com/hyperledger-labs/fabric-private-chaincode/internal/protos" | ||
"github.com/hyperledger/fabric-chaincode-go/shim" | ||
"golang.org/x/sync/semaphore" | ||
) | ||
|
@@ -29,7 +28,6 @@ import ( | |
import "C" | ||
|
||
const enclaveLibFile = "enclave/lib/enclave.signed.so" | ||
const maxResponseSize = 1024 * 100 // Let's be really conservative ... | ||
|
||
type EnclaveStub struct { | ||
eid C.enclave_id_t | ||
|
@@ -43,14 +41,17 @@ func NewEnclaveStub() StubInterface { | |
} | ||
|
||
func (e *EnclaveStub) Init(chaincodeParams, hostParams, attestationParams []byte) ([]byte, error) { | ||
// Estimate of the buffer length that is necessary for the credentials. It should be conservative. | ||
const credentialsBufferMaxLen = 16 * 1024 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This number sounds like magic. Can you add a comment on how you got to this number? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added comment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, the comment doesn't really mention on how you got to that number. That it was an estimate i already had figured out before :-) |
||
|
||
if e.isInitialized { | ||
return nil, fmt.Errorf("enclave already initialized") | ||
} | ||
|
||
var eid C.enclave_id_t | ||
|
||
// prepare output buffer for credentials | ||
credentialsBuffer := C.malloc(maxResponseSize) | ||
credentialsBuffer := C.malloc(credentialsBufferMaxLen) | ||
defer C.free(credentialsBuffer) | ||
credentialsSize := C.uint32_t(0) | ||
|
||
|
@@ -70,7 +71,7 @@ func (e *EnclaveStub) Init(chaincodeParams, hostParams, attestationParams []byte | |
(*C.uint8_t)(C.CBytes(hostParams)), | ||
C.uint32_t(len(hostParams)), | ||
(*C.uint8_t)(credentialsBuffer), | ||
C.uint32_t(maxResponseSize), | ||
C.uint32_t(credentialsBufferMaxLen), | ||
&credentialsSize) | ||
|
||
if ret != 0 { | ||
|
@@ -106,6 +107,9 @@ func (e *EnclaveStub) GetEnclaveId() (string, error) { | |
|
||
// ChaincodeInvoke calls the enclave for transaction processing | ||
func (e *EnclaveStub) ChaincodeInvoke(stub shim.ChaincodeStubInterface, crmProtoBytes []byte) ([]byte, error) { | ||
// Estimate of the buffer length where the enclave will write the response. | ||
const scresmProtoBytesMaxLen = 1024 * 100 // Let's be really conservative ... | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above, would be useful to add some comments on how we came to this number. Maybe also add a comment in the protobufs pointing to here so if we change there we also adapt number here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added comment, if there isn't enough space...it will fail. In the future we should make it adaptive. |
||
|
||
if !e.isInitialized { | ||
return nil, fmt.Errorf("enclave not yet initialized") | ||
} | ||
|
@@ -128,9 +132,9 @@ func (e *EnclaveStub) ChaincodeInvoke(stub shim.ChaincodeStubInterface, crmProto | |
defer C.free(unsafe.Pointer(signedProposalPtr)) | ||
|
||
// prep response | ||
cresmProtoBytesLenOut := C.uint32_t(0) // We pass maximal length separately; set to zero so we can detect valid responses | ||
cresmProtoBytesPtr := C.malloc(maxResponseSize) | ||
defer C.free(cresmProtoBytesPtr) | ||
scresmProtoBytesLenOut := C.uint32_t(0) // We pass maximal length separately; set to zero so we can detect valid responses | ||
scresmProtoBytesPtr := C.malloc(scresmProtoBytesMaxLen) | ||
defer C.free(scresmProtoBytesPtr) | ||
|
||
crmProtoBytesPtr := C.CBytes(crmProtoBytes) | ||
defer C.free(unsafe.Pointer(crmProtoBytesPtr)) | ||
|
@@ -146,31 +150,12 @@ func (e *EnclaveStub) ChaincodeInvoke(stub shim.ChaincodeStubInterface, crmProto | |
(C.uint32_t)(len(signedProposalBytes)), | ||
(*C.uint8_t)(crmProtoBytesPtr), | ||
(C.uint32_t)(len(crmProtoBytes)), | ||
(*C.uint8_t)(cresmProtoBytesPtr), (C.uint32_t)(maxResponseSize), &cresmProtoBytesLenOut, | ||
(*C.uint8_t)(scresmProtoBytesPtr), (C.uint32_t)(scresmProtoBytesMaxLen), &scresmProtoBytesLenOut, | ||
ctx) | ||
e.sem.Release(1) | ||
if invokeRet != 0 { | ||
return nil, fmt.Errorf("invoke failed. Reason: %d", int(invokeRet)) | ||
} | ||
|
||
cresmProtoBytes := C.GoBytes(cresmProtoBytesPtr, C.int(cresmProtoBytesLenOut)) | ||
|
||
responseMsg := &protos.ChaincodeResponseMessage{} | ||
err = proto.Unmarshal(cresmProtoBytes, responseMsg) | ||
if err != nil { | ||
return nil, fmt.Errorf("cannot unmarshal ChaincodeResponseMessage: %s", err.Error()) | ||
} | ||
|
||
// include proposal here | ||
responseMsg.Proposal = proposal | ||
|
||
// TODO set RW set | ||
//responseMsg.RwSet = ... | ||
|
||
cresmProtoBytes, err = proto.Marshal(responseMsg) | ||
if err != nil { | ||
return nil, fmt.Errorf("cannot marshal ChaincodeResponseMessage: %s", err.Error()) | ||
} | ||
|
||
return cresmProtoBytes, nil | ||
return C.GoBytes(scresmProtoBytesPtr, C.int(scresmProtoBytesLenOut)), nil | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for
mock_enclave.go
(and for symmetry) you will also need the generate signature?