func (t *AssetManagementChaincode) isCaller(stub *shim.ChaincodeStub, certificate []byte) (bool, error) {
	// In order to enforce access control, we require that the
	// metadata contains the signature under the signing key corresponding
	// to the verification key inside certificate of
	// the payload of the transaction (namely, function name and args) and
	// the transaction binding (to avoid copying attacks)

	// Verify \sigma=Sign(certificate.sk, tx.Payload||tx.Binding) against certificate.vk
	// \sigma is in the metadata

	sigma, err := stub.GetCallerMetadata()
	if err != nil {
		return false, errors.New("Failed getting metadata")
	}
	payload, err := stub.GetPayload()
	if err != nil {
		return false, errors.New("Failed getting payload")
	}
	binding, err := stub.GetBinding()
	if err != nil {
		return false, errors.New("Failed getting binding")
	}

	myLogger.Debug("passed certificate [% x]", certificate)
	myLogger.Debug("passed sigma [% x]", sigma)
	myLogger.Debug("passed payload [% x]", payload)
	myLogger.Debug("passed binding [% x]", binding)

	return stub.VerifySignature(
		certificate,
		sigma,
		append(payload, binding...),
	)
}
Beispiel #2
0
func (t *RBACChaincode) hasInvokerRole(stub *shim.ChaincodeStub, role string) (bool, []byte, error) {
	// In order to enforce access control, we require that the
	// metadata contains the following items:
	// 1. a certificate Cert
	// 2. a signature Sigma under the signing key corresponding
	// to the verification key inside Cert of :
	// (a) Cert;
	// (b) The payload of the transaction (namely, function name and args) and
	// (c) the transaction binding.

	// Verify Sigma=Sign(certificate.sk, Cert||tx.Payload||tx.Binding) against Cert.vk

	// Unmarshall metadata
	metadata, err := stub.GetCallerMetadata()
	rbacMetadata := new(RBACMetadata)
	_, err = asn1.Unmarshal(metadata, rbacMetadata)
	if err != nil {
		return false, nil, fmt.Errorf("Failed unmarshalling metadata [%s]", err)
	}

	// Verify signature
	payload, err := stub.GetPayload()
	if err != nil {
		return false, nil, errors.New("Failed getting payload")
	}
	binding, err := stub.GetBinding()
	if err != nil {
		return false, nil, errors.New("Failed getting binding")
	}

	myLogger.Debug("passed certificate [% x]", rbacMetadata.Cert)
	myLogger.Debug("passed sigma [% x]", rbacMetadata.Sigma)
	myLogger.Debug("passed payload [% x]", payload)
	myLogger.Debug("passed binding [% x]", binding)

	ok, err := stub.VerifySignature(
		rbacMetadata.Cert,
		rbacMetadata.Sigma,
		append(rbacMetadata.Cert, append(payload, binding...)...),
	)
	if err != nil {
		return false, nil, fmt.Errorf("Failed verifying signature [%s]", err)
	}
	if !ok {
		return false, nil, fmt.Errorf("Signature is not valid!")
	}

	myLogger.Debug("Signature verified. Check for role...")

	myLogger.Debug("ID [% x]", rbacMetadata.Cert)

	// Check role
	var columns []shim.Column
	idCol := shim.Column{Value: &shim.Column_Bytes{Bytes: rbacMetadata.Cert}}
	columns = append(columns, idCol)
	row, err := stub.GetRow("RBAC", columns)
	if err != nil {
		return false, nil, fmt.Errorf("Failed retrieveing RBAC row [%s]", err)
	}
	if len(row.GetColumns()) == 0 {
		return false, nil, fmt.Errorf("Failed retrieveing RBAC row [%s]", err)
	}

	myLogger.Debug("#Columns: [%d]", len(row.Columns))
	roles := row.Columns[1].GetString_()

	result := strings.Split(roles, " ")
	for i := range result {
		if result[i] == role {
			myLogger.Debug("Role found.")
			return true, rbacMetadata.Cert, nil
		}
	}

	myLogger.Debug("Role not found.")

	return false, nil, nil
}