// EXP_GetApplicationTCert retrieves an application TCert for the supplied user func (d *Devops) EXP_GetApplicationTCert(ctx context.Context, secret *pb.Secret) (*pb.Response, error) { var sec crypto.Client var err error if d.isSecurityEnabled { if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debug("Initializing secure devops using context %s", secret.EnrollId) } sec, err = crypto.InitClient(secret.EnrollId, nil) defer crypto.CloseClient(sec) if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil } devopsLogger.Debug("Getting TCert for id: %s", secret.EnrollId) tcertHandler, err := sec.GetTCertificateHandlerNext() if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil } certDER := tcertHandler.GetCertificate() return &pb.Response{Status: pb.Response_SUCCESS, Msg: certDER}, nil } devopsLogger.Warning("Security NOT enabled") return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte("Security NOT enabled")}, nil // TODO: Handle timeout and expiration }
// EXP_PrepareForTx prepares a binding/TXHandler pair to be used in subsequent TX func (d *Devops) EXP_PrepareForTx(ctx context.Context, secret *pb.Secret) (*pb.Response, error) { var sec crypto.Client var err error var txHandler crypto.TransactionHandler var binding []byte if d.isSecurityEnabled { if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debug("Initializing secure devops using context %s", secret.EnrollId) } sec, err = crypto.InitClient(secret.EnrollId, nil) defer crypto.CloseClient(sec) if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil } devopsLogger.Debug("Getting TXHandler for id: %s", secret.EnrollId) tcertHandler, err := sec.GetTCertificateHandlerNext() if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil } txHandler, err = tcertHandler.GetTransactionHandler() binding, err = txHandler.GetBinding() if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil } // Now add to binding map d.bindingMap.addBinding(binding, txHandler) return &pb.Response{Status: pb.Response_SUCCESS, Msg: binding}, nil } devopsLogger.Warning("Security NOT enabled") return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte("Security NOT enabled")}, nil // TODO: Handle timeout and expiration }
func createTransaction(invokeTx bool, spec *pb.ChaincodeInvocationSpec, uuid string) (*pb.Transaction, error) { var tx *pb.Transaction var err error var sec crypto.Client if nil != sec { sec, err = crypto.InitClient(spec.ChaincodeSpec.SecureContext, nil) defer crypto.CloseClient(sec) if nil != err { return nil, err } if invokeTx { tx, err = sec.NewChaincodeExecute(spec, uuid) } else { tx, err = sec.NewChaincodeQuery(spec, uuid) } if nil != err { return nil, err } } else { var t pb.Transaction_Type if invokeTx { t = pb.Transaction_CHAINCODE_INVOKE } else { t = pb.Transaction_CHAINCODE_QUERY } tx, err = pb.NewChaincodeExecute(spec, uuid, t) if nil != err { return nil, err } } return tx, nil }
func (d *Devops) createExecTx(spec *pb.ChaincodeInvocationSpec, attributes []string, uuid string, invokeTx bool, sec crypto.Client) (*pb.Transaction, error) { var tx *pb.Transaction var err error //TODO What should we do with the attributes if nil != sec { if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debugf("Creating secure invocation transaction %s", uuid) } if invokeTx { tx, err = sec.NewChaincodeExecute(spec, uuid, attributes...) } else { tx, err = sec.NewChaincodeQuery(spec, uuid, attributes...) } if nil != err { return nil, err } } else { if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debugf("Creating invocation transaction (%s)", uuid) } var t pb.Transaction_Type if invokeTx { t = pb.Transaction_CHAINCODE_INVOKE } else { t = pb.Transaction_CHAINCODE_QUERY } tx, err = pb.NewChaincodeExecute(spec, uuid, t) if nil != err { return nil, err } } return tx, nil }
func deployInternal(deployer crypto.Client, adminCert crypto.CertificateHandler) (resp *pb.Response, err error) { // Prepare the spec. The metadata includes the identity of the administrator spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Path: "github.com/hyperledger/fabric/examples/chaincode/go/asset_management"}, //ChaincodeID: &pb.ChaincodeID{Name: chaincodeName}, CtorMsg: &pb.ChaincodeInput{Args: util.ToChaincodeArgs("init")}, Metadata: adminCert.GetCertificate(), ConfidentialityLevel: confidentialityLevel, } // First build the deployment spec cds, err := getChaincodeBytes(spec) if err != nil { return nil, fmt.Errorf("Error getting deployment spec: %s ", err) } // Now create the Transactions message and send to Peer. transaction, err := deployer.NewChaincodeDeployTransaction(cds, cds.ChaincodeSpec.ChaincodeID.Name) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s ", err) } resp, err = processTransaction(transaction) appLogger.Debugf("resp [%s]", resp.String()) chaincodeName = cds.ChaincodeSpec.ChaincodeID.Name appLogger.Debugf("ChaincodeName [%s]", chaincodeName) return }
func transferOwnership(owner crypto.Client, ownerCert crypto.CertificateHandler, asset string, newOwnerCert crypto.CertificateHandler) error { // Get a transaction handler to be used to submit the execute transaction // and bind the chaincode access control logic using the binding submittingCertHandler, err := owner.GetTCertificateHandlerNext() if err != nil { return err } txHandler, err := submittingCertHandler.GetTransactionHandler() if err != nil { return err } binding, err := txHandler.GetBinding() if err != nil { return err } chaincodeInput := &pb.ChaincodeInput{Function: "transfer", Args: []string{asset, string(newOwnerCert.GetCertificate())}} chaincodeInputRaw, err := proto.Marshal(chaincodeInput) if err != nil { return err } // Access control. Owner signs chaincodeInputRaw || binding to confirm his identity sigma, err := ownerCert.Sign(append(chaincodeInputRaw, binding...)) if err != nil { return err } // Prepare spec and submit spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "mycc"}, CtorMsg: chaincodeInput, Metadata: sigma, // Proof of identity ConfidentialityLevel: pb.ConfidentialityLevel_PUBLIC, } var ctx = context.Background() chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} tid := chaincodeInvocationSpec.ChaincodeSpec.ChaincodeID.Name // Now create the Transactions message and send to Peer. transaction, err := txHandler.NewChaincodeExecute(chaincodeInvocationSpec, tid) if err != nil { return fmt.Errorf("Error deploying chaincode: %s ", err) } ledger, err := ledger.GetLedger() ledger.BeginTxBatch("1") _, err = chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction) if err != nil { return fmt.Errorf("Error deploying chaincode: %s", err) } ledger.CommitTxBatch("1", []*pb.Transaction{transaction}, nil, nil) return err }
// Deploy deploys the supplied chaincode image to the validators through a transaction func (d *Devops) Deploy(ctx context.Context, spec *pb.ChaincodeSpec) (*pb.ChaincodeDeploymentSpec, error) { // get the deployment spec chaincodeDeploymentSpec, err := d.getChaincodeBytes(ctx, spec) if err != nil { devopsLogger.Error(fmt.Sprintf("Error deploying chaincode spec: %v\n\n error: %s", spec, err)) return nil, err } // Now create the Transactions message and send to Peer. transID := chaincodeDeploymentSpec.ChaincodeSpec.ChaincodeID.Name var tx *pb.Transaction var sec crypto.Client if peer.SecurityEnabled() { if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debugf("Initializing secure devops using context %s", spec.SecureContext) } sec, err = crypto.InitClient(spec.SecureContext, nil) defer crypto.CloseClient(sec) // remove the security context since we are no longer need it down stream spec.SecureContext = "" if nil != err { return nil, err } if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debugf("Creating secure transaction %s", transID) } tx, err = sec.NewChaincodeDeployTransaction(chaincodeDeploymentSpec, transID, spec.Attributes...) if nil != err { return nil, err } } else { if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debugf("Creating deployment transaction (%s)", transID) } tx, err = pb.NewChaincodeDeployTransaction(chaincodeDeploymentSpec, transID) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s ", err) } } if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debugf("Sending deploy transaction (%s) to validator", tx.Uuid) } resp := d.coord.ExecuteTransaction(tx) if resp.Status == pb.Response_FAILURE { err = fmt.Errorf(string(resp.Msg)) } return chaincodeDeploymentSpec, err }
func (d *Devops) invokeOrQuery(ctx context.Context, chaincodeInvocationSpec *pb.ChaincodeInvocationSpec, attributes []string, invoke bool) (*pb.Response, error) { if chaincodeInvocationSpec.ChaincodeSpec.ChaincodeID.Name == "" { return nil, fmt.Errorf("name not given for invoke/query") } // Now create the Transactions message and send to Peer. var customIDgenAlg = strings.ToLower(chaincodeInvocationSpec.IdGenerationAlg) var id string var generr error if customIDgenAlg != "" { id, generr = util.GenerateIDWithAlg(customIDgenAlg, chaincodeInvocationSpec.ChaincodeSpec.CtorMsg.Args[0]) if generr != nil { return nil, generr } } else { id = util.GenerateUUID() } devopsLogger.Infof("Transaction ID: %v", id) var transaction *pb.Transaction var err error var sec crypto.Client if peer.SecurityEnabled() { if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debugf("Initializing secure devops using context %s", chaincodeInvocationSpec.ChaincodeSpec.SecureContext) } sec, err = crypto.InitClient(chaincodeInvocationSpec.ChaincodeSpec.SecureContext, nil) defer crypto.CloseClient(sec) // remove the security context since we are no longer need it down stream chaincodeInvocationSpec.ChaincodeSpec.SecureContext = "" if nil != err { return nil, err } } transaction, err = d.createExecTx(chaincodeInvocationSpec, attributes, id, invoke, sec) if err != nil { return nil, err } if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debugf("Sending invocation transaction (%s) to validator", transaction.Uuid) } resp := d.coord.ExecuteTransaction(transaction) if resp.Status == pb.Response_FAILURE { err = fmt.Errorf(string(resp.Msg)) } else { if !invoke && nil != sec && viper.GetBool("security.privacy") { if resp.Msg, err = sec.DecryptQueryResult(transaction, resp.Msg); nil != err { devopsLogger.Errorf("Failed decrypting query transaction result %s", string(resp.Msg[:])) //resp = &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())} } } } return resp, err }
func transferOwnership(owner crypto.Client, ownerCert crypto.CertificateHandler, fromAttributes string, newOwnerCert crypto.CertificateHandler, toAttributes string, amount string) error { // Get a transaction handler to be used to submit the execute transaction // and bind the chaincode access control logic using the binding submittingCertHandler, err := owner.GetTCertificateHandlerNext("role") if err != nil { return err } txHandler, err := submittingCertHandler.GetTransactionHandler() if err != nil { return err } chaincodeInput := &pb.ChaincodeInput{Args: util.ToChaincodeArgs( "transferOwnership", base64.StdEncoding.EncodeToString(ownerCert.GetCertificate()), fromAttributes, base64.StdEncoding.EncodeToString(newOwnerCert.GetCertificate()), toAttributes, amount)} // Prepare spec and submit spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "mycc"}, CtorMsg: chaincodeInput, ConfidentialityLevel: pb.ConfidentialityLevel_PUBLIC, } var ctx = context.Background() chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} tid := chaincodeInvocationSpec.ChaincodeSpec.ChaincodeID.Name // Now create the Transactions message and send to Peer. transaction, err := txHandler.NewChaincodeExecute(chaincodeInvocationSpec, tid) if err != nil { return fmt.Errorf("Error deploying chaincode: %s ", err) } ledger, err := ledger.GetLedger() ledger.BeginTxBatch("1") _, _, err = chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction) if err != nil { return fmt.Errorf("Error deploying chaincode: %s", err) } ledger.CommitTxBatch("1", []*pb.Transaction{transaction}, nil, nil) return err }
func transferOwnershipInternal(owner crypto.Client, ownerCert crypto.CertificateHandler, asset string, newOwnerCert crypto.CertificateHandler) (resp *pb.Response, err error) { // Get a transaction handler to be used to submit the execute transaction // and bind the chaincode access control logic using the binding submittingCertHandler, err := owner.GetTCertificateHandlerNext() if err != nil { return nil, err } txHandler, err := submittingCertHandler.GetTransactionHandler() if err != nil { return nil, err } binding, err := txHandler.GetBinding() if err != nil { return nil, err } chaincodeInput := &pb.ChaincodeInput{ Function: "transfer", Args: []string{asset, base64.StdEncoding.EncodeToString(newOwnerCert.GetCertificate())}, } chaincodeInputRaw, err := proto.Marshal(chaincodeInput) if err != nil { return nil, err } // Access control. Owner signs chaincodeInputRaw || binding to confirm his identity sigma, err := ownerCert.Sign(append(chaincodeInputRaw, binding...)) if err != nil { return nil, err } // Prepare spec and submit spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: chaincodeName}, CtorMsg: chaincodeInput, Metadata: sigma, // Proof of identity ConfidentialityLevel: confidentialityLevel, } chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} // Now create the Transactions message and send to Peer. transaction, err := txHandler.NewChaincodeExecute(chaincodeInvocationSpec, util.GenerateUUID()) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s ", err) } return processTransaction(transaction) }
// EXP_ProduceSigma produces a sigma as []byte and returns in response func (d *Devops) EXP_ProduceSigma(ctx context.Context, sigmaInput *pb.SigmaInput) (*pb.Response, error) { var sec crypto.Client var err error var sigma []byte secret := sigmaInput.Secret type RBACMetatdata struct { Cert []byte Sigma []byte } if d.isSecurityEnabled { if devopsLogger.IsEnabledFor(logging.DEBUG) { devopsLogger.Debug("Initializing secure devops using context %s", secret.EnrollId) } sec, err = crypto.InitClient(secret.EnrollId, nil) defer crypto.CloseClient(sec) if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil } devopsLogger.Debug("Getting TCertHandler for id: %s, from DER = %s", secret.EnrollId, sigmaInput.AppTCert) tcertHandler, err := sec.GetTCertificateHandlerFromDER(sigmaInput.AppTCert) //tcertHandler, err := sec.GetTCertificateHandlerNext() if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(fmt.Errorf("Error getting TCertHandler from DER: %s", err).Error())}, nil } tcert := sigmaInput.AppTCert //tcertHandler.GetCertificate() sigma, err = tcertHandler.Sign(append(tcert, sigmaInput.Data...)) if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(fmt.Errorf("Error signing with TCertHandler from DER: %s", err).Error())}, nil } // Produce the SigmaOutput asn1Encoding, err := asn1.Marshal(RBACMetatdata{Cert: tcert, Sigma: sigma}) if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil } sigmaOutput := &pb.SigmaOutput{Tcert: tcert, Sigma: sigma, Asn1Encoding: asn1Encoding} sigmaOutputBytes, err := proto.Marshal(sigmaOutput) if nil != err { return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil } return &pb.Response{Status: pb.Response_SUCCESS, Msg: sigmaOutputBytes}, nil } devopsLogger.Warning("Security NOT enabled") return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte("Security NOT enabled")}, nil }
func whoIsTheOwner(invoker crypto.Client, asset string) (transaction *pb.Transaction, resp *pb.Response, err error) { chaincodeInput := &pb.ChaincodeInput{Args: util.ToChaincodeArgs("query", asset)} // Prepare spec and submit spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: chaincodeName}, CtorMsg: chaincodeInput, ConfidentialityLevel: confidentialityLevel, } chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} // Now create the Transactions message and send to Peer. transaction, err = invoker.NewChaincodeQuery(chaincodeInvocationSpec, util.GenerateUUID()) if err != nil { return nil, nil, fmt.Errorf("Error deploying chaincode: %s ", err) } resp, err = processTransaction(transaction) return }
func createDeployTransaction(dspec *pb.ChaincodeDeploymentSpec, uuid string) (*pb.Transaction, error) { var tx *pb.Transaction var err error var sec crypto.Client if dspec.ChaincodeSpec.SecureContext != "" { sec, err = crypto.InitClient(dspec.ChaincodeSpec.SecureContext, nil) defer crypto.CloseClient(sec) if nil != err { return nil, err } tx, err = sec.NewChaincodeDeployTransaction(dspec, uuid) if nil != err { return nil, err } } else { tx, err = pb.NewChaincodeDeployTransaction(dspec, uuid) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s ", err) } } return tx, nil }
func read(invoker crypto.Client, invokerCert crypto.CertificateHandler) ([]byte, error) { // Get a transaction handler to be used to submit the query transaction // and bind the chaincode access control logic using the binding submittingCertHandler, err := invoker.GetTCertificateHandlerNext() if err != nil { return nil, err } txHandler, err := submittingCertHandler.GetTransactionHandler() if err != nil { return nil, err } binding, err := txHandler.GetBinding() if err != nil { return nil, err } chaincodeInput := &pb.ChaincodeInput{Args: util.ToChaincodeArgs("read")} chaincodeInputRaw, err := proto.Marshal(chaincodeInput) if err != nil { return nil, err } // Access control: // invokerCert signs invokerCert.GetCertificate() || chaincodeInputRaw || binding to confirm his identity sigma, err := invokerCert.Sign(append(invokerCert.GetCertificate(), append(chaincodeInputRaw, binding...)...)) if err != nil { return nil, err } rbacMetadata := RBACMetadata{invokerCert.GetCertificate(), sigma} rbacMetadataRaw, err := asn1.Marshal(rbacMetadata) if err != nil { return nil, err } // Prepare spec and submit spec := &pb.ChaincodeSpec{ Type: 1, ChaincodeID: &pb.ChaincodeID{Name: "mycc"}, CtorMsg: chaincodeInput, Metadata: rbacMetadataRaw, ConfidentialityLevel: pb.ConfidentialityLevel_PUBLIC, } var ctx = context.Background() chaincodeInvocationSpec := &pb.ChaincodeInvocationSpec{ChaincodeSpec: spec} tid := chaincodeInvocationSpec.ChaincodeSpec.ChaincodeID.Name // Now create the Transactions message and send to Peer. transaction, err := txHandler.NewChaincodeQuery(chaincodeInvocationSpec, tid) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s ", err) } ledger, err := ledger.GetLedger() ledger.BeginTxBatch("1") result, _, err := chaincode.Execute(ctx, chaincode.GetChain(chaincode.DefaultChain), transaction) if err != nil { return nil, fmt.Errorf("Error deploying chaincode: %s", err) } ledger.CommitTxBatch("1", []*pb.Transaction{transaction}, nil, nil) return result, err }