diff --git a/Makefile b/Makefile index 4b52a99eff3..7d0c145ede1 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,6 @@ # - checks - runs all tests/checks # - peer - builds the fabric peer binary # - orderer - builds the fabric orderer binary -# - membersrvc - builds the membersrvc binary # - unit-test - runs the go-test based unit tests # - behave - runs the behave test # - behave-deps - ensures pre-requisites are availble for running behave manually @@ -31,7 +30,6 @@ # - images[-clean] - ensures all docker images are available[/cleaned] # - peer-image[-clean] - ensures the peer-image is available[/cleaned] (for behave, etc) # - orderer-image[-clean] - ensures the orderer-image is available[/cleaned] (for behave, etc) -# - membersrvc-image[-clean] - ensures the membersrvc-image is available[/cleaned] (for behave, etc) # - protos - generate all protobuf artifacts based on .proto files # - clean - cleans the build area # - dist-clean - superset of 'clean' that also removes persistent state @@ -69,10 +67,10 @@ SUBDIRS:=$(strip $(SUBDIRS)) GOSHIM_DEPS = $(shell ./scripts/goListFiles.sh github.com/hyperledger/fabric/core/chaincode/shim | sort | uniq) JAVASHIM_DEPS = $(shell git ls-files core/chaincode/shim/java) PROJECT_FILES = $(shell git ls-files) -IMAGES = src ccenv peer membersrvc javaenv orderer +IMAGES = src ccenv peer javaenv orderer -all: peer orderer membersrvc checks +all: peer orderer checks checks: linter unit-test behave @@ -80,6 +78,9 @@ checks: linter unit-test behave $(SUBDIRS): cd $@ && $(MAKE) +membersrvc-image: + @echo "membersrvc has been removed from this build" + .PHONY: peer peer: build/bin/peer peer-image: build/image/peer/.dummy @@ -88,10 +89,6 @@ peer-image: build/image/peer/.dummy orderer: build/bin/orderer orderer-image: build/image/orderer/.dummy -.PHONY: membersrvc -membersrvc: build/bin/membersrvc -membersrvc-image: build/image/membersrvc/.dummy - unit-test: peer-image gotools @./scripts/goUnitTests.sh $(DOCKER_TAG) "$(GO_LDFLAGS)" @@ -111,7 +108,6 @@ linter: gotools go vet ./core/... go vet ./events/... go vet ./examples/... - go vet ./membersrvc/... go vet ./peer/... go vet ./protos/... go vet ./orderer/... @@ -144,7 +140,7 @@ build/bin/chaintool: Makefile # JIRA FAB-243 - Mark build/docker/bin artifacts explicitly as secondary # since they are never referred to directly. This prevents # the makefile from deleting them inadvertently. -.SECONDARY: build/docker/bin/peer build/docker/bin/orderer build/docker/bin/membersrvc +.SECONDARY: build/docker/bin/peer build/docker/bin/orderer # We (re)build a package within a docker context but persist the $GOPATH/pkg # directory so that subsequent builds are faster @@ -247,7 +243,7 @@ build/image/%/.dummy: build/image/src/.dummy build/docker/bin/% protos: gotools ./devenv/compile_protos.sh -src-image-clean: ccenv-image-clean peer-image-clean orderer-image-clean membersrvc-image-clean +src-image-clean: ccenv-image-clean peer-image-clean orderer-image-clean %-image-clean: $(eval TARGET = ${patsubst %-image-clean,%,${@}}) diff --git a/core/chaincode/exectransaction_test.go b/core/chaincode/exectransaction_test.go index 4203da54189..7a46e8ad3b6 100644 --- a/core/chaincode/exectransaction_test.go +++ b/core/chaincode/exectransaction_test.go @@ -34,7 +34,6 @@ import ( "github.com/hyperledger/fabric/core/ledger" "github.com/hyperledger/fabric/core/ledger/kvledger" "github.com/hyperledger/fabric/core/util" - "github.com/hyperledger/fabric/membersrvc/ca" pb "github.com/hyperledger/fabric/protos" putils "github.com/hyperledger/fabric/protos/utils" @@ -53,42 +52,6 @@ func getNowMillis() int64 { return nanos / 1000000 } -//initialize memberservices and startup -func initMemSrvc() (net.Listener, error) { - //start clean - finitMemSrvc(nil) - - ca.CacheConfiguration() // Cache configuration - - aca := ca.NewACA() - eca := ca.NewECA(aca) - tca := ca.NewTCA(eca) - tlsca := ca.NewTLSCA(eca) - - sockp, err := net.Listen("tcp", viper.GetString("server.port")) - if err != nil { - return nil, err - } - - var opts []grpc.ServerOption - server := grpc.NewServer(opts...) - - aca.Start(server) - eca.Start(server) - tca.Start(server) - tlsca.Start(server) - - go server.Serve(sockp) - - return sockp, nil -} - -//cleanup memberservice debris -func finitMemSrvc(lis net.Listener) { - closeListenerAndSleep(lis) - os.RemoveAll(filepath.Join(os.TempDir(), "ca")) -} - //initialize peer and start up. If security==enabled, login as vp func initPeer() (net.Listener, error) { //start clean @@ -120,15 +83,7 @@ func initPeer() (net.Listener, error) { // Install security object for peer var secHelper crypto.Peer if viper.GetBool("security.enabled") { - enrollID := viper.GetString("security.enrollID") - enrollSecret := viper.GetString("security.enrollSecret") - if err = crypto.RegisterValidator(enrollID, nil, enrollID, enrollSecret); nil != err { - return nil, err - } - secHelper, err = crypto.InitValidator(enrollID, nil) - if nil != err { - return nil, err - } + //TODO: Integrate new crypto / idp code } ccStartupTimeout := time.Duration(chaincodeStartupTimeoutDefault) * time.Millisecond @@ -216,24 +171,12 @@ func getDeploymentSpec(context context.Context, spec *pb.ChaincodeSpec) (*pb.Cha 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 - } + //TODO: integrate new crypto / idp code if applicable - tx, err = sec.NewChaincodeDeployTransaction(dspec, uuid, attributes...) - 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) - } + tx, err = pb.NewChaincodeDeployTransaction(dspec, uuid) + if err != nil { + return nil, fmt.Errorf("Error deploying chaincode: %s ", err) } return tx, nil } @@ -241,32 +184,18 @@ func createDeployTransaction(dspec *pb.ChaincodeDeploymentSpec, uuid string) (*p 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, attributes...) - } else { - tx, err = sec.NewChaincodeQuery(spec, uuid, attributes...) - } - if nil != err { - return nil, err - } + + //TODO: integrate new crypto / idp code if applicable + + var t pb.Transaction_Type + if invokeTx { + t = pb.Transaction_CHAINCODE_INVOKE } 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 - } + t = pb.Transaction_CHAINCODE_QUERY + } + tx, err = pb.NewChaincodeExecute(spec, uuid, t) + if nil != err { + return nil, err } return tx, nil } @@ -1069,48 +998,7 @@ func TestChaincodeQueryChaincodeWithSec(t *testing.T) { viper.Set("security.enabled", "true") - //Initialize crypto - if err := crypto.Init(); err != nil { - panic(fmt.Errorf("Failed initializing the crypto layer [%s]", err)) - } - - //set paths for memberservice to pick up - viper.Set("peer.fileSystemPath", filepath.Join(os.TempDir(), "hyperledger", "production")) - viper.Set("server.rootpath", filepath.Join(os.TempDir(), "ca")) - - var err error - var memSrvcLis net.Listener - if memSrvcLis, err = initMemSrvc(); err != nil { - t.Fail() - t.Logf("Error registering user %s", err) - return - } - - defer finitMemSrvc(memSrvcLis) - - time.Sleep(2 * time.Second) - - var peerLis net.Listener - if peerLis, err = initPeer(); err != nil { - t.Fail() - t.Logf("Error registering user %s", err) - return - } - - defer finitPeer(peerLis) - - if err = crypto.RegisterClient("jim", nil, "jim", "6avZQLwcUe9b"); err != nil { - t.Fail() - t.Logf("Error registering user %s", err) - return - } - - //login as jim and test chaincode-chaincode interaction with security - if err = chaincodeQueryChaincode("jim"); err != nil { - t.Fail() - t.Logf("Error executing test %s", err) - return - } + //TODO: integrate new crypto / idp code if applicable } // Test the invocation of a transaction. diff --git a/core/crypto/client.go b/core/crypto/client.go deleted file mode 100644 index 07ee25e5a7f..00000000000 --- a/core/crypto/client.go +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "sync" - - "github.com/hyperledger/fabric/core/crypto/utils" -) - -// Private Variables - -type clientEntry struct { - client Client - counter int64 -} - -var ( - // Map of initialized clients - clients = make(map[string]clientEntry) - - // Sync - clientMutex sync.Mutex -) - -// Public Methods - -// RegisterClient registers a client to the PKI infrastructure -func RegisterClient(name string, pwd []byte, enrollID, enrollPWD string) error { - clientMutex.Lock() - defer clientMutex.Unlock() - - log.Infof("Registering client [%s] with name [%s]...", enrollID, name) - - if _, ok := clients[name]; ok { - log.Infof("Registering client [%s] with name [%s]...done. Already initialized.", enrollID, name) - - return nil - } - - client := newClient() - if err := client.register(name, pwd, enrollID, enrollPWD); err != nil { - if err != utils.ErrAlreadyRegistered && err != utils.ErrAlreadyInitialized { - log.Errorf("Failed registering client [%s] with name [%s] [%s].", enrollID, name, err) - return err - } - log.Infof("Registering client [%s] with name [%s]...done. Already registered or initiliazed.", enrollID, name) - } - err := client.close() - if err != nil { - // It is not necessary to report this error to the caller - log.Warningf("Registering client [%s] with name [%s]. Failed closing [%s].", enrollID, name, err) - } - - log.Infof("Registering client [%s] with name [%s]...done!", enrollID, name) - - return nil -} - -// InitClient initializes a client named name with password pwd -func InitClient(name string, pwd []byte) (Client, error) { - clientMutex.Lock() - defer clientMutex.Unlock() - - log.Infof("Initializing client [%s]...", name) - - if entry, ok := clients[name]; ok { - log.Infof("Client already initiliazied [%s]. Increasing counter from [%d]", name, clients[name].counter) - entry.counter++ - clients[name] = entry - - return clients[name].client, nil - } - - client := newClient() - if err := client.init(name, pwd); err != nil { - log.Errorf("Failed client initialization [%s]: [%s].", name, err) - - return nil, err - } - - clients[name] = clientEntry{client, 1} - log.Infof("Initializing client [%s]...done!", name) - - return client, nil -} - -// CloseClient releases all the resources allocated by clients -func CloseClient(client Client) error { - clientMutex.Lock() - defer clientMutex.Unlock() - - return closeClientInternal(client, false) -} - -// CloseAllClients closes all the clients initialized so far -func CloseAllClients() (bool, []error) { - clientMutex.Lock() - defer clientMutex.Unlock() - - log.Info("Closing all clients...") - - errs := make([]error, len(clients)) - for _, value := range clients { - err := closeClientInternal(value.client, true) - - errs = append(errs, err) - } - - log.Info("Closing all clients...done!") - - return len(errs) != 0, errs -} - -// Private Methods - -func newClient() *clientImpl { - return &clientImpl{&nodeImpl{}, nil, nil, nil, nil} -} - -func closeClientInternal(client Client, force bool) error { - if client == nil { - return utils.ErrNilArgument - } - - name := client.GetName() - log.Infof("Closing client [%s]...", name) - entry, ok := clients[name] - if !ok { - return utils.ErrInvalidReference - } - if entry.counter == 1 || force { - defer delete(clients, name) - err := clients[name].client.(*clientImpl).close() - log.Debugf("Closing client [%s]...cleanup! [%s].", name, utils.ErrToString(err)) - - return err - } - - // decrease counter - entry.counter-- - clients[name] = entry - log.Debugf("Closing client [%s]...decreased counter at [%d].", name, clients[name].counter) - - return nil -} diff --git a/core/crypto/client_confidentiality.go b/core/crypto/client_confidentiality.go deleted file mode 100644 index 20552ec5495..00000000000 --- a/core/crypto/client_confidentiality.go +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/rand" - "encoding/asn1" - "errors" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -func (client *clientImpl) encryptTx(tx *obc.Transaction) error { - - if len(tx.Nonce) == 0 { - return errors.New("Failed encrypting payload. Invalid nonce.") - } - - client.Debugf("Confidentiality protocol version [%s]", tx.ConfidentialityProtocolVersion) - switch tx.ConfidentialityProtocolVersion { - case "1.2": - client.Debug("Using confidentiality protocol version 1.2") - return client.encryptTxVersion1_2(tx) - } - - return utils.ErrInvalidProtocolVersion -} - -// chainCodeValidatorMessage1_2 represents a message to validators -type chainCodeValidatorMessage1_2 struct { - PrivateKey []byte - StateKey []byte -} - -func (client *clientImpl) encryptTxVersion1_2(tx *obc.Transaction) error { - // Create (PK_C,SK_C) pair - ccPrivateKey, err := client.eciesSPI.NewPrivateKey(rand.Reader, primitives.GetDefaultCurve()) - if err != nil { - client.Errorf("Failed generate chaincode keypair: [%s]", err) - - return err - } - - // Prepare message to the validators - var ( - stateKey []byte - privBytes []byte - ) - - switch tx.Type { - case obc.Transaction_CHAINCODE_DEPLOY: - // Prepare chaincode stateKey and privateKey - stateKey, err = primitives.GenAESKey() - if err != nil { - client.Errorf("Failed creating state key: [%s]", err) - - return err - } - - privBytes, err = client.eciesSPI.SerializePrivateKey(ccPrivateKey) - if err != nil { - client.Errorf("Failed serializing chaincode key: [%s]", err) - - return err - } - - break - case obc.Transaction_CHAINCODE_QUERY: - // Prepare chaincode stateKey and privateKey - stateKey = primitives.HMACAESTruncated(client.queryStateKey, append([]byte{6}, tx.Nonce...)) - - privBytes, err = client.eciesSPI.SerializePrivateKey(ccPrivateKey) - if err != nil { - client.Errorf("Failed serializing chaincode key: [%s]", err) - - return err - } - - break - case obc.Transaction_CHAINCODE_INVOKE: - // Prepare chaincode stateKey and privateKey - stateKey = make([]byte, 0) - - privBytes, err = client.eciesSPI.SerializePrivateKey(ccPrivateKey) - if err != nil { - client.Errorf("Failed serializing chaincode key: [%s]", err) - - return err - } - break - } - - // Encrypt message to the validators - cipher, err := client.eciesSPI.NewAsymmetricCipherFromPublicKey(client.chainPublicKey) - if err != nil { - client.Errorf("Failed creating new encryption scheme: [%s]", err) - - return err - } - - msgToValidators, err := asn1.Marshal(chainCodeValidatorMessage1_2{privBytes, stateKey}) - if err != nil { - client.Errorf("Failed preparing message to the validators: [%s]", err) - - return err - } - - encMsgToValidators, err := cipher.Process(msgToValidators) - if err != nil { - client.Errorf("Failed encrypting message to the validators: [%s]", err) - - return err - } - tx.ToValidators = encMsgToValidators - - // Encrypt the rest of the fields - - // Init with chainccode pk - cipher, err = client.eciesSPI.NewAsymmetricCipherFromPublicKey(ccPrivateKey.GetPublicKey()) - if err != nil { - client.Errorf("Failed initiliazing encryption scheme: [%s]", err) - - return err - } - - // Encrypt chaincodeID using pkC - encryptedChaincodeID, err := cipher.Process(tx.ChaincodeID) - if err != nil { - client.Errorf("Failed encrypting chaincodeID: [%s]", err) - - return err - } - tx.ChaincodeID = encryptedChaincodeID - - // Encrypt payload using pkC - encryptedPayload, err := cipher.Process(tx.Payload) - if err != nil { - client.Errorf("Failed encrypting payload: [%s]", err) - - return err - } - tx.Payload = encryptedPayload - - // Encrypt metadata using pkC - if len(tx.Metadata) != 0 { - encryptedMetadata, err := cipher.Process(tx.Metadata) - if err != nil { - client.Errorf("Failed encrypting metadata: [%s]", err) - - return err - } - tx.Metadata = encryptedMetadata - } - - return nil -} diff --git a/core/crypto/client_crypto.go b/core/crypto/client_crypto.go deleted file mode 100644 index 94f6132ddea..00000000000 --- a/core/crypto/client_crypto.go +++ /dev/null @@ -1,61 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/ecdsa" - - "github.com/hyperledger/fabric/core/crypto/primitives" -) - -func (client *clientImpl) registerCryptoEngine() (err error) { - // Store query state key - client.queryStateKey, err = primitives.GetRandomNonce() - if err != nil { - log.Errorf("Failed generating query state key: [%s].", err.Error()) - return - } - - err = client.ks.storeKey(client.conf.getQueryStateKeyFilename(), client.queryStateKey) - if err != nil { - log.Errorf("Failed storing query state key: [%s].", err.Error()) - return - } - - return -} - -func (client *clientImpl) initCryptoEngine() (err error) { - // Load TCertOwnerKDFKey - if err = client.initTCertEngine(); err != nil { - return - } - - // Init query state key - client.queryStateKey, err = client.ks.loadKey(client.conf.getQueryStateKeyFilename()) - if err != nil { - return - } - - // Init chain publicKey - client.chainPublicKey, err = client.eciesSPI.NewPublicKey(nil, client.enrollChainKey.(*ecdsa.PublicKey)) - if err != nil { - return - } - - return -} diff --git a/core/crypto/client_ecert_handler.go b/core/crypto/client_ecert_handler.go deleted file mode 100644 index bec964c2a2e..00000000000 --- a/core/crypto/client_ecert_handler.go +++ /dev/null @@ -1,115 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -type eCertHandlerImpl struct { - client *clientImpl -} - -type eCertTransactionHandlerImpl struct { - client *clientImpl - - nonce []byte - binding []byte -} - -func (handler *eCertHandlerImpl) init(client *clientImpl) error { - handler.client = client - - return nil -} - -// GetCertificate returns the TCert DER -func (handler *eCertHandlerImpl) GetCertificate() []byte { - return utils.Clone(handler.client.enrollCert.Raw) -} - -// Sign signs msg using the signing key corresponding to this TCert -func (handler *eCertHandlerImpl) Sign(msg []byte) ([]byte, error) { - return handler.client.signWithEnrollmentKey(msg) -} - -// Verify verifies msg using the verifying key corresponding to this TCert -func (handler *eCertHandlerImpl) Verify(signature []byte, msg []byte) error { - ok, err := handler.client.verifyWithEnrollmentCert(msg, signature) - if err != nil { - return err - } - if !ok { - return utils.ErrInvalidSignature - } - return nil -} - -// GetTransactionHandler returns the transaction handler relative to this certificate -func (handler *eCertHandlerImpl) GetTransactionHandler() (TransactionHandler, error) { - txHandler := &eCertTransactionHandlerImpl{} - err := txHandler.init(handler.client) - if err != nil { - handler.client.Errorf("Failed getting transaction handler [%s]", err) - - return nil, err - } - - return txHandler, nil -} - -func (handler *eCertTransactionHandlerImpl) init(client *clientImpl) error { - nonce, err := client.createTransactionNonce() - if err != nil { - client.Errorf("Failed initiliazing transaction handler [%s]", err) - - return err - } - - handler.client = client - handler.nonce = nonce - handler.binding = primitives.Hash(append(handler.client.enrollCert.Raw, handler.nonce...)) - - return nil -} - -// GetCertificateHandler returns the certificate handler relative to the certificate mapped to this transaction -func (handler *eCertTransactionHandlerImpl) GetCertificateHandler() (CertificateHandler, error) { - return handler.client.GetEnrollmentCertificateHandler() -} - -// GetBinding returns an Binding to the underlying transaction layer -func (handler *eCertTransactionHandlerImpl) GetBinding() ([]byte, error) { - return utils.Clone(handler.binding), nil -} - -// NewChaincodeDeployTransaction is used to deploy chaincode. -func (handler *eCertTransactionHandlerImpl) NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string, attributeNames ...string) (*obc.Transaction, error) { - return handler.client.newChaincodeDeployUsingECert(chaincodeDeploymentSpec, uuid, handler.nonce) -} - -// NewChaincodeExecute is used to execute chaincode's functions. -func (handler *eCertTransactionHandlerImpl) NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, attributeNames ...string) (*obc.Transaction, error) { - return handler.client.newChaincodeExecuteUsingECert(chaincodeInvocation, uuid, handler.nonce) -} - -// NewChaincodeQuery is used to query chaincode's functions. -func (handler *eCertTransactionHandlerImpl) NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, attributeNames ...string) (*obc.Transaction, error) { - return handler.client.newChaincodeQueryUsingECert(chaincodeInvocation, uuid, handler.nonce) -} diff --git a/core/crypto/client_impl.go b/core/crypto/client_impl.go deleted file mode 100644 index 7f3f5751bd7..00000000000 --- a/core/crypto/client_impl.go +++ /dev/null @@ -1,270 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "errors" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -type clientImpl struct { - *nodeImpl - - // Chain - chainPublicKey primitives.PublicKey - queryStateKey []byte - - // TCA KDFKey - tCertOwnerKDFKey []byte - tCertPool tCertPool -} - -// NewChaincodeDeployTransaction is used to deploy chaincode. -func (client *clientImpl) NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string, attributes ...string) (*obc.Transaction, error) { - // Verify that the client is initialized - if !client.IsInitialized() { - return nil, utils.ErrNotInitialized - } - - // Get next available (not yet used) transaction certificate - tCerts, err := client.tCertPool.GetNextTCerts(1, attributes...) - if err != nil { - client.Errorf("Failed to obtain a (not yet used) TCert for Chaincode Deploy[%s].", err.Error()) - return nil, err - } - - if len(tCerts) != 1 { - client.Error("Failed to obtain a (not yet used) TCert.") - return nil, errors.New("Failed to obtain a TCert for Chaincode Deploy Transaction using TCert. Expected exactly one returned TCert.") - } - - // Create Transaction - return client.newChaincodeDeployUsingTCert(chaincodeDeploymentSpec, uuid, attributes, tCerts[0].tCert, nil) -} - -// GetNextTCerts Gets next available (not yet used) transaction certificate. -func (client *clientImpl) GetNextTCerts(nCerts int, attributes ...string) (tCerts []tCert, err error) { - if nCerts < 1 { - return nil, errors.New("Number of requested TCerts has to be positive!") - } - - // Verify that the client is initialized - if !client.IsInitialized() { - return nil, utils.ErrNotInitialized - } - - // Get next available (not yet used) transaction certificate - tBlocks, err := client.tCertPool.GetNextTCerts(nCerts, attributes...) - if err != nil { - client.Errorf("Failed getting [%d] (not yet used) Transaction Certificates (TCerts) [%s].", nCerts, err.Error()) - return nil, err - } - tCerts = make([]tCert, len(tBlocks)) - for i, eachBlock := range tBlocks { - tCerts[i] = eachBlock.tCert - } - return tCerts, nil -} - -// NewChaincodeInvokeTransaction is used to invoke chaincode's functions. -func (client *clientImpl) NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, attributes ...string) (*obc.Transaction, error) { - // Verify that the client is initialized - if !client.IsInitialized() { - return nil, utils.ErrNotInitialized - } - - // Get next available (not yet used) transaction certificate - tBlocks, err := client.tCertPool.GetNextTCerts(1, attributes...) - if err != nil { - client.Errorf("Failed to obtain a (not yet used) TCert [%s].", err.Error()) - return nil, err - } - - if len(tBlocks) != 1 { - client.Error("Failed to obtain a (not yet used) TCert.") - return nil, errors.New("Failed to obtain a TCert for Chaincode Execution. Expected exactly one returned TCert.") - } - - // Create Transaction - return client.newChaincodeExecuteUsingTCert(chaincodeInvocation, uuid, attributes, tBlocks[0].tCert, nil) -} - -// NewChaincodeQuery is used to query chaincode's functions. -func (client *clientImpl) NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, attributes ...string) (*obc.Transaction, error) { - // Verify that the client is initialized - if !client.IsInitialized() { - return nil, utils.ErrNotInitialized - } - - // Get next available (not yet used) transaction certificate - tBlocks, err := client.tCertPool.GetNextTCerts(1, attributes...) - if err != nil { - client.Errorf("Failed to obtain a (not yet used) TCert [%s].", err.Error()) - return nil, err - } - - if len(tBlocks) != 1 { - client.Error("Failed to obtain a (not yet used) TCert.") - return nil, errors.New("Failed to obtain a TCert for Chaincode Invocation. Expected exactly one returned TCert.") - } - - // Create Transaction - return client.newChaincodeQueryUsingTCert(chaincodeInvocation, uuid, attributes, tBlocks[0].tCert, nil) -} - -// GetEnrollmentCertHandler returns a CertificateHandler whose certificate is the enrollment certificate -func (client *clientImpl) GetEnrollmentCertificateHandler() (CertificateHandler, error) { - // Verify that the client is initialized - if !client.IsInitialized() { - return nil, utils.ErrNotInitialized - } - - // Return the handler - handler := &eCertHandlerImpl{} - err := handler.init(client) - if err != nil { - client.Errorf("Failed getting handler [%s].", err.Error()) - return nil, err - } - - return handler, nil -} - -// GetTCertHandlerNext returns a CertificateHandler whose certificate is the next available TCert -func (client *clientImpl) GetTCertificateHandlerNext(attributes ...string) (CertificateHandler, error) { - // Verify that the client is initialized - if !client.IsInitialized() { - return nil, utils.ErrNotInitialized - } - - // Get next TCert - tBlocks, err := client.tCertPool.GetNextTCerts(1, attributes...) - if err != nil { - client.Errorf("Failed to obtain a (not yet used) TCert for creating a CertificateHandler [%s].", err.Error()) - return nil, err - } - - if len(tBlocks) != 1 { - client.Error("Failed to obtain a TCert for creating a CertificateHandler.") - return nil, errors.New("Failed to obtain a TCert for creating a CertificateHandler") - } - - // Return the handler - handler := &tCertHandlerImpl{} - err = handler.init(client, tBlocks[0].tCert) - if err != nil { - client.Errorf("Failed getting handler [%s].", err.Error()) - return nil, err - } - - return handler, nil -} - -// GetTCertHandlerFromDER returns a CertificateHandler whose certificate is the one passed -func (client *clientImpl) GetTCertificateHandlerFromDER(tCertDER []byte) (CertificateHandler, error) { - // Verify that the client is initialized - if !client.IsInitialized() { - return nil, utils.ErrNotInitialized - } - - // Validate the transaction certificate - tCert, err := client.getTCertFromExternalDER(tCertDER) - if err != nil { - client.Warningf("Failed validating transaction certificate [%s].", err) - - return nil, err - } - - // Return the handler - handler := &tCertHandlerImpl{} - err = handler.init(client, tCert) - if err != nil { - client.Errorf("Failed getting handler [%s].", err.Error()) - return nil, err - } - - return handler, nil -} - -func (client *clientImpl) register(id string, pwd []byte, enrollID, enrollPWD string) (err error) { - - clentRegFunc := func(eType NodeType, name string, pwd []byte, enrollID, enrollPWD string) error { - client.Info("Register crypto engine...") - err = client.registerCryptoEngine() - if err != nil { - client.Errorf("Failed registering crypto engine [%s]: [%s].", enrollID, err.Error()) - return nil - } - client.Info("Register crypto engine...done.") - return nil - } - - if err = client.nodeImpl.register(NodeClient, id, pwd, enrollID, enrollPWD, clentRegFunc); err != nil { - client.Errorf("Failed registering client [%s]: [%s]", enrollID, err) - return err - } - - return nil -} - -func (client *clientImpl) init(id string, pwd []byte) error { - - clientInitFunc := func(eType NodeType, name string, pwd []byte) error { - // Initialize keystore - client.Debug("Init keystore...") - err := client.initKeyStore() - if err != nil { - if err != utils.ErrKeyStoreAlreadyInitialized { - client.Error("Keystore already initialized.") - } else { - client.Errorf("Failed initiliazing keystore [%s].", err.Error()) - - return err - } - } - client.Debug("Init keystore...done.") - - // Init crypto engine - err = client.initCryptoEngine() - if err != nil { - client.Errorf("Failed initiliazing crypto engine [%s].", err.Error()) - return err - } - return nil - } - - if err := client.nodeImpl.init(NodeClient, id, pwd, clientInitFunc); err != nil { - return err - } - return nil -} - -func (client *clientImpl) close() (err error) { - if client.tCertPool != nil { - if err = client.tCertPool.Stop(); err != nil { - client.Errorf("Failed closing TCertPool [%s]", err) - } - } - - if err = client.nodeImpl.close(); err != nil { - client.Errorf("Failed closing node [%s]", err) - } - return -} diff --git a/core/crypto/client_ks.go b/core/crypto/client_ks.go deleted file mode 100644 index 8905049e089..00000000000 --- a/core/crypto/client_ks.go +++ /dev/null @@ -1,203 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "database/sql" - "os" -) - -func (client *clientImpl) initKeyStore() error { - // Create TCerts directory - os.MkdirAll(client.conf.getTCertsPath(), 0755) - - // create tables - client.Debugf("Create Table if not exists [TCert] at [%s].", client.conf.getKeyStorePath()) - if _, err := client.ks.sqlDB.Exec("CREATE TABLE IF NOT EXISTS TCerts (id INTEGER, attrhash VARCHAR, cert BLOB, prkz BLOB, PRIMARY KEY (id))"); err != nil { - client.Errorf("Failed creating table [%s].", err) - return err - } - - client.Debugf("Create Table if not exists [UsedTCert] at [%s].", client.conf.getKeyStorePath()) - if _, err := client.ks.sqlDB.Exec("CREATE TABLE IF NOT EXISTS UsedTCert (id INTEGER, attrhash VARCHAR, cert BLOB, prkz BLOB, PRIMARY KEY (id))"); err != nil { - client.Errorf("Failed creating table [%s].", err) - return err - } - - return nil -} - -func (ks *keyStore) storeUsedTCert(tCertBlck *TCertBlock) (err error) { - ks.m.Lock() - defer ks.m.Unlock() - - ks.node.Debug("Storing used TCert...") - - // Open transaction - tx, err := ks.sqlDB.Begin() - if err != nil { - ks.node.Errorf("Failed beginning transaction [%s].", err) - - return - } - - // Insert into UsedTCert - if _, err = tx.Exec("INSERT INTO UsedTCert (attrhash, cert, prkz) VALUES (?, ?, ?)", tCertBlck.attributesHash, tCertBlck.tCert.GetCertificate().Raw, tCertBlck.tCert.GetPreK0()); err != nil { - ks.node.Errorf("Failed inserting TCert to UsedTCert: [%s].", err) - - tx.Rollback() - - return - } - - // Finalize - err = tx.Commit() - if err != nil { - ks.node.Errorf("Failed commiting [%s].", err) - tx.Rollback() - - return - } - - ks.node.Debug("Storing used TCert...done!") - - //name, err := utils.TempFile(ks.conf.getTCertsPath(), "tcert_") - //if err != nil { - // ks.node.error("Failed storing TCert: [%s]", err) - // return - //} - // - //err = ioutil.WriteFile(name, tCert.GetCertificate().Raw, 0700) - //if err != nil { - // ks.node.error("Failed storing TCert: [%s]", err) - // return - //} - - return -} - -func (ks *keyStore) storeUnusedTCerts(tCertBlocks []*TCertBlock) (err error) { - ks.node.Debug("Storing unused TCerts...") - - if len(tCertBlocks) == 0 { - ks.node.Debug("Empty list of unused TCerts.") - return - } - - // Open transaction - tx, err := ks.sqlDB.Begin() - if err != nil { - ks.node.Errorf("Failed beginning transaction [%s].", err) - - return - } - - for _, tCertBlck := range tCertBlocks { - // Insert into UsedTCert - if _, err = tx.Exec("INSERT INTO TCerts (attrhash, cert, prkz) VALUES (?, ?, ?)", tCertBlck.attributesHash, tCertBlck.tCert.GetCertificate().Raw, tCertBlck.tCert.GetPreK0()); err != nil { - ks.node.Errorf("Failed inserting unused TCert to TCerts: [%s].", err) - - tx.Rollback() - - return - } - } - - // Finalize - err = tx.Commit() - if err != nil { - ks.node.Errorf("Failed commiting [%s].", err) - tx.Rollback() - - return - } - - ks.node.Debug("Storing unused TCerts...done!") - - return -} - -//Used by the MT pool -func (ks *keyStore) loadUnusedTCert() ([]byte, error) { - // Get the first row available - var id int - var cert []byte - row := ks.sqlDB.QueryRow("SELECT id, cert FROM TCerts") - err := row.Scan(&id, &cert) - - if err == sql.ErrNoRows { - return nil, nil - } else if err != nil { - ks.node.Errorf("Error during select [%s].", err.Error()) - - return nil, err - } - - // Remove from TCert - if _, err := ks.sqlDB.Exec("DELETE FROM TCerts WHERE id = ?", id); err != nil { - ks.node.Errorf("Failed removing row [%d] from TCert: [%s].", id, err.Error()) - - return nil, err - } - - return cert, nil -} - -func (ks *keyStore) loadUnusedTCerts() ([]*TCertDBBlock, error) { - // Get unused TCerts - rows, err := ks.sqlDB.Query("SELECT attrhash, cert, prkz FROM TCerts") - if err == sql.ErrNoRows { - return nil, nil - } else if err != nil { - ks.node.Errorf("Error during select [%s].", err) - - return nil, err - } - - tCertDBBlocks := []*TCertDBBlock{} - - for { - if rows.Next() { - var tCertDER []byte - var attributeHash string - var prek0 []byte - if err := rows.Scan(&attributeHash, &tCertDER, &prek0); err != nil { - ks.node.Errorf("Error during scan [%s].", err) - - continue - } - - var tCertBlk = new(TCertDBBlock) - tCertBlk.attributesHash = attributeHash - tCertBlk.preK0 = prek0 - tCertBlk.tCertDER = tCertDER - - tCertDBBlocks = append(tCertDBBlocks, tCertBlk) - } else { - break - } - } - - // Delete all entries - if _, err = ks.sqlDB.Exec("DELETE FROM TCerts"); err != nil { - ks.node.Errorf("Failed cleaning up unused TCert entries: [%s].", err) - - return nil, err - } - - return tCertDBBlocks, nil -} diff --git a/core/crypto/client_state.go b/core/crypto/client_state.go deleted file mode 100644 index db7e98be780..00000000000 --- a/core/crypto/client_state.go +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/aes" - "crypto/cipher" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -// DecryptQueryResult is used to decrypt the result of a query transaction -func (client *clientImpl) DecryptQueryResult(queryTx *obc.Transaction, ct []byte) ([]byte, error) { - // Verify that the client is initialized - if !client.isInitialized { - return nil, utils.ErrNotInitialized - } - - var queryKey []byte - - switch queryTx.ConfidentialityProtocolVersion { - case "1.2": - queryKey = primitives.HMACAESTruncated(client.queryStateKey, append([]byte{6}, queryTx.Nonce...)) - } - - if len(ct) <= primitives.NonceSize { - return nil, utils.ErrDecrypt - } - - c, err := aes.NewCipher(queryKey) - if err != nil { - return nil, err - } - - gcm, err := cipher.NewGCM(c) - if err != nil { - return nil, err - } - - nonce := make([]byte, gcm.NonceSize()) - copy(nonce, ct) - - out, err := gcm.Open(nil, nonce, ct[gcm.NonceSize():], nil) - if err != nil { - client.Errorf("Failed decrypting query result [%s].", err.Error()) - return nil, utils.ErrDecrypt - } - return out, nil -} diff --git a/core/crypto/client_tca.go b/core/crypto/client_tca.go deleted file mode 100644 index b929d7d32fe..00000000000 --- a/core/crypto/client_tca.go +++ /dev/null @@ -1,615 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - membersrvc "github.com/hyperledger/fabric/membersrvc/protos" - - "bytes" - "crypto/ecdsa" - "crypto/hmac" - - "errors" - "fmt" - - "math/big" - "time" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/hyperledger/fabric/core/crypto/primitives" - "golang.org/x/net/context" -) - -func (client *clientImpl) initTCertEngine() (err error) { - // load TCertOwnerKDFKey - if err = client.loadTCertOwnerKDFKey(); err != nil { - return - } - - // init TCerPool - client.Debugf("Using multithreading [%t]", client.conf.IsMultithreadingEnabled()) - client.Debugf("TCert batch size [%d]", client.conf.getTCertBatchSize()) - - if client.conf.IsMultithreadingEnabled() { - client.tCertPool = new(tCertPoolMultithreadingImpl) - } else { - client.tCertPool = new(tCertPoolSingleThreadImpl) - } - - if err = client.tCertPool.init(client); err != nil { - client.Errorf("Failied inizializing TCertPool: [%s]", err) - - return - } - if err = client.tCertPool.Start(); err != nil { - client.Errorf("Failied starting TCertPool: [%s]", err) - - return - } - return -} - -func (client *clientImpl) storeTCertOwnerKDFKey() error { - if err := client.ks.storeKey(client.conf.getTCertOwnerKDFKeyFilename(), client.tCertOwnerKDFKey); err != nil { - client.Errorf("Failed storing TCertOwnerKDFKey [%s].", err.Error()) - - return err - } - return nil -} - -func (client *clientImpl) loadTCertOwnerKDFKey() error { - // Load TCertOwnerKDFKey - client.Debug("Loading TCertOwnerKDFKey...") - - if !client.ks.isAliasSet(client.conf.getTCertOwnerKDFKeyFilename()) { - client.Debug("TCertOwnerKDFKey is missing, maybe the client has not requested any TCerts from TCA yet") - - return nil - } - - tCertOwnerKDFKey, err := client.ks.loadKey(client.conf.getTCertOwnerKDFKeyFilename()) - if err != nil { - client.Errorf("Failed parsing TCertOwnerKDFKey [%s].", err.Error()) - - return err - } - client.tCertOwnerKDFKey = tCertOwnerKDFKey - - client.Debug("Loading TCertOwnerKDFKey...done!") - - return nil -} - -func (client *clientImpl) getTCertFromExternalDER(der []byte) (tCert, error) { - // DER to x509 - x509Cert, err := primitives.DERToX509Certificate(der) - if err != nil { - client.Errorf("Failed parsing certificate [% x]: [%s].", der, err) - - return nil, err - } - - // Handle Critical Extension TCertEncTCertIndex - tCertIndexCT, err := primitives.GetCriticalExtension(x509Cert, primitives.TCertEncTCertIndex) - if err != nil { - client.Errorf("Failed getting extension TCERT_ENC_TCERTINDEX [% x]: [%s].", der, err) - - return nil, err - } - - // Handle Critical Extension TCertEncEnrollmentID TODO validate encEnrollmentID - _, err = primitives.GetCriticalExtension(x509Cert, primitives.TCertEncEnrollmentID) - if err != nil { - client.Errorf("Failed getting extension TCERT_ENC_ENROLLMENT_ID [%s].", err.Error()) - - return nil, err - } - - // Handle Critical Extension TCertAttributes - // for i := 0; i < len(x509Cert.Extensions) - 2; i++ { - // attributeExtensionIdentifier := append(utils.TCertEncAttributesBase, i + 9) - // _ , err = utils.GetCriticalExtension(x509Cert, attributeExtensionIdentifier) - // if err != nil { - // client.Errorf("Failed getting extension TCERT_ATTRIBUTE_%s [%s].", i, err.Error()) - // - // return nil, err - // } - // } - - // Verify certificate against root - if _, err := primitives.CheckCertAgainRoot(x509Cert, client.tcaCertPool); err != nil { - client.Warningf("Warning verifing certificate [% x]: [%s].", der, err) - - return nil, err - } - - // Try to extract the signing key from the TCert by decrypting the TCertIndex - - // 384-bit ExpansionValue = HMAC(Expansion_Key, TCertIndex) - // Let TCertIndex = Timestamp, RandValue, 1,2,… - // Timestamp assigned, RandValue assigned and counter reinitialized to 1 per batch - // Decrypt ct to TCertIndex (TODO: || EnrollPub_Key || EnrollID ?) - TCertOwnerEncryptKey := primitives.HMACAESTruncated(client.tCertOwnerKDFKey, []byte{1}) - ExpansionKey := primitives.HMAC(client.tCertOwnerKDFKey, []byte{2}) - pt, err := primitives.CBCPKCS7Decrypt(TCertOwnerEncryptKey, tCertIndexCT) - - if err == nil { - // Compute ExpansionValue based on TCertIndex - TCertIndex := pt - // TCertIndex := []byte(strconv.Itoa(i)) - - // TODO: verify that TCertIndex has right format. - - client.Debugf("TCertIndex: [% x].", TCertIndex) - mac := hmac.New(primitives.NewHash, ExpansionKey) - mac.Write(TCertIndex) - ExpansionValue := mac.Sum(nil) - - // Derive tpk and tsk accordingly to ExpansionValue from enrollment pk,sk - // Computable by TCA / Auditor: TCertPub_Key = EnrollPub_Key + ExpansionValue G - // using elliptic curve point addition per NIST FIPS PUB 186-4- specified P-384 - - // Compute temporary secret key - tempSK := &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: client.enrollPrivKey.Curve, - X: new(big.Int), - Y: new(big.Int), - }, - D: new(big.Int), - } - - var k = new(big.Int).SetBytes(ExpansionValue) - var one = new(big.Int).SetInt64(1) - n := new(big.Int).Sub(client.enrollPrivKey.Params().N, one) - k.Mod(k, n) - k.Add(k, one) - - tempSK.D.Add(client.enrollPrivKey.D, k) - tempSK.D.Mod(tempSK.D, client.enrollPrivKey.PublicKey.Params().N) - - // Compute temporary public key - tempX, tempY := client.enrollPrivKey.PublicKey.ScalarBaseMult(k.Bytes()) - tempSK.PublicKey.X, tempSK.PublicKey.Y = - tempSK.PublicKey.Add( - client.enrollPrivKey.PublicKey.X, client.enrollPrivKey.PublicKey.Y, - tempX, tempY, - ) - - // Verify temporary public key is a valid point on the reference curve - isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y) - if !isOn { - client.Warning("Failed temporary public key IsOnCurve check. This is an foreign certificate.") - - return &tCertImpl{client, x509Cert, nil, []byte{}}, nil - } - - // Check that the derived public key is the same as the one in the certificate - certPK := x509Cert.PublicKey.(*ecdsa.PublicKey) - - if certPK.X.Cmp(tempSK.PublicKey.X) != 0 { - client.Warning("Derived public key is different on X. This is an foreign certificate.") - - return &tCertImpl{client, x509Cert, nil, []byte{}}, nil - } - - if certPK.Y.Cmp(tempSK.PublicKey.Y) != 0 { - client.Warning("Derived public key is different on Y. This is an foreign certificate.") - - return &tCertImpl{client, x509Cert, nil, []byte{}}, nil - } - - // Verify the signing capability of tempSK - err = primitives.VerifySignCapability(tempSK, x509Cert.PublicKey) - if err != nil { - client.Warning("Failed verifing signing capability [%s]. This is an foreign certificate.", err.Error()) - - return &tCertImpl{client, x509Cert, nil, []byte{}}, nil - } - - // Marshall certificate and secret key to be stored in the database - if err != nil { - client.Warningf("Failed marshalling private key [%s]. This is an foreign certificate.", err.Error()) - - return &tCertImpl{client, x509Cert, nil, []byte{}}, nil - } - - if err = primitives.CheckCertPKAgainstSK(x509Cert, interface{}(tempSK)); err != nil { - client.Warningf("Failed checking TCA cert PK against private key [%s]. This is an foreign certificate.", err.Error()) - - return &tCertImpl{client, x509Cert, nil, []byte{}}, nil - } - - return &tCertImpl{client, x509Cert, tempSK, []byte{}}, nil - } - client.Warningf("Failed decrypting extension TCERT_ENC_TCERTINDEX [%s]. This is an foreign certificate.", err.Error()) - return &tCertImpl{client, x509Cert, nil, []byte{}}, nil -} - -func (client *clientImpl) getTCertFromDER(certBlk *TCertDBBlock) (certBlock *TCertBlock, err error) { - if client.tCertOwnerKDFKey == nil { - return nil, fmt.Errorf("KDF key not initialized yet") - } - - TCertOwnerEncryptKey := primitives.HMACAESTruncated(client.tCertOwnerKDFKey, []byte{1}) - ExpansionKey := primitives.HMAC(client.tCertOwnerKDFKey, []byte{2}) - - // DER to x509 - x509Cert, err := primitives.DERToX509Certificate(certBlk.tCertDER) - if err != nil { - client.Errorf("Failed parsing certificate [% x]: [%s].", certBlk.tCertDER, err) - - return - } - - // Handle Critical Extenstion TCertEncTCertIndex - tCertIndexCT, err := primitives.GetCriticalExtension(x509Cert, primitives.TCertEncTCertIndex) - if err != nil { - client.Errorf("Failed getting extension TCERT_ENC_TCERTINDEX [%v].", err.Error()) - - return - } - - // Verify certificate against root - if _, err = primitives.CheckCertAgainRoot(x509Cert, client.tcaCertPool); err != nil { - client.Warningf("Warning verifing certificate [%s].", err.Error()) - - return - } - - // Verify public key - - // 384-bit ExpansionValue = HMAC(Expansion_Key, TCertIndex) - // Let TCertIndex = Timestamp, RandValue, 1,2,… - // Timestamp assigned, RandValue assigned and counter reinitialized to 1 per batch - - // Decrypt ct to TCertIndex (TODO: || EnrollPub_Key || EnrollID ?) - pt, err := primitives.CBCPKCS7Decrypt(TCertOwnerEncryptKey, tCertIndexCT) - if err != nil { - client.Errorf("Failed decrypting extension TCERT_ENC_TCERTINDEX [%s].", err.Error()) - - return - } - - // Compute ExpansionValue based on TCertIndex - TCertIndex := pt - // TCertIndex := []byte(strconv.Itoa(i)) - - client.Debugf("TCertIndex: [% x].", TCertIndex) - mac := hmac.New(primitives.NewHash, ExpansionKey) - mac.Write(TCertIndex) - ExpansionValue := mac.Sum(nil) - - // Derive tpk and tsk accordingly to ExpansionValue from enrollment pk,sk - // Computable by TCA / Auditor: TCertPub_Key = EnrollPub_Key + ExpansionValue G - // using elliptic curve point addition per NIST FIPS PUB 186-4- specified P-384 - - // Compute temporary secret key - tempSK := &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: client.enrollPrivKey.Curve, - X: new(big.Int), - Y: new(big.Int), - }, - D: new(big.Int), - } - - var k = new(big.Int).SetBytes(ExpansionValue) - var one = new(big.Int).SetInt64(1) - n := new(big.Int).Sub(client.enrollPrivKey.Params().N, one) - k.Mod(k, n) - k.Add(k, one) - - tempSK.D.Add(client.enrollPrivKey.D, k) - tempSK.D.Mod(tempSK.D, client.enrollPrivKey.PublicKey.Params().N) - - // Compute temporary public key - tempX, tempY := client.enrollPrivKey.PublicKey.ScalarBaseMult(k.Bytes()) - tempSK.PublicKey.X, tempSK.PublicKey.Y = - tempSK.PublicKey.Add( - client.enrollPrivKey.PublicKey.X, client.enrollPrivKey.PublicKey.Y, - tempX, tempY, - ) - - // Verify temporary public key is a valid point on the reference curve - isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y) - if !isOn { - client.Error("Failed temporary public key IsOnCurve check.") - - return nil, fmt.Errorf("Failed temporary public key IsOnCurve check.") - } - - // Check that the derived public key is the same as the one in the certificate - certPK := x509Cert.PublicKey.(*ecdsa.PublicKey) - - if certPK.X.Cmp(tempSK.PublicKey.X) != 0 { - client.Error("Derived public key is different on X") - - return nil, fmt.Errorf("Derived public key is different on X") - } - - if certPK.Y.Cmp(tempSK.PublicKey.Y) != 0 { - client.Error("Derived public key is different on Y") - - return nil, fmt.Errorf("Derived public key is different on Y") - } - - // Verify the signing capability of tempSK - err = primitives.VerifySignCapability(tempSK, x509Cert.PublicKey) - if err != nil { - client.Errorf("Failed verifing signing capability [%s].", err.Error()) - - return - } - - // Marshall certificate and secret key to be stored in the database - if err != nil { - client.Errorf("Failed marshalling private key [%s].", err.Error()) - - return - } - - if err = primitives.CheckCertPKAgainstSK(x509Cert, interface{}(tempSK)); err != nil { - client.Errorf("Failed checking TCA cert PK against private key [%s].", err.Error()) - - return - } - - certBlock = &TCertBlock{&tCertImpl{client, x509Cert, tempSK, certBlk.preK0}, certBlk.attributesHash} - - return -} - -func (client *clientImpl) getTCertsFromTCA(attrhash string, attributes []string, num int) error { - client.Debugf("Get [%d] certificates from the TCA...", num) - - // Contact the TCA - TCertOwnerKDFKey, certDERs, err := client.callTCACreateCertificateSet(num, attributes) - if err != nil { - client.Errorf("Failed contacting TCA [%s].", err.Error()) - - return err - } - - // client.debug("TCertOwnerKDFKey [%s].", utils.EncodeBase64(TCertOwnerKDFKey)) - - // Store TCertOwnerKDFKey and checks that every time it is always the same key - if client.tCertOwnerKDFKey != nil { - // Check that the keys are the same - equal := bytes.Equal(client.tCertOwnerKDFKey, TCertOwnerKDFKey) - if !equal { - return errors.New("Failed reciving kdf key from TCA. The keys are different.") - } - } else { - client.tCertOwnerKDFKey = TCertOwnerKDFKey - - // TODO: handle this situation more carefully - if err := client.storeTCertOwnerKDFKey(); err != nil { - client.Errorf("Failed storing TCertOwnerKDFKey [%s].", err.Error()) - - return err - } - } - - // Validate the Certificates obtained - - TCertOwnerEncryptKey := primitives.HMACAESTruncated(client.tCertOwnerKDFKey, []byte{1}) - ExpansionKey := primitives.HMAC(client.tCertOwnerKDFKey, []byte{2}) - - j := 0 - for i := 0; i < num; i++ { - // DER to x509 - x509Cert, err := primitives.DERToX509Certificate(certDERs[i].Cert) - prek0 := certDERs[i].Prek0 - if err != nil { - client.Errorf("Failed parsing certificate [% x]: [%s].", certDERs[i].Cert, err) - - continue - } - - // Handle Critical Extenstion TCertEncTCertIndex - tCertIndexCT, err := primitives.GetCriticalExtension(x509Cert, primitives.TCertEncTCertIndex) - if err != nil { - client.Errorf("Failed getting extension TCERT_ENC_TCERTINDEX [% x]: [%s].", primitives.TCertEncTCertIndex, err) - - continue - } - - // Verify certificate against root - if _, err := primitives.CheckCertAgainRoot(x509Cert, client.tcaCertPool); err != nil { - client.Warningf("Warning verifing certificate [%s].", err.Error()) - - continue - } - - // Verify public key - - // 384-bit ExpansionValue = HMAC(Expansion_Key, TCertIndex) - // Let TCertIndex = Timestamp, RandValue, 1,2,… - // Timestamp assigned, RandValue assigned and counter reinitialized to 1 per batch - - // Decrypt ct to TCertIndex (TODO: || EnrollPub_Key || EnrollID ?) - pt, err := primitives.CBCPKCS7Decrypt(TCertOwnerEncryptKey, tCertIndexCT) - if err != nil { - client.Errorf("Failed decrypting extension TCERT_ENC_TCERTINDEX [%s].", err.Error()) - - continue - } - - // Compute ExpansionValue based on TCertIndex - TCertIndex := pt - // TCertIndex := []byte(strconv.Itoa(i)) - - client.Debugf("TCertIndex: [% x].", TCertIndex) - mac := hmac.New(primitives.NewHash, ExpansionKey) - mac.Write(TCertIndex) - ExpansionValue := mac.Sum(nil) - - // Derive tpk and tsk accordingly to ExpansionValue from enrollment pk,sk - // Computable by TCA / Auditor: TCertPub_Key = EnrollPub_Key + ExpansionValue G - // using elliptic curve point addition per NIST FIPS PUB 186-4- specified P-384 - - // Compute temporary secret key - tempSK := &ecdsa.PrivateKey{ - PublicKey: ecdsa.PublicKey{ - Curve: client.enrollPrivKey.Curve, - X: new(big.Int), - Y: new(big.Int), - }, - D: new(big.Int), - } - - var k = new(big.Int).SetBytes(ExpansionValue) - var one = new(big.Int).SetInt64(1) - n := new(big.Int).Sub(client.enrollPrivKey.Params().N, one) - k.Mod(k, n) - k.Add(k, one) - - tempSK.D.Add(client.enrollPrivKey.D, k) - tempSK.D.Mod(tempSK.D, client.enrollPrivKey.PublicKey.Params().N) - - // Compute temporary public key - tempX, tempY := client.enrollPrivKey.PublicKey.ScalarBaseMult(k.Bytes()) - tempSK.PublicKey.X, tempSK.PublicKey.Y = - tempSK.PublicKey.Add( - client.enrollPrivKey.PublicKey.X, client.enrollPrivKey.PublicKey.Y, - tempX, tempY, - ) - - // Verify temporary public key is a valid point on the reference curve - isOn := tempSK.Curve.IsOnCurve(tempSK.PublicKey.X, tempSK.PublicKey.Y) - if !isOn { - client.Error("Failed temporary public key IsOnCurve check.") - - continue - } - - // Check that the derived public key is the same as the one in the certificate - certPK := x509Cert.PublicKey.(*ecdsa.PublicKey) - - if certPK.X.Cmp(tempSK.PublicKey.X) != 0 { - client.Error("Derived public key is different on X") - - continue - } - - if certPK.Y.Cmp(tempSK.PublicKey.Y) != 0 { - client.Error("Derived public key is different on Y") - - continue - } - - // Verify the signing capability of tempSK - err = primitives.VerifySignCapability(tempSK, x509Cert.PublicKey) - if err != nil { - client.Errorf("Failed verifing signing capability [%s].", err.Error()) - - continue - } - - // Marshall certificate and secret key to be stored in the database - if err != nil { - client.Errorf("Failed marshalling private key [%s].", err.Error()) - - continue - } - - if err := primitives.CheckCertPKAgainstSK(x509Cert, interface{}(tempSK)); err != nil { - client.Errorf("Failed checking TCA cert PK against private key [%s].", err.Error()) - - continue - } - - client.Debugf("Sub index [%d]", j) - j++ - client.Debugf("Certificate [%d] validated.", i) - - prek0Cp := make([]byte, len(prek0)) - copy(prek0Cp, prek0) - - tcertBlk := new(TCertBlock) - - tcertBlk.tCert = &tCertImpl{client, x509Cert, tempSK, prek0Cp} - tcertBlk.attributesHash = attrhash - - client.tCertPool.AddTCert(tcertBlk) - } - - if j == 0 { - client.Error("No valid TCert was sent") - - return errors.New("No valid TCert was sent.") - } - - return nil -} - -func (client *clientImpl) callTCACreateCertificateSet(num int, attributes []string) ([]byte, []*membersrvc.TCert, error) { - // Get a TCA Client - sock, tcaP, err := client.getTCAClient() - defer sock.Close() - - var attributesList []*membersrvc.TCertAttribute - - for _, k := range attributes { - tcertAttr := new(membersrvc.TCertAttribute) - tcertAttr.AttributeName = k - attributesList = append(attributesList, tcertAttr) - } - - // Execute the protocol - now := time.Now() - timestamp := timestamp.Timestamp{Seconds: int64(now.Second()), Nanos: int32(now.Nanosecond())} - req := &membersrvc.TCertCreateSetReq{ - Ts: ×tamp, - Id: &membersrvc.Identity{Id: client.enrollID}, - Num: uint32(num), - Attributes: attributesList, - Sig: nil, - } - - rawReq, err := proto.Marshal(req) - if err != nil { - client.Errorf("Failed marshaling request [%s].", err.Error()) - return nil, nil, err - } - - // 2. Sign rawReq - r, s, err := client.ecdsaSignWithEnrollmentKey(rawReq) - if err != nil { - client.Errorf("Failed creating signature for [% x]: [%s].", rawReq, err.Error()) - return nil, nil, err - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - // 3. Append the signature - req.Sig = &membersrvc.Signature{Type: membersrvc.CryptoType_ECDSA, R: R, S: S} - - // 4. Send request - certSet, err := tcaP.CreateCertificateSet(context.Background(), req) - if err != nil { - client.Errorf("Failed requesting tca create certificate set [%s].", err.Error()) - - return nil, nil, err - } - - return certSet.Certs.Key, certSet.Certs.Certs, nil -} diff --git a/core/crypto/client_tcert.go b/core/crypto/client_tcert.go deleted file mode 100644 index 1c99e63cef7..00000000000 --- a/core/crypto/client_tcert.go +++ /dev/null @@ -1,88 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/x509" - - "github.com/hyperledger/fabric/core/crypto/attributes" - "github.com/hyperledger/fabric/core/crypto/utils" -) - -type tCert interface { - //GetCertificate returns the x509 certificate of the TCert. - GetCertificate() *x509.Certificate - - //GetPreK0 returns the PreK0 of the TCert. This key is used to derivate attributes keys. - GetPreK0() []byte - - //Sign signs a msg with the TCert secret key an returns the signature. - Sign(msg []byte) ([]byte, error) - - //Verify verifies signature and message using the TCert public key. - Verify(signature, msg []byte) error - - //GetKForAttribute derives the key for a specific attribute name. - GetKForAttribute(attributeName string) ([]byte, error) -} - -type tCertImpl struct { - client *clientImpl - cert *x509.Certificate - sk interface{} - preK0 []byte -} - -//GetCertificate returns the x509 certificate of the TCert. -func (tCert *tCertImpl) GetCertificate() *x509.Certificate { - return tCert.cert -} - -//GetPreK0 returns the PreK0 of the TCert. This key is used to derivate attributes keys. -func (tCert *tCertImpl) GetPreK0() []byte { - return tCert.preK0 -} - -//Sign signs a msg with the TCert secret key an returns the signature. -func (tCert *tCertImpl) Sign(msg []byte) ([]byte, error) { - if tCert.sk == nil { - return nil, utils.ErrNilArgument - } - - return tCert.client.sign(tCert.sk, msg) -} - -//Verify verifies signature and message using the TCert public key. -func (tCert *tCertImpl) Verify(signature, msg []byte) (err error) { - ok, err := tCert.client.verify(tCert.cert.PublicKey, msg, signature) - if err != nil { - return - } - if !ok { - return utils.ErrInvalidSignature - } - return -} - -//GetKForAttribute derives the key for a specific attribute name. -func (tCert *tCertImpl) GetKForAttribute(attributeName string) ([]byte, error) { - if tCert.preK0 == nil { - return nil, utils.ErrNilArgument - } - - return attributes.GetKForAttribute(attributeName, tCert.preK0, tCert.GetCertificate()) -} diff --git a/core/crypto/client_tcert_handler.go b/core/crypto/client_tcert_handler.go deleted file mode 100644 index ca8b0b388df..00000000000 --- a/core/crypto/client_tcert_handler.go +++ /dev/null @@ -1,111 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -type tCertHandlerImpl struct { - client *clientImpl - - tCert tCert -} - -type tCertTransactionHandlerImpl struct { - tCertHandler *tCertHandlerImpl - - nonce []byte - binding []byte -} - -func (handler *tCertHandlerImpl) init(client *clientImpl, tCert tCert) error { - handler.client = client - handler.tCert = tCert - - return nil -} - -// GetCertificate returns the TCert DER -func (handler *tCertHandlerImpl) GetCertificate() []byte { - return utils.Clone(handler.tCert.GetCertificate().Raw) -} - -// Sign signs msg using the signing key corresponding to this TCert -func (handler *tCertHandlerImpl) Sign(msg []byte) ([]byte, error) { - return handler.tCert.Sign(msg) -} - -// Verify verifies msg using the verifying key corresponding to this TCert -func (handler *tCertHandlerImpl) Verify(signature []byte, msg []byte) error { - return handler.tCert.Verify(signature, msg) -} - -// GetTransactionHandler returns the transaction handler relative to this certificate -func (handler *tCertHandlerImpl) GetTransactionHandler() (TransactionHandler, error) { - txHandler := &tCertTransactionHandlerImpl{} - err := txHandler.init(handler) - if err != nil { - handler.client.Errorf("Failed initiliazing transaction handler [%s]", err) - - return nil, err - } - - return txHandler, nil -} - -func (handler *tCertTransactionHandlerImpl) init(tCertHandler *tCertHandlerImpl) error { - nonce, err := tCertHandler.client.createTransactionNonce() - if err != nil { - tCertHandler.client.Errorf("Failed initiliazing transaction handler [%s]", err) - - return err - } - - handler.tCertHandler = tCertHandler - handler.nonce = nonce - handler.binding = primitives.Hash(append(handler.tCertHandler.tCert.GetCertificate().Raw, nonce...)) - - return nil -} - -// GetCertificateHandler returns the certificate handler relative to the certificate mapped to this transaction -func (handler *tCertTransactionHandlerImpl) GetCertificateHandler() (CertificateHandler, error) { - return handler.tCertHandler, nil -} - -// GetBinding returns an Binding to the underlying transaction layer -func (handler *tCertTransactionHandlerImpl) GetBinding() ([]byte, error) { - return utils.Clone(handler.binding), nil -} - -// NewChaincodeDeployTransaction is used to deploy chaincode. -func (handler *tCertTransactionHandlerImpl) NewChaincodeDeployTransaction(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string, attributeNames ...string) (*obc.Transaction, error) { - return handler.tCertHandler.client.newChaincodeDeployUsingTCert(chaincodeDeploymentSpec, uuid, attributeNames, handler.tCertHandler.tCert, handler.nonce) -} - -// NewChaincodeExecute is used to execute chaincode's functions. -func (handler *tCertTransactionHandlerImpl) NewChaincodeExecute(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, attributeNames ...string) (*obc.Transaction, error) { - return handler.tCertHandler.client.newChaincodeExecuteUsingTCert(chaincodeInvocation, uuid, attributeNames, handler.tCertHandler.tCert, handler.nonce) -} - -// NewChaincodeQuery is used to query chaincode's functions. -func (handler *tCertTransactionHandlerImpl) NewChaincodeQuery(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, attributeNames ...string) (*obc.Transaction, error) { - return handler.tCertHandler.client.newChaincodeQueryUsingTCert(chaincodeInvocation, uuid, attributeNames, handler.tCertHandler.tCert, handler.nonce) -} diff --git a/core/crypto/client_tcert_pool.go b/core/crypto/client_tcert_pool.go deleted file mode 100644 index 775341b6b3c..00000000000 --- a/core/crypto/client_tcert_pool.go +++ /dev/null @@ -1,29 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -type tCertPool interface { - init(client *clientImpl) error - - Start() error - - Stop() error - - GetNextTCerts(nCerts int, attributes ...string) ([]*TCertBlock, error) - - AddTCert(tCertBlock *TCertBlock) (err error) -} diff --git a/core/crypto/client_tcert_pool_mt.go b/core/crypto/client_tcert_pool_mt.go deleted file mode 100644 index 6e60b62d49d..00000000000 --- a/core/crypto/client_tcert_pool_mt.go +++ /dev/null @@ -1,366 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "errors" - "runtime" - "strings" - "sync" - "time" -) - -type tCertPoolEntry struct { - attributes []string - tCertChannel chan *TCertBlock - tCertChannelFeedback chan struct{} - done chan struct{} - client *clientImpl -} - -const maxFillerThreads = 5 - -//NewTCertPoolEntry creates a new tcert pool entry -func newTCertPoolEntry(client *clientImpl, attributes []string) *tCertPoolEntry { - var tCertChannel chan *TCertBlock - var tCertChannelFeedback chan struct{} - - if client.conf.IsMultiChannelEnabled() { - tCertChannel = make(chan *TCertBlock, client.conf.getTCertBatchSize()*maxFillerThreads) - tCertChannelFeedback = make(chan struct{}, maxFillerThreads) - } else { - tCertChannel = make(chan *TCertBlock, client.conf.getTCertBatchSize()*2) - tCertChannelFeedback = make(chan struct{}, client.conf.getTCertBatchSize()*2) - } - done := make(chan struct{}, 1) - return &tCertPoolEntry{attributes, tCertChannel, tCertChannelFeedback, done, client} -} - -//Start starts the pool entry filler loop. -func (tCertPoolEntry *tCertPoolEntry) Start() (err error) { - // Start the filler - go tCertPoolEntry.filler() - return -} - -//Stop stops the pool entry filler loop. -func (tCertPoolEntry *tCertPoolEntry) Stop() (err error) { - // Stop the filler - tCertPoolEntry.done <- struct{}{} - - // Store unused TCert - tCertPoolEntry.client.Debug("Store unused TCerts...") - - tCerts := make([]*TCertBlock, 0) - for { - if len(tCertPoolEntry.tCertChannel) > 0 { - tCerts = append(tCerts, <-tCertPoolEntry.tCertChannel) - } else { - break - } - } - - tCertPoolEntry.client.Debugf("Found %d unused TCerts...", len(tCerts)) - - tCertPoolEntry.client.ks.storeUnusedTCerts(tCerts) - - tCertPoolEntry.client.Debug("Store unused TCerts...done!") - - return -} - -//AddTCert add a tcert to the poolEntry. -func (tCertPoolEntry *tCertPoolEntry) AddTCert(tCertBlock *TCertBlock) (err error) { - tCertPoolEntry.tCertChannel <- tCertBlock - return -} - -//GetNextTCert gets the next tcert of the pool. -func (tCertPoolEntry *tCertPoolEntry) GetNextTCert(attributes ...string) (tCertBlock *TCertBlock, err error) { - for i := 0; i < 3; i++ { - tCertPoolEntry.client.Debugf("Getting next TCert... %d out of 3", i) - select { - case tCertBlock = <-tCertPoolEntry.tCertChannel: - break - case <-time.After(30 * time.Second): - tCertPoolEntry.client.Error("Failed getting a new TCert. Buffer is empty!") - } - if tCertBlock != nil { - if !tCertPoolEntry.client.conf.IsMultiChannelEnabled() { - // Send feedback to the filler - tCertPoolEntry.client.Debug("Send feedback") - tCertPoolEntry.tCertChannelFeedback <- struct{}{} - } - break - } - } - - if tCertBlock == nil { - // TODO: change error here - return nil, errors.New("Failed getting a new TCert. Buffer is empty!") - } - - tCertPoolEntry.client.Debugf("Cert [% x].", tCertBlock.tCert.GetCertificate().Raw) - - // Store the TCert permanently - tCertPoolEntry.client.ks.storeUsedTCert(tCertBlock) - - tCertPoolEntry.client.Debug("Getting next TCert...done!") - - return -} - -func (tCertPoolEntry *tCertPoolEntry) filler() { - // Load unused TCerts - stop := false - full := false - tCertPoolEntry.client.Debug("Filler()") - - attributeHash := calculateAttributesHash(tCertPoolEntry.attributes) - for { - // Check if Stop was called - select { - case <-tCertPoolEntry.done: - tCertPoolEntry.client.Debug("Force stop!") - stop = true - default: - } - if stop { - break - } - - tCertDBBlocks, err := tCertPoolEntry.client.ks.loadUnusedTCerts() - - if err != nil { - tCertPoolEntry.client.Errorf("Failed loading TCert: [%s]", err) - break - } - if tCertDBBlocks == nil { - tCertPoolEntry.client.Debug("No more TCerts in cache!") - break - } - - var tCert *TCertBlock - for _, tCertDBBlock := range tCertDBBlocks { - if strings.Compare(attributeHash, tCertDBBlock.attributesHash) == 0 { - tCertBlock, err := tCertPoolEntry.client.getTCertFromDER(tCertDBBlock) - if err != nil { - tCertPoolEntry.client.Errorf("Failed paring TCert [% x]: [%s]", tCertDBBlock.tCertDER, err) - continue - } - tCert = tCertBlock - } - } - - if tCert != nil { - // Try to send the tCert to the channel if not full - select { - case tCertPoolEntry.tCertChannel <- tCert: - tCertPoolEntry.client.Debug("TCert send to the channel!") - default: - tCertPoolEntry.client.Debug("Channell Full!") - full = true - } - if full { - break - } - } else { - tCertPoolEntry.client.Debug("No more TCerts in cache!") - break - } - } - - tCertPoolEntry.client.Debug("Load unused TCerts...done!") - - if !stop { - fillerThreads := 0 - var ticker *time.Ticker - if tCertPoolEntry.client.conf.IsMultiChannelEnabled() { - ticker = time.NewTicker(200 * time.Millisecond) - } else { - ticker = time.NewTicker(1 * time.Second) - } - for { - select { - case <-tCertPoolEntry.done: - stop = true - tCertPoolEntry.client.Debug("Done signal.") - case <-tCertPoolEntry.tCertChannelFeedback: - if tCertPoolEntry.client.conf.IsMultiChannelEnabled() { - fillerThreads-- - } else { - tCertPoolEntry.client.Debug("Feedback received. Time to check for tcerts") - } - case <-ticker.C: - tCertPoolEntry.client.Debug("Time elapsed. Time to check for tcerts") - } - - if stop { - tCertPoolEntry.client.Debug("Quitting filler...") - break - } - - if tCertPoolEntry.client.conf.IsMultiChannelEnabled() { - - for len(tCertPoolEntry.tCertChannel) <= tCertPoolEntry.client.conf.getTCertBatchSize()*(maxFillerThreads-fillerThreads-1) { - tCertPoolEntry.client.Debugf("Refill TCert Pool. Current size [%d].", len(tCertPoolEntry.tCertChannel)) - numTCerts := tCertPoolEntry.client.conf.getTCertBatchSize() - - tCertPoolEntry.client.Infof("Refilling [%d] TCerts.", numTCerts) - fillerThreads++ - - go func() { - err := tCertPoolEntry.client.getTCertsFromTCA(calculateAttributesHash(tCertPoolEntry.attributes), tCertPoolEntry.attributes, numTCerts) - if err != nil { - tCertPoolEntry.client.Errorf("Failed getting TCerts from the TCA: [%s]", err) - } - tCertPoolEntry.tCertChannelFeedback <- struct{}{} - }() - } - } else { - if len(tCertPoolEntry.tCertChannel) < tCertPoolEntry.client.conf.getTCertBatchSize() { - tCertPoolEntry.client.Debugf("Refill TCert Pool. Current size [%d].", len(tCertPoolEntry.tCertChannel)) - var numTCerts = cap(tCertPoolEntry.tCertChannel) - len(tCertPoolEntry.tCertChannel) - if len(tCertPoolEntry.tCertChannel) == 0 { - numTCerts = cap(tCertPoolEntry.tCertChannel) / 10 - if numTCerts < 1 { - numTCerts = 1 - } - } - tCertPoolEntry.client.Infof("Refilling [%d] TCerts.", numTCerts) - - err := tCertPoolEntry.client.getTCertsFromTCA(calculateAttributesHash(tCertPoolEntry.attributes), tCertPoolEntry.attributes, numTCerts) - if err != nil { - tCertPoolEntry.client.Errorf("Failed getting TCerts from the TCA: [%s]", err) - } - } - } - } - } - - tCertPoolEntry.client.Debug("TCert filler stopped.") -} - -// The Multi-threaded tCertPool is currently not used. -// It plays only a role in testing. -type tCertPoolMultithreadingImpl struct { - client *clientImpl - poolEntries map[string]*tCertPoolEntry - entriesMutex *sync.Mutex -} - -//Start starts the pool processing. -func (tCertPool *tCertPoolMultithreadingImpl) Start() (err error) { - // Start the filler, initializes a poolEntry without attributes. - var attributes []string - _, err = tCertPool.getOrCreatePoolEntry(attributes) - return -} - -func (tCertPool *tCertPoolMultithreadingImpl) lockEntries() { - tCertPool.entriesMutex.Lock() -} - -func (tCertPool *tCertPoolMultithreadingImpl) releaseEntries() { - tCertPool.entriesMutex.Unlock() - runtime.Gosched() -} - -//Stop stops the pool. -func (tCertPool *tCertPoolMultithreadingImpl) Stop() (err error) { - // Stop the filler - tCertPool.lockEntries() - defer tCertPool.releaseEntries() - for _, entry := range tCertPool.poolEntries { - err := entry.Stop() - if err != nil { - return err - } - } - return -} - -//Returns a tCertPoolEntry for the attributes "attributes", if the tCertPoolEntry doesn't exists a new tCertPoolEntry will be create for that attributes. -func (tCertPool *tCertPoolMultithreadingImpl) getPoolEntryFromHash(attributeHash string) *tCertPoolEntry { - tCertPool.lockEntries() - defer tCertPool.releaseEntries() - poolEntry := tCertPool.poolEntries[attributeHash] - return poolEntry - -} - -//Returns a tCertPoolEntry for the attributes "attributes", if the tCertPoolEntry doesn't exists a new tCertPoolEntry will be create for that attributes. -func (tCertPool *tCertPoolMultithreadingImpl) getOrCreatePoolEntry(attributes []string) (*tCertPoolEntry, error) { - tCertPool.client.Debug("Getting pool entry %v \n", attributes) - attributeHash := calculateAttributesHash(attributes) - tCertPool.lockEntries() - defer tCertPool.releaseEntries() - poolEntry := tCertPool.poolEntries[attributeHash] - if poolEntry == nil { - tCertPool.client.Debugf("New pool entry %v \n", attributes) - - poolEntry = newTCertPoolEntry(tCertPool.client, attributes) - tCertPool.poolEntries[attributeHash] = poolEntry - if err := poolEntry.Start(); err != nil { - return nil, err - } - tCertPool.client.Debugf("Pool entry started %v \n", attributes) - - } - return poolEntry, nil -} - -//GetNextTCert returns a TCert from the pool valid to the passed attributes. If no TCert is available TCA is invoked to generate it. -func (tCertPool *tCertPoolMultithreadingImpl) GetNextTCerts(nCerts int, attributes ...string) ([]*TCertBlock, error) { - blocks := make([]*TCertBlock, nCerts) - for i := 0; i < nCerts; i++ { - block, err := tCertPool.getNextTCert(attributes...) - if err != nil { - return nil, err - } - blocks[i] = block - } - return blocks, nil -} - -func (tCertPool *tCertPoolMultithreadingImpl) getNextTCert(attributes ...string) (tCertBlock *TCertBlock, err error) { - poolEntry, err := tCertPool.getOrCreatePoolEntry(attributes) - if err != nil { - return nil, err - } - tCertPool.client.Debugf("Requesting tcert to the pool entry. %v", calculateAttributesHash(attributes)) - return poolEntry.GetNextTCert(attributes...) -} - -//AddTCert adds a TCert into the pool is invoked by the client after TCA is called. -func (tCertPool *tCertPoolMultithreadingImpl) AddTCert(tCertBlock *TCertBlock) (err error) { - poolEntry := tCertPool.getPoolEntryFromHash(tCertBlock.attributesHash) - if poolEntry == nil { - return errors.New("No pool entry found for that attributes.") - } - tCertPool.client.Debugf("Adding %v \n.", tCertBlock.attributesHash) - poolEntry.AddTCert(tCertBlock) - - return -} - -func (tCertPool *tCertPoolMultithreadingImpl) init(client *clientImpl) (err error) { - tCertPool.client = client - tCertPool.poolEntries = make(map[string]*tCertPoolEntry) - tCertPool.entriesMutex = &sync.Mutex{} - return -} diff --git a/core/crypto/client_tcert_pool_st.go b/core/crypto/client_tcert_pool_st.go deleted file mode 100644 index 3edd59dd69f..00000000000 --- a/core/crypto/client_tcert_pool_st.go +++ /dev/null @@ -1,192 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "encoding/hex" - "fmt" - "sort" - "sync" - - "github.com/hyperledger/fabric/core/crypto/primitives" -) - -//TCertBlock is an object that include the generated TCert and the attributes used to generate it. -type TCertBlock struct { - tCert tCert - attributesHash string -} - -//TCertDBBlock is an object used to store the TCert in the database. A raw field is used to represent the TCert and the preK0, a string field is use to the attributesHash. -type TCertDBBlock struct { - tCertDER []byte - attributesHash string - preK0 []byte -} - -type tCertPoolSingleThreadImpl struct { - client *clientImpl - - empty bool - - length map[string]int - - tCerts map[string][]*TCertBlock - - m sync.Mutex -} - -//Start starts the pool processing. -func (tCertPool *tCertPoolSingleThreadImpl) Start() (err error) { - tCertPool.m.Lock() - defer tCertPool.m.Unlock() - - tCertPool.client.Debug("Starting TCert Pool...") - - // Load unused TCerts if any - tCertDBBlocks, err := tCertPool.client.ks.loadUnusedTCerts() - if err != nil { - tCertPool.client.Errorf("Failed loading TCerts from cache: [%s]", err) - - return - } - - if len(tCertDBBlocks) > 0 { - - tCertPool.client.Debug("TCerts in cache found! Loading them...") - - for _, tCertDBBlock := range tCertDBBlocks { - tCertBlock, err := tCertPool.client.getTCertFromDER(tCertDBBlock) - if err != nil { - tCertPool.client.Errorf("Failed paring TCert [% x]: [%s]", tCertDBBlock.tCertDER, err) - - continue - } - tCertPool.AddTCert(tCertBlock) - } - } //END-IF - - return -} - -//Stop stops the pool. -func (tCertPool *tCertPoolSingleThreadImpl) Stop() (err error) { - tCertPool.m.Lock() - defer tCertPool.m.Unlock() - for k := range tCertPool.tCerts { - certList := tCertPool.tCerts[k] - certListLen := tCertPool.length[k] - tCertPool.client.ks.storeUnusedTCerts(certList[:certListLen]) - } - - tCertPool.client.Debug("Store unused TCerts...done!") - - return -} - -//calculateAttributesHash generates a unique hash using the passed attributes. -func calculateAttributesHash(attributes []string) (attrHash string) { - - keys := make([]string, len(attributes)) - - for _, k := range attributes { - keys = append(keys, k) - } - - sort.Strings(keys) - - values := make([]byte, len(keys)) - - for _, k := range keys { - vb := []byte(k) - for _, bval := range vb { - values = append(values, bval) - } - } - attributesHash := primitives.Hash(values) - return hex.EncodeToString(attributesHash) - -} - -//GetNextTCert returns a TCert from the pool valid to the passed attributes. If no TCert is available TCA is invoked to generate it. -func (tCertPool *tCertPoolSingleThreadImpl) GetNextTCerts(nCerts int, attributes ...string) ([]*TCertBlock, error) { - blocks := make([]*TCertBlock, nCerts) - for i := 0; i < nCerts; i++ { - block, err := tCertPool.getNextTCert(attributes...) - if err != nil { - return nil, err - } - blocks[i] = block - } - return blocks, nil -} - -func (tCertPool *tCertPoolSingleThreadImpl) getNextTCert(attributes ...string) (tCert *TCertBlock, err error) { - - tCertPool.m.Lock() - defer tCertPool.m.Unlock() - - attributesHash := calculateAttributesHash(attributes) - - poolLen := tCertPool.length[attributesHash] - - if poolLen <= 0 { - // Reload - if err := tCertPool.client.getTCertsFromTCA(attributesHash, attributes, tCertPool.client.conf.getTCertBatchSize()); err != nil { - return nil, fmt.Errorf("Failed loading TCerts from TCA") - } - } - - tCert = tCertPool.tCerts[attributesHash][tCertPool.length[attributesHash]-1] - - tCertPool.length[attributesHash] = tCertPool.length[attributesHash] - 1 - - return tCert, nil -} - -//AddTCert adds a TCert into the pool is invoked by the client after TCA is called. -func (tCertPool *tCertPoolSingleThreadImpl) AddTCert(tCertBlock *TCertBlock) (err error) { - - tCertPool.client.Debugf("Adding new Cert [% x].", tCertBlock.tCert.GetCertificate().Raw) - - if tCertPool.length[tCertBlock.attributesHash] <= 0 { - tCertPool.length[tCertBlock.attributesHash] = 0 - } - - tCertPool.length[tCertBlock.attributesHash] = tCertPool.length[tCertBlock.attributesHash] + 1 - - if tCertPool.tCerts[tCertBlock.attributesHash] == nil { - - tCertPool.tCerts[tCertBlock.attributesHash] = make([]*TCertBlock, tCertPool.client.conf.getTCertBatchSize()) - - } - - tCertPool.tCerts[tCertBlock.attributesHash][tCertPool.length[tCertBlock.attributesHash]-1] = tCertBlock - - return nil -} - -func (tCertPool *tCertPoolSingleThreadImpl) init(client *clientImpl) (err error) { - tCertPool.client = client - tCertPool.client.Debug("Init TCert Pool...") - - tCertPool.tCerts = make(map[string][]*TCertBlock) - - tCertPool.length = make(map[string]int) - - return -} diff --git a/core/crypto/client_tx.go b/core/crypto/client_tx.go deleted file mode 100644 index 4c7254fdb89..00000000000 --- a/core/crypto/client_tx.go +++ /dev/null @@ -1,472 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "fmt" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -func (client *clientImpl) createTransactionNonce() ([]byte, error) { - nonce, err := primitives.GetRandomNonce() - if err != nil { - client.Errorf("Failed creating nonce [%s].", err.Error()) - return nil, err - } - - return nonce, err -} - -func (client *clientImpl) createDeployTx(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string, nonce []byte, tCert tCert, attrs ...string) (*obc.Transaction, error) { - // Create a new transaction - tx, err := obc.NewChaincodeDeployTransaction(chaincodeDeploymentSpec, uuid) - if err != nil { - client.Errorf("Failed creating new transaction [%s].", err.Error()) - return nil, err - } - - // Copy metadata from ChaincodeSpec - tx.Metadata, err = getMetadata(chaincodeDeploymentSpec.GetChaincodeSpec(), tCert, attrs...) - if err != nil { - client.Errorf("Failed creating new transaction [%s].", err.Error()) - return nil, err - } - - if nonce == nil { - tx.Nonce, err = primitives.GetRandomNonce() - if err != nil { - client.Errorf("Failed creating nonce [%s].", err.Error()) - return nil, err - } - } else { - // TODO: check that it is a well formed nonce - tx.Nonce = nonce - } - - // Handle confidentiality - if chaincodeDeploymentSpec.ChaincodeSpec.ConfidentialityLevel == obc.ConfidentialityLevel_CONFIDENTIAL { - // 1. set confidentiality level and nonce - tx.ConfidentialityLevel = obc.ConfidentialityLevel_CONFIDENTIAL - - // 2. set confidentiality protocol version - tx.ConfidentialityProtocolVersion = client.conf.GetConfidentialityProtocolVersion() - - // 3. encrypt tx - err = client.encryptTx(tx) - if err != nil { - client.Errorf("Failed encrypting payload [%s].", err.Error()) - return nil, err - - } - } - - return tx, nil -} - -func getMetadata(chaincodeSpec *obc.ChaincodeSpec, tCert tCert, attrs ...string) ([]byte, error) { - //TODO this code is being commented due temporarily is not enabled attributes encryption. - /* - isAttributesEnabled := viper.GetBool("security.attributes.enabled") - if !isAttributesEnabled { - return chaincodeSpec.Metadata, nil - } - - if tCert == nil { - return nil, errors.New("Invalid TCert.") - } - - return attributes.CreateAttributesMetadata(tCert.GetCertificate().Raw, chaincodeSpec.Metadata, tCert.GetPreK0(), attrs) - */ - return chaincodeSpec.Metadata, nil -} - -func (client *clientImpl) createExecuteTx(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, nonce []byte, tCert tCert, attrs ...string) (*obc.Transaction, error) { - /// Create a new transaction - tx, err := obc.NewChaincodeExecute(chaincodeInvocation, uuid, obc.Transaction_CHAINCODE_INVOKE) - if err != nil { - client.Errorf("Failed creating new transaction [%s].", err.Error()) - return nil, err - } - - // Copy metadata from ChaincodeSpec - tx.Metadata, err = getMetadata(chaincodeInvocation.GetChaincodeSpec(), tCert, attrs...) - if err != nil { - client.Errorf("Failed creating new transaction [%s].", err.Error()) - return nil, err - } - if nonce == nil { - tx.Nonce, err = primitives.GetRandomNonce() - if err != nil { - client.Errorf("Failed creating nonce [%s].", err.Error()) - return nil, err - } - } else { - // TODO: check that it is a well formed nonce - tx.Nonce = nonce - } - - // Handle confidentiality - if chaincodeInvocation.ChaincodeSpec.ConfidentialityLevel == obc.ConfidentialityLevel_CONFIDENTIAL { - // 1. set confidentiality level and nonce - tx.ConfidentialityLevel = obc.ConfidentialityLevel_CONFIDENTIAL - - // 2. set confidentiality protocol version - tx.ConfidentialityProtocolVersion = client.conf.GetConfidentialityProtocolVersion() - - // 3. encrypt tx - err = client.encryptTx(tx) - if err != nil { - client.Errorf("Failed encrypting payload [%s].", err.Error()) - return nil, err - - } - } - - return tx, nil -} - -func (client *clientImpl) createQueryTx(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, nonce []byte, tCert tCert, attrs ...string) (*obc.Transaction, error) { - // Create a new transaction - tx, err := obc.NewChaincodeExecute(chaincodeInvocation, uuid, obc.Transaction_CHAINCODE_QUERY) - if err != nil { - client.Errorf("Failed creating new transaction [%s].", err.Error()) - return nil, err - } - - // Copy metadata from ChaincodeSpec - tx.Metadata, err = getMetadata(chaincodeInvocation.GetChaincodeSpec(), tCert, attrs...) - if err != nil { - client.Errorf("Failed creating new transaction [%s].", err.Error()) - return nil, err - } - if nonce == nil { - tx.Nonce, err = primitives.GetRandomNonce() - if err != nil { - client.Errorf("Failed creating nonce [%s].", err.Error()) - return nil, err - } - } else { - // TODO: check that it is a well formed nonce - tx.Nonce = nonce - } - - // Handle confidentiality - if chaincodeInvocation.ChaincodeSpec.ConfidentialityLevel == obc.ConfidentialityLevel_CONFIDENTIAL { - // 1. set confidentiality level and nonce - tx.ConfidentialityLevel = obc.ConfidentialityLevel_CONFIDENTIAL - - // 2. set confidentiality protocol version - tx.ConfidentialityProtocolVersion = client.conf.GetConfidentialityProtocolVersion() - - // 3. encrypt tx - err = client.encryptTx(tx) - if err != nil { - client.Errorf("Failed encrypting payload [%s].", err.Error()) - return nil, err - - } - } - - return tx, nil -} - -func (client *clientImpl) newChaincodeDeployUsingTCert(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string, attributeNames []string, tCert tCert, nonce []byte) (*obc.Transaction, error) { - // Create a new transaction - tx, err := client.createDeployTx(chaincodeDeploymentSpec, uuid, nonce, tCert, attributeNames...) - if err != nil { - client.Errorf("Failed creating new deploy transaction [%s].", err.Error()) - return nil, err - } - - // Sign the transaction - - // Append the certificate to the transaction - client.Debugf("Appending certificate [% x].", tCert.GetCertificate().Raw) - tx.Cert = tCert.GetCertificate().Raw - - // Sign the transaction and append the signature - // 1. Marshall tx to bytes - rawTx, err := proto.Marshal(tx) - if err != nil { - client.Errorf("Failed marshaling tx [%s].", err.Error()) - return nil, err - } - - // 2. Sign rawTx and check signature - rawSignature, err := tCert.Sign(rawTx) - if err != nil { - client.Errorf("Failed creating signature [% x]: [%s].", rawTx, err.Error()) - return nil, err - } - - // 3. Append the signature - tx.Signature = rawSignature - - client.Debugf("Appending signature: [% x]", rawSignature) - - return tx, nil -} - -func (client *clientImpl) newChaincodeExecuteUsingTCert(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, attributeKeys []string, tCert tCert, nonce []byte) (*obc.Transaction, error) { - /// Create a new transaction - tx, err := client.createExecuteTx(chaincodeInvocation, uuid, nonce, tCert, attributeKeys...) - if err != nil { - client.Errorf("Failed creating new execute transaction [%s].", err.Error()) - return nil, err - } - - // Sign the transaction - - // Append the certificate to the transaction - client.Debugf("Appending certificate [% x].", tCert.GetCertificate().Raw) - tx.Cert = tCert.GetCertificate().Raw - - // Sign the transaction and append the signature - // 1. Marshall tx to bytes - rawTx, err := proto.Marshal(tx) - if err != nil { - client.Errorf("Failed marshaling tx [%s].", err.Error()) - return nil, err - } - - // 2. Sign rawTx and check signature - rawSignature, err := tCert.Sign(rawTx) - if err != nil { - client.Errorf("Failed creating signature [% x]: [%s].", rawSignature, err.Error()) - return nil, err - } - - // 3. Append the signature - tx.Signature = rawSignature - - client.Debugf("Appending signature [% x].", rawSignature) - - return tx, nil -} - -func (client *clientImpl) newChaincodeQueryUsingTCert(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, attributeNames []string, tCert tCert, nonce []byte) (*obc.Transaction, error) { - // Create a new transaction - tx, err := client.createQueryTx(chaincodeInvocation, uuid, nonce, tCert, attributeNames...) - if err != nil { - client.Errorf("Failed creating new query transaction [%s].", err.Error()) - return nil, err - } - - // Sign the transaction - - // Append the certificate to the transaction - client.Debugf("Appending certificate [% x].", tCert.GetCertificate().Raw) - tx.Cert = tCert.GetCertificate().Raw - - // Sign the transaction and append the signature - // 1. Marshall tx to bytes - rawTx, err := proto.Marshal(tx) - if err != nil { - client.Errorf("Failed marshaling tx [%s].", err.Error()) - return nil, err - } - - // 2. Sign rawTx and check signature - rawSignature, err := tCert.Sign(rawTx) - if err != nil { - client.Errorf("Failed creating signature [% x]: [%s].", rawSignature, err.Error()) - return nil, err - } - - // 3. Append the signature - tx.Signature = rawSignature - - client.Debugf("Appending signature [% x].", rawSignature) - - return tx, nil -} - -func (client *clientImpl) newChaincodeDeployUsingECert(chaincodeDeploymentSpec *obc.ChaincodeDeploymentSpec, uuid string, nonce []byte) (*obc.Transaction, error) { - // Create a new transaction - tx, err := client.createDeployTx(chaincodeDeploymentSpec, uuid, nonce, nil) - if err != nil { - client.Errorf("Failed creating new deploy transaction [%s].", err.Error()) - return nil, err - } - - // Sign the transaction - - // Append the certificate to the transaction - client.Debugf("Appending certificate [% x].", client.enrollCert.Raw) - tx.Cert = client.enrollCert.Raw - - // Sign the transaction and append the signature - // 1. Marshall tx to bytes - rawTx, err := proto.Marshal(tx) - if err != nil { - client.Errorf("Failed marshaling tx [%s].", err.Error()) - return nil, err - } - - // 2. Sign rawTx and check signature - rawSignature, err := client.signWithEnrollmentKey(rawTx) - if err != nil { - client.Errorf("Failed creating signature [% x]: [%s].", rawTx, err.Error()) - return nil, err - } - - // 3. Append the signature - tx.Signature = rawSignature - - client.Debugf("Appending signature: [% x]", rawSignature) - - return tx, nil -} - -func (client *clientImpl) newChaincodeExecuteUsingECert(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, nonce []byte) (*obc.Transaction, error) { - /// Create a new transaction - tx, err := client.createExecuteTx(chaincodeInvocation, uuid, nonce, nil) - if err != nil { - client.Errorf("Failed creating new execute transaction [%s].", err.Error()) - return nil, err - } - - // Sign the transaction - - // Append the certificate to the transaction - client.Debugf("Appending certificate [% x].", client.enrollCert.Raw) - tx.Cert = client.enrollCert.Raw - - // Sign the transaction and append the signature - // 1. Marshall tx to bytes - rawTx, err := proto.Marshal(tx) - if err != nil { - client.Errorf("Failed marshaling tx [%s].", err.Error()) - return nil, err - } - - // 2. Sign rawTx and check signature - rawSignature, err := client.signWithEnrollmentKey(rawTx) - if err != nil { - client.Errorf("Failed creating signature [% x]: [%s].", rawTx, err.Error()) - return nil, err - } - - // 3. Append the signature - tx.Signature = rawSignature - - client.Debugf("Appending signature [% x].", rawSignature) - - return tx, nil -} - -func (client *clientImpl) newChaincodeQueryUsingECert(chaincodeInvocation *obc.ChaincodeInvocationSpec, uuid string, nonce []byte) (*obc.Transaction, error) { - // Create a new transaction - tx, err := client.createQueryTx(chaincodeInvocation, uuid, nonce, nil) - if err != nil { - client.Errorf("Failed creating new query transaction [%s].", err.Error()) - return nil, err - } - - // Sign the transaction - - // Append the certificate to the transaction - client.Debugf("Appending certificate [% x].", client.enrollCert.Raw) - tx.Cert = client.enrollCert.Raw - - // Sign the transaction and append the signature - // 1. Marshall tx to bytes - rawTx, err := proto.Marshal(tx) - if err != nil { - client.Errorf("Failed marshaling tx [%s].", err.Error()) - return nil, err - } - - // 2. Sign rawTx and check signature - rawSignature, err := client.signWithEnrollmentKey(rawTx) - if err != nil { - client.Errorf("Failed creating signature [% x]: [%s].", rawTx, err.Error()) - return nil, err - } - - // 3. Append the signature - tx.Signature = rawSignature - - client.Debugf("Appending signature [% x].", rawSignature) - - return tx, nil -} - -// CheckTransaction is used to verify that a transaction -// is well formed with the respect to the security layer -// prescriptions. To be used for internal verifications. -func (client *clientImpl) checkTransaction(tx *obc.Transaction) error { - if !client.isInitialized { - return utils.ErrNotInitialized - } - - if tx.Cert == nil && tx.Signature == nil { - return utils.ErrTransactionMissingCert - } - - if tx.Cert != nil && tx.Signature != nil { - // Verify the transaction - // 1. Unmarshal cert - cert, err := primitives.DERToX509Certificate(tx.Cert) - if err != nil { - client.Errorf("Failed unmarshalling cert [%s].", err.Error()) - return err - } - - // a. Get rid of the extensions that cannot be checked now - cert.UnhandledCriticalExtensions = nil - // b. Check against TCA certPool - if _, err = primitives.CheckCertAgainRoot(cert, client.tcaCertPool); err != nil { - client.Warningf("Failed verifing certificate against TCA cert pool [%s].", err.Error()) - // c. Check against ECA certPool, if this check also fails then return an error - if _, err = primitives.CheckCertAgainRoot(cert, client.ecaCertPool); err != nil { - client.Warningf("Failed verifing certificate against ECA cert pool [%s].", err.Error()) - - return fmt.Errorf("Certificate has not been signed by a trusted authority. [%s]", err) - } - } - - // 2. Marshall tx without signature - signature := tx.Signature - tx.Signature = nil - rawTx, err := proto.Marshal(tx) - if err != nil { - client.Errorf("Failed marshaling tx [%s].", err.Error()) - return err - } - tx.Signature = signature - - // 3. Verify signature - ver, err := client.verify(cert.PublicKey, rawTx, tx.Signature) - if err != nil { - client.Errorf("Failed marshaling tx [%s].", err.Error()) - return err - } - - if ver { - return nil - } - - return utils.ErrInvalidTransactionSignature - } - - return utils.ErrTransactionMissingCert -} diff --git a/core/crypto/crypto.go b/core/crypto/crypto.go index 409bdf3b811..4bc117dcd68 100644 --- a/core/crypto/crypto.go +++ b/core/crypto/crypto.go @@ -59,18 +59,6 @@ type Client interface { // DecryptQueryResult is used to decrypt the result of a query transaction DecryptQueryResult(queryTx *obc.Transaction, result []byte) ([]byte, error) - - // GetEnrollmentCertHandler returns a CertificateHandler whose certificate is the enrollment certificate - GetEnrollmentCertificateHandler() (CertificateHandler, error) - - // GetTCertHandlerNext returns a CertificateHandler whose certificate is the next available TCert - GetTCertificateHandlerNext(attributes ...string) (CertificateHandler, error) - - // GetTCertHandlerFromDER returns a CertificateHandler whose certificate is the one passed - GetTCertificateHandlerFromDER(tCertDER []byte) (CertificateHandler, error) - - // GetNextTCert returns a slice of a requested number of (not yet used) transaction certificates - GetNextTCerts(nCerts int, attributes ...string) ([]tCert, error) } // Peer is an entity able to verify transactions diff --git a/core/crypto/crypto_profile.sh b/core/crypto/crypto_profile.sh deleted file mode 100755 index 8061805aa0f..00000000000 --- a/core/crypto/crypto_profile.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env bash - -if [ -f "crypto.test" ] -then - echo Removing crypto.test - rm crypto.test -fi - -echo Compile, banchmark, pprof... - -go test -c -#./crypto.test -test.cpuprofile=crypto.prof -#./crypto.test -test.bench BenchmarkConfidentialTCertHExecuteTransaction -test.run XXX -test.cpuprofile=crypto.prof -./crypto.test -test.bench BenchmarkTransaction -test.run XXX -test.cpuprofile=crypto.prof -#./crypto.test -test.run TestParallelInitClose -test.cpuprofile=crypto.prof -go tool pprof crypto.test crypto.prof \ No newline at end of file diff --git a/core/crypto/crypto_protocol.go b/core/crypto/crypto_protocol.go deleted file mode 100644 index d3654c3951c..00000000000 --- a/core/crypto/crypto_protocol.go +++ /dev/null @@ -1,39 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - obc "github.com/hyperledger/fabric/protos" -) - -type nodeProtocol interface { - init(node Node) - - parseTransaction(tx *obc.Transaction) (*obc.Transaction, error) -} - -type clientProtocol interface { - nodeProtocol - - decryptQueryResult(queryTx *obc.Transaction, result []byte) ([]byte, error) -} - -type validatorProtocol interface { - nodeProtocol - - getStateEncryptor(deployTx, executeTx *obc.Transaction) (StateEncryptor, error) -} diff --git a/core/crypto/crypto_settings.go b/core/crypto/crypto_settings.go deleted file mode 100644 index aec68621262..00000000000 --- a/core/crypto/crypto_settings.go +++ /dev/null @@ -1,57 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/op/go-logging" - "github.com/spf13/viper" -) - -var ( - log = logging.MustGetLogger("crypto") -) - -// Init initializes the crypto layer. It load from viper the security level -// and the logging setting. -func Init() (err error) { - // Init security level - securityLevel := 256 - if viper.IsSet("security.level") { - ovveride := viper.GetInt("security.level") - if ovveride != 0 { - securityLevel = ovveride - } - } - - hashAlgorithm := "SHA3" - if viper.IsSet("security.hashAlgorithm") { - ovveride := viper.GetString("security.hashAlgorithm") - if ovveride != "" { - hashAlgorithm = ovveride - } - } - - log.Debugf("Working at security level [%d]", securityLevel) - if err = primitives.InitSecurityLevel(hashAlgorithm, securityLevel); err != nil { - log.Errorf("Failed setting security level: [%s]", err) - - return - } - - return -} diff --git a/core/crypto/crypto_settings_test.go b/core/crypto/crypto_settings_test.go deleted file mode 100755 index 5789bfcc4c6..00000000000 --- a/core/crypto/crypto_settings_test.go +++ /dev/null @@ -1,49 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "testing" - - "github.com/op/go-logging" - "github.com/spf13/viper" -) - -func TestCryptoInitInheritsLoggingLevel(t *testing.T) { - logging.SetLevel(logging.WARNING, "crypto") - - Init() - - assertCryptoLoggingLevel(t, logging.WARNING) -} - -func TestCryptoInitDoesntOverrideLoggingLevel(t *testing.T) { - logging.SetLevel(logging.WARNING, "crypto") - viper.Set("logging.crypto", "info") - - Init() - - assertCryptoLoggingLevel(t, logging.WARNING) -} - -func assertCryptoLoggingLevel(t *testing.T, expected logging.Level) { - actual := logging.GetLevel("crypto") - - if expected != actual { - t.Errorf("Expected %v, got %v", expected, actual) - } -} diff --git a/core/crypto/crypto_test.go b/core/crypto/crypto_test.go deleted file mode 100644 index 0584ad17fa0..00000000000 --- a/core/crypto/crypto_test.go +++ /dev/null @@ -1,2167 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - obc "github.com/hyperledger/fabric/protos" - "github.com/op/go-logging" - - "bytes" - "fmt" - "net" - "os" - "path/filepath" - "reflect" - "testing" - - "crypto/rand" - - "runtime" - "time" - - "github.com/hyperledger/fabric/core/crypto/attributes" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - "github.com/hyperledger/fabric/core/util" - "github.com/hyperledger/fabric/membersrvc/ca" - "github.com/spf13/viper" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -type createTxFunc func(t *testing.T) (*obc.Transaction, *obc.Transaction, error) - -var ( - validator Peer - - peer Peer - - deployer Client - invoker Client - - server *grpc.Server - aca *ca.ACA - eca *ca.ECA - tca *ca.TCA - tlsca *ca.TLSCA - - deployTxCreators []createTxFunc - executeTxCreators []createTxFunc - queryTxCreators []createTxFunc - - ksPwd = []byte("This is a very very very long pw") - - attrs = []string{"company", "position"} -) - -func TestMain(m *testing.M) { - // Setup the test - setup() - - //Define a map to store the scenarios properties - properties := make(map[string]interface{}) - ret := 0 - - //First scenario with crypto_test.yaml - ret = runTestsOnScenario(m, properties, "Using crypto_test.yaml properties") - if ret != 0 { - os.Exit(ret) - } - - //Second scenario with multithread - properties["security.multithreading.enabled"] = "true" - ret = runTestsOnScenario(m, properties, "Using multithread enabled") - if ret != 0 { - os.Exit(ret) - } - - // Third scenario (repeat the above) now also with 'security.multithreading.multichannel' enabled. - properties["security.multithreading.multichannel"] = "true" - ret = runTestsOnScenario(m, properties, "Using multithread + multichannel enabled") - if ret != 0 { - os.Exit(ret) - } - properties["security.multithreading.enabled"] = "false" - - //Fourth scenario with security level = 384 - properties["security.hashAlgorithm"] = "SHA3" - properties["security.level"] = "384" - ret = runTestsOnScenario(m, properties, "Using SHA3-384") - if ret != 0 { - os.Exit(ret) - } - - //Fifth scenario with SHA2 - properties["security.hashAlgorithm"] = "SHA2" - properties["security.level"] = "256" - ret = runTestsOnScenario(m, properties, "Using SHA2-256") - if ret != 0 { - os.Exit(ret) - } - - //Sixth scenario with SHA2 - properties["security.hashAlgorithm"] = "SHA2" - properties["security.level"] = "384" - ret = runTestsOnScenario(m, properties, "Using SHA2-384") - if ret != 0 { - os.Exit(ret) - } - - os.Exit(ret) -} - -//loadConfigScennario loads the properties in the viper and returns the current values. -func loadConfigScenario(properties map[string]interface{}) map[string]interface{} { - currentValues := make(map[string]interface{}) - for k, v := range properties { - currentValues[k] = viper.Get(k) - viper.Set(k, v) - } - return currentValues -} - -func before() { - // Init PKI - initPKI() - go startPKI() -} - -func after() { - cleanup() -} - -func runTestsOnScenario(m *testing.M, properties map[string]interface{}, scenarioName string) int { - fmt.Printf("=== Start tests for scenario '%v' ===\n", scenarioName) - currentValues := make(map[string]interface{}) - if len(properties) > 0 { - currentValues = loadConfigScenario(properties) - } - primitives.SetSecurityLevel(viper.GetString("security.hashAlgorithm"), viper.GetInt("security.level")) - - before() - ret := m.Run() - after() - - if len(properties) > 0 { - _ = loadConfigScenario(currentValues) - } - fmt.Printf("=== End tests for scenario '%v' ===\n", scenarioName) - return ret -} - -func TestParallelInitClose(t *testing.T) { - clientConf := utils.NodeConfiguration{Type: "client", Name: "userthread"} - peerConf := utils.NodeConfiguration{Type: "peer", Name: "peerthread"} - validatorConf := utils.NodeConfiguration{Type: "validator", Name: "validatorthread"} - - if err := RegisterClient(clientConf.Name, nil, clientConf.GetEnrollmentID(), clientConf.GetEnrollmentPWD()); err != nil { - t.Fatalf("Failed registerting userthread.") - } - - if err := RegisterPeer(peerConf.Name, nil, peerConf.GetEnrollmentID(), peerConf.GetEnrollmentPWD()); err != nil { - t.Fatalf("Failed registerting peerthread") - } - - if err := RegisterValidator(validatorConf.Name, nil, validatorConf.GetEnrollmentID(), validatorConf.GetEnrollmentPWD()); err != nil { - t.Fatalf("Failed registerting validatorthread") - } - - done := make(chan bool) - - n := 10 - var peer Peer - var validator Peer - var client Client - - var err error - for i := 0; i < n; i++ { - go func() { - if err := RegisterPeer(peerConf.Name, nil, peerConf.GetEnrollmentID(), peerConf.GetEnrollmentPWD()); err != nil { - t.Logf("Failed registerting peerthread") - } - peer, err = InitPeer(peerConf.Name, nil) - if err != nil { - t.Logf("Failed peer initialization [%s]", err) - } - - if err := RegisterValidator(validatorConf.Name, nil, validatorConf.GetEnrollmentID(), validatorConf.GetEnrollmentPWD()); err != nil { - t.Logf("Failed registerting validatorthread") - } - validator, err = InitValidator(validatorConf.Name, nil) - if err != nil { - t.Logf("Failed validator initialization [%s]", err) - } - - if err := RegisterClient(clientConf.Name, nil, clientConf.GetEnrollmentID(), clientConf.GetEnrollmentPWD()); err != nil { - t.Logf("Failed registerting userthread.") - } - client, err = InitClient(clientConf.Name, nil) - if err != nil { - t.Logf("Failed client initialization [%s]", err) - } - - for i := 0; i < 5; i++ { - client, err := InitClient(clientConf.Name, nil) - if err != nil { - t.Logf("Failed client initialization [%s]", err) - } - - runtime.Gosched() - time.Sleep(500 * time.Millisecond) - - err = CloseClient(client) - if err != nil { - t.Logf("Failed client closing [%s]", err) - } - } - done <- true - }() - } - - for i := 0; i < n; i++ { - log.Info("Waiting") - <-done - log.Info("+1") - } - - // Close Client, Peer and Validator n times - for i := 0; i < n; i++ { - if err := CloseClient(client); err != nil { - t.Fatalf("Client should be still closable. [%d][%d]", i, n) - } - - if err := ClosePeer(peer); err != nil { - t.Fatalf("Peer should be still closable. [%d][%d]", i, n) - } - - if err := CloseValidator(validator); err != nil { - t.Fatalf("Validator should be still closable. [%d][%d]", i, n) - } - } -} - -func TestRegistrationSameEnrollIDDifferentRole(t *testing.T) { - conf := utils.NodeConfiguration{Type: "client", Name: "TestRegistrationSameEnrollIDDifferentRole"} - if err := RegisterClient(conf.Name, nil, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()); err != nil { - t.Fatalf("Failed client registration [%s]", err) - } - - if err := RegisterValidator(conf.Name, nil, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()); err == nil { - t.Fatal("Reusing the same enrollment id must be forbidden", err) - } - - if err := RegisterPeer(conf.Name, nil, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()); err == nil { - t.Fatal("Reusing the same enrollment id must be forbidden", err) - } -} - -func TestTLSCertificateDeletion(t *testing.T) { - conf := utils.NodeConfiguration{Type: "peer", Name: "peer"} - - peer, err := registerAndReturnPeer(conf.Name, nil, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()) - if err != nil { - t.Fatalf("Failed peer registration [%s]", err) - } - - if peer.ks.certMissing(peer.conf.getTLSCertFilename()) { - t.Fatal("TLS shouldn't be missing after peer registration") - } - - if err := peer.deleteTLSCertificate(conf.GetEnrollmentID(), conf.GetEnrollmentPWD()); err != nil { - t.Fatalf("Failed deleting TLS certificate [%s]", err) - } - - if !peer.ks.certMissing(peer.conf.getTLSCertFilename()) { - t.Fatal("TLS certificate should be missing after deletion") - } -} - -func TestRegistrationAfterDeletingTLSCertificate(t *testing.T) { - conf := utils.NodeConfiguration{Type: "peer", Name: "peer"} - - peer, err := registerAndReturnPeer(conf.Name, nil, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()) - if err != nil { - t.Fatalf("Failed peer registration [%s]", err) - } - - if err := peer.deleteTLSCertificate(conf.GetEnrollmentID(), conf.GetEnrollmentPWD()); err != nil { - t.Fatalf("Failed deleting TLS certificate [%s]", err) - } - - if _, err := registerAndReturnPeer(conf.Name, nil, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()); err != nil { - t.Fatalf("Failed peer registration [%s]", err) - } -} - -func registerAndReturnPeer(name string, pwd []byte, enrollID, enrollPWD string) (*peerImpl, error) { - peer := newPeer() - if err := peer.register(NodePeer, name, pwd, enrollID, enrollPWD, nil); err != nil { - return nil, err - } - if err := peer.close(); err != nil { - return nil, err - } - return peer, nil -} - -func TestInitialization(t *testing.T) { - // Init fake client - client, err := InitClient("", nil) - if err == nil || client != nil { - t.Fatal("Init should fail") - } - err = CloseClient(client) - if err == nil { - t.Fatal("Close should fail") - } - - // Init fake peer - peer, err = InitPeer("", nil) - if err == nil || peer != nil { - t.Fatal("Init should fail") - } - err = ClosePeer(peer) - if err == nil { - t.Fatal("Close should fail") - } - - // Init fake validator - validator, err = InitValidator("", nil) - if err == nil || validator != nil { - t.Fatal("Init should fail") - } - err = CloseValidator(validator) - if err == nil { - t.Fatal("Close should fail") - } -} - -func TestClientDeployTransaction(t *testing.T) { - initNodes() - defer closeNodes() - for i, createTx := range deployTxCreators { - t.Logf("TestClientDeployTransaction with [%d]\n", i) - - _, tx, err := createTx(t) - - if err != nil { - t.Fatalf("Failed creating deploy transaction [%s].", err) - } - - if tx == nil { - t.Fatalf("Result must be different from nil") - } - - // Check transaction. For test purposes only - err = deployer.(*clientImpl).checkTransaction(tx) - if err != nil { - t.Fatalf("Failed checking transaction [%s].", err) - } - } -} - -func TestClientExecuteTransaction(t *testing.T) { - initNodes() - defer closeNodes() - for i, createTx := range executeTxCreators { - t.Logf("TestClientExecuteTransaction with [%d]\n", i) - - _, tx, err := createTx(t) - - if err != nil { - t.Fatalf("Failed creating deploy transaction [%s].", err) - } - - if tx == nil { - t.Fatalf("Result must be different from nil") - } - - // Check transaction. For test purposes only - err = invoker.(*clientImpl).checkTransaction(tx) - if err != nil { - t.Fatalf("Failed checking transaction [%s].", err) - } - } -} - -func TestClientQueryTransaction(t *testing.T) { - initNodes() - defer closeNodes() - for i, createTx := range queryTxCreators { - t.Logf("TestClientQueryTransaction with [%d]\n", i) - - _, tx, err := createTx(t) - - if err != nil { - t.Fatalf("Failed creating deploy transaction [%s].", err) - } - - if tx == nil { - t.Fatalf("Result must be different from nil") - } - - // Check transaction. For test purposes only - err = invoker.(*clientImpl).checkTransaction(tx) - if err != nil { - t.Fatalf("Failed checking transaction [%s].", err) - } - } -} - -func TestClientMultiExecuteTransaction(t *testing.T) { - initNodes() - defer closeNodes() - for i := 0; i < 24; i++ { - _, tx, err := createConfidentialExecuteTransaction(t) - - if err != nil { - t.Fatalf("Failed creating execute transaction [%s].", err) - } - - if tx == nil { - t.Fatalf("Result must be different from nil") - } - - // Check transaction. For test purposes only - err = invoker.(*clientImpl).checkTransaction(tx) - if err != nil { - t.Fatalf("Failed checking transaction [%s].", err) - } - } -} - -func TestClientGetNextTCerts(t *testing.T) { - - initNodes() - defer closeNodes() - - // Some positive flow tests here - var nCerts int = 1 - for i := 1; i < 3; i++ { - nCerts *= 10 - t.Logf("Calling GetNextTCerts(%d)", nCerts) - rvCerts, err := deployer.GetNextTCerts(nCerts) - if err != nil { - t.Fatalf("Could not receive %d TCerts", nCerts) - } - if len(rvCerts) != nCerts { - t.Fatalf("Expected exactly '%d' TCerts as a return from GetNextTCert(%d)", nCerts, nCerts) - } - - for nPos, cert := range rvCerts { - if cert == nil { - t.Fatalf("Returned TCert (at position %d) cannot be nil", nPos) - } - } - } - - // Some negative flow tests here - _, err := deployer.GetNextTCerts(0) - if err == nil { - t.Fatalf("Requesting 0 TCerts: expected an error when calling GetNextTCerts(0)") - } - - _, err = deployer.GetNextTCerts(-1) - if err == nil { - t.Fatalf("Requesting -1 TCerts: expected an error when calling GetNextTCerts(-1)") - } - -} - -//TestClientGetAttributesFromTCert verifies that the value read from the TCert is the expected value "ACompany". -func TestClientGetAttributesFromTCert(t *testing.T) { - initNodes() - defer closeNodes() - - tCerts, err := deployer.GetNextTCerts(1, attrs...) - - if err != nil { - t.Fatalf("Failed getting TCert by calling GetNextTCerts(1): [%s]", err) - } - if tCerts == nil { - t.Fatalf("TCert should be different from nil") - } - if len(tCerts) != 1 { - t.Fatalf("Expected one TCert returned from GetNextTCerts(1)") - } - - tcertDER := tCerts[0].GetCertificate().Raw - - if tcertDER == nil { - t.Fatalf("Cert should be different from nil") - } - if len(tcertDER) == 0 { - t.Fatalf("Cert should have length > 0") - } - - attributeBytes, err := attributes.GetValueForAttribute("company", tCerts[0].GetPreK0(), tCerts[0].GetCertificate()) - if err != nil { - t.Fatalf("Error retrieving attribute from TCert: [%s]", err) - } - - attributeValue := string(attributeBytes[:]) - - if attributeValue != "ACompany" { - t.Fatalf("Wrong attribute retrieved from TCert. Expected [%s], Actual [%s]", "ACompany", attributeValue) - } -} - -func TestClientGetAttributesFromTCertWithUnusedTCerts(t *testing.T) { - initNodes() - defer closeNodes() - - _, _ = deployer.GetNextTCerts(1, attrs...) - - CloseAllClients() // Remove client and store unused TCerts. - initClients() // Restart fresh client. - - tcerts, err := deployer.GetNextTCerts(1, attrs...) - - if err != nil { - t.Fatalf("Failed getting tcert: [%s]", err) - } - if tcerts == nil { - t.Fatalf("Returned TCerts slice should be different from nil") - } - if tcerts[0] == nil { - t.Fatalf("Returned TCerts slice's first entry should be different from nil") - } - - tcertDER := tcerts[0].GetCertificate().Raw - - if tcertDER == nil { - t.Fatalf("Cert should be different from nil") - } - if len(tcertDER) == 0 { - t.Fatalf("Cert should have length > 0") - } - - attributeBytes, err := attributes.GetValueForAttribute("company", tcerts[0].GetPreK0(), tcerts[0].GetCertificate()) - if err != nil { - t.Fatalf("Error retrieving attribute from TCert: [%s]", err) - } - - attributeValue := string(attributeBytes[:]) - - if attributeValue != "ACompany" { - t.Fatalf("Wrong attribute retrieved from TCert. Expected [%s], Actual [%s]", "ACompany", attributeValue) - } -} - -func TestClientGetTCertHandlerNext(t *testing.T) { - initNodes() - defer closeNodes() - - handler, err := deployer.GetTCertificateHandlerNext(attrs...) - - if err != nil { - t.Fatalf("Failed getting handler: [%s]", err) - } - if handler == nil { - t.Fatalf("Handler should be different from nil") - } - - certDER := handler.GetCertificate() - - if certDER == nil { - t.Fatalf("Cert should be different from nil") - } - if len(certDER) == 0 { - t.Fatalf("Cert should have length > 0") - } -} - -func TestClientGetTCertHandlerFromDER(t *testing.T) { - initNodes() - defer closeNodes() - - handler, err := deployer.GetTCertificateHandlerNext(attrs...) - if err != nil { - t.Fatalf("Failed getting handler: [%s]", err) - } - - handler2, err := deployer.GetTCertificateHandlerFromDER(handler.GetCertificate()) - if err != nil { - t.Fatalf("Failed getting tcert: [%s]", err) - } - if handler == nil { - t.Fatalf("Handler should be different from nil") - } - tCertDER := handler2.GetCertificate() - if tCertDER == nil { - t.Fatalf("TCert should be different from nil") - } - if len(tCertDER) == 0 { - t.Fatalf("TCert should have length > 0") - } - - if !reflect.DeepEqual(handler.GetCertificate(), tCertDER) { - t.Fatalf("TCerts must be the same") - } -} - -func TestClientTCertHandlerSign(t *testing.T) { - initNodes() - defer closeNodes() - - handlerDeployer, err := deployer.GetTCertificateHandlerNext(attrs...) - if err != nil { - t.Fatalf("Failed getting handler: [%s]", err) - } - - msg := []byte("Hello World!!!") - signature, err := handlerDeployer.Sign(msg) - if err != nil { - t.Fatalf("Failed getting tcert: [%s]", err) - } - if signature == nil || len(signature) == 0 { - t.Fatalf("Failed getting non-nil signature") - } - - err = handlerDeployer.Verify(signature, msg) - if err != nil { - t.Fatalf("Failed verifying signature: [%s]", err) - } - - // Check that deployer can reload the cert handler from DER and sign - handlerDeployer2, err := deployer.GetTCertificateHandlerFromDER(handlerDeployer.GetCertificate()) - if err != nil { - t.Fatalf("Failed getting tcert: [%s]", err) - } - - msg = []byte("Hello World!!!") - signature, err = handlerDeployer2.Sign(msg) - if err != nil { - t.Fatalf("Failed getting tcert: [%s]", err) - } - if signature == nil || len(signature) == 0 { - t.Fatalf("Failed getting non-nil signature") - } - - err = handlerDeployer2.Verify(signature, msg) - if err != nil { - t.Fatalf("Failed verifying signature: [%s]", err) - } - - // Check that invoker (another party) can verify the signature - handlerInvoker, err := invoker.GetTCertificateHandlerFromDER(handlerDeployer.GetCertificate()) - if err != nil { - t.Fatalf("Failed getting tcert: [%s]", err) - } - - err = handlerInvoker.Verify(signature, msg) - if err != nil { - t.Fatalf("Failed verifying signature: [%s]", err) - } - - // Check that invoker cannot sign using a tcert obtained by the deployer - signature, err = handlerInvoker.Sign(msg) - if err == nil { - t.Fatalf("Bob should not be able to use Alice's tcert to sign") - } - if signature != nil { - t.Fatalf("Signature should be nil") - } -} - -func TestClientGetEnrollmentCertHandler(t *testing.T) { - initNodes() - defer closeNodes() - - handler, err := deployer.GetEnrollmentCertificateHandler() - - if err != nil { - t.Fatalf("Failed getting handler: [%s]", err) - } - if handler == nil { - t.Fatalf("Handler should be different from nil") - } - - certDER := handler.GetCertificate() - - if certDER == nil { - t.Fatalf("Cert should be different from nil") - } - if len(certDER) == 0 { - t.Fatalf("Cert should have length > 0") - } -} - -func TestClientGetEnrollmentCertHandlerSign(t *testing.T) { - initNodes() - defer closeNodes() - - handlerDeployer, err := deployer.GetEnrollmentCertificateHandler() - if err != nil { - t.Fatalf("Failed getting handler: [%s]", err) - } - - msg := []byte("Hello World!!!") - signature, err := handlerDeployer.Sign(msg) - if err != nil { - t.Fatalf("Failed getting tcert: [%s]", err) - } - if signature == nil || len(signature) == 0 { - t.Fatalf("Failed getting non-nil signature") - } - - err = handlerDeployer.Verify(signature, msg) - if err != nil { - t.Fatalf("Failed verifying signature: [%s]", err) - } - - // Check that invoker (another party) can verify the signature - handlerInvoker, err := invoker.GetEnrollmentCertificateHandler() - if err != nil { - t.Fatalf("Failed getting tcert: [%s]", err) - } - - err = handlerInvoker.Verify(signature, msg) - if err == nil { - t.Fatalf("Failed verifying signature: [%s]", err) - } - -} - -func TestPeerID(t *testing.T) { - initNodes() - defer closeNodes() - - // Verify that any id modification doesn't change - id := peer.GetID() - - if id == nil { - t.Fatalf("Id is nil.") - } - - if len(id) == 0 { - t.Fatalf("Id length is zero.") - } - - id[0] = id[0] + 1 - id2 := peer.GetID() - if id2[0] == id[0] { - t.Fatalf("Invariant not respected.") - } -} - -func TestPeerDeployTransaction(t *testing.T) { - initNodes() - defer closeNodes() - - for i, createTx := range deployTxCreators { - t.Logf("TestPeerDeployTransaction with [%d]\n", i) - - _, tx, err := createTx(t) - if err != nil { - t.Fatalf("TransactionPreValidation: failed creating transaction [%s].", err) - } - - res, err := peer.TransactionPreValidation(tx) - if err != nil { - t.Fatalf("Error must be nil [%s].", err) - } - if res == nil { - t.Fatalf("Result must be diffrent from nil") - } - - res, err = peer.TransactionPreExecution(tx) - if err != utils.ErrNotImplemented { - t.Fatalf("Error must be ErrNotImplemented [%s].", err) - } - if res != nil { - t.Fatalf("Result must nil") - } - - // Test no Cert - oldCert := tx.Cert - tx.Cert = nil - _, err = peer.TransactionPreValidation(tx) - if err == nil { - t.Fatalf("Pre Validatiotn should fail. No Cert. %s", err) - } - tx.Cert = oldCert - - // Test no Signature - oldSig := tx.Signature - tx.Signature = nil - _, err = peer.TransactionPreValidation(tx) - if err == nil { - t.Fatalf("Pre Validatiotn should fail. No Signature. %s", err) - } - tx.Signature = oldSig - - // Test Invalid Cert - oldCert = tx.Cert - tx.Cert = []byte{0, 1, 2, 3, 4} - _, err = peer.TransactionPreValidation(tx) - if err == nil { - t.Fatalf("Pre Validatiotn should fail. Invalid Cert. %s", err) - } - tx.Cert = oldCert - - // Test self signed certificate Cert - oldCert = tx.Cert - rawSelfSignedCert, _, err := primitives.NewSelfSignedCert() - if err != nil { - t.Fatalf("Failed creating self signed cert [%s]", err) - } - tx.Cert = rawSelfSignedCert - _, err = peer.TransactionPreValidation(tx) - if err == nil { - t.Fatalf("Pre Validatiotn should fail. Invalid Cert. %s", err) - } - tx.Cert = oldCert - - // Test invalid Signature - oldSig = tx.Signature - tx.Signature = []byte{0, 1, 2, 3, 4} - _, err = peer.TransactionPreValidation(tx) - if err == nil { - t.Fatalf("Pre Validatiotn should fail. Invalid Signature. %s", err) - } - tx.Signature = oldSig - } -} - -func TestPeerExecuteTransaction(t *testing.T) { - initNodes() - defer closeNodes() - - for i, createTx := range executeTxCreators { - t.Logf("TestPeerExecuteTransaction with [%d]\n", i) - - _, tx, err := createTx(t) - if err != nil { - t.Fatalf("TransactionPreValidation: failed creating transaction [%s].", err) - } - - res, err := peer.TransactionPreValidation(tx) - if err != nil { - t.Fatalf("Error must be nil [%s].", err) - } - if res == nil { - t.Fatalf("Result must be diffrent from nil") - } - - res, err = peer.TransactionPreExecution(tx) - if err != utils.ErrNotImplemented { - t.Fatalf("Error must be ErrNotImplemented [%s].", err) - } - if res != nil { - t.Fatalf("Result must nil") - } - } -} - -func TestPeerQueryTransaction(t *testing.T) { - initNodes() - defer closeNodes() - - for i, createTx := range queryTxCreators { - t.Logf("TestPeerQueryTransaction with [%d]\n", i) - - _, tx, err := createTx(t) - if err != nil { - t.Fatalf("Failed creating query transaction [%s].", err) - } - - res, err := peer.TransactionPreValidation(tx) - if err != nil { - t.Fatalf("Error must be nil [%s].", err) - } - if res == nil { - t.Fatalf("Result must be diffrent from nil") - } - - res, err = peer.TransactionPreExecution(tx) - if err != utils.ErrNotImplemented { - t.Fatalf("Error must be ErrNotImplemented [%s].", err) - } - if res != nil { - t.Fatalf("Result must nil") - } - } -} - -func TestPeerStateEncryptor(t *testing.T) { - initNodes() - defer closeNodes() - - _, deployTx, err := createConfidentialDeployTransaction(t) - if err != nil { - t.Fatalf("Failed creating deploy transaction [%s].", err) - } - _, invokeTxOne, err := createConfidentialExecuteTransaction(t) - if err != nil { - t.Fatalf("Failed creating invoke transaction [%s].", err) - } - - res, err := peer.GetStateEncryptor(deployTx, invokeTxOne) - if err != utils.ErrNotImplemented { - t.Fatalf("Error must be ErrNotImplemented [%s].", err) - } - if res != nil { - t.Fatalf("Result must be nil") - } -} - -func TestPeerSignVerify(t *testing.T) { - initNodes() - defer closeNodes() - - msg := []byte("Hello World!!!") - signature, err := peer.Sign(msg) - if err != nil { - t.Fatalf("TestSign: failed generating signature [%s].", err) - } - - err = peer.Verify(peer.GetID(), signature, msg) - if err != nil { - t.Fatalf("TestSign: failed validating signature [%s].", err) - } - - signature, err = validator.Sign(msg) - if err != nil { - t.Fatalf("TestSign: failed generating signature [%s].", err) - } - - err = peer.Verify(validator.GetID(), signature, msg) - if err != nil { - t.Fatalf("TestSign: failed validating signature [%s].", err) - } -} - -func TestPeerVerify(t *testing.T) { - initNodes() - defer closeNodes() - - msg := []byte("Hello World!!!") - signature, err := validator.Sign(msg) - if err != nil { - t.Fatalf("Failed generating signature [%s].", err) - } - - err = peer.Verify(nil, signature, msg) - if err == nil { - t.Fatal("Verify should fail when given an empty id.", err) - } - - err = peer.Verify(msg, signature, msg) - if err == nil { - t.Fatal("Verify should fail when given an invalid id.", err) - } - - err = peer.Verify(validator.GetID(), nil, msg) - if err == nil { - t.Fatal("Verify should fail when given an invalid signature.", err) - } - - err = peer.Verify(validator.GetID(), msg, msg) - if err == nil { - t.Fatal("Verify should fail when given an invalid signature.", err) - } - - err = peer.Verify(validator.GetID(), signature, nil) - if err == nil { - t.Fatal("Verify should fail when given an invalid messahe.", err) - } -} - -func TestValidatorID(t *testing.T) { - initNodes() - defer closeNodes() - - // Verify that any id modification doesn't change - id := validator.GetID() - - if id == nil { - t.Fatalf("Id is nil.") - } - - if len(id) == 0 { - t.Fatalf("Id length is zero.") - } - - id[0] = id[0] + 1 - id2 := validator.GetID() - if id2[0] == id[0] { - t.Fatalf("Invariant not respected.") - } -} - -func TestValidatorDeployTransaction(t *testing.T) { - initNodes() - defer closeNodes() - - for i, createTx := range deployTxCreators { - t.Logf("TestValidatorDeployTransaction with [%d]\n", i) - - otx, tx, err := createTx(t) - if err != nil { - t.Fatalf("Failed creating deploy transaction [%s].", err) - } - - res, err := validator.TransactionPreValidation(tx) - if err != nil { - t.Fatalf("Error must be nil [%s].", err) - } - if res == nil { - t.Fatalf("Result must be diffrent from nil") - } - - res, err = validator.TransactionPreExecution(tx) - if err != nil { - t.Fatalf("Error must be nil [%s].", err) - } - if res == nil { - t.Fatalf("Result must be diffrent from nil") - } - - // Test invalid ConfidentialityLevel - oldConfidentialityLevel := tx.ConfidentialityLevel - tx.ConfidentialityLevel = -1 - _, err = validator.TransactionPreExecution(tx) - if err == nil { - t.Fatalf("TransactionPreExecution should fail. Invalid ConfidentialityLevel. %s", err) - } - if err != utils.ErrInvalidConfidentialityLevel { - t.Fatalf("TransactionPreExecution should with ErrInvalidConfidentialityLevel rather than [%s]", err) - } - tx.ConfidentialityLevel = oldConfidentialityLevel - - if tx.ConfidentialityLevel == obc.ConfidentialityLevel_CONFIDENTIAL { - if reflect.DeepEqual(res, tx) { - t.Fatalf("Src and Dest Transaction should be different after PreExecution") - } - if err := isEqual(otx, res); err != nil { - t.Fatalf("Decrypted transaction differs from the original: [%s]", err) - } - - // Test no ToValidators - oldToValidators := tx.ToValidators - tx.ToValidators = nil - _, err = validator.TransactionPreExecution(tx) - if err == nil { - t.Fatalf("TransactionPreExecution should fail. No ToValidators. %s", err) - } - tx.ToValidators = oldToValidators - - // Test invalid ToValidators - oldToValidators = tx.ToValidators - tx.ToValidators = []byte{0, 1, 2, 3, 4} - _, err = validator.TransactionPreExecution(tx) - if err == nil { - t.Fatalf("TransactionPreExecution should fail. Invalid ToValidators. %s", err) - } - tx.ToValidators = oldToValidators - - // Test no Payload - oldPayload := tx.Payload - tx.Payload = nil - _, err = validator.TransactionPreExecution(tx) - if err == nil { - t.Fatalf("TransactionPreExecution should fail. No Payload. %s", err) - } - tx.Payload = oldPayload - - // Test invalid Payload - oldPayload = tx.Payload - tx.Payload = []byte{0, 1, 2, 3, 4} - _, err = validator.TransactionPreExecution(tx) - if err == nil { - t.Fatalf("TransactionPreExecution should fail. Invalid Payload. %s", err) - } - tx.Payload = oldPayload - - // Test no Payload - oldChaincodeID := tx.ChaincodeID - tx.ChaincodeID = nil - _, err = validator.TransactionPreExecution(tx) - if err == nil { - t.Fatalf("TransactionPreExecution should fail. No ChaincodeID. %s", err) - } - tx.ChaincodeID = oldChaincodeID - - // Test invalid Payload - oldChaincodeID = tx.ChaincodeID - tx.ChaincodeID = []byte{0, 1, 2, 3, 4} - _, err = validator.TransactionPreExecution(tx) - if err == nil { - t.Fatalf("TransactionPreExecution should fail. Invalid ChaincodeID. %s", err) - } - tx.ChaincodeID = oldChaincodeID - } - } -} - -func TestValidatorExecuteTransaction(t *testing.T) { - initNodes() - defer closeNodes() - - for i, createTx := range executeTxCreators { - t.Logf("TestValidatorExecuteTransaction with [%d]\n", i) - - otx, tx, err := createTx(t) - if err != nil { - t.Fatalf("Failed creating execute transaction [%s].", err) - } - - res, err := validator.TransactionPreValidation(tx) - if err != nil { - t.Fatalf("Error must be nil [%s].", err) - } - if res == nil { - t.Fatalf("Result must be diffrent from nil") - } - - res, err = validator.TransactionPreExecution(tx) - if err != nil { - t.Fatalf("Error must be nil [%s].", err) - } - if res == nil { - t.Fatalf("Result must be diffrent from nil") - } - - if tx.ConfidentialityLevel == obc.ConfidentialityLevel_CONFIDENTIAL { - if reflect.DeepEqual(res, tx) { - t.Fatalf("Src and Dest Transaction should be different after PreExecution") - } - if err := isEqual(otx, res); err != nil { - t.Fatalf("Decrypted transaction differs from the original: [%s]", err) - } - } - } -} - -func TestValidatorQueryTransaction(t *testing.T) { - initNodes() - defer closeNodes() - - for i, createTx := range queryTxCreators { - t.Logf("TestValidatorConfidentialQueryTransaction with [%d]\n", i) - - _, deployTx, err := deployTxCreators[i](t) - if err != nil { - t.Fatalf("Failed creating deploy transaction [%s].", err) - } - _, invokeTxOne, err := executeTxCreators[i](t) - if err != nil { - t.Fatalf("Failed creating invoke transaction [%s].", err) - } - _, invokeTxTwo, err := executeTxCreators[i](t) - if err != nil { - t.Fatalf("Failed creating invoke transaction [%s].", err) - } - otx, queryTx, err := createTx(t) - if err != nil { - t.Fatalf("Failed creating query transaction [%s].", err) - } - - if queryTx.ConfidentialityLevel == obc.ConfidentialityLevel_CONFIDENTIAL { - - // Transactions must be PreExecuted by the validators before getting the StateEncryptor - if _, err = validator.TransactionPreValidation(deployTx); err != nil { - t.Fatalf("Failed pre-validating deploty transaction [%s].", err) - } - if deployTx, err = validator.TransactionPreExecution(deployTx); err != nil { - t.Fatalf("Failed pre-executing deploty transaction [%s].", err) - } - if _, err = validator.TransactionPreValidation(invokeTxOne); err != nil { - t.Fatalf("Failed pre-validating exec1 transaction [%s].", err) - } - if invokeTxOne, err = validator.TransactionPreExecution(invokeTxOne); err != nil { - t.Fatalf("Failed pre-executing exec1 transaction [%s].", err) - } - if _, err = validator.TransactionPreValidation(invokeTxTwo); err != nil { - t.Fatalf("Failed pre-validating exec2 transaction [%s].", err) - } - if invokeTxTwo, err = validator.TransactionPreExecution(invokeTxTwo); err != nil { - t.Fatalf("Failed pre-executing exec2 transaction [%s].", err) - } - if _, err = validator.TransactionPreValidation(queryTx); err != nil { - t.Fatalf("Failed pre-validating query transaction [%s].", err) - } - if queryTx, err = validator.TransactionPreExecution(queryTx); err != nil { - t.Fatalf("Failed pre-executing query transaction [%s].", err) - } - if err := isEqual(otx, queryTx); err != nil { - t.Fatalf("Decrypted transaction differs from the original: [%s]", err) - } - - // First invokeTx - seOne, err := validator.GetStateEncryptor(deployTx, invokeTxOne) - if err != nil { - t.Fatalf("Failed creating state encryptor [%s].", err) - } - pt := []byte("Hello World") - aCt, err := seOne.Encrypt(pt) - if err != nil { - t.Fatalf("Failed encrypting state [%s].", err) - } - aPt, err := seOne.Decrypt(aCt) - if err != nil { - t.Fatalf("Failed decrypting state [%s].", err) - } - if !bytes.Equal(pt, aPt) { - t.Fatalf("Failed decrypting state [%s != %s]: %s", string(pt), string(aPt), err) - } - // Try to decrypt nil. It should return nil with no error - out, err := seOne.Decrypt(nil) - if err != nil { - t.Fatal("Decrypt should not fail on nil input") - } - if out != nil { - t.Fatal("Nil input should decrypt to nil") - } - - // Second invokeTx - seTwo, err := validator.GetStateEncryptor(deployTx, invokeTxTwo) - if err != nil { - t.Fatalf("Failed creating state encryptor [%s].", err) - } - aPt2, err := seTwo.Decrypt(aCt) - if err != nil { - t.Fatalf("Failed decrypting state [%s].", err) - } - if !bytes.Equal(pt, aPt2) { - t.Fatalf("Failed decrypting state [%s != %s]: %s", string(pt), string(aPt), err) - } - // Reencrypt the state - aCt, err = seTwo.Encrypt(pt) - if err != nil { - t.Fatalf("Failed encrypting state [%s].", err) - } - - // Try to decrypt nil. It should return nil with no error - out, err = seTwo.Decrypt(nil) - if err != nil { - t.Fatal("Decrypt should not fail on nil input") - } - if out != nil { - t.Fatal("Nil input should decrypt to nil") - } - - // queryTx - seThree, err := validator.GetStateEncryptor(deployTx, queryTx) - aPt2, err = seThree.Decrypt(aCt) - if err != nil { - t.Fatalf("Failed decrypting state [%s].", err) - } - if !bytes.Equal(pt, aPt2) { - t.Fatalf("Failed decrypting state [%s != %s]: %s", string(pt), string(aPt), err) - } - - ctQ, err := seThree.Encrypt(aPt2) - if err != nil { - t.Fatalf("Failed encrypting query result [%s].", err) - } - aPt3, err := invoker.DecryptQueryResult(queryTx, ctQ) - if err != nil { - t.Fatalf("Failed decrypting query result [%s].", err) - } - if !bytes.Equal(aPt2, aPt3) { - t.Fatalf("Failed decrypting query result [%s != %s]: %s", string(aPt2), string(aPt3), err) - } - } - } -} - -func TestValidatorStateEncryptor(t *testing.T) { - initNodes() - defer closeNodes() - - _, deployTx, err := createConfidentialDeployTransaction(t) - if err != nil { - t.Fatalf("Failed creating deploy transaction [%s]", err) - } - _, invokeTxOne, err := createConfidentialExecuteTransaction(t) - if err != nil { - t.Fatalf("Failed creating invoke transaction [%s]", err) - } - _, invokeTxTwo, err := createConfidentialExecuteTransaction(t) - if err != nil { - t.Fatalf("Failed creating invoke transaction [%s]", err) - } - - // Transactions must be PreExecuted by the validators before getting the StateEncryptor - if _, err = validator.TransactionPreValidation(deployTx); err != nil { - t.Fatalf("Failed pre-validating deploty transaction [%s].", err) - } - if deployTx, err = validator.TransactionPreExecution(deployTx); err != nil { - t.Fatalf("Failed pre-validating deploty transaction [%s].", err) - } - if _, err = validator.TransactionPreValidation(invokeTxOne); err != nil { - t.Fatalf("Failed pre-validating exec1 transaction [%s].", err) - } - if invokeTxOne, err = validator.TransactionPreExecution(invokeTxOne); err != nil { - t.Fatalf("Failed pre-validating exec1 transaction [%s].", err) - } - if _, err = validator.TransactionPreValidation(invokeTxTwo); err != nil { - t.Fatalf("Failed pre-validating exec2 transaction [%s].", err) - } - if invokeTxTwo, err = validator.TransactionPreExecution(invokeTxTwo); err != nil { - t.Fatalf("Failed pre-validating exec2 transaction [%s].", err) - } - - seOne, err := validator.GetStateEncryptor(deployTx, invokeTxOne) - if err != nil { - t.Fatalf("Failed creating state encryptor [%s].", err) - } - pt := []byte("Hello World") - aCt, err := seOne.Encrypt(pt) - if err != nil { - t.Fatalf("Failed encrypting state [%s].", err) - } - aPt, err := seOne.Decrypt(aCt) - if err != nil { - t.Fatalf("Failed decrypting state [%s].", err) - } - if !bytes.Equal(pt, aPt) { - t.Fatalf("Failed decrypting state [%s != %s]: %s", string(pt), string(aPt), err) - } - - // Try to decrypt nil. It should return nil with no error - out, err := seOne.Decrypt(nil) - if err != nil { - t.Fatal("Decrypt should not fail on nil input") - } - if out != nil { - t.Fatal("Nil input should decrypt to nil") - } - - seTwo, err := validator.GetStateEncryptor(deployTx, invokeTxTwo) - if err != nil { - t.Fatalf("Failed creating state encryptor [%s].", err) - } - aPt2, err := seTwo.Decrypt(aCt) - if err != nil { - t.Fatalf("Failed decrypting state [%s].", err) - } - if !bytes.Equal(pt, aPt2) { - t.Fatalf("Failed decrypting state [%s != %s]: %s", string(pt), string(aPt), err) - } - - // Try to decrypt nil. It should return nil with no error - out, err = seTwo.Decrypt(nil) - if err != nil { - t.Fatal("Decrypt should not fail on nil input") - } - if out != nil { - t.Fatal("Nil input should decrypt to nil") - } - -} - -func TestValidatorSignVerify(t *testing.T) { - initNodes() - defer closeNodes() - - msg := []byte("Hello World!!!") - signature, err := validator.Sign(msg) - if err != nil { - t.Fatalf("TestSign: failed generating signature [%s].", err) - } - - err = validator.Verify(validator.GetID(), signature, msg) - if err != nil { - t.Fatalf("TestSign: failed validating signature [%s].", err) - } -} - -func TestValidatorVerify(t *testing.T) { - initNodes() - defer closeNodes() - - msg := []byte("Hello World!!!") - signature, err := validator.Sign(msg) - if err != nil { - t.Fatalf("Failed generating signature [%s].", err) - } - - err = validator.Verify(nil, signature, msg) - if err == nil { - t.Fatal("Verify should fail when given an empty id.", err) - } - - err = validator.Verify(msg, signature, msg) - if err == nil { - t.Fatal("Verify should fail when given an invalid id.", err) - } - - err = validator.Verify(validator.GetID(), nil, msg) - if err == nil { - t.Fatal("Verify should fail when given an invalid signature.", err) - } - - err = validator.Verify(validator.GetID(), msg, msg) - if err == nil { - t.Fatal("Verify should fail when given an invalid signature.", err) - } - - err = validator.Verify(validator.GetID(), signature, nil) - if err == nil { - t.Fatal("Verify should fail when given an invalid messahe.", err) - } -} - -func BenchmarkTransactionCreation(b *testing.B) { - initNodes() - defer closeNodes() - - b.StopTimer() - b.ResetTimer() - cis := &obc.ChaincodeInvocationSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - }, - } - invoker.GetTCertificateHandlerNext(attrs...) - - for i := 0; i < b.N; i++ { - uuid := util.GenerateUUID() - b.StartTimer() - invoker.NewChaincodeExecute(cis, uuid, attrs...) - b.StopTimer() - } -} - -func BenchmarkTransactionValidation(b *testing.B) { - initNodes() - defer closeNodes() - - b.StopTimer() - b.ResetTimer() - for i := 0; i < b.N; i++ { - _, tx, _ := createConfidentialTCertHExecuteTransaction(nil) - - b.StartTimer() - validator.TransactionPreValidation(tx) - validator.TransactionPreExecution(tx) - b.StopTimer() - } -} - -func BenchmarkSign(b *testing.B) { - b.StopTimer() - b.ResetTimer() - - //b.Logf("#iterations %d\n", b.N) - signKey, _ := primitives.NewECDSAKey() - hash := make([]byte, 48) - - for i := 0; i < b.N; i++ { - rand.Read(hash) - b.StartTimer() - primitives.ECDSASign(signKey, hash) - b.StopTimer() - } -} - -func BenchmarkVerify(b *testing.B) { - b.StopTimer() - b.ResetTimer() - - //b.Logf("#iterations %d\n", b.N) - signKey, _ := primitives.NewECDSAKey() - verKey := signKey.PublicKey - hash := make([]byte, 48) - - for i := 0; i < b.N; i++ { - rand.Read(hash) - sigma, _ := primitives.ECDSASign(signKey, hash) - b.StartTimer() - primitives.ECDSAVerify(&verKey, hash, sigma) - b.StopTimer() - } -} - -func setup() { - // Conf - viper.SetConfigName("crypto_test") // name of config file (without extension) - viper.AddConfigPath(".") // path to look for the config file in - err := viper.ReadInConfig() // Find and read the config file - if err != nil { // Handle errors reading the config file - panic(fmt.Errorf("Fatal error config file [%s] \n", err)) - } - - // Set Default properties - viper.Set("peer.fileSystemPath", filepath.Join(os.TempDir(), "obc-crypto-tests", "peers")) - viper.Set("server.rootpath", filepath.Join(os.TempDir(), "obc-crypto-tests", "ca")) - viper.Set("peer.pki.tls.rootcert.file", filepath.Join(os.TempDir(), "obc-crypto-tests", "ca", "tlsca.cert")) - - // Logging - var formatter = logging.MustStringFormatter( - `%{color}[%{module}] %{shortfunc} [%{shortfile}] -> %{level:.4s} %{id:03x}%{color:reset} %{message}`, - ) - logging.SetFormatter(formatter) - - // TX creators - deployTxCreators = []createTxFunc{ - createPublicDeployTransaction, - createConfidentialDeployTransaction, - createConfidentialTCertHDeployTransaction, - createConfidentialECertHDeployTransaction, - } - executeTxCreators = []createTxFunc{ - createPublicExecuteTransaction, - createConfidentialExecuteTransaction, - createConfidentialTCertHExecuteTransaction, - createConfidentialECertHExecuteTransaction, - } - queryTxCreators = []createTxFunc{ - createPublicQueryTransaction, - createConfidentialQueryTransaction, - createConfidentialTCertHQueryTransaction, - createConfidentialECertHQueryTransaction, - } - - // Init crypto layer - Init() - - // Clenaup folders - removeFolders() -} - -func initPKI() { - ca.CacheConfiguration() // Need cache the configuration first - aca = ca.NewACA() - eca = ca.NewECA(aca) - tca = ca.NewTCA(eca) - tlsca = ca.NewTLSCA(eca) -} - -func startPKI() { - var opts []grpc.ServerOption - if viper.GetBool("peer.pki.tls.enabled") { - // TLS configuration - creds, err := credentials.NewServerTLSFromFile( - filepath.Join(viper.GetString("server.rootpath"), "tlsca.cert"), - filepath.Join(viper.GetString("server.rootpath"), "tlsca.priv"), - ) - if err != nil { - panic("Failed creating credentials for OBC-CA: " + err.Error()) - } - opts = []grpc.ServerOption{grpc.Creds(creds)} - } - - fmt.Printf("open socket...\n") - sockp, err := net.Listen("tcp", viper.GetString("server.port")) - if err != nil { - panic("Cannot open port: " + err.Error()) - } - fmt.Printf("open socket...done\n") - - server = grpc.NewServer(opts...) - aca.Start(server) - eca.Start(server) - tca.Start(server) - tlsca.Start(server) - - fmt.Printf("start serving...\n") - server.Serve(sockp) -} - -func initNodes() { - // Init clients - err := initClients() - if err != nil { - panic(fmt.Errorf("Failed initializing clients [%s].", err)) - } - - // Init peer - err = initPeers() - if err != nil { - panic(fmt.Errorf("Failed initializing peers [%s].", err)) - } - - // Init validators - err = initValidators() - if err != nil { - panic(fmt.Errorf("Failed initializing validators [%s].", err)) - } - -} - -func closeNodes() { - ok, errs := CloseAllClients() - if !ok { - for _, err := range errs { - log.Errorf("Failed closing clients [%s]", err) - } - } - ok, errs = CloseAllPeers() - if !ok { - for _, err := range errs { - log.Errorf("Failed closing clients [%s]", err) - } - } - ok, errs = CloseAllValidators() -} - -func initClients() error { - // Deployer - deployerConf := utils.NodeConfiguration{Type: "client", Name: "user1"} - if err := RegisterClient(deployerConf.Name, ksPwd, deployerConf.GetEnrollmentID(), deployerConf.GetEnrollmentPWD()); err != nil { - return err - } - var err error - deployer, err = InitClient(deployerConf.Name, ksPwd) - if err != nil { - return err - } - - // Invoker - invokerConf := utils.NodeConfiguration{Type: "client", Name: "user2"} - if err = RegisterClient(invokerConf.Name, ksPwd, invokerConf.GetEnrollmentID(), invokerConf.GetEnrollmentPWD()); err != nil { - return err - } - invoker, err = InitClient(invokerConf.Name, ksPwd) - if err != nil { - return err - } - - return nil -} - -func initPeers() error { - // Register - conf := utils.NodeConfiguration{Type: "peer", Name: "peer"} - err := RegisterPeer(conf.Name, ksPwd, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()) - if err != nil { - return err - } - - // Verify that a second call to Register fails - err = RegisterPeer(conf.Name, ksPwd, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()) - if err != nil { - return err - } - - // Init - peer, err = InitPeer(conf.Name, ksPwd) - if err != nil { - return err - } - - err = RegisterPeer(conf.Name, ksPwd, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()) - if err != nil { - return err - } - - return err -} - -func initValidators() error { - // Register - conf := utils.NodeConfiguration{Type: "validator", Name: "validator"} - err := RegisterValidator(conf.Name, ksPwd, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()) - if err != nil { - return err - } - - // Verify that a second call to Register fails - err = RegisterValidator(conf.Name, ksPwd, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()) - if err != nil { - return err - } - - // Init - validator, err = InitValidator(conf.Name, ksPwd) - if err != nil { - return err - } - - err = RegisterValidator(conf.Name, ksPwd, conf.GetEnrollmentID(), conf.GetEnrollmentPWD()) - if err != nil { - return err - } - - return err -} - -func createConfidentialDeployTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cds := &obc.ChaincodeDeploymentSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - Metadata: []byte("Hello World"), - }, - EffectiveDate: nil, - CodePackage: nil, - } - - otx, err := obc.NewChaincodeDeployTransaction(cds, uuid) - otx.Metadata = cds.ChaincodeSpec.Metadata - if err != nil { - return nil, nil, err - } - tx, err := deployer.NewChaincodeDeployTransaction(cds, uuid, attrs...) - return otx, tx, err -} - -func createConfidentialExecuteTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cis := &obc.ChaincodeInvocationSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - Metadata: []byte("Hello World"), - }, - } - - otx, err := obc.NewChaincodeExecute(cis, uuid, obc.Transaction_CHAINCODE_INVOKE) - otx.Metadata = cis.ChaincodeSpec.Metadata - if err != nil { - return nil, nil, err - } - tx, err := invoker.NewChaincodeExecute(cis, uuid, attrs...) - return otx, tx, err -} - -func createConfidentialQueryTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cis := &obc.ChaincodeInvocationSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - Metadata: []byte("Hello World"), - }, - } - - otx, err := obc.NewChaincodeExecute(cis, uuid, obc.Transaction_CHAINCODE_QUERY) - otx.Metadata = cis.ChaincodeSpec.Metadata - if err != nil { - return nil, nil, err - } - tx, err := invoker.NewChaincodeQuery(cis, uuid, attrs...) - return otx, tx, err -} - -func createConfidentialTCertHDeployTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cds := &obc.ChaincodeDeploymentSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - }, - EffectiveDate: nil, - CodePackage: nil, - } - - otx, err := obc.NewChaincodeDeployTransaction(cds, uuid) - if err != nil { - return nil, nil, err - } - handler, err := deployer.GetTCertificateHandlerNext(attrs...) - if err != nil { - return nil, nil, err - } - txHandler, err := handler.GetTransactionHandler() - if err != nil { - return nil, nil, err - } - tx, err := txHandler.NewChaincodeDeployTransaction(cds, uuid, attrs...) - - // Check binding consistency - binding, err := txHandler.GetBinding() - if err != nil { - t.Fatal("Failed getting binding from transaction handler.") - } - - txBinding, err := validator.GetTransactionBinding(tx) - if err != nil { - t.Fatal("Failed getting transaction binding.") - } - - if !reflect.DeepEqual(binding, txBinding) { - t.Fatal("Binding is malformed!") - } - - // Check confidentiality level - if tx.ConfidentialityLevel != cds.ChaincodeSpec.ConfidentialityLevel { - t.Fatal("Failed setting confidentiality level") - } - - // Check metadata - if !reflect.DeepEqual(cds.ChaincodeSpec.Metadata, tx.Metadata) { - t.Fatal("Failed copying metadata") - } - - return otx, tx, err -} - -func createConfidentialTCertHExecuteTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cis := &obc.ChaincodeInvocationSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - }, - } - - otx, err := obc.NewChaincodeExecute(cis, uuid, obc.Transaction_CHAINCODE_INVOKE) - if err != nil { - return nil, nil, err - } - handler, err := invoker.GetTCertificateHandlerNext(attrs...) - - if err != nil { - return nil, nil, err - } - txHandler, err := handler.GetTransactionHandler() - if err != nil { - return nil, nil, err - } - tx, err := txHandler.NewChaincodeExecute(cis, uuid, attrs...) - - // Check binding consistency - binding, _ := txHandler.GetBinding() - if !reflect.DeepEqual(binding, primitives.Hash(append(handler.GetCertificate(), tx.Nonce...))) { - t.Fatal("Binding is malformed!") - } - - // Check confidentiality level - if tx.ConfidentialityLevel != cis.ChaincodeSpec.ConfidentialityLevel { - t.Fatal("Failed setting confidentiality level") - } - - // Check metadata - if !reflect.DeepEqual(cis.ChaincodeSpec.Metadata, tx.Metadata) { - t.Fatal("Failed copying metadata") - } - - return otx, tx, err -} - -func createConfidentialTCertHQueryTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cis := &obc.ChaincodeInvocationSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - }, - } - - otx, err := obc.NewChaincodeExecute(cis, uuid, obc.Transaction_CHAINCODE_QUERY) - if err != nil { - return nil, nil, err - } - handler, err := invoker.GetTCertificateHandlerNext(attrs...) - if err != nil { - return nil, nil, err - } - txHandler, err := handler.GetTransactionHandler() - if err != nil { - return nil, nil, err - } - tx, err := txHandler.NewChaincodeQuery(cis, uuid, attrs...) - - // Check binding consistency - binding, _ := txHandler.GetBinding() - if !reflect.DeepEqual(binding, primitives.Hash(append(handler.GetCertificate(), tx.Nonce...))) { - t.Fatal("Binding is malformed!") - } - - // Check confidentiality level - if tx.ConfidentialityLevel != cis.ChaincodeSpec.ConfidentialityLevel { - t.Fatal("Failed setting confidentiality level") - } - - // Check metadata - if !reflect.DeepEqual(cis.ChaincodeSpec.Metadata, tx.Metadata) { - t.Fatal("Failed copying metadata") - } - - return otx, tx, err -} - -func createConfidentialECertHDeployTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cds := &obc.ChaincodeDeploymentSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - }, - EffectiveDate: nil, - CodePackage: nil, - } - - otx, err := obc.NewChaincodeDeployTransaction(cds, uuid) - if err != nil { - return nil, nil, err - } - handler, err := deployer.GetEnrollmentCertificateHandler() - if err != nil { - return nil, nil, err - } - txHandler, err := handler.GetTransactionHandler() - if err != nil { - return nil, nil, err - } - tx, err := txHandler.NewChaincodeDeployTransaction(cds, uuid, attrs...) - - // Check binding consistency - binding, _ := txHandler.GetBinding() - if !reflect.DeepEqual(binding, primitives.Hash(append(handler.GetCertificate(), tx.Nonce...))) { - t.Fatal("Binding is malformed!") - } - - // Check confidentiality level - if tx.ConfidentialityLevel != cds.ChaincodeSpec.ConfidentialityLevel { - t.Fatal("Failed setting confidentiality level") - } - - // Check metadata - if !reflect.DeepEqual(cds.ChaincodeSpec.Metadata, tx.Metadata) { - t.Fatal("Failed copying metadata") - } - - return otx, tx, err -} - -func createConfidentialECertHExecuteTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cis := &obc.ChaincodeInvocationSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - }, - } - - otx, err := obc.NewChaincodeExecute(cis, uuid, obc.Transaction_CHAINCODE_INVOKE) - if err != nil { - return nil, nil, err - } - handler, err := invoker.GetEnrollmentCertificateHandler() - if err != nil { - return nil, nil, err - } - txHandler, err := handler.GetTransactionHandler() - if err != nil { - return nil, nil, err - } - tx, err := txHandler.NewChaincodeExecute(cis, uuid, attrs...) - // Check binding consistency - binding, _ := txHandler.GetBinding() - if !reflect.DeepEqual(binding, primitives.Hash(append(handler.GetCertificate(), tx.Nonce...))) { - t.Fatal("Binding is malformed!") - } - - // Check confidentiality level - if tx.ConfidentialityLevel != cis.ChaincodeSpec.ConfidentialityLevel { - t.Fatal("Failed setting confidentiality level") - } - - // Check metadata - if !reflect.DeepEqual(cis.ChaincodeSpec.Metadata, tx.Metadata) { - t.Fatal("Failed copying metadata") - } - - return otx, tx, err -} - -func createConfidentialECertHQueryTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cis := &obc.ChaincodeInvocationSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_CONFIDENTIAL, - }, - } - - otx, err := obc.NewChaincodeExecute(cis, uuid, obc.Transaction_CHAINCODE_QUERY) - if err != nil { - return nil, nil, err - } - handler, err := invoker.GetEnrollmentCertificateHandler() - if err != nil { - return nil, nil, err - } - txHandler, err := handler.GetTransactionHandler() - if err != nil { - return nil, nil, err - } - tx, err := txHandler.NewChaincodeQuery(cis, uuid, attrs...) - // Check binding consistency - binding, _ := txHandler.GetBinding() - if !reflect.DeepEqual(binding, primitives.Hash(append(handler.GetCertificate(), tx.Nonce...))) { - t.Fatal("Binding is malformed!") - } - - // Check confidentiality level - if tx.ConfidentialityLevel != cis.ChaincodeSpec.ConfidentialityLevel { - t.Fatal("Failed setting confidentiality level") - } - - // Check metadata - if !reflect.DeepEqual(cis.ChaincodeSpec.Metadata, tx.Metadata) { - t.Fatal("Failed copying metadata") - } - - return otx, tx, err -} - -func createPublicDeployTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cds := &obc.ChaincodeDeploymentSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_PUBLIC, - }, - EffectiveDate: nil, - CodePackage: nil, - } - - otx, err := obc.NewChaincodeDeployTransaction(cds, uuid) - if err != nil { - return nil, nil, err - } - tx, err := deployer.NewChaincodeDeployTransaction(cds, uuid, attrs...) - return otx, tx, err -} - -func createPublicExecuteTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cis := &obc.ChaincodeInvocationSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_PUBLIC, - }, - } - - otx, err := obc.NewChaincodeExecute(cis, uuid, obc.Transaction_CHAINCODE_INVOKE) - if err != nil { - return nil, nil, err - } - tx, err := invoker.NewChaincodeExecute(cis, uuid, attrs...) - return otx, tx, err -} - -func createPublicQueryTransaction(t *testing.T) (*obc.Transaction, *obc.Transaction, error) { - uuid := util.GenerateUUID() - - cis := &obc.ChaincodeInvocationSpec{ - ChaincodeSpec: &obc.ChaincodeSpec{ - Type: obc.ChaincodeSpec_GOLANG, - ChaincodeID: &obc.ChaincodeID{Path: "Contract001"}, - CtorMsg: nil, - ConfidentialityLevel: obc.ConfidentialityLevel_PUBLIC, - }, - } - - otx, err := obc.NewChaincodeExecute(cis, uuid, obc.Transaction_CHAINCODE_QUERY) - if err != nil { - return nil, nil, err - } - tx, err := invoker.NewChaincodeQuery(cis, uuid, attrs...) - return otx, tx, err -} - -func isEqual(src, dst *obc.Transaction) error { - if !reflect.DeepEqual(src.Payload, dst.Payload) { - return fmt.Errorf("Different Payload [%s]!=[%s].", utils.EncodeBase64(src.Payload), utils.EncodeBase64(dst.Payload)) - } - - if !reflect.DeepEqual(src.ChaincodeID, dst.ChaincodeID) { - return fmt.Errorf("Different ChaincodeID [%s]!=[%s].", utils.EncodeBase64(src.ChaincodeID), utils.EncodeBase64(dst.ChaincodeID)) - } - - if !reflect.DeepEqual(src.Metadata, dst.Metadata) { - return fmt.Errorf("Different Metadata [%s]!=[%s].", utils.EncodeBase64(src.Metadata), utils.EncodeBase64(dst.Metadata)) - } - - return nil -} - -func cleanup() { - fmt.Println("Cleanup...") - ok, errs := CloseAllClients() - if !ok { - for _, err := range errs { - log.Errorf("Failed closing clients [%s]", err) - } - } - ok, errs = CloseAllPeers() - if !ok { - for _, err := range errs { - log.Errorf("Failed closing clients [%s]", err) - } - } - ok, errs = CloseAllValidators() - if !ok { - for _, err := range errs { - log.Errorf("Failed closing clients [%s]", err) - } - } - stopPKI() - removeFolders() - fmt.Println("Cleanup...done!") -} - -func stopPKI() { - aca.Stop() - eca.Stop() - tca.Stop() - tlsca.Stop() - - server.Stop() -} - -func removeFolders() { - if err := os.RemoveAll(filepath.Join(os.TempDir(), "obc-crypto-tests")); err != nil { - fmt.Printf("Failed removing [%s] [%s]\n", "obc-crypto-tests", err) - } - -} diff --git a/core/crypto/crypto_test.yaml b/core/crypto/crypto_test.yaml deleted file mode 100644 index 9b1e25230e0..00000000000 --- a/core/crypto/crypto_test.yaml +++ /dev/null @@ -1,196 +0,0 @@ -############################################################################### -# -# CAs section -# -############################################################################### -server: - version: "0.1" - port: ":50541" - - -security: - # Can be 256 or 384 - # Must be the same as in core.yaml - level: 256 - - # Enable/Disable multithread - multithreading: - enabled: false - - # TCerts related configuration - tcert: - batch: - # The size of the batch of TCerts - size: 200 - level: 256 - hashAlgorithm: SHA3 - -eca: - affiliations: - banks_and_institutions: - banks: - - bank_a - - bank_b - - bank_c - institutions: - - institution_a - - users: - # clients - userthread: 1 9gvZQRwhUq9q bank_a - user1: 1 9gvZQRwhUq9q bank_a - user2: 1 9gvZQRwhUq9q bank_a - TestRegistrationSameEnrollIDDifferentRole: 1 9gvZQRwhUq9q bank_a - - # peers - peer: 2 9gvZQRwhUq9q bank_a - peerthread: 2 9gvZQRwhUq9q bank_a - - # validators - validator: 4 9gvZQRwhUq9q bank_a - validatorthread: 4 9gvZQRwhUq9q bank_a - -tca: - attribute-encryption: - enabled: true - -aca: - attributes: - attribute-entry-0: user1;bank_a;company;ACompany;2015-01-01T00:00:00-03:00;; - attribute-entry-1: user1;bank_a;position;Software Staff;2015-01-01T00:00:00-03:00;2015-07-12T23:59:59-03:00; - attribute-entry-2: user1;bank_a;position;Software Engineer;2015-07-13T00:00:00-03:00;; - attribute-entry-3: user2;bank_a;company;ACompany;2001-02-02T00:00:00-03:00;; - attribute-entry-4: user2;bank_a;position;Project Manager;2001-02-02T00:00:00-03:00;; - address: localhost:50541 - server-name: acap - enabled: true - - -############################################################################### -# -# Peer section -# -############################################################################### - - -peer: - pki: - eca: - paddr: localhost:50541 - - tca: - paddr: localhost:50541 - - tlsca: - paddr: localhost:50541 - - tls: - enabled: false - rootcert: - - # The server name use to verify the hostname returned by TLS handshake - serverhostoverride: - - validator: - enabled: false - -############################################################################### -# -# Security section - Applied to all entities (client, NVP, VP) -# -############################################################################### -security: - # TCerts related configuration - tcert: - batch: - # The size of the batch of TCerts - size: 10 - attributes: - company: ACompany - position: "Software Engineer" - abac: - enabled: true - level: 256 - hashAlgorithm: SHA3 - -############################################################################### -# -# Test parameters section -# -############################################################################### - -logging: - - # Valid logging levels are case-insensitive strings chosen from - - # CRITICAL | ERROR | WARNING | NOTICE | INFO | DEBUG - - # Logging 'module' names are also strings, however valid module names are - # defined at runtime and are not checked for validity during option - # processing. - - # Default logging levels are specified here for each of the obc-peer - # commands. For commands that have subcommands, the defaults also apply to - # all subcommands of the command. These logging levels can be overridden - # on the command line using the --logging-level command-line option, or by - # setting the CORE_LOGGING_LEVEL environment variable. - - # The logging level specification is of the form - - # [[,...]=][:[[,...]=]...] - - # A logging level by itself is taken as the overall default. Otherwise, - # overrides for individual or groups of modules can be specified using the - # [,...]= syntax. - - # Examples: - # info - Set default to INFO - # warning:main,db=debug:chaincode=info - Override default WARNING in main,db,chaincode - # chaincode=info:main=debug:db=debug:warning - Same as above - peer: info - crypto: info - status: warning - stop: warning - login: warning - vm: warning - chaincode: warning - - - -tests: - - crypto: - - users: - - user1: - enrollid: user1 - enrollpw: 9gvZQRwhUq9q - - user2: - enrollid: user2 - enrollpw: 9gvZQRwhUq9q - - validator: - enrollid: validator - enrollpw: 9gvZQRwhUq9q - - validatorthread: - enrollid: validatorthread - enrollpw: 9gvZQRwhUq9q - - peer: - enrollid: peer - enrollpw: 9gvZQRwhUq9q - - peerthread: - enrollid: peerthread - enrollpw: 9gvZQRwhUq9q - - TestRegistrationSameEnrollIDDifferentRole: - enrollid: TestRegistrationSameEnrollIDDifferentRole - enrollpw: 9gvZQRwhUq9q - - userthread: - enrollid: userthread - enrollpw: 9gvZQRwhUq9q diff --git a/core/crypto/node.go b/core/crypto/node.go deleted file mode 100644 index c397e01a95c..00000000000 --- a/core/crypto/node.go +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -// Utility functions - -func eTypeToString(eType NodeType) string { - switch eType { - case NodeClient: - return "client" - case NodePeer: - return "peer" - case NodeValidator: - return "validator" - } - return "Invalid Type" -} diff --git a/core/crypto/node_conf.go b/core/crypto/node_conf.go deleted file mode 100644 index a9382282ef0..00000000000 --- a/core/crypto/node_conf.go +++ /dev/null @@ -1,308 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "errors" - "path/filepath" - - "github.com/spf13/viper" -) - -func (node *nodeImpl) initConfiguration(name string) (err error) { - // Set logger - prefix := eTypeToString(node.eType) - - // Set configuration - node.conf = &configuration{prefix: prefix, name: name} - if err = node.conf.init(); err != nil { - return - } - - node.Debugf("Data will be stored at [%s]", node.conf.configurationPath) - - return -} - -type configuration struct { - prefix string - name string - - logPrefix string - - rootDataPath string - configurationPath string - keystorePath string - rawsPath string - tCertsPath string - - configurationPathProperty string - ecaPAddressProperty string - tcaPAddressProperty string - tlscaPAddressProperty string - - securityLevel int - hashAlgorithm string - confidentialityProtocolVersion string - - tlsServerName string - - multiThreading bool - multiChannel bool - - tCertBatchSize int -} - -func (conf *configuration) init() error { - conf.configurationPathProperty = "peer.fileSystemPath" - conf.ecaPAddressProperty = "peer.pki.eca.paddr" - conf.tcaPAddressProperty = "peer.pki.tca.paddr" - conf.tlscaPAddressProperty = "peer.pki.tlsca.paddr" - conf.logPrefix = "[" + conf.prefix + "." + conf.name + "] " - - // Check mandatory fields - if err := conf.checkProperty(conf.configurationPathProperty); err != nil { - return err - } - if err := conf.checkProperty(conf.ecaPAddressProperty); err != nil { - return err - } - if err := conf.checkProperty(conf.tcaPAddressProperty); err != nil { - return err - } - if err := conf.checkProperty(conf.tlscaPAddressProperty); err != nil { - return err - } - - conf.configurationPath = viper.GetString(conf.configurationPathProperty) - conf.rootDataPath = conf.configurationPath - - // Set configuration path - conf.configurationPath = filepath.Join( - conf.configurationPath, - "crypto", conf.prefix, conf.name, - ) - - // Set ks path - conf.keystorePath = filepath.Join(conf.configurationPath, "ks") - - // Set raws path - conf.rawsPath = filepath.Join(conf.keystorePath, "raw") - - // Set tCerts path - conf.tCertsPath = filepath.Join(conf.keystorePath, "tcerts") - - conf.securityLevel = 384 - if viper.IsSet("security.level") { - ovveride := viper.GetInt("security.level") - if ovveride != 0 { - conf.securityLevel = ovveride - } - } - - conf.hashAlgorithm = "SHA3" - if viper.IsSet("security.hashAlgorithm") { - ovveride := viper.GetString("security.hashAlgorithm") - if ovveride != "" { - conf.hashAlgorithm = ovveride - } - } - - conf.confidentialityProtocolVersion = "1.2" - if viper.IsSet("security.confidentialityProtocolVersion") { - ovveride := viper.GetString("security.confidentialityProtocolVersion") - if ovveride != "" { - conf.confidentialityProtocolVersion = ovveride - } - } - - // Set TLS host override - conf.tlsServerName = "tlsca" - if viper.IsSet("peer.pki.tls.serverhostoverride") { - ovveride := viper.GetString("peer.pki.tls.serverhostoverride") - if ovveride != "" { - conf.tlsServerName = ovveride - } - } - - // Set tCertBatchSize - conf.tCertBatchSize = 200 - if viper.IsSet("security.tcert.batch.size") { - ovveride := viper.GetInt("security.tcert.batch.size") - if ovveride != 0 { - conf.tCertBatchSize = ovveride - } - } - - // Set multithread - conf.multiThreading = false - if viper.IsSet("security.multithreading.enabled") { - conf.multiThreading = viper.GetBool("security.multithreading.enabled") - } - - // Set multichannel - conf.multiChannel = false - if viper.IsSet("security.multithreading.multichannel") { - conf.multiChannel = viper.GetBool("security.multithreading.multichannel") - } - - return nil -} - -func (conf *configuration) checkProperty(property string) error { - res := viper.GetString(property) - if res == "" { - return errors.New("Property not specified in configuration file. Please check that property is set: " + property) - } - return nil -} - -func (conf *configuration) getTCAPAddr() string { - return viper.GetString(conf.tcaPAddressProperty) -} - -func (conf *configuration) getECAPAddr() string { - return viper.GetString(conf.ecaPAddressProperty) -} - -func (conf *configuration) getTLSCAPAddr() string { - return viper.GetString(conf.tlscaPAddressProperty) -} - -func (conf *configuration) getConfPath() string { - return conf.configurationPath -} - -func (conf *configuration) getTCertsPath() string { - return conf.tCertsPath -} - -func (conf *configuration) getKeyStorePath() string { - return conf.keystorePath -} - -func (conf *configuration) getRootDatastorePath() string { - return conf.rootDataPath -} - -func (conf *configuration) getRawsPath() string { - return conf.rawsPath -} - -func (conf *configuration) getKeyStoreFilename() string { - return "db" -} - -func (conf *configuration) getKeyStoreFilePath() string { - return filepath.Join(conf.getKeyStorePath(), conf.getKeyStoreFilename()) -} - -func (conf *configuration) getPathForAlias(alias string) string { - return filepath.Join(conf.getRawsPath(), alias) -} - -func (conf *configuration) getQueryStateKeyFilename() string { - return "query.key" -} - -func (conf *configuration) getEnrollmentKeyFilename() string { - return "enrollment.key" -} - -func (conf *configuration) getEnrollmentCertFilename() string { - return "enrollment.cert" -} - -func (conf *configuration) getEnrollmentIDPath() string { - return filepath.Join(conf.getRawsPath(), conf.getEnrollmentIDFilename()) -} - -func (conf *configuration) getEnrollmentIDFilename() string { - return "enrollment.id" -} - -func (conf *configuration) getTCACertsChainFilename() string { - return "tca.cert.chain" -} - -func (conf *configuration) getECACertsChainFilename() string { - return "eca.cert.chain" -} - -func (conf *configuration) getTLSCACertsChainFilename() string { - return "tlsca.cert.chain" -} - -func (conf *configuration) getTLSCACertsExternalPath() string { - return viper.GetString("peer.pki.tls.rootcert.file") -} - -func (conf *configuration) isTLSEnabled() bool { - return viper.GetBool("peer.pki.tls.enabled") -} - -func (conf *configuration) isTLSClientAuthEnabled() bool { - return viper.GetBool("peer.pki.tls.client.auth.enabled") -} - -func (conf *configuration) IsMultithreadingEnabled() bool { - return conf.multiThreading -} - -func (conf *configuration) IsMultiChannelEnabled() bool { - return conf.multiChannel -} - -func (conf *configuration) getTCAServerName() string { - return conf.tlsServerName -} - -func (conf *configuration) getECAServerName() string { - return conf.tlsServerName -} - -func (conf *configuration) getTLSCAServerName() string { - return conf.tlsServerName -} - -func (conf *configuration) getTLSKeyFilename() string { - return "tls.key" -} - -func (conf *configuration) getTLSCertFilename() string { - return "tls.cert" -} - -func (conf *configuration) getTLSRootCertFilename() string { - return "tls.cert.chain" -} - -func (conf *configuration) getEnrollmentChainKeyFilename() string { - return "chain.key" -} - -func (conf *configuration) getTCertOwnerKDFKeyFilename() string { - return "tca.kdf.key" -} - -func (conf *configuration) getTCertBatchSize() int { - return conf.tCertBatchSize -} - -func (conf *configuration) GetConfidentialityProtocolVersion() string { - return conf.confidentialityProtocolVersion -} diff --git a/core/crypto/node_crypto.go b/core/crypto/node_crypto.go deleted file mode 100644 index 014c75ab257..00000000000 --- a/core/crypto/node_crypto.go +++ /dev/null @@ -1,121 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/x509" - - ecies "github.com/hyperledger/fabric/core/crypto/primitives/ecies" -) - -func (node *nodeImpl) registerCryptoEngine(enrollID, enrollPWD string) error { - node.Debug("Registering node crypto engine...") - - // Init CLI - node.eciesSPI = ecies.NewSPI() - - if err := node.initTLS(); err != nil { - node.Errorf("Failed initliazing TLS [%s].", err.Error()) - - return err - } - - if err := node.retrieveECACertsChain(enrollID); err != nil { - node.Errorf("Failed retrieving ECA certs chain [%s].", err.Error()) - - return err - } - - if err := node.retrieveTCACertsChain(enrollID); err != nil { - node.Errorf("Failed retrieving ECA certs chain [%s].", err.Error()) - - return err - } - - if err := node.retrieveEnrollmentData(enrollID, enrollPWD); err != nil { - node.Errorf("Failed retrieving enrollment data [%s].", err.Error()) - - return err - } - - if err := node.retrieveTLSCertificate(enrollID, enrollPWD); err != nil { - node.Errorf("Failed retrieving enrollment data: %s", err) - - return err - } - - node.Debug("Registering node crypto engine...done!") - - return nil -} - -func (node *nodeImpl) initCryptoEngine() error { - node.Debug("Initializing node crypto engine...") - - // Init CLI - node.eciesSPI = ecies.NewSPI() - - // Init certPools - node.rootsCertPool = x509.NewCertPool() - node.tlsCertPool = x509.NewCertPool() - node.ecaCertPool = x509.NewCertPool() - node.tcaCertPool = x509.NewCertPool() - - // Load ECA certs chain - if err := node.loadECACertsChain(); err != nil { - return err - } - - // Load TCA certs chain - if err := node.loadTCACertsChain(); err != nil { - return err - } - - // Load enrollment secret key - if err := node.loadEnrollmentKey(); err != nil { - return err - } - - // Load enrollment certificate and set validator ID - if err := node.loadEnrollmentCertificate(); err != nil { - return err - } - - // Load enrollment id - if err := node.loadEnrollmentID(); err != nil { - return err - } - - // Load enrollment chain key - if err := node.loadEnrollmentChainKey(); err != nil { - return err - } - - // Load TLS certs chain certificate - if err := node.loadTLSCACertsChain(); err != nil { - return err - } - - // Load tls certificate - if err := node.loadTLSCertificate(); err != nil { - return err - } - - node.Debug("Initializing node crypto engine...done!") - - return nil -} diff --git a/core/crypto/node_eca.go b/core/crypto/node_eca.go deleted file mode 100644 index 2c29fdd2d76..00000000000 --- a/core/crypto/node_eca.go +++ /dev/null @@ -1,485 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/ecdsa" - "crypto/rand" - "crypto/x509" - "time" - - membersrvc "github.com/hyperledger/fabric/membersrvc/protos" - - "encoding/asn1" - "errors" - "io/ioutil" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/primitives/ecies" - "golang.org/x/net/context" - "google.golang.org/grpc" -) - -var ( - // ECertSubjectRole is the ASN1 object identifier of the subject's role. - ECertSubjectRole = asn1.ObjectIdentifier{2, 1, 3, 4, 5, 6, 7} -) - -func (node *nodeImpl) retrieveECACertsChain(userID string) error { - if !node.ks.certMissing(node.conf.getECACertsChainFilename()) { - return nil - } - - // Retrieve ECA certificate and verify it - ecaCertRaw, err := node.getECACertificate() - if err != nil { - node.Errorf("Failed getting ECA certificate [%s].", err.Error()) - - return err - } - node.Debugf("ECA certificate [% x].", ecaCertRaw) - - // TODO: Test ECA cert againt root CA - // TODO: check response.Cert against rootCA - x509ECACert, err := primitives.DERToX509Certificate(ecaCertRaw) - if err != nil { - node.Errorf("Failed parsing ECA certificate [%s].", err.Error()) - - return err - } - - // Prepare ecaCertPool - node.ecaCertPool = x509.NewCertPool() - node.ecaCertPool.AddCert(x509ECACert) - - // Store ECA cert - node.Debugf("Storing ECA certificate for [%s]...", userID) - - if err := node.ks.storeCert(node.conf.getECACertsChainFilename(), ecaCertRaw); err != nil { - node.Errorf("Failed storing eca certificate [%s].", err.Error()) - return err - } - - return nil -} - -func (node *nodeImpl) retrieveEnrollmentData(enrollID, enrollPWD string) error { - if !node.ks.certMissing(node.conf.getEnrollmentCertFilename()) { - return nil - } - - key, enrollCertRaw, enrollChainKey, err := node.getEnrollmentCertificateFromECA(enrollID, enrollPWD) - if err != nil { - node.Errorf("Failed getting enrollment certificate [id=%s]: [%s]", enrollID, err) - - return err - } - node.Debugf("Enrollment certificate [% x].", enrollCertRaw) - - node.Debugf("Storing enrollment data for user [%s]...", enrollID) - - // Store enrollment id - err = ioutil.WriteFile(node.conf.getEnrollmentIDPath(), []byte(enrollID), 0700) - if err != nil { - node.Errorf("Failed storing enrollment certificate [id=%s]: [%s]", enrollID, err) - return err - } - - // Store enrollment key - if err := node.ks.storePrivateKey(node.conf.getEnrollmentKeyFilename(), key); err != nil { - node.Errorf("Failed storing enrollment key [id=%s]: [%s]", enrollID, err) - return err - } - - // Store enrollment cert - if err := node.ks.storeCert(node.conf.getEnrollmentCertFilename(), enrollCertRaw); err != nil { - node.Errorf("Failed storing enrollment certificate [id=%s]: [%s]", enrollID, err) - return err - } - - // Code for confidentiality 1.2 - // Store enrollment chain key - if node.eType == NodeValidator { - node.Debugf("Enrollment chain key for validator [%s]...", enrollID) - // enrollChainKey is a secret key - - node.Debugf("key [%s]...", string(enrollChainKey)) - - key, err := primitives.PEMtoPrivateKey(enrollChainKey, nil) - if err != nil { - node.Errorf("Failed unmarshalling enrollment chain key [id=%s]: [%s]", enrollID, err) - return err - } - - if err := node.ks.storePrivateKey(node.conf.getEnrollmentChainKeyFilename(), key); err != nil { - node.Errorf("Failed storing enrollment chain key [id=%s]: [%s]", enrollID, err) - return err - } - } else { - node.Debugf("Enrollment chain key for non-validator [%s]...", enrollID) - // enrollChainKey is a public key - - key, err := primitives.PEMtoPublicKey(enrollChainKey, nil) - if err != nil { - node.Errorf("Failed unmarshalling enrollment chain key [id=%s]: [%s]", enrollID, err) - return err - } - node.Debugf("Key decoded from PEM [%s]...", enrollID) - - if err := node.ks.storePublicKey(node.conf.getEnrollmentChainKeyFilename(), key); err != nil { - node.Errorf("Failed storing enrollment chain key [id=%s]: [%s]", enrollID, err) - return err - } - } - - return nil -} - -func (node *nodeImpl) loadEnrollmentKey() error { - node.Debug("Loading enrollment key...") - - enrollPrivKey, err := node.ks.loadPrivateKey(node.conf.getEnrollmentKeyFilename()) - if err != nil { - node.Errorf("Failed loading enrollment private key [%s].", err.Error()) - - return err - } - - node.enrollPrivKey = enrollPrivKey.(*ecdsa.PrivateKey) - - return nil -} - -func (node *nodeImpl) loadEnrollmentCertificate() error { - node.Debug("Loading enrollment certificate...") - - cert, der, err := node.ks.loadCertX509AndDer(node.conf.getEnrollmentCertFilename()) - if err != nil { - node.Errorf("Failed parsing enrollment certificate [%s].", err.Error()) - - return err - } - node.enrollCert = cert - - // TODO: move this to retrieve - pk := node.enrollCert.PublicKey.(*ecdsa.PublicKey) - err = primitives.VerifySignCapability(node.enrollPrivKey, pk) - if err != nil { - node.Errorf("Failed checking enrollment certificate against enrollment key [%s].", err.Error()) - - return err - } - - // Set node ID - node.id = primitives.Hash(der) - node.Debugf("Setting id to [% x].", node.id) - - // Set eCertHash - node.enrollCertHash = primitives.Hash(der) - node.Debugf("Setting enrollCertHash to [% x].", node.enrollCertHash) - - return nil -} - -func (node *nodeImpl) loadEnrollmentID() error { - node.Debugf("Loading enrollment id at [%s]...", node.conf.getEnrollmentIDPath()) - - enrollID, err := ioutil.ReadFile(node.conf.getEnrollmentIDPath()) - if err != nil { - node.Errorf("Failed loading enrollment id [%s].", err.Error()) - - return err - } - - // Set enrollment ID - node.enrollID = string(enrollID) - node.Debugf("Setting enrollment id to [%s].", node.enrollID) - - return nil -} - -func (node *nodeImpl) loadEnrollmentChainKey() error { - node.Debug("Loading enrollment chain key...") - - // Code for confidentiality 1.2 - if node.eType == NodeValidator { - // enrollChainKey is a secret key - enrollChainKey, err := node.ks.loadPrivateKey(node.conf.getEnrollmentChainKeyFilename()) - if err != nil { - node.Errorf("Failed loading enrollment chain key: [%s]", err) - return err - } - node.enrollChainKey = enrollChainKey - } else { - // enrollChainKey is a public key - enrollChainKey, err := node.ks.loadPublicKey(node.conf.getEnrollmentChainKeyFilename()) - if err != nil { - node.Errorf("Failed load enrollment chain key: [%s]", err) - return err - } - node.enrollChainKey = enrollChainKey - } - - return nil -} - -func (node *nodeImpl) loadECACertsChain() error { - node.Debug("Loading ECA certificates chain...") - - pem, err := node.ks.loadCert(node.conf.getECACertsChainFilename()) - if err != nil { - node.Errorf("Failed loading ECA certificates chain [%s].", err.Error()) - - return err - } - - ok := node.ecaCertPool.AppendCertsFromPEM(pem) - if !ok { - node.Error("Failed appending ECA certificates chain.") - - return errors.New("Failed appending ECA certificates chain.") - } - - return nil -} - -func (node *nodeImpl) getECAClient() (*grpc.ClientConn, membersrvc.ECAPClient, error) { - node.Debug("Getting ECA client...") - - conn, err := node.getClientConn(node.conf.getECAPAddr(), node.conf.getECAServerName()) - if err != nil { - node.Errorf("Failed getting client connection: [%s]", err) - } - - client := membersrvc.NewECAPClient(conn) - - node.Debug("Getting ECA client...done") - - return conn, client, nil -} - -func (node *nodeImpl) callECAReadCACertificate(ctx context.Context, opts ...grpc.CallOption) (*membersrvc.Cert, error) { - // Get an ECA Client - sock, ecaP, err := node.getECAClient() - defer sock.Close() - - // Issue the request - cert, err := ecaP.ReadCACertificate(ctx, &membersrvc.Empty{}, opts...) - if err != nil { - node.Errorf("Failed requesting read certificate [%s].", err.Error()) - - return nil, err - } - - return cert, nil -} - -func (node *nodeImpl) callECAReadCertificate(ctx context.Context, in *membersrvc.ECertReadReq, opts ...grpc.CallOption) (*membersrvc.CertPair, error) { - // Get an ECA Client - sock, ecaP, err := node.getECAClient() - defer sock.Close() - - // Issue the request - resp, err := ecaP.ReadCertificatePair(ctx, in, opts...) - if err != nil { - node.Errorf("Failed requesting read certificate [%s].", err.Error()) - - return nil, err - } - - return resp, nil -} - -func (node *nodeImpl) callECAReadCertificateByHash(ctx context.Context, in *membersrvc.Hash, opts ...grpc.CallOption) (*membersrvc.CertPair, error) { - // Get an ECA Client - sock, ecaP, err := node.getECAClient() - defer sock.Close() - - // Issue the request - resp, err := ecaP.ReadCertificateByHash(ctx, in, opts...) - if err != nil { - node.Errorf("Failed requesting read certificate [%s].", err.Error()) - - return nil, err - } - - return &membersrvc.CertPair{Sign: resp.Cert, Enc: nil}, nil -} - -func (node *nodeImpl) getEnrollmentCertificateFromECA(id, pw string) (interface{}, []byte, []byte, error) { - // Get a new ECA Client - sock, ecaP, err := node.getECAClient() - defer sock.Close() - - // Run the protocol - - signPriv, err := primitives.NewECDSAKey() - if err != nil { - node.Errorf("Failed generating ECDSA key [%s].", err.Error()) - - return nil, nil, nil, err - } - signPub, err := x509.MarshalPKIXPublicKey(&signPriv.PublicKey) - if err != nil { - node.Errorf("Failed mashalling ECDSA key [%s].", err.Error()) - - return nil, nil, nil, err - } - - encPriv, err := primitives.NewECDSAKey() - if err != nil { - node.Errorf("Failed generating Encryption key [%s].", err.Error()) - - return nil, nil, nil, err - } - encPub, err := x509.MarshalPKIXPublicKey(&encPriv.PublicKey) - if err != nil { - node.Errorf("Failed marshalling Encryption key [%s].", err.Error()) - - return nil, nil, nil, err - } - - req := &membersrvc.ECertCreateReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &membersrvc.Identity{Id: id}, - Tok: &membersrvc.Token{Tok: []byte(pw)}, - Sign: &membersrvc.PublicKey{Type: membersrvc.CryptoType_ECDSA, Key: signPub}, - Enc: &membersrvc.PublicKey{Type: membersrvc.CryptoType_ECDSA, Key: encPub}, - Sig: nil} - - resp, err := ecaP.CreateCertificatePair(context.Background(), req) - if err != nil { - node.Errorf("Failed invoking CreateCertficatePair [%s].", err.Error()) - - return nil, nil, nil, err - } - - if resp.FetchResult != nil && resp.FetchResult.Status != membersrvc.FetchAttrsResult_SUCCESS { - node.Warning(resp.FetchResult.Msg) - } - //out, err := rsa.DecryptPKCS1v15(rand.Reader, encPriv, resp.Tok.Tok) - spi := ecies.NewSPI() - eciesKey, err := spi.NewPrivateKey(nil, encPriv) - if err != nil { - node.Errorf("Failed parsing decrypting key [%s].", err.Error()) - - return nil, nil, nil, err - } - - ecies, err := spi.NewAsymmetricCipherFromPublicKey(eciesKey) - if err != nil { - node.Errorf("Failed creating asymmetrinc cipher [%s].", err.Error()) - - return nil, nil, nil, err - } - - out, err := ecies.Process(resp.Tok.Tok) - if err != nil { - node.Errorf("Failed decrypting toke [%s].", err.Error()) - - return nil, nil, nil, err - } - - req.Tok.Tok = out - req.Sig = nil - - hash := primitives.NewHash() - raw, _ := proto.Marshal(req) - hash.Write(raw) - - r, s, err := ecdsa.Sign(rand.Reader, signPriv, hash.Sum(nil)) - if err != nil { - node.Errorf("Failed signing [%s].", err.Error()) - - return nil, nil, nil, err - } - R, _ := r.MarshalText() - S, _ := s.MarshalText() - req.Sig = &membersrvc.Signature{Type: membersrvc.CryptoType_ECDSA, R: R, S: S} - - resp, err = ecaP.CreateCertificatePair(context.Background(), req) - if err != nil { - node.Errorf("Failed invoking CreateCertificatePair [%s].", err.Error()) - - return nil, nil, nil, err - } - - // Verify response - - // Verify cert for signing - node.Debugf("Enrollment certificate for signing [% x]", primitives.Hash(resp.Certs.Sign)) - - x509SignCert, err := primitives.DERToX509Certificate(resp.Certs.Sign) - if err != nil { - node.Errorf("Failed parsing signing enrollment certificate for signing: [%s]", err) - - return nil, nil, nil, err - } - - _, err = primitives.GetCriticalExtension(x509SignCert, ECertSubjectRole) - if err != nil { - node.Errorf("Failed parsing ECertSubjectRole in enrollment certificate for signing: [%s]", err) - - return nil, nil, nil, err - } - - err = primitives.CheckCertAgainstSKAndRoot(x509SignCert, signPriv, node.ecaCertPool) - if err != nil { - node.Errorf("Failed checking signing enrollment certificate for signing: [%s]", err) - - return nil, nil, nil, err - } - - // Verify cert for encrypting - node.Debugf("Enrollment certificate for encrypting [% x]", primitives.Hash(resp.Certs.Enc)) - - x509EncCert, err := primitives.DERToX509Certificate(resp.Certs.Enc) - if err != nil { - node.Errorf("Failed parsing signing enrollment certificate for encrypting: [%s]", err) - - return nil, nil, nil, err - } - - _, err = primitives.GetCriticalExtension(x509EncCert, ECertSubjectRole) - if err != nil { - node.Errorf("Failed parsing ECertSubjectRole in enrollment certificate for encrypting: [%s]", err) - - return nil, nil, nil, err - } - - err = primitives.CheckCertAgainstSKAndRoot(x509EncCert, encPriv, node.ecaCertPool) - if err != nil { - node.Errorf("Failed checking signing enrollment certificate for encrypting: [%s]", err) - - return nil, nil, nil, err - } - - return signPriv, resp.Certs.Sign, resp.Pkchain, nil -} - -func (node *nodeImpl) getECACertificate() ([]byte, error) { - responce, err := node.callECAReadCACertificate(context.Background()) - if err != nil { - node.Errorf("Failed requesting ECA certificate [%s].", err.Error()) - - return nil, err - } - - return responce.Cert, nil -} diff --git a/core/crypto/node_grpc.go b/core/crypto/node_grpc.go deleted file mode 100644 index 9d1fcb6b0f1..00000000000 --- a/core/crypto/node_grpc.go +++ /dev/null @@ -1,75 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/tls" - "crypto/x509" - "errors" - - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - - "github.com/hyperledger/fabric/core/comm" -) - -func (node *nodeImpl) initTLS() error { - node.Debug("Initiliazing TLS...") - - if node.conf.isTLSEnabled() { - pem, err := node.ks.loadExternalCert(node.conf.getTLSCACertsExternalPath()) - if err != nil { - node.Errorf("Failed loading TLSCA certificates chain [%s].", err.Error()) - - return err - } - - node.tlsCertPool = x509.NewCertPool() - ok := node.tlsCertPool.AppendCertsFromPEM(pem) - if !ok { - node.Error("Failed appending TLSCA certificates chain.") - - return errors.New("Failed appending TLSCA certificates chain.") - } - node.Debug("Initiliazing TLS...Done") - } else { - node.Debug("Initiliazing TLS...Disabled!!!") - } - - return nil -} - -func (node *nodeImpl) getClientConn(address string, serverName string) (*grpc.ClientConn, error) { - node.Debugf("Dial to addr:[%s], with serverName:[%s]...", address, serverName) - - if node.conf.isTLSEnabled() { - node.Debug("TLS enabled...") - - config := tls.Config{ - InsecureSkipVerify: false, - RootCAs: node.tlsCertPool, - ServerName: serverName, - } - if node.conf.isTLSClientAuthEnabled() { - - } - - return comm.NewClientConnectionWithAddress(address, false, true, credentials.NewTLS(&config)) - } - node.Debug("TLS disabled...") - return comm.NewClientConnectionWithAddress(address, false, false, nil) -} diff --git a/core/crypto/node_impl.go b/core/crypto/node_impl.go deleted file mode 100644 index 5fff6479cef..00000000000 --- a/core/crypto/node_impl.go +++ /dev/null @@ -1,213 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/ecdsa" - "crypto/x509" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" -) - -// Public Struct - -type nodeImpl struct { - isRegistered bool - isInitialized bool - - // Node type - eType NodeType - - // Configuration - conf *configuration - - // keyStore - ks *keyStore - - // Certs Pool - rootsCertPool *x509.CertPool - tlsCertPool *x509.CertPool - ecaCertPool *x509.CertPool - tcaCertPool *x509.CertPool - - // 48-bytes identifier - id []byte - - // Enrollment Certificate and private key - enrollID string - enrollCert *x509.Certificate - enrollPrivKey *ecdsa.PrivateKey - enrollCertHash []byte - - // Enrollment Chain - enrollChainKey interface{} - - // TLS - tlsCert *x509.Certificate - - // Crypto SPI - eciesSPI primitives.AsymmetricCipherSPI -} - -type registerFunc func(eType NodeType, name string, pwd []byte, enrollID, enrollPWD string) error -type initalizationFunc func(eType NodeType, name string, pwd []byte) error - -func (node *nodeImpl) GetType() NodeType { - return node.eType -} - -func (node *nodeImpl) GetName() string { - return node.conf.name -} - -func (node *nodeImpl) IsInitialized() bool { - return node.isInitialized -} - -func (node *nodeImpl) setInitialized() { - node.isInitialized = true -} - -func (node *nodeImpl) IsRegistered() bool { - return node.isRegistered -} - -func (node *nodeImpl) setRegistered() { - node.isRegistered = true -} - -func (node *nodeImpl) register(eType NodeType, name string, pwd []byte, enrollID, enrollPWD string, regFunc registerFunc) error { - // Set entity type - node.eType = eType - - // Init Conf - if err := node.initConfiguration(name); err != nil { - node.Errorf("Failed initiliazing configuration [%s]: [%s].", enrollID, err) - return err - } - - // Initialize keystore - err := node.initKeyStore(pwd) - if err != nil { - if err == utils.ErrKeyStoreAlreadyInitialized { - node.Error("Keystore already initialized.") - } else { - node.Errorf("Failed initiliazing keystore [%s].", err.Error()) - } - return err - } - - if node.IsRegistered() { - return utils.ErrAlreadyRegistered - } - if node.IsInitialized() { - return utils.ErrAlreadyInitialized - } - - err = node.nodeRegister(eType, name, pwd, enrollID, enrollPWD) - if err != nil { - return err - } - - if regFunc != nil { - err = regFunc(eType, name, pwd, enrollID, enrollPWD) - if err != nil { - return err - } - } - - node.setRegistered() - node.Debugf("Registration of node [%s] with name [%s] completed", eType, name) - - return nil -} - -func (node *nodeImpl) nodeRegister(eType NodeType, name string, pwd []byte, enrollID, enrollPWD string) error { - // Register crypto engine - err := node.registerCryptoEngine(enrollID, enrollPWD) - if err != nil { - node.Errorf("Failed registering node crypto engine [%s].", err.Error()) - return err - } - - return nil -} - -func (node *nodeImpl) init(eType NodeType, name string, pwd []byte, initFunc initalizationFunc) error { - // Set entity type - node.eType = eType - - // Init Conf - if err := node.initConfiguration(name); err != nil { - node.Errorf("Failed initiliazing configuration: [%s]", err) - return err - } - - // Initialize keystore - err := node.initKeyStore(pwd) - if err != nil { - if err == utils.ErrKeyStoreAlreadyInitialized { - node.Error("Keystore already initialized.") - } else { - node.Errorf("Failed initiliazing keystore [%s].", err.Error()) - } - return err - } - - if node.IsInitialized() { - return utils.ErrAlreadyInitialized - } - - err = node.nodeInit(eType, name, pwd) - if err != nil { - return err - } - - if initFunc != nil { - err = initFunc(eType, name, pwd) - if err != nil { - return err - } - } - - node.setInitialized() - - return nil -} - -func (node *nodeImpl) nodeInit(eType NodeType, name string, pwd []byte) error { - // Init crypto engine - err := node.initCryptoEngine() - if err != nil { - node.Errorf("Failed initiliazing crypto engine [%s]. %s", err.Error(), utils.ErrRegistrationRequired.Error()) - return err - } - - return nil -} - -func (node *nodeImpl) close() error { - // Close keystore - var err error - - if node.ks != nil { - err = node.ks.close() - } - - return err -} diff --git a/core/crypto/node_ks.go b/core/crypto/node_ks.go deleted file mode 100644 index 1a12d7cb32e..00000000000 --- a/core/crypto/node_ks.go +++ /dev/null @@ -1,415 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/x509" - "database/sql" - "io/ioutil" - "os" - "path/filepath" - "sync" - - "github.com/hyperledger/fabric/core/crypto/utils" - - // Required to successfully initialized the driver - "github.com/hyperledger/fabric/core/crypto/primitives" - _ "github.com/mattn/go-sqlite3" -) - -/* -var ( - defaultCerts = make(map[string][]byte) -) - -func addDefaultCert(key string, cert []byte) error { - log.Debugf("Adding Default Cert [%s][%s]", key, utils.EncodeBase64(cert)) - - der, err := utils.PEMtoDER(cert) - if err != nil { - log.Errorf("Failed adding default cert: [%s]", err) - - return err - } - - defaultCerts[key] = der - - return nil -} -*/ - -func (node *nodeImpl) initKeyStore(pwd []byte) error { - ks := keyStore{} - if err := ks.init(node, pwd); err != nil { - return err - } - node.ks = &ks - - /* - // Add default certs - for key, value := range defaultCerts { - node.debug("Adding Default Cert to the keystore [%s][%s]", key, utils.EncodeBase64(value)) - ks.storeCert(key, value) - } - */ - - return nil -} - -type keyStore struct { - node *nodeImpl - - isOpen bool - - pwd []byte - - // backend - sqlDB *sql.DB - - // Sync - m sync.Mutex -} - -func (ks *keyStore) init(node *nodeImpl, pwd []byte) error { - ks.m.Lock() - defer ks.m.Unlock() - - if ks.isOpen { - return utils.ErrKeyStoreAlreadyInitialized - } - - ks.node = node - ks.pwd = utils.Clone(pwd) - - err := ks.createKeyStoreIfNotExists() - if err != nil { - return err - } - - err = ks.openKeyStore() - if err != nil { - return err - } - - return nil -} - -func (ks *keyStore) isAliasSet(alias string) bool { - missing, _ := utils.FilePathMissing(ks.node.conf.getPathForAlias(alias)) - if missing { - return false - } - - return true -} - -func (ks *keyStore) storePrivateKey(alias string, privateKey interface{}) error { - rawKey, err := primitives.PrivateKeyToPEM(privateKey, ks.pwd) - if err != nil { - ks.node.Errorf("Failed converting private key to PEM [%s]: [%s]", alias, err) - return err - } - - err = ioutil.WriteFile(ks.node.conf.getPathForAlias(alias), rawKey, 0700) - if err != nil { - ks.node.Errorf("Failed storing private key [%s]: [%s]", alias, err) - return err - } - - return nil -} - -func (ks *keyStore) storePrivateKeyInClear(alias string, privateKey interface{}) error { - rawKey, err := primitives.PrivateKeyToPEM(privateKey, nil) - if err != nil { - ks.node.Errorf("Failed converting private key to PEM [%s]: [%s]", alias, err) - return err - } - - err = ioutil.WriteFile(ks.node.conf.getPathForAlias(alias), rawKey, 0700) - if err != nil { - ks.node.Errorf("Failed storing private key [%s]: [%s]", alias, err) - return err - } - - return nil -} - -func (ks *keyStore) deletePrivateKeyInClear(alias string) error { - return os.Remove(ks.node.conf.getPathForAlias(alias)) -} - -func (ks *keyStore) loadPrivateKey(alias string) (interface{}, error) { - path := ks.node.conf.getPathForAlias(alias) - ks.node.Debugf("Loading private key [%s] at [%s]...", alias, path) - - raw, err := ioutil.ReadFile(path) - if err != nil { - ks.node.Errorf("Failed loading private key [%s]: [%s].", alias, err.Error()) - - return nil, err - } - - privateKey, err := primitives.PEMtoPrivateKey(raw, ks.pwd) - if err != nil { - ks.node.Errorf("Failed parsing private key [%s]: [%s].", alias, err.Error()) - - return nil, err - } - - return privateKey, nil -} - -func (ks *keyStore) storePublicKey(alias string, publicKey interface{}) error { - rawKey, err := primitives.PublicKeyToPEM(publicKey, ks.pwd) - if err != nil { - ks.node.Errorf("Failed converting public key to PEM [%s]: [%s]", alias, err) - return err - } - - err = ioutil.WriteFile(ks.node.conf.getPathForAlias(alias), rawKey, 0700) - if err != nil { - ks.node.Errorf("Failed storing private key [%s]: [%s]", alias, err) - return err - } - - return nil -} - -func (ks *keyStore) loadPublicKey(alias string) (interface{}, error) { - path := ks.node.conf.getPathForAlias(alias) - ks.node.Debugf("Loading public key [%s] at [%s]...", alias, path) - - raw, err := ioutil.ReadFile(path) - if err != nil { - ks.node.Errorf("Failed loading public key [%s]: [%s].", alias, err.Error()) - - return nil, err - } - - privateKey, err := primitives.PEMtoPublicKey(raw, ks.pwd) - if err != nil { - ks.node.Errorf("Failed parsing private key [%s]: [%s].", alias, err.Error()) - - return nil, err - } - - return privateKey, nil -} - -func (ks *keyStore) storeKey(alias string, key []byte) error { - pem, err := primitives.AEStoEncryptedPEM(key, ks.pwd) - if err != nil { - ks.node.Errorf("Failed converting key to PEM [%s]: [%s]", alias, err) - return err - } - - err = ioutil.WriteFile(ks.node.conf.getPathForAlias(alias), pem, 0700) - if err != nil { - ks.node.Errorf("Failed storing key [%s]: [%s]", alias, err) - return err - } - - return nil -} - -func (ks *keyStore) loadKey(alias string) ([]byte, error) { - path := ks.node.conf.getPathForAlias(alias) - ks.node.Debugf("Loading key [%s] at [%s]...", alias, path) - - pem, err := ioutil.ReadFile(path) - if err != nil { - ks.node.Errorf("Failed loading key [%s]: [%s].", alias, err.Error()) - - return nil, err - } - - key, err := primitives.PEMtoAES(pem, ks.pwd) - if err != nil { - ks.node.Errorf("Failed parsing key [%s]: [%s]", alias, err) - - return nil, err - } - - return key, nil -} - -func (ks *keyStore) storeCert(alias string, der []byte) error { - err := ioutil.WriteFile(ks.node.conf.getPathForAlias(alias), primitives.DERCertToPEM(der), 0700) - if err != nil { - ks.node.Errorf("Failed storing certificate [%s]: [%s]", alias, err) - return err - } - - return nil -} - -func (ks *keyStore) certMissing(alias string) bool { - return !ks.isAliasSet(alias) -} - -func (ks *keyStore) deleteCert(alias string) error { - return os.Remove(ks.node.conf.getPathForAlias(alias)) -} - -func (ks *keyStore) loadCert(alias string) ([]byte, error) { - path := ks.node.conf.getPathForAlias(alias) - ks.node.Debugf("Loading certificate [%s] at [%s]...", alias, path) - - pem, err := ioutil.ReadFile(path) - if err != nil { - ks.node.Errorf("Failed loading certificate [%s]: [%s].", alias, err.Error()) - - return nil, err - } - - return pem, nil -} - -func (ks *keyStore) loadExternalCert(path string) ([]byte, error) { - ks.node.Debugf("Loading external certificate at [%s]...", path) - - pem, err := ioutil.ReadFile(path) - if err != nil { - ks.node.Errorf("Failed loading external certificate: [%s].", err.Error()) - - return nil, err - } - - return pem, nil -} - -func (ks *keyStore) loadCertX509AndDer(alias string) (*x509.Certificate, []byte, error) { - path := ks.node.conf.getPathForAlias(alias) - ks.node.Debugf("Loading certificate [%s] at [%s]...", alias, path) - - pem, err := ioutil.ReadFile(path) - if err != nil { - ks.node.Errorf("Failed loading certificate [%s]: [%s].", alias, err.Error()) - - return nil, nil, err - } - - cert, der, err := primitives.PEMtoCertificateAndDER(pem) - if err != nil { - ks.node.Errorf("Failed parsing certificate [%s]: [%s].", alias, err.Error()) - - return nil, nil, err - } - - return cert, der, nil -} - -func (ks *keyStore) close() error { - ks.node.Debug("Closing keystore...") - err := ks.sqlDB.Close() - - if err != nil { - ks.node.Errorf("Failed closing keystore [%s].", err.Error()) - } else { - ks.node.Debug("Closing keystore...done!") - } - - ks.isOpen = false - return err -} - -func (ks *keyStore) createKeyStoreIfNotExists() error { - // Check keystore directory - ksPath := ks.node.conf.getKeyStorePath() - missing, err := utils.DirMissingOrEmpty(ksPath) - ks.node.Debugf("Keystore path [%s] missing [%t]: [%s]", ksPath, missing, utils.ErrToString(err)) - - if !missing { - // Check keystore file - missing, err = utils.FileMissing(ks.node.conf.getKeyStorePath(), ks.node.conf.getKeyStoreFilename()) - ks.node.Debugf("Keystore [%s] missing [%t]:[%s]", ks.node.conf.getKeyStoreFilePath(), missing, utils.ErrToString(err)) - } - - if missing { - err := ks.createKeyStore() - if err != nil { - ks.node.Errorf("Failed creating db At [%s]: [%s]", ks.node.conf.getKeyStoreFilePath(), err.Error()) - return nil - } - } - - return nil -} - -func (ks *keyStore) createKeyStore() error { - // Create keystore directory root if it doesn't exist yet - ksPath := ks.node.conf.getKeyStorePath() - ks.node.Debugf("Creating Keystore at [%s]...", ksPath) - - missing, err := utils.FileMissing(ksPath, ks.node.conf.getKeyStoreFilename()) - if !missing { - ks.node.Debugf("Creating Keystore at [%s]. Keystore already there", ksPath) - return nil - } - - os.MkdirAll(ksPath, 0755) - - // Create Raw material folder - os.MkdirAll(ks.node.conf.getRawsPath(), 0755) - - // Create DB - ks.node.Debug("Open Keystore DB...") - db, err := sql.Open("sqlite3", filepath.Join(ksPath, ks.node.conf.getKeyStoreFilename())) - if err != nil { - return err - } - - ks.node.Debug("Ping Keystore DB...") - err = db.Ping() - if err != nil { - ks.node.Errorf("Failend pinged keystore DB: [%s]", err) - - return err - } - defer db.Close() - - ks.node.Debugf("Keystore created at [%s].", ksPath) - return nil -} - -func (ks *keyStore) deleteKeyStore() error { - ks.node.Debugf("Removing KeyStore at [%s].", ks.node.conf.getKeyStorePath()) - - return os.RemoveAll(ks.node.conf.getKeyStorePath()) -} - -func (ks *keyStore) openKeyStore() error { - if ks.isOpen { - return nil - } - - // Open DB - ksPath := ks.node.conf.getKeyStorePath() - - sqlDB, err := sql.Open("sqlite3", filepath.Join(ksPath, ks.node.conf.getKeyStoreFilename())) - if err != nil { - ks.node.Errorf("Error opening keystore%s", err.Error()) - return err - } - ks.isOpen = true - ks.sqlDB = sqlDB - - ks.node.Debugf("Keystore opened at [%s]...done", ksPath) - - return nil -} diff --git a/core/crypto/node_log.go b/core/crypto/node_log.go deleted file mode 100644 index 36c06250c87..00000000000 --- a/core/crypto/node_log.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -func (node *nodeImpl) prependPrefix(args []interface{}) []interface{} { - return append([]interface{}{node.conf.logPrefix}, args...) -} - -func (node *nodeImpl) Infof(format string, args ...interface{}) { - log.Infof(node.conf.logPrefix+format, args...) -} - -func (node *nodeImpl) Info(args ...interface{}) { - log.Info(node.prependPrefix(args)...) -} - -func (node *nodeImpl) Debugf(format string, args ...interface{}) { - log.Debugf(node.conf.logPrefix+format, args...) -} - -func (node *nodeImpl) Debug(args ...interface{}) { - log.Debug(node.prependPrefix(args)...) -} - -func (node *nodeImpl) Errorf(format string, args ...interface{}) { - log.Errorf(node.conf.logPrefix+format, args...) -} - -func (node *nodeImpl) Error(args ...interface{}) { - log.Error(node.prependPrefix(args)...) -} - -func (node *nodeImpl) Warningf(format string, args ...interface{}) { - log.Warningf(node.conf.logPrefix+format, args...) -} - -func (node *nodeImpl) Warning(args ...interface{}) { - log.Warning(node.prependPrefix(args)...) -} diff --git a/core/crypto/node_sign.go b/core/crypto/node_sign.go deleted file mode 100644 index 9b45aa1ac99..00000000000 --- a/core/crypto/node_sign.go +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "math/big" - - "github.com/hyperledger/fabric/core/crypto/primitives" -) - -func (node *nodeImpl) sign(signKey interface{}, msg []byte) ([]byte, error) { - return primitives.ECDSASign(signKey, msg) -} - -func (node *nodeImpl) signWithEnrollmentKey(msg []byte) ([]byte, error) { - return primitives.ECDSASign(node.enrollPrivKey, msg) -} - -func (node *nodeImpl) ecdsaSignWithEnrollmentKey(msg []byte) (*big.Int, *big.Int, error) { - return primitives.ECDSASignDirect(node.enrollPrivKey, msg) -} - -func (node *nodeImpl) verify(verKey interface{}, msg, signature []byte) (bool, error) { - return primitives.ECDSAVerify(verKey, msg, signature) -} - -func (node *nodeImpl) verifyWithEnrollmentCert(msg, signature []byte) (bool, error) { - return primitives.ECDSAVerify(node.enrollCert.PublicKey, msg, signature) -} diff --git a/core/crypto/node_tca.go b/core/crypto/node_tca.go deleted file mode 100644 index 38068944131..00000000000 --- a/core/crypto/node_tca.go +++ /dev/null @@ -1,126 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - membersrvc "github.com/hyperledger/fabric/membersrvc/protos" - - "errors" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "golang.org/x/net/context" - "google.golang.org/grpc" -) - -func (node *nodeImpl) retrieveTCACertsChain(userID string) error { - if !node.ks.certMissing(node.conf.getTCACertsChainFilename()) { - return nil - } - - // Retrieve TCA certificate and verify it - tcaCertRaw, err := node.getTCACertificate() - if err != nil { - node.Errorf("Failed getting TCA certificate [%s].", err.Error()) - - return err - } - node.Debugf("TCA certificate [% x]", tcaCertRaw) - - // TODO: Test TCA cert againt root CA - _, err = primitives.DERToX509Certificate(tcaCertRaw) - if err != nil { - node.Errorf("Failed parsing TCA certificate [%s].", err.Error()) - - return err - } - - // Store TCA cert - node.Debugf("Storing TCA certificate for [%s]...", userID) - - if err := node.ks.storeCert(node.conf.getTCACertsChainFilename(), tcaCertRaw); err != nil { - node.Errorf("Failed storing tca certificate [%s].", err.Error()) - return err - } - - return nil -} - -func (node *nodeImpl) loadTCACertsChain() error { - // Load TCA certs chain - node.Debug("Loading TCA certificates chain...") - - cert, err := node.ks.loadCert(node.conf.getTCACertsChainFilename()) - if err != nil { - node.Errorf("Failed loading TCA certificates chain [%s].", err.Error()) - - return err - } - - // Prepare ecaCertPool - ok := node.tcaCertPool.AppendCertsFromPEM(cert) - if !ok { - node.Error("Failed appending TCA certificates chain.") - - return errors.New("Failed appending TCA certificates chain.") - } - - return nil -} - -func (node *nodeImpl) getTCAClient() (*grpc.ClientConn, membersrvc.TCAPClient, error) { - node.Debug("Getting TCA client...") - - conn, err := node.getClientConn(node.conf.getTCAPAddr(), node.conf.getTCAServerName()) - if err != nil { - node.Errorf("Failed getting client connection: [%s]", err) - } - - client := membersrvc.NewTCAPClient(conn) - - node.Debug("Getting TCA client...done") - - return conn, client, nil -} - -func (node *nodeImpl) callTCAReadCACertificate(ctx context.Context, opts ...grpc.CallOption) (*membersrvc.Cert, error) { - // Get a TCA Client - sock, tcaP, err := node.getTCAClient() - defer sock.Close() - - // Issue the request - cert, err := tcaP.ReadCACertificate(ctx, &membersrvc.Empty{}, opts...) - if err != nil { - node.Errorf("Failed requesting tca read certificate [%s].", err.Error()) - - return nil, err - } - - return cert, nil -} - -func (node *nodeImpl) getTCACertificate() ([]byte, error) { - response, err := node.callTCAReadCACertificate(context.Background()) - if err != nil { - node.Errorf("Failed requesting TCA certificate [%s].", err.Error()) - - return nil, err - } - - // TODO: check response.Cert against rootCA - - return response.Cert, nil -} diff --git a/core/crypto/node_tlsca.go b/core/crypto/node_tlsca.go deleted file mode 100644 index 647d37681f2..00000000000 --- a/core/crypto/node_tlsca.go +++ /dev/null @@ -1,206 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - membersrvc "github.com/hyperledger/fabric/membersrvc/protos" - - "crypto/ecdsa" - "crypto/rand" - "crypto/x509" - "errors" - "time" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/util" - "golang.org/x/net/context" - "google.golang.org/grpc" -) - -func (node *nodeImpl) retrieveTLSCertificate(id, affiliation string) error { - if !node.ks.certMissing(node.conf.getTLSCertFilename()) { - return nil - } - - key, tlsCertRaw, err := node.getTLSCertificateFromTLSCA(id, affiliation) - if err != nil { - node.Errorf("Failed getting tls certificate [id=%s] %s", id, err) - - return err - } - node.Debugf("TLS Cert [% x]", tlsCertRaw) - - node.Debugf("Storing TLS key and certificate for user [%s]...", id) - - // Store tls key. - if err := node.ks.storePrivateKeyInClear(node.conf.getTLSKeyFilename(), key); err != nil { - node.Errorf("Failed storing tls key [id=%s]: %s", id, err) - return err - } - - // Store tls cert - if err := node.ks.storeCert(node.conf.getTLSCertFilename(), tlsCertRaw); err != nil { - node.Errorf("Failed storing tls certificate [id=%s]: %s", id, err) - return err - } - - return nil -} - -func (node *nodeImpl) deleteTLSCertificate(id, affiliation string) error { - if err := node.ks.deletePrivateKeyInClear(node.conf.getTLSKeyFilename()); err != nil { - node.Errorf("Failed deleting tls key [id=%s]: %s", id, err) - return err - } - - // Store tls cert - if err := node.ks.deleteCert(node.conf.getTLSCertFilename()); err != nil { - node.Errorf("Failed deleting tls certificate [id=%s]: %s", id, err) - return err - } - - return nil -} - -func (node *nodeImpl) loadTLSCertificate() error { - node.Debug("Loading tls certificate...") - - cert, _, err := node.ks.loadCertX509AndDer(node.conf.getTLSCertFilename()) - if err != nil { - node.Errorf("Failed parsing tls certificate [%s].", err.Error()) - - return err - } - node.tlsCert = cert - - return nil -} - -func (node *nodeImpl) loadTLSCACertsChain() error { - if node.conf.isTLSEnabled() { - node.Debug("Loading TLSCA certificates chain...") - - pem, err := node.ks.loadExternalCert(node.conf.getTLSCACertsExternalPath()) - if err != nil { - node.Errorf("Failed loading TLSCA certificates chain [%s].", err.Error()) - - return err - } - - ok := node.tlsCertPool.AppendCertsFromPEM(pem) - if !ok { - node.Error("Failed appending TLSCA certificates chain.") - - return errors.New("Failed appending TLSCA certificates chain.") - } - - node.Debug("Loading TLSCA certificates chain...done") - - } else { - node.Debug("TLS is disabled!!!") - } - - return nil -} - -func (node *nodeImpl) getTLSCertificateFromTLSCA(id, affiliation string) (interface{}, []byte, error) { - node.Debug("getTLSCertificate...") - - priv, err := primitives.NewECDSAKey() - - if err != nil { - node.Errorf("Failed generating key: %s", err) - - return nil, nil, err - } - - uuid := util.GenerateUUID() - - // Prepare the request - pubraw, _ := x509.MarshalPKIXPublicKey(&priv.PublicKey) - now := time.Now() - timestamp := timestamp.Timestamp{Seconds: int64(now.Second()), Nanos: int32(now.Nanosecond())} - - req := &membersrvc.TLSCertCreateReq{ - Ts: ×tamp, - Id: &membersrvc.Identity{Id: id + "-" + uuid}, - Pub: &membersrvc.PublicKey{ - Type: membersrvc.CryptoType_ECDSA, - Key: pubraw, - }, Sig: nil} - rawreq, _ := proto.Marshal(req) - r, s, err := ecdsa.Sign(rand.Reader, priv, primitives.Hash(rawreq)) - if err != nil { - panic(err) - } - R, _ := r.MarshalText() - S, _ := s.MarshalText() - req.Sig = &membersrvc.Signature{Type: membersrvc.CryptoType_ECDSA, R: R, S: S} - - pbCert, err := node.callTLSCACreateCertificate(context.Background(), req) - if err != nil { - node.Errorf("Failed requesting tls certificate: %s", err) - - return nil, nil, err - } - - node.Debug("Verifing tls certificate...") - - tlsCert, err := primitives.DERToX509Certificate(pbCert.Cert.Cert) - certPK := tlsCert.PublicKey.(*ecdsa.PublicKey) - primitives.VerifySignCapability(priv, certPK) - - node.Debug("Verifing tls certificate...done!") - - return priv, pbCert.Cert.Cert, nil -} - -func (node *nodeImpl) getTLSCAClient() (*grpc.ClientConn, membersrvc.TLSCAPClient, error) { - node.Debug("Getting TLSCA client...") - - conn, err := node.getClientConn(node.conf.getTLSCAPAddr(), node.conf.getTLSCAServerName()) - if err != nil { - node.Errorf("Failed getting client connection: [%s]", err) - } - - client := membersrvc.NewTLSCAPClient(conn) - - node.Debug("Getting TLSCA client...done") - - return conn, client, nil -} - -func (node *nodeImpl) callTLSCACreateCertificate(ctx context.Context, in *membersrvc.TLSCertCreateReq, opts ...grpc.CallOption) (*membersrvc.TLSCertCreateResp, error) { - conn, tlscaP, err := node.getTLSCAClient() - if err != nil { - node.Errorf("Failed dialing in: %s", err) - - return nil, err - } - defer conn.Close() - - resp, err := tlscaP.CreateCertificate(ctx, in, opts...) - if err != nil { - node.Errorf("Failed requesting tls certificate: %s", err) - - return nil, err - } - - return resp, nil -} diff --git a/core/crypto/peer.go b/core/crypto/peer.go deleted file mode 100644 index 691736fbb99..00000000000 --- a/core/crypto/peer.go +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "sync" - - "github.com/hyperledger/fabric/core/crypto/utils" -) - -// Private types and variables - -type peerEntry struct { - peer Peer - counter int64 -} - -var ( - // Map of initialized peers - peers = make(map[string]peerEntry) - - // Sync - peerMutex sync.Mutex -) - -// Public Methods - -// RegisterPeer registers a peer to the PKI infrastructure -func RegisterPeer(name string, pwd []byte, enrollID, enrollPWD string) error { - peerMutex.Lock() - defer peerMutex.Unlock() - - log.Infof("Registering peer [%s] with id [%s]...", enrollID, name) - - if _, ok := peers[name]; ok { - log.Infof("Registering peer [%s] with id [%s]...done. Already initialized.", enrollID, name) - - return nil - } - - peer := newPeer() - if err := peer.register(NodePeer, name, pwd, enrollID, enrollPWD, nil); err != nil { - if err != utils.ErrAlreadyRegistered && err != utils.ErrAlreadyInitialized { - log.Errorf("Failed registering peer [%s] with id [%s] [%s].", enrollID, name, err) - return err - } - log.Infof("Registering peer [%s] with id [%s]...done. Already registered or initiliazed.", enrollID, name) - } - err := peer.close() - if err != nil { - // It is not necessary to report this error to the caller - log.Warningf("Registering peer [%s] with id [%s]. Failed closing [%s].", enrollID, name, err) - } - - log.Infof("Registering peer [%s] with id [%s]...done!", enrollID, name) - - return nil -} - -// InitPeer initializes a peer named name with password pwd -func InitPeer(name string, pwd []byte) (Peer, error) { - peerMutex.Lock() - defer peerMutex.Unlock() - - log.Infof("Initializing peer [%s]...", name) - - if entry, ok := peers[name]; ok { - log.Infof("Peer already initiliazied [%s]. Increasing counter from [%d]", name, peers[name].counter) - entry.counter++ - peers[name] = entry - - return peers[name].peer, nil - } - - peer := newPeer() - if err := peer.init(NodePeer, name, pwd, nil); err != nil { - log.Errorf("Failed peer initialization [%s]: [%s]", name, err) - - return nil, err - } - - peers[name] = peerEntry{peer, 1} - log.Infof("Initializing peer [%s]...done!", name) - - return peer, nil -} - -// ClosePeer releases all the resources allocated by peers -func ClosePeer(peer Peer) error { - peerMutex.Lock() - defer peerMutex.Unlock() - - return closePeerInternal(peer, false) -} - -// CloseAllPeers closes all the peers initialized so far -func CloseAllPeers() (bool, []error) { - peerMutex.Lock() - defer peerMutex.Unlock() - - log.Info("Closing all peers...") - - errs := make([]error, len(peers)) - for _, value := range peers { - err := closePeerInternal(value.peer, true) - - errs = append(errs, err) - } - - log.Info("Closing all peers...done!") - - return len(errs) != 0, errs -} - -// Private Methods - -func newPeer() *peerImpl { - return &peerImpl{&nodeImpl{}, sync.RWMutex{}, nil} -} - -func closePeerInternal(peer Peer, force bool) error { - if peer == nil { - return utils.ErrNilArgument - } - - name := peer.GetName() - log.Infof("Closing peer [%s]...", name) - entry, ok := peers[name] - if !ok { - return utils.ErrInvalidReference - } - if entry.counter == 1 || force { - defer delete(peers, name) - err := peers[name].peer.(*peerImpl).close() - log.Infof("Closing peer [%s]...done! [%s].", name, utils.ErrToString(err)) - - return err - } - - // decrease counter - entry.counter-- - peers[name] = entry - log.Infof("Closing peer [%s]...decreased counter at [%d].", name, peers[name].counter) - - return nil -} diff --git a/core/crypto/peer_eca.go b/core/crypto/peer_eca.go deleted file mode 100644 index dd713f642a9..00000000000 --- a/core/crypto/peer_eca.go +++ /dev/null @@ -1,121 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/x509" - "fmt" - "strconv" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - membersrvc "github.com/hyperledger/fabric/membersrvc/protos" - "golang.org/x/net/context" -) - -func (peer *peerImpl) getEnrollmentCert(id []byte) (*x509.Certificate, error) { - if len(id) == 0 { - return nil, fmt.Errorf("Invalid peer id. It is empty.") - } - - sid := utils.EncodeBase64(id) - - peer.Debugf("Getting enrollment certificate for [%s]", sid) - - if cert := peer.getNodeEnrollmentCertificate(sid); cert != nil { - peer.Debugf("Enrollment certificate for [%s] already in memory.", sid) - return cert, nil - } - - // Retrieve from the DB or from the ECA in case - peer.Debugf("Retrieve Enrollment certificate for [%s]...", sid) - rawCert, err := peer.ks.GetSignEnrollmentCert(id, peer.getEnrollmentCertByHashFromECA) - if err != nil { - peer.Errorf("Failed getting enrollment certificate for [%s]: [%s]", sid, err) - - return nil, err - } - - cert, err := primitives.DERToX509Certificate(rawCert) - if err != nil { - peer.Errorf("Failed parsing enrollment certificate for [%s]: [% x],[% x]", sid, rawCert, err) - - return nil, err - } - - peer.putNodeEnrollmentCertificate(sid, cert) - - return cert, nil -} - -func (peer *peerImpl) getEnrollmentCertByHashFromECA(id []byte) ([]byte, []byte, error) { - // Prepare the request - peer.Debugf("Reading certificate for hash [% x]", id) - - req := &membersrvc.Hash{Hash: id} - response, err := peer.callECAReadCertificateByHash(context.Background(), req) - if err != nil { - peer.Errorf("Failed requesting enrollment certificate [%s].", err.Error()) - - return nil, nil, err - } - - peer.Debugf("Certificate for hash [% x] = [% x][% x]", id, response.Sign, response.Enc) - - // Verify response.Sign - x509Cert, err := primitives.DERToX509Certificate(response.Sign) - if err != nil { - peer.Errorf("Failed parsing signing enrollment certificate for encrypting: [%s]", err) - - return nil, nil, err - } - - // Check role - roleRaw, err := primitives.GetCriticalExtension(x509Cert, ECertSubjectRole) - if err != nil { - peer.Errorf("Failed parsing ECertSubjectRole in enrollment certificate for signing: [%s]", err) - - return nil, nil, err - } - - role, err := strconv.ParseInt(string(roleRaw), 10, len(roleRaw)*8) - if err != nil { - peer.Errorf("Failed parsing ECertSubjectRole in enrollment certificate for signing: [%s]", err) - - return nil, nil, err - } - - if membersrvc.Role(role) != membersrvc.Role_VALIDATOR && membersrvc.Role(role) != membersrvc.Role_PEER { - peer.Errorf("Invalid ECertSubjectRole in enrollment certificate for signing. Not a validator or peer: [%s]", err) - - return nil, nil, err - } - - return response.Sign, response.Enc, nil -} - -func (peer *peerImpl) getNodeEnrollmentCertificate(sid string) *x509.Certificate { - peer.nodeEnrollmentCertificatesMutex.RLock() - defer peer.nodeEnrollmentCertificatesMutex.RUnlock() - return peer.nodeEnrollmentCertificates[sid] -} - -func (peer *peerImpl) putNodeEnrollmentCertificate(sid string, cert *x509.Certificate) { - peer.nodeEnrollmentCertificatesMutex.Lock() - defer peer.nodeEnrollmentCertificatesMutex.Unlock() - peer.nodeEnrollmentCertificates[sid] = cert -} diff --git a/core/crypto/peer_impl.go b/core/crypto/peer_impl.go deleted file mode 100644 index e848b167528..00000000000 --- a/core/crypto/peer_impl.go +++ /dev/null @@ -1,234 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/ecdsa" - "crypto/x509" - "fmt" - "sync" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -type peerImpl struct { - *nodeImpl - - nodeEnrollmentCertificatesMutex sync.RWMutex - nodeEnrollmentCertificates map[string]*x509.Certificate -} - -// Public methods - -// GetID returns this peer's identifier -func (peer *peerImpl) GetID() []byte { - return utils.Clone(peer.id) -} - -// GetEnrollmentID returns this peer's enrollment id -func (peer *peerImpl) GetEnrollmentID() string { - return peer.enrollID -} - -// TransactionPreValidation verifies that the transaction is -// well formed with the respect to the security layer -// prescriptions (i.e. signature verification). -func (peer *peerImpl) TransactionPreValidation(tx *obc.Transaction) (*obc.Transaction, error) { - if !peer.IsInitialized() { - return nil, utils.ErrNotInitialized - } - - // peer.debug("Pre validating [%s].", tx.String()) - peer.Debugf("Tx confdential level [%s].", tx.ConfidentialityLevel.String()) - - if tx.Cert != nil && tx.Signature != nil { - // Verify the transaction - // 1. Unmarshal cert - cert, err := primitives.DERToX509Certificate(tx.Cert) - if err != nil { - peer.Errorf("TransactionPreExecution: failed unmarshalling cert [%s].", err.Error()) - return tx, err - } - - // Verify transaction certificate against root - // DER to x509 - x509Cert, err := primitives.DERToX509Certificate(tx.Cert) - if err != nil { - peer.Debugf("Failed parsing certificate [% x]: [%s].", tx.Cert, err) - - return tx, err - } - - // 1. Get rid of the extensions that cannot be checked now - x509Cert.UnhandledCriticalExtensions = nil - // 2. Check against TCA certPool - if _, err = primitives.CheckCertAgainRoot(x509Cert, peer.tcaCertPool); err != nil { - peer.Warningf("Failed verifing certificate against TCA cert pool [%s].", err.Error()) - // 3. Check against ECA certPool, if this check also fails then return an error - if _, err = primitives.CheckCertAgainRoot(x509Cert, peer.ecaCertPool); err != nil { - peer.Warningf("Failed verifing certificate against ECA cert pool [%s].", err.Error()) - - return tx, fmt.Errorf("Certificate has not been signed by a trusted authority. [%s]", err) - } - } - - // 3. Marshall tx without signature - signature := tx.Signature - tx.Signature = nil - rawTx, err := proto.Marshal(tx) - if err != nil { - peer.Errorf("TransactionPreExecution: failed marshaling tx [%s].", err.Error()) - return tx, err - } - tx.Signature = signature - - // 2. Verify signature - ok, err := peer.verify(cert.PublicKey, rawTx, tx.Signature) - if err != nil { - peer.Errorf("TransactionPreExecution: failed marshaling tx [%s].", err.Error()) - return tx, err - } - - if !ok { - return tx, utils.ErrInvalidTransactionSignature - } - } else { - if tx.Cert == nil { - return tx, utils.ErrTransactionCertificate - } - - if tx.Signature == nil { - return tx, utils.ErrTransactionSignature - } - } - - return tx, nil -} - -// TransactionPreValidation verifies that the transaction is -// well formed with the respect to the security layer -// prescriptions (i.e. signature verification). If this is the case, -// the method prepares the transaction to be executed. -func (peer *peerImpl) TransactionPreExecution(tx *obc.Transaction) (*obc.Transaction, error) { - return nil, utils.ErrNotImplemented -} - -// Sign signs msg with this validator's signing key and outputs -// the signature if no error occurred. -func (peer *peerImpl) Sign(msg []byte) ([]byte, error) { - return peer.signWithEnrollmentKey(msg) -} - -// Verify checks that signature if a valid signature of message under vkID's verification key. -// If the verification succeeded, Verify returns nil meaning no error occurred. -// If vkID is nil, then the signature is verified against this validator's verification key. -func (peer *peerImpl) Verify(vkID, signature, message []byte) error { - if len(vkID) == 0 { - return fmt.Errorf("Invalid peer id. It is empty.") - } - if len(signature) == 0 { - return fmt.Errorf("Invalid signature. It is empty.") - } - if len(message) == 0 { - return fmt.Errorf("Invalid message. It is empty.") - } - - cert, err := peer.getEnrollmentCert(vkID) - if err != nil { - peer.Errorf("Failed getting enrollment cert for [% x]: [%s]", vkID, err) - - return err - } - - vk := cert.PublicKey.(*ecdsa.PublicKey) - - ok, err := peer.verify(vk, message, signature) - if err != nil { - peer.Errorf("Failed verifying signature for [% x]: [%s]", vkID, err) - - return err - } - - if !ok { - peer.Errorf("Failed invalid signature for [% x]", vkID) - - return utils.ErrInvalidSignature - } - - return nil -} - -func (peer *peerImpl) GetStateEncryptor(deployTx, invokeTx *obc.Transaction) (StateEncryptor, error) { - return nil, utils.ErrNotImplemented -} - -func (peer *peerImpl) GetTransactionBinding(tx *obc.Transaction) ([]byte, error) { - return primitives.Hash(append(tx.Cert, tx.Nonce...)), nil -} - -// Private methods - -func (peer *peerImpl) register(eType NodeType, name string, pwd []byte, enrollID, enrollPWD string, regFunc registerFunc) error { - - if err := peer.nodeImpl.register(eType, name, pwd, enrollID, enrollPWD, regFunc); err != nil { - peer.Errorf("Failed registering peer [%s]: [%s]", enrollID, err) - return err - } - - return nil -} - -func (peer *peerImpl) init(eType NodeType, id string, pwd []byte, initFunc initalizationFunc) error { - - peerInitFunc := func(eType NodeType, name string, pwd []byte) error { - // Initialize keystore - peer.Debug("Init keystore...") - err := peer.initKeyStore() - if err != nil { - if err != utils.ErrKeyStoreAlreadyInitialized { - peer.Error("Keystore already initialized.") - } else { - peer.Errorf("Failed initiliazing keystore [%s].", err) - - return err - } - } - peer.Debug("Init keystore...done.") - - // EnrollCerts - peer.nodeEnrollmentCertificates = make(map[string]*x509.Certificate) - - if initFunc != nil { - return initFunc(eType, id, pwd) - } - - return nil - } - - if err := peer.nodeImpl.init(eType, id, pwd, peerInitFunc); err != nil { - return err - } - - return nil -} - -func (peer *peerImpl) close() error { - return peer.nodeImpl.close() -} diff --git a/core/crypto/peer_ks.go b/core/crypto/peer_ks.go deleted file mode 100644 index 748290916a6..00000000000 --- a/core/crypto/peer_ks.go +++ /dev/null @@ -1,133 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "database/sql" - "fmt" - - "github.com/hyperledger/fabric/core/crypto/utils" -) - -func (peer *peerImpl) initKeyStore() error { - // create tables - peer.Debugf("Create Table [%s] if not exists", "Certificates") - if _, err := peer.ks.sqlDB.Exec("CREATE TABLE IF NOT EXISTS Certificates (id VARCHAR, certsign BLOB, certenc BLOB, PRIMARY KEY (id))"); err != nil { - peer.Errorf("Failed creating table [%s].", err.Error()) - return err - } - - return nil -} - -func (ks *keyStore) GetSignEnrollmentCert(id []byte, certFetcher func(id []byte) ([]byte, []byte, error)) ([]byte, error) { - if len(id) == 0 { - return nil, fmt.Errorf("Invalid peer id. It is empty.") - } - - ks.m.Lock() - defer ks.m.Unlock() - - sid := utils.EncodeBase64(id) - - certSign, certEnc, err := ks.selectSignEnrollmentCert(sid) - if err != nil { - ks.node.Errorf("Failed selecting enrollment cert [%s].", err.Error()) - - return nil, err - } - - if certSign == nil { - ks.node.Debugf("Cert for [%s] not available. Fetching from ECA....", sid) - - // If No cert is available, fetch from ECA - - // 1. Fetch - ks.node.Debug("Fectch Enrollment Certificate from ECA...") - certSign, certEnc, err = certFetcher(id) - if err != nil { - return nil, err - } - - // 2. Store - ks.node.Debug("Store certificate...") - tx, err := ks.sqlDB.Begin() - if err != nil { - ks.node.Errorf("Failed beginning transaction [%s].", err.Error()) - - return nil, err - } - - ks.node.Debugf("Insert id [%s].", sid) - ks.node.Debugf("Insert cert [% x].", certSign) - - _, err = tx.Exec("INSERT INTO Certificates (id, certsign, certenc) VALUES (?, ?, ?)", sid, certSign, certEnc) - - if err != nil { - ks.node.Errorf("Failed inserting cert [%s].", err.Error()) - - tx.Rollback() - - return nil, err - } - - err = tx.Commit() - if err != nil { - ks.node.Errorf("Failed committing transaction [%s].", err.Error()) - - tx.Rollback() - - return nil, err - } - - ks.node.Debug("Fectch Enrollment Certificate from ECA...done!") - - certSign, certEnc, err = ks.selectSignEnrollmentCert(sid) - if err != nil { - ks.node.Errorf("Failed selecting next TCert after fetching [%s].", err.Error()) - - return nil, err - } - } - - ks.node.Debugf("Cert for [%s] = [% x]", sid, certSign) - - return certSign, nil -} - -func (ks *keyStore) selectSignEnrollmentCert(id string) ([]byte, []byte, error) { - ks.node.Debugf("Select Sign Enrollment Cert for id [%s]", id) - - // Get the first row available - var cert []byte - row := ks.sqlDB.QueryRow("SELECT certsign FROM Certificates where id = ?", id) - err := row.Scan(&cert) - - if err == sql.ErrNoRows { - return nil, nil, nil - } else if err != nil { - ks.node.Errorf("Error during select [%s].", err.Error()) - - return nil, nil, err - } - - ks.node.Debugf("Cert [% x].", cert) - - ks.node.Debug("Select Enrollment Cert...done!") - - return cert, nil, nil -} diff --git a/core/crypto/validator.go b/core/crypto/validator.go deleted file mode 100644 index d8b74a1e605..00000000000 --- a/core/crypto/validator.go +++ /dev/null @@ -1,160 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "sync" - - "github.com/hyperledger/fabric/core/crypto/utils" -) - -// Private type and variables - -type validatorEntry struct { - validator Peer - counter int64 -} - -var ( - // Map of initialized validators - validators = make(map[string]validatorEntry) - - // Sync - mutex sync.Mutex -) - -// Public Methods - -// RegisterValidator registers a validator to the PKI infrastructure -func RegisterValidator(name string, pwd []byte, enrollID, enrollPWD string) error { - mutex.Lock() - defer mutex.Unlock() - - log.Infof("Registering validator [%s] with name [%s]...", enrollID, name) - - if _, ok := validators[name]; ok { - log.Infof("Registering validator [%s] with name [%s]...done. Already initialized.", enrollID, name) - - return nil - } - - validator := newValidator() - if err := validator.register(name, pwd, enrollID, enrollPWD, nil); err != nil { - if err != utils.ErrAlreadyRegistered && err != utils.ErrAlreadyInitialized { - log.Errorf("Failed registering validator [%s] with name [%s] [%s].", enrollID, name, err) - return err - } - log.Infof("Registering validator [%s] with name [%s]...done. Already registered or initiliazed.", enrollID, name) - } - err := validator.close() - if err != nil { - // It is not necessary to report this error to the caller - log.Warningf("Registering validator [%s] with name [%s]. Failed closing [%s].", enrollID, name, err) - } - - log.Infof("Registering validator [%s] with name [%s]...done!", enrollID, name) - - return nil -} - -// InitValidator initializes a validator named name with password pwd -func InitValidator(name string, pwd []byte) (Peer, error) { - mutex.Lock() - defer mutex.Unlock() - - log.Infof("Initializing validator [%s]...", name) - - if entry, ok := validators[name]; ok { - log.Infof("Validator already initiliazied [%s]. Increasing counter from [%d]", name, validators[name].counter) - entry.counter++ - validators[name] = entry - - return validators[name].validator, nil - } - - validator := newValidator() - if err := validator.init(name, pwd, nil); err != nil { - log.Errorf("Failed validator initialization [%s]: [%s]", name, err) - - return nil, err - } - - validators[name] = validatorEntry{validator, 1} - log.Infof("Initializing validator [%s]...done!", name) - - return validator, nil -} - -// CloseValidator releases all the resources allocated by the validator -func CloseValidator(peer Peer) error { - mutex.Lock() - defer mutex.Unlock() - - return closeValidatorInternal(peer, false) -} - -// CloseAllValidators closes all the validators initialized so far -func CloseAllValidators() (bool, []error) { - mutex.Lock() - defer mutex.Unlock() - - log.Info("Closing all validators...") - - errs := make([]error, len(validators)) - for _, value := range validators { - err := closeValidatorInternal(value.validator, true) - - errs = append(errs, err) - } - - log.Info("Closing all validators...done!") - - return len(errs) != 0, errs -} - -// Private Methods - -func newValidator() *validatorImpl { - return &validatorImpl{&peerImpl{&nodeImpl{}, sync.RWMutex{}, nil}, nil} -} - -func closeValidatorInternal(peer Peer, force bool) error { - if peer == nil { - return utils.ErrNilArgument - } - - name := peer.GetName() - log.Infof("Closing validator [%s]...", name) - entry, ok := validators[name] - if !ok { - return utils.ErrInvalidReference - } - if entry.counter == 1 || force { - defer delete(validators, name) - err := validators[name].validator.(*validatorImpl).close() - log.Infof("Closing validator [%s]...done! [%s].", name, utils.ErrToString(err)) - - return err - } - - // decrease counter - entry.counter-- - validators[name] = entry - log.Infof("Closing validator [%s]...decreased counter at [%d].", name, validators[name].counter) - - return nil -} diff --git a/core/crypto/validator_confidentiality.go b/core/crypto/validator_confidentiality.go deleted file mode 100644 index 80506e03d07..00000000000 --- a/core/crypto/validator_confidentiality.go +++ /dev/null @@ -1,135 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "encoding/asn1" - "errors" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -func (validator *validatorImpl) deepCloneTransaction(tx *obc.Transaction) (*obc.Transaction, error) { - raw, err := proto.Marshal(tx) - if err != nil { - validator.Errorf("Failed cloning transaction [%s].", err.Error()) - - return nil, err - } - - clone := &obc.Transaction{} - err = proto.Unmarshal(raw, clone) - if err != nil { - validator.Errorf("Failed cloning transaction [%s].", err.Error()) - - return nil, err - } - - return clone, nil -} - -func (validator *validatorImpl) deepCloneAndDecryptTx(tx *obc.Transaction) (*obc.Transaction, error) { - switch tx.ConfidentialityProtocolVersion { - case "1.2": - return validator.deepCloneAndDecryptTx1_2(tx) - } - return nil, utils.ErrInvalidProtocolVersion -} - -func (validator *validatorImpl) deepCloneAndDecryptTx1_2(tx *obc.Transaction) (*obc.Transaction, error) { - if tx.Nonce == nil || len(tx.Nonce) == 0 { - return nil, errors.New("Failed decrypting payload. Invalid nonce.") - } - - // clone tx - clone, err := validator.deepCloneTransaction(tx) - if err != nil { - validator.Errorf("Failed deep cloning [%s].", err.Error()) - return nil, err - } - - var ccPrivateKey primitives.PrivateKey - - validator.Debugf("Transaction type [%s].", tx.Type.String()) - - validator.Debug("Extract transaction key...") - - // Derive transaction key - cipher, err := validator.eciesSPI.NewAsymmetricCipherFromPrivateKey(validator.chainPrivateKey) - if err != nil { - validator.Errorf("Failed init decryption engine [%s].", err.Error()) - return nil, err - } - - msgToValidatorsRaw, err := cipher.Process(tx.ToValidators) - if err != nil { - validator.Errorf("Failed decrypting message to validators [% x]: [%s].", tx.ToValidators, err.Error()) - return nil, err - } - - msgToValidators := new(chainCodeValidatorMessage1_2) - _, err = asn1.Unmarshal(msgToValidatorsRaw, msgToValidators) - if err != nil { - validator.Errorf("Failed unmarshalling message to validators [%s].", err.Error()) - return nil, err - } - - validator.Debugf("Deserializing transaction key [% x].", msgToValidators.PrivateKey) - ccPrivateKey, err = validator.eciesSPI.DeserializePrivateKey(msgToValidators.PrivateKey) - if err != nil { - validator.Errorf("Failed deserializing transaction key [%s].", err.Error()) - return nil, err - } - - validator.Debug("Extract transaction key...done") - - cipher, err = validator.eciesSPI.NewAsymmetricCipherFromPrivateKey(ccPrivateKey) - if err != nil { - validator.Errorf("Failed init transaction decryption engine [%s].", err.Error()) - return nil, err - } - // Decrypt Payload - payload, err := cipher.Process(clone.Payload) - if err != nil { - validator.Errorf("Failed decrypting payload [%s].", err.Error()) - return nil, err - } - clone.Payload = payload - - // Decrypt ChaincodeID - chaincodeID, err := cipher.Process(clone.ChaincodeID) - if err != nil { - validator.Errorf("Failed decrypting chaincode [%s].", err.Error()) - return nil, err - } - clone.ChaincodeID = chaincodeID - - // Decrypt metadata - if len(clone.Metadata) != 0 { - metadata, err := cipher.Process(clone.Metadata) - if err != nil { - validator.Errorf("Failed decrypting metadata [%s].", err.Error()) - return nil, err - } - clone.Metadata = metadata - } - - return clone, nil -} diff --git a/core/crypto/validator_impl.go b/core/crypto/validator_impl.go deleted file mode 100644 index 403e05c5492..00000000000 --- a/core/crypto/validator_impl.go +++ /dev/null @@ -1,174 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "crypto/ecdsa" - - "fmt" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -// Public Struct - -type validatorImpl struct { - *peerImpl - - // Chain - chainPrivateKey primitives.PrivateKey -} - -// TransactionPreValidation verifies that the transaction is -// well formed with the respect to the security layer -// prescriptions (i.e. signature verification). -func (validator *validatorImpl) TransactionPreValidation(tx *obc.Transaction) (*obc.Transaction, error) { - if !validator.isInitialized { - return nil, utils.ErrNotInitialized - } - - return validator.peerImpl.TransactionPreValidation(tx) -} - -// TransactionPreValidation verifies that the transaction is -// well formed with the respect to the security layer -// prescriptions (i.e. signature verification). If this is the case, -// the method prepares the transaction to be executed. -func (validator *validatorImpl) TransactionPreExecution(tx *obc.Transaction) (*obc.Transaction, error) { - if !validator.isInitialized { - return nil, utils.ErrNotInitialized - } - - // validator.debug("Pre executing [%s].", tx.String()) - validator.Debugf("Tx confdential level [%s].", tx.ConfidentialityLevel.String()) - - switch tx.ConfidentialityLevel { - case obc.ConfidentialityLevel_PUBLIC: - // Nothing to do here! - - return tx, nil - case obc.ConfidentialityLevel_CONFIDENTIAL: - validator.Debug("Clone and Decrypt.") - - // Clone the transaction and decrypt it - newTx, err := validator.deepCloneAndDecryptTx(tx) - if err != nil { - validator.Errorf("Failed decrypting [%s].", err.Error()) - - return nil, err - } - - return newTx, nil - default: - return nil, utils.ErrInvalidConfidentialityLevel - } -} - -// Sign signs msg with this validator's signing key and outputs -// the signature if no error occurred. -func (validator *validatorImpl) Sign(msg []byte) ([]byte, error) { - return validator.signWithEnrollmentKey(msg) -} - -// Verify checks that signature if a valid signature of message under vkID's verification key. -// If the verification succeeded, Verify returns nil meaning no error occurred. -// If vkID is nil, then the signature is verified against this validator's verification key. -func (validator *validatorImpl) Verify(vkID, signature, message []byte) error { - if len(vkID) == 0 { - return fmt.Errorf("Invalid peer id. It is empty.") - } - if len(signature) == 0 { - return fmt.Errorf("Invalid signature. It is empty.") - } - if len(message) == 0 { - return fmt.Errorf("Invalid message. It is empty.") - } - - cert, err := validator.getEnrollmentCert(vkID) - if err != nil { - validator.Errorf("Failed getting enrollment cert for [% x]: [%s]", vkID, err) - - return err - } - - vk := cert.PublicKey.(*ecdsa.PublicKey) - - ok, err := validator.verify(vk, message, signature) - if err != nil { - validator.Errorf("Failed verifying signature for [% x]: [%s]", vkID, err) - - return err - } - - if !ok { - validator.Errorf("Failed invalid signature for [% x]", vkID) - - return utils.ErrInvalidSignature - } - - return nil -} - -// Private Methods - -func (validator *validatorImpl) register(id string, pwd []byte, enrollID, enrollPWD string, regFunc registerFunc) error { - // Register node - if err := validator.peerImpl.register(NodeValidator, id, pwd, enrollID, enrollPWD, nil); err != nil { - validator.Errorf("Failed registering [%s]: [%s]", enrollID, err) - return err - } - - return nil -} - -func (validator *validatorImpl) init(name string, pwd []byte, regFunc registerFunc) error { - - validatorInitFunc := func(eType NodeType, name string, pwd []byte) error { - // Init crypto engine - err := validator.initCryptoEngine() - if err != nil { - validator.Errorf("Failed initiliazing crypto engine [%s].", err.Error()) - return err - } - - return nil - } - - if err := validator.peerImpl.init(NodeValidator, name, pwd, validatorInitFunc); err != nil { - return err - } - - return nil -} - -func (validator *validatorImpl) initCryptoEngine() (err error) { - // Init chain publicKey - validator.chainPrivateKey, err = validator.eciesSPI.NewPrivateKey( - nil, validator.enrollChainKey.(*ecdsa.PrivateKey), - ) - if err != nil { - return - } - - return -} - -func (validator *validatorImpl) close() error { - return validator.peerImpl.close() -} diff --git a/core/crypto/validator_state.go b/core/crypto/validator_state.go deleted file mode 100644 index d8f169a87f9..00000000000 --- a/core/crypto/validator_state.go +++ /dev/null @@ -1,320 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package crypto - -import ( - "errors" - "reflect" - - "crypto/aes" - "crypto/cipher" - "encoding/asn1" - "encoding/binary" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/utils" - obc "github.com/hyperledger/fabric/protos" -) - -func (validator *validatorImpl) GetStateEncryptor(deployTx, executeTx *obc.Transaction) (StateEncryptor, error) { - switch executeTx.ConfidentialityProtocolVersion { - case "1.2": - return validator.getStateEncryptor1_2(deployTx, executeTx) - } - - return nil, utils.ErrInvalidConfidentialityLevel -} - -func (validator *validatorImpl) getStateEncryptor1_2(deployTx, executeTx *obc.Transaction) (StateEncryptor, error) { - // Check nonce - if deployTx.Nonce == nil || len(deployTx.Nonce) == 0 { - return nil, errors.New("Invalid deploy nonce.") - } - if executeTx.Nonce == nil || len(executeTx.Nonce) == 0 { - return nil, errors.New("Invalid invoke nonce.") - } - // Check ChaincodeID - if deployTx.ChaincodeID == nil { - return nil, errors.New("Invalid deploy chaincodeID.") - } - if executeTx.ChaincodeID == nil { - return nil, errors.New("Invalid execute chaincodeID.") - } - // Check that deployTx and executeTx refers to the same chaincode - if !reflect.DeepEqual(deployTx.ChaincodeID, executeTx.ChaincodeID) { - return nil, utils.ErrDifferentChaincodeID - } - // Check the confidentiality protocol version - if deployTx.ConfidentialityProtocolVersion != executeTx.ConfidentialityProtocolVersion { - return nil, utils.ErrDifferrentConfidentialityProtocolVersion - } - - validator.Debugf("Parsing transaction. Type [%s]. Confidentiality Protocol Version [%s]", executeTx.Type.String(), executeTx.ConfidentialityProtocolVersion) - - deployStateKey, err := validator.getStateKeyFromTransaction(deployTx) - - if executeTx.Type == obc.Transaction_CHAINCODE_QUERY { - validator.Debug("Parsing Query transaction...") - - executeStateKey, err := validator.getStateKeyFromTransaction(executeTx) - - // Compute deployTxKey key from the deploy transaction. This is used to decrypt the actual state - // of the chaincode - deployTxKey := primitives.HMAC(deployStateKey, deployTx.Nonce) - - // Compute the key used to encrypt the result of the query - //queryKey := utils.HMACTruncated(executeStateKey, append([]byte{6}, executeTx.Nonce...), utils.AESKeyLength) - - // Init the state encryptor - se := queryStateEncryptor{} - err = se.init(validator.nodeImpl, executeStateKey, deployTxKey) - if err != nil { - return nil, err - } - - return &se, nil - } - - // Compute deployTxKey key from the deploy transaction - deployTxKey := primitives.HMAC(deployStateKey, deployTx.Nonce) - - // Mask executeTx.Nonce - executeTxNonce := primitives.HMACTruncated(deployTxKey, primitives.Hash(executeTx.Nonce), primitives.NonceSize) - - // Compute stateKey to encrypt the states and nonceStateKey to generates IVs. This - // allows validators to reach consesus - stateKey := primitives.HMACTruncated(deployTxKey, append([]byte{3}, executeTxNonce...), primitives.AESKeyLength) - nonceStateKey := primitives.HMAC(deployTxKey, append([]byte{4}, executeTxNonce...)) - - // Init the state encryptor - se := stateEncryptorImpl{} - err = se.init(validator.nodeImpl, stateKey, nonceStateKey, deployTxKey, executeTxNonce) - if err != nil { - return nil, err - } - - return &se, nil -} - -func (validator *validatorImpl) getStateKeyFromTransaction(tx *obc.Transaction) ([]byte, error) { - cipher, err := validator.eciesSPI.NewAsymmetricCipherFromPrivateKey(validator.chainPrivateKey) - if err != nil { - validator.Errorf("Failed init decryption engine [%s].", err.Error()) - return nil, err - } - - msgToValidatorsRaw, err := cipher.Process(tx.ToValidators) - if err != nil { - validator.Errorf("Failed decrypting message to validators [% x]: [%s].", tx.ToValidators, err.Error()) - return nil, err - } - - msgToValidators := new(chainCodeValidatorMessage1_2) - _, err = asn1.Unmarshal(msgToValidatorsRaw, msgToValidators) - if err != nil { - validator.Errorf("Failed unmarshalling message to validators [% x]: [%s].", msgToValidators, err.Error()) - return nil, err - } - - return msgToValidators.StateKey, nil -} - -type stateEncryptorImpl struct { - node *nodeImpl - - deployTxKey []byte - invokeTxNonce []byte - - stateKey []byte - nonceStateKey []byte - - gcmEnc cipher.AEAD - nonceSize int - - counter uint64 -} - -func (se *stateEncryptorImpl) init(node *nodeImpl, stateKey, nonceStateKey, deployTxKey, invokeTxNonce []byte) error { - // Initi fields - se.counter = 0 - se.node = node - se.stateKey = stateKey - se.nonceStateKey = nonceStateKey - se.deployTxKey = deployTxKey - se.invokeTxNonce = invokeTxNonce - - // Init aes - c, err := aes.NewCipher(se.stateKey) - if err != nil { - return err - } - - // Init gcm for encryption - se.gcmEnc, err = cipher.NewGCM(c) - if err != nil { - return err - } - - // Init nonce size - se.nonceSize = se.gcmEnc.NonceSize() - return nil -} - -func (se *stateEncryptorImpl) Encrypt(msg []byte) ([]byte, error) { - var b = make([]byte, 8) - binary.BigEndian.PutUint64(b, se.counter) - - se.node.Debugf("Encrypting with counter [% x].", b) - // se.log.Infof("Encrypting with txNonce ", utils.EncodeBase64(se.txNonce)) - - nonce := primitives.HMACTruncated(se.nonceStateKey, b, se.nonceSize) - - se.counter++ - - // Seal will append the output to the first argument; the usage - // here appends the ciphertext to the nonce. The final parameter - // is any additional data to be authenticated. - out := se.gcmEnc.Seal(nonce, nonce, msg, se.invokeTxNonce) - - return append(se.invokeTxNonce, out...), nil -} - -func (se *stateEncryptorImpl) Decrypt(raw []byte) ([]byte, error) { - if len(raw) == 0 { - // A nil ciphertext decrypts to nil - return nil, nil - } - - if len(raw) <= primitives.NonceSize { - return nil, utils.ErrDecrypt - } - - // raw consists of (txNonce, ct) - txNonce := raw[:primitives.NonceSize] - // se.log.Infof("Decrypting with txNonce ", utils.EncodeBase64(txNonce)) - ct := raw[primitives.NonceSize:] - - nonce := make([]byte, se.nonceSize) - copy(nonce, ct) - - key := primitives.HMACTruncated(se.deployTxKey, append([]byte{3}, txNonce...), primitives.AESKeyLength) - // se.log.Infof("Decrypting with key ", utils.EncodeBase64(key)) - c, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - gcm, err := cipher.NewGCM(c) - if err != nil { - return nil, err - } - - se.nonceSize = se.gcmEnc.NonceSize() - - out, err := gcm.Open(nil, nonce, ct[se.nonceSize:], txNonce) - if err != nil { - return nil, utils.ErrDecrypt - } - return out, nil -} - -type queryStateEncryptor struct { - node *nodeImpl - - deployTxKey []byte - - gcmEnc cipher.AEAD - nonceSize int -} - -func (se *queryStateEncryptor) init(node *nodeImpl, queryKey, deployTxKey []byte) error { - // Initi fields - se.node = node - se.deployTxKey = deployTxKey - - // se.log.Infof("QUERY Encrypting with key ", utils.EncodeBase64(queryKey)) - - // Init aes - c, err := aes.NewCipher(queryKey) - if err != nil { - return err - } - - // Init gcm for encryption - se.gcmEnc, err = cipher.NewGCM(c) - if err != nil { - return err - } - - // Init nonce size - se.nonceSize = se.gcmEnc.NonceSize() - return nil -} - -func (se *queryStateEncryptor) Encrypt(msg []byte) ([]byte, error) { - nonce, err := primitives.GetRandomBytes(se.nonceSize) - if err != nil { - se.node.Errorf("Failed getting randomness [%s].", err.Error()) - return nil, err - } - - // Seal will append the output to the first argument; the usage - // here appends the ciphertext to the nonce. The final parameter - // is any additional data to be authenticated. - out := se.gcmEnc.Seal(nonce, nonce, msg, nil) - - return out, nil -} - -func (se *queryStateEncryptor) Decrypt(raw []byte) ([]byte, error) { - if len(raw) == 0 { - // A nil ciphertext decrypts to nil - return nil, nil - } - - if len(raw) <= primitives.NonceSize { - return nil, utils.ErrDecrypt - } - - // raw consists of (txNonce, ct) - txNonce := raw[:primitives.NonceSize] - // se.log.Infof("Decrypting with txNonce ", utils.EncodeBase64(txNonce)) - ct := raw[primitives.NonceSize:] - - nonce := make([]byte, se.nonceSize) - copy(nonce, ct) - - key := primitives.HMACTruncated(se.deployTxKey, append([]byte{3}, txNonce...), primitives.AESKeyLength) - // se.log.Infof("Decrypting with key ", utils.EncodeBase64(key)) - c, err := aes.NewCipher(key) - if err != nil { - return nil, err - } - - gcm, err := cipher.NewGCM(c) - if err != nil { - return nil, err - } - - se.nonceSize = se.gcmEnc.NonceSize() - - out, err := gcm.Open(nil, nonce, ct[se.nonceSize:], txNonce) - if err != nil { - return nil, utils.ErrDecrypt - } - return out, nil -} diff --git a/core/devops.go b/core/devops.go index ab96713681e..02f2a0683c3 100644 --- a/core/devops.go +++ b/core/devops.go @@ -29,7 +29,6 @@ import ( "encoding/base64" "sync" - "github.com/golang/protobuf/proto" "github.com/hyperledger/fabric/core/chaincode" "github.com/hyperledger/fabric/core/chaincode/platforms" "github.com/hyperledger/fabric/core/container" @@ -88,10 +87,8 @@ func (b *bindingMap) getTxHandlerForBinding(binding []byte) (crypto.TransactionH // Login establishes the security context with the Devops service func (d *Devops) Login(ctx context.Context, secret *pb.Secret) (*pb.Response, error) { - if err := crypto.RegisterClient(secret.EnrollId, nil, secret.EnrollId, secret.EnrollSecret); nil != err { - return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil - } - return &pb.Response{Status: pb.Response_SUCCESS}, nil + + return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte("login command has been removed")}, nil // TODO: Handle timeout and expiration } @@ -158,37 +155,13 @@ func (d *Devops) Deploy(ctx context.Context, spec *pb.ChaincodeSpec) (*pb.Chainc 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("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) { @@ -232,18 +205,6 @@ func (d *Devops) invokeOrQuery(ctx context.Context, chaincodeInvocationSpec *pb. 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 { @@ -328,152 +289,31 @@ func CheckSpec(spec *pb.ChaincodeSpec) error { // 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 + devopsLogger.Warning("GetApplicationTCert no longer supported") + return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte("no longer supported")}, 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 + devopsLogger.Warning("PrepareForTx no longer supported") + return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte("no longer supported")}, nil // TODO: Handle timeout and expiration } // 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 + devopsLogger.Warning("ProduceSigma no longer supported") + return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte("no longer supported")}, nil } // EXP_ExecuteWithBinding executes a transaction with a specific binding/TXHandler func (d *Devops) EXP_ExecuteWithBinding(ctx context.Context, executeWithBinding *pb.ExecuteWithBinding) (*pb.Response, error) { - if d.isSecurityEnabled { - devopsLogger.Debug("Getting TxHandler for binding") - - txHandler, err := d.bindingMap.getTxHandlerForBinding(executeWithBinding.Binding) - - if nil != err { - return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte(err.Error())}, nil - } - - ctorbytes, merr := asn1.Marshal(*executeWithBinding.ChaincodeInvocationSpec.ChaincodeSpec.CtorMsg) - if merr != nil { - return nil, fmt.Errorf("Error marshalling constructor: %s", err) - } - tid, generr := util.GenerateIDWithAlg("", ctorbytes) - if generr != nil { - return nil, fmt.Errorf("Error: cannot generate TX ID (executing with binding)") - } - - tx, err := txHandler.NewChaincodeExecute(executeWithBinding.ChaincodeInvocationSpec, tid) - if err != nil { - return nil, fmt.Errorf("Error creating executing with binding: %s", err) - } - - return d.coord.ExecuteTransaction(tx), nil - //return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte("NOT IMPLEMENTED")}, 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 + devopsLogger.Warning("ExecuteWithBinding no longer supported") + return &pb.Response{Status: pb.Response_FAILURE, Msg: []byte("no longer supported")}, nil } diff --git a/core/endorser/endorser_test.go b/core/endorser/endorser_test.go index 33c1dd78435..bf6390fe9fb 100644 --- a/core/endorser/endorser_test.go +++ b/core/endorser/endorser_test.go @@ -75,15 +75,7 @@ func initPeer() (net.Listener, error) { // Install security object for peer var secHelper crypto.Peer if viper.GetBool("security.enabled") { - enrollID := viper.GetString("security.enrollID") - enrollSecret := viper.GetString("security.enrollSecret") - if err = crypto.RegisterValidator(enrollID, nil, enrollID, enrollSecret); nil != err { - return nil, err - } - secHelper, err = crypto.InitValidator(enrollID, nil) - if nil != err { - return nil, err - } + //TODO: integrate new crypto / idp } ccStartupTimeout := time.Duration(30000) * time.Millisecond diff --git a/core/rest/rest_api.go b/core/rest/rest_api.go index f41041b8a1e..54f85c4409a 100644 --- a/core/rest/rest_api.go +++ b/core/rest/rest_api.go @@ -23,7 +23,6 @@ import ( "io" "io/ioutil" "net/http" - "net/url" "os" "regexp" "strconv" @@ -40,8 +39,6 @@ import ( core "github.com/hyperledger/fabric/core" "github.com/hyperledger/fabric/core/chaincode" "github.com/hyperledger/fabric/core/comm" - "github.com/hyperledger/fabric/core/crypto" - "github.com/hyperledger/fabric/core/crypto/primitives" pb "github.com/hyperledger/fabric/protos" ) @@ -422,82 +419,13 @@ func (s *ServerOpenchainREST) GetEnrollmentCert(rw web.ResponseWriter, req *web. encoder := json.NewEncoder(rw) - // If security is enabled, initialize the crypto client - if core.SecurityEnabled() { - if restLogger.IsEnabledFor(logging.DEBUG) { - restLogger.Debugf("Initializing secure client using context '%s'", enrollmentID) - } - - // Initialize the security client - sec, err := crypto.InitClient(enrollmentID, nil) - if err != nil { - rw.WriteHeader(http.StatusBadRequest) - encoder.Encode(restResult{Error: err.Error()}) - restLogger.Errorf("Error: %s", err) - - return - } - - // Obtain the client CertificateHandler - handler, err := sec.GetEnrollmentCertificateHandler() - if err != nil { - rw.WriteHeader(http.StatusInternalServerError) - encoder.Encode(restResult{Error: err.Error()}) - restLogger.Errorf("Error: %s", err) - - return - } - - // Certificate handler can not be hil - if handler == nil { - rw.WriteHeader(http.StatusInternalServerError) - encoder.Encode(restResult{Error: "Error retrieving certificate handler."}) - restLogger.Errorf("Error: Error retrieving certificate handler.") - - return - } - - // Obtain the DER encoded certificate - certDER := handler.GetCertificate() - - // Confirm the retrieved enrollment certificate is not nil - if certDER == nil { - rw.WriteHeader(http.StatusInternalServerError) - encoder.Encode(restResult{Error: "Enrollment certificate is nil."}) - restLogger.Errorf("Error: Enrollment certificate is nil.") + // Security must be enabled to request enrollment certificates + rw.WriteHeader(http.StatusBadRequest) + encoder.Encode(restResult{Error: "GetEnrollmentCert no longer supported"}) + restLogger.Errorf("Error: GetEnrollmentCert no longer supported") - return - } - - // Confirm the retrieved enrollment certificate has non-zero length - if len(certDER) == 0 { - rw.WriteHeader(http.StatusInternalServerError) - encoder.Encode(restResult{Error: "Enrollment certificate length is 0."}) - restLogger.Errorf("Error: Enrollment certificate length is 0.") - - return - } - - // Transforms the DER encoded certificate to a PEM encoded certificate - certPEM := primitives.DERCertToPEM(certDER) - - // As the enrollment certificate contains \n characters, url encode it before outputting - urlEncodedCert := url.QueryEscape(string(certPEM)) - - // Close the security client - crypto.CloseClient(sec) - - rw.WriteHeader(http.StatusOK) - encoder.Encode(restResult{OK: urlEncodedCert}) - restLogger.Debugf("Successfully retrieved enrollment certificate for secure context '%s'", enrollmentID) - } else { - // Security must be enabled to request enrollment certificates - rw.WriteHeader(http.StatusBadRequest) - encoder.Encode(restResult{Error: "Security functionality must be enabled before requesting client certificates."}) - restLogger.Errorf("Error: Security functionality must be enabled before requesting client certificates.") + return - return - } } // GetTransactionCert retrieves the transaction certificate(s) for a given user. @@ -513,125 +441,13 @@ func (s *ServerOpenchainREST) GetTransactionCert(rw web.ResponseWriter, req *web encoder := json.NewEncoder(rw) - // Parse out the count query parameter - req.ParseForm() - queryParams := req.Form - - // The default number of TCerts to retrieve is 1 - var count uint32 = 1 - - // If the query parameter is present, examine the supplied value - if queryParams["count"] != nil { - // Convert string to uint. The parse function return the widest type (uint64) - // Setting base to 32 allows you to subsequently cast the value to uint32 - qParam, err := strconv.ParseUint(queryParams["count"][0], 10, 32) - - // Check for count parameter being a non-negative integer - if err != nil { - rw.WriteHeader(http.StatusBadRequest) - encoder.Encode(restResult{Error: "Count query parameter must be a non-negative integer."}) - restLogger.Errorf("Error: Count query parameter must be a non-negative integer.") - - return - } - - // If the query parameter is within the allowed range, record it - if qParam > 0 && qParam <= 500 { - count = uint32(qParam) - } - - // Limit the number of TCerts retrieved to 500 - if qParam > 500 { - count = 500 - } - } - - // If security is enabled, initialize the crypto client - if core.SecurityEnabled() { - if restLogger.IsEnabledFor(logging.DEBUG) { - restLogger.Debugf("Initializing secure client using context '%s'", enrollmentID) - } - - // Initialize the security client - sec, err := crypto.InitClient(enrollmentID, nil) - if err != nil { - rw.WriteHeader(http.StatusBadRequest) - encoder.Encode(restResult{Error: err.Error()}) - restLogger.Errorf("Error: %s", err) - - return - } - - // Obtain the client CertificateHandler - // TODO - Replace empty attributes map - attributes := []string{} - handler, err := sec.GetTCertificateHandlerNext(attributes...) - if err != nil { - rw.WriteHeader(http.StatusInternalServerError) - encoder.Encode(restResult{Error: err.Error()}) - restLogger.Errorf("Error: %s", err) - - return - } - - // Certificate handler can not be hil - if handler == nil { - rw.WriteHeader(http.StatusInternalServerError) - encoder.Encode(restResult{Error: "Error retrieving certificate handler."}) - restLogger.Errorf("Error: Error retrieving certificate handler.") + // Security must be enabled to request transaction certificates + rw.WriteHeader(http.StatusBadRequest) + encoder.Encode(restResult{Error: "GetTransactionCert no longer supported"}) + restLogger.Errorf("Error: GetTransactionCert no longer supported") - return - } - - // Retrieve the required number of TCerts - tcertArray := make([]string, count) - var i uint32 - for i = 0; i < count; i++ { - // Obtain the DER encoded certificate - certDER := handler.GetCertificate() - - // Confirm the retrieved enrollment certificate is not nil - if certDER == nil { - rw.WriteHeader(http.StatusInternalServerError) - encoder.Encode(restResult{Error: "Transaction certificate is nil."}) - restLogger.Errorf("Error: Transaction certificate is nil.") - - return - } - - // Confirm the retrieved enrollment certificate has non-zero length - if len(certDER) == 0 { - rw.WriteHeader(http.StatusInternalServerError) - encoder.Encode(restResult{Error: "Transaction certificate length is 0."}) - restLogger.Errorf("Error: Transaction certificate length is 0.") - - return - } - - // Transforms the DER encoded certificate to a PEM encoded certificate - certPEM := primitives.DERCertToPEM(certDER) - - // As the transaction certificate contains \n characters, url encode it before outputting - urlEncodedCert := url.QueryEscape(string(certPEM)) - - // Add the urlEncodedCert transaction certificate to the certificate array - tcertArray[i] = urlEncodedCert - } - - // Close the security client - crypto.CloseClient(sec) - - rw.WriteHeader(http.StatusOK) - encoder.Encode(tcertsResult{OK: tcertArray}) - restLogger.Debugf("Successfully retrieved transaction certificates for secure context '%s'", enrollmentID) - } else { - // Security must be enabled to request transaction certificates - rw.WriteHeader(http.StatusBadRequest) - encoder.Encode(restResult{Error: "Security functionality must be enabled before requesting client certificates."}) - restLogger.Errorf("Error: Security functionality must be enabled before requesting client certificates.") + return - return - } } // GetBlockchainInfo returns information about the blockchain ledger such as diff --git a/membersrvc/ca/aca.go b/membersrvc/ca/aca.go deleted file mode 100644 index 22e9428b139..00000000000 --- a/membersrvc/ca/aca.go +++ /dev/null @@ -1,399 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "encoding/asn1" - "errors" - "strings" - "time" - - "crypto/x509" - - "database/sql" - - "github.com/hyperledger/fabric/flogging" - "github.com/op/go-logging" - "github.com/spf13/viper" - "google.golang.org/grpc" - - "github.com/golang/protobuf/ptypes/timestamp" - pb "github.com/hyperledger/fabric/membersrvc/protos" -) - -var acaLogger = logging.MustGetLogger("aca") - -var ( - //ACAAttribute is the base OID to the attributes extensions. - ACAAttribute = asn1.ObjectIdentifier{1, 2, 3, 4, 5, 6, 10} -) - -// ACA is the attribute certificate authority. -type ACA struct { - *CA - gRPCServer *grpc.Server -} - -// ACAA serves the administrator GRPC interface of the ACA. -// -type ACAA struct { - aca *ACA -} - -//IsAttributeOID returns if the oid passed as parameter is or not linked with an attribute -func IsAttributeOID(oid asn1.ObjectIdentifier) bool { - l := len(oid) - if len(ACAAttribute) != l { - return false - } - for i := 0; i < l-1; i++ { - if ACAAttribute[i] != oid[i] { - return false - } - } - - return ACAAttribute[l-1] < oid[l-1] -} - -func initializeACATables(db *sql.DB) error { - if _, err := db.Exec("CREATE TABLE IF NOT EXISTS Attributes (row INTEGER PRIMARY KEY, id VARCHAR(64), affiliation VARCHAR(64), attributeName VARCHAR(64), validFrom DATETIME, validTo DATETIME, attributeValue BLOB)"); err != nil { - return err - } - return nil -} - -//AttributeOwner is the struct that contains the data related with the user who owns the attribute. -type AttributeOwner struct { - id string - affiliation string -} - -//AttributePair is an struct that store the relation between an owner (user who owns the attribute), attributeName (name of the attribute), attributeValue (value of the attribute), -//validFrom (time since the attribute is valid) and validTo (time until the attribute will be valid). -type AttributePair struct { - owner *AttributeOwner - attributeName string - attributeValue []byte - validFrom time.Time - validTo time.Time -} - -//NewAttributePair creates a new attribute pair associated with . -func NewAttributePair(attributeVals []string, attrOwner *AttributeOwner) (*AttributePair, error) { - if len(attributeVals) < 6 { - return nil, errors.New("Invalid attribute entry") - } - var attrPair = *new(AttributePair) - if attrOwner != nil { - attrPair.SetOwner(attrOwner) - } else { - attrPair.SetOwner(&AttributeOwner{strings.TrimSpace(attributeVals[0]), strings.TrimSpace(attributeVals[1])}) - } - attrPair.SetAttributeName(strings.TrimSpace(attributeVals[2])) - attrPair.SetAttributeValue([]byte(strings.TrimSpace(attributeVals[3]))) - //Reading validFrom date - dateStr := strings.TrimSpace(attributeVals[4]) - if dateStr != "" { - var t time.Time - var err error - if t, err = time.Parse(time.RFC3339, dateStr); err != nil { - return nil, err - } - attrPair.SetValidFrom(t) - } - //Reading validTo date - dateStr = strings.TrimSpace(attributeVals[5]) - if dateStr != "" { - var t time.Time - var err error - if t, err = time.Parse(time.RFC3339, dateStr); err != nil { - return nil, err - } - attrPair.SetValidTo(t) - } - return &attrPair, nil -} - -//GetID returns the id of the attributeOwner. -func (attrOwner *AttributeOwner) GetID() string { - return attrOwner.id -} - -//GetAffiliation returns the affiliation related with the owner. -func (attrOwner *AttributeOwner) GetAffiliation() string { - return attrOwner.affiliation -} - -//GetOwner returns the owner of the attribute pair. -func (attrPair *AttributePair) GetOwner() *AttributeOwner { - return attrPair.owner -} - -//SetOwner sets the owner of the attributes. -func (attrPair *AttributePair) SetOwner(owner *AttributeOwner) { - attrPair.owner = owner -} - -//GetID returns the id of the attributePair. -func (attrPair *AttributePair) GetID() string { - return attrPair.owner.GetID() -} - -//GetAffiliation gets the affilition of the attribute pair. -func (attrPair *AttributePair) GetAffiliation() string { - return attrPair.owner.GetAffiliation() -} - -//GetAttributeName gets the attribute name related with the attribute pair. -func (attrPair *AttributePair) GetAttributeName() string { - return attrPair.attributeName -} - -//SetAttributeName sets the name related with the attribute pair. -func (attrPair *AttributePair) SetAttributeName(name string) { - attrPair.attributeName = name -} - -//GetAttributeValue returns the value of the pair. -func (attrPair *AttributePair) GetAttributeValue() []byte { - return attrPair.attributeValue -} - -//SetAttributeValue sets the value of the pair. -func (attrPair *AttributePair) SetAttributeValue(val []byte) { - attrPair.attributeValue = val -} - -//IsValidFor returns if the pair is valid for date. -func (attrPair *AttributePair) IsValidFor(date time.Time) bool { - return (attrPair.validFrom.Before(date) || attrPair.validFrom.Equal(date)) && (attrPair.validTo.IsZero() || attrPair.validTo.After(date)) -} - -//GetValidFrom returns time which is valid from the pair. -func (attrPair *AttributePair) GetValidFrom() time.Time { - return attrPair.validFrom -} - -//SetValidFrom returns time which is valid from the pair. -func (attrPair *AttributePair) SetValidFrom(date time.Time) { - attrPair.validFrom = date -} - -//GetValidTo returns time which is valid to the pair. -func (attrPair *AttributePair) GetValidTo() time.Time { - return attrPair.validTo -} - -//SetValidTo returns time which is valid to the pair. -func (attrPair *AttributePair) SetValidTo(date time.Time) { - attrPair.validTo = date -} - -//ToACAAttribute converts the receiver to the protobuf format. -func (attrPair *AttributePair) ToACAAttribute() *pb.ACAAttribute { - var from, to *timestamp.Timestamp - if attrPair.validFrom.IsZero() { - from = nil - } else { - from = ×tamp.Timestamp{Seconds: attrPair.validFrom.Unix(), Nanos: int32(attrPair.validFrom.UnixNano())} - } - if attrPair.validTo.IsZero() { - to = nil - } else { - to = ×tamp.Timestamp{Seconds: attrPair.validTo.Unix(), Nanos: int32(attrPair.validTo.UnixNano())} - - } - return &pb.ACAAttribute{AttributeName: attrPair.attributeName, AttributeValue: attrPair.attributeValue, ValidFrom: from, ValidTo: to} -} - -// NewACA sets up a new ACA. -func NewACA() *ACA { - aca := &ACA{CA: NewCA("aca", initializeACATables)} - flogging.LoggingInit("aca") - return aca -} - -func (aca *ACA) getECACertificate() (*x509.Certificate, error) { - raw, err := aca.readCACertificate("eca") - if err != nil { - return nil, err - } - return x509.ParseCertificate(raw) -} - -func (aca *ACA) getTCACertificate() (*x509.Certificate, error) { - raw, err := aca.readCACertificate("tca") - if err != nil { - return nil, err - } - return x509.ParseCertificate(raw) -} - -func (aca *ACA) fetchAttributes(id, affiliation string) ([]*AttributePair, error) { - // TODO this attributes should be readed from the outside world in place of configuration file. - var attributes = make([]*AttributePair, 0) - attrs := viper.GetStringMapString("aca.attributes") - - for _, flds := range attrs { - vals := strings.Fields(flds) - if len(vals) >= 1 { - val := "" - for _, eachVal := range vals { - val = val + " " + eachVal - } - attributeVals := strings.Split(val, ";") - if len(attributeVals) >= 6 { - attrPair, err := NewAttributePair(attributeVals, nil) - if err != nil { - return nil, errors.New("Invalid attribute entry " + val + " " + err.Error()) - } - if attrPair.GetID() != id || attrPair.GetAffiliation() != affiliation { - continue - } - attributes = append(attributes, attrPair) - } else { - acaLogger.Errorf("Invalid attribute entry '%v'", vals[0]) - } - } - } - - acaLogger.Debugf("%v %v", id, attributes) - - return attributes, nil -} - -func (aca *ACA) PopulateAttributes(attrs []*AttributePair) error { - - acaLogger.Debugf("PopulateAttributes: %+v", attrs) - - mutex.Lock() - defer mutex.Unlock() - - tx, dberr := aca.db.Begin() - if dberr != nil { - return dberr - } - for _, attr := range attrs { - acaLogger.Debugf("attr: %+v", attr) - if err := aca.populateAttribute(tx, attr); err != nil { - dberr = tx.Rollback() - if dberr != nil { - return dberr - } - return err - } - } - dberr = tx.Commit() - if dberr != nil { - return dberr - } - return nil -} - -func (aca *ACA) populateAttribute(tx *sql.Tx, attr *AttributePair) error { - var count int - err := tx.QueryRow("SELECT count(row) AS cant FROM Attributes WHERE id=? AND affiliation =? AND attributeName =?", - attr.GetID(), attr.GetAffiliation(), attr.GetAttributeName()).Scan(&count) - - if err != nil { - return err - } - - if count > 0 { - _, err = tx.Exec("UPDATE Attributes SET validFrom = ?, validTo = ?, attributeValue = ? WHERE id=? AND affiliation =? AND attributeName =? AND validFrom < ?", - attr.GetValidFrom(), attr.GetValidTo(), attr.GetAttributeValue(), attr.GetID(), attr.GetAffiliation(), attr.GetAttributeName(), attr.GetValidFrom()) - if err != nil { - return err - } - } else { - _, err = tx.Exec("INSERT INTO Attributes (validFrom , validTo, attributeValue, id, affiliation, attributeName) VALUES (?,?,?,?,?,?)", - attr.GetValidFrom(), attr.GetValidTo(), attr.GetAttributeValue(), attr.GetID(), attr.GetAffiliation(), attr.GetAttributeName()) - if err != nil { - return err - } - } - return nil -} - -func (aca *ACA) fetchAndPopulateAttributes(id, affiliation string) error { - var attrs []*AttributePair - attrs, err := aca.fetchAttributes(id, affiliation) - if err != nil { - return err - } - err = aca.PopulateAttributes(attrs) - if err != nil { - return err - } - return nil -} - -func (aca *ACA) findAttribute(owner *AttributeOwner, attributeName string) (*AttributePair, error) { - var count int - - mutex.RLock() - defer mutex.RUnlock() - - err := aca.db.QueryRow("SELECT count(row) AS cant FROM Attributes WHERE id=? AND affiliation =? AND attributeName =?", - owner.GetID(), owner.GetAffiliation(), attributeName).Scan(&count) - if err != nil { - return nil, err - } - - if count == 0 { - return nil, nil - } - - var attName string - var attValue []byte - var validFrom, validTo time.Time - err = aca.db.QueryRow("SELECT attributeName, attributeValue, validFrom, validTo AS cant FROM Attributes WHERE id=? AND affiliation =? AND attributeName =?", - owner.GetID(), owner.GetAffiliation(), attributeName).Scan(&attName, &attValue, &validFrom, &validTo) - if err != nil { - return nil, err - } - - return &AttributePair{owner, attName, attValue, validFrom, validTo}, nil -} - -func (aca *ACA) startACAP(srv *grpc.Server) { - pb.RegisterACAPServer(srv, &ACAP{aca}) - acaLogger.Info("ACA PUBLIC gRPC API server started") -} - -// Start starts the ACA. -func (aca *ACA) Start(srv *grpc.Server) { - acaLogger.Info("Staring ACA services...") - aca.startACAP(srv) - aca.gRPCServer = srv - acaLogger.Info("ACA services started") -} - -// Stop stops the ACA -func (aca *ACA) Stop() error { - acaLogger.Info("Stopping the ACA services...") - if aca.gRPCServer != nil { - aca.gRPCServer.Stop() - } - err := aca.CA.Stop() - if err != nil { - acaLogger.Errorf("Error stopping the ACA services: %s ", err) - } else { - acaLogger.Info("ACA services stopped") - } - return err -} diff --git a/membersrvc/ca/aca_test.go b/membersrvc/ca/aca_test.go deleted file mode 100644 index 476085a7e26..00000000000 --- a/membersrvc/ca/aca_test.go +++ /dev/null @@ -1,624 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "bytes" - "errors" - "io/ioutil" - "math/big" - "strings" - "testing" - "time" - - "crypto/x509" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/hyperledger/fabric/core/crypto/primitives" - pb "github.com/hyperledger/fabric/membersrvc/protos" - "golang.org/x/net/context" -) - -var identity = "test_user0" - -func loadECert(identityID string) (*x509.Certificate, error) { - ecertRaw, err := ioutil.ReadFile("./test_resources/ecert_" + identityID + ".dump") - if err != nil { - return nil, err - } - - ecert, err := x509.ParseCertificate(ecertRaw) - - if err != nil { - return nil, err - } - - var certificateID = strings.Split(ecert.Subject.CommonName, "\\")[0] - - if identityID != certificateID { - return nil, errors.New("Incorrect ecert user.") - } - - return ecert, nil -} - -func TestFetchAttributes(t *testing.T) { - resp, err := fetchAttributes() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status == pb.ACAFetchAttrResp_FAILURE { - t.Fatalf("Error executing test: %v", "Error fetching attributes.") - } -} - -func TestFetchAttributes_MultipleInvocations(t *testing.T) { - expectedAttributesSize := 3 - expectedCount := 3 - - resp, err := fetchAttributes() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status == pb.ACAFetchAttrResp_FAILURE { - t.Fatalf("Error executing test: %v", "Error fetching attributes.") - } - - attributesMap1, count, err := readAttributesFromDB("test_user0", "bank_a") - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if count != expectedCount { - t.Fatalf("Error executing test: Expected count [%v], Actual count [%v]", expectedCount, count) - } - - resp, err = fetchAttributes() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status == pb.ACAFetchAttrResp_FAILURE { - t.Fatalf("Error executing test: %v", "Error fetching attributes.") - } - - attributesMap2, count, err := readAttributesFromDB("test_user0", "bank_a") - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if count != expectedCount { - t.Fatalf("Error executing test: Expected count [%v], Actual count [%v]", expectedCount, count) - } - - if len(attributesMap1) != expectedAttributesSize { - t.Fatalf("Error executing test: Expected attributes size [%v], Actual attributes size [%v]", expectedAttributesSize, len(attributesMap1)) - } - - if len(attributesMap1) != len(attributesMap2) { - t.Fatalf("Error executing test: %v", "attributes should be the same each time") - } - - for key, value := range attributesMap1 { - if bytes.Compare(value, attributesMap2[key]) != 0 { - t.Fatalf("Error executing test: %v. Expected: [%v], Actual: [%v]", "attributes should be the same each time", value, attributesMap2[key]) - } - } - - if len(attributesMap1) != len(attributesMap2) { - t.Fatalf("Error executing test: %v", "attributes should be the same each time") - } - -} - -func readAttributesFromDB(id string, affiliation string) (map[string][]byte, int, error) { - var attributeName string - var attributeValue []byte - - query := "SELECT attributeName, attributeValue FROM attributes WHERE id=? AND affiliation=?" - - rows, err := aca.db.Query(query, id, affiliation) - if err != nil { - return nil, 0, err - } - - defer rows.Close() - - count := 0 - attributesMap := make(map[string][]byte) - for rows.Next() { - err := rows.Scan(&attributeName, &attributeValue) - if err != nil { - return nil, 0, err - } - attributesMap[attributeName] = attributeValue - count++ - } - - return attributesMap, count, nil -} - -func fetchAttributes() (*pb.ACAFetchAttrResp, error) { - cert, err := loadECert(identity) - - if err != nil { - return nil, err - } - sock, acaP, err := GetACAClient() - if err != nil { - return nil, err - } - defer sock.Close() - - req := &pb.ACAFetchAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - ECert: &pb.Cert{Cert: cert.Raw}, - Signature: nil} - - var rawReq []byte - rawReq, err = proto.Marshal(req) - if err != nil { - return nil, err - } - - var r, s *big.Int - - r, s, err = primitives.ECDSASignDirect(eca.priv, rawReq) - - if err != nil { - return nil, err - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - req.Signature = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err := acaP.FetchAttributes(context.Background(), req) - - return resp, err -} - -func TestFetchAttributes_MissingSignature(t *testing.T) { - - cert, err := loadECert(identity) - - if err != nil { - t.Fatalf("Error loading ECert: %v", err) - } - sock, acaP, err := GetACAClient() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - defer sock.Close() - - req := &pb.ACAFetchAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - ECert: &pb.Cert{Cert: cert.Raw}, - Signature: nil} - - resp, err := acaP.FetchAttributes(context.Background(), req) - - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status == pb.ACAFetchAttrResp_SUCCESS { - t.Fatalf("Fetching attributes without a signature should fail") - } -} - -func TestRequestAttributes(t *testing.T) { - - cert, err := loadECert(identity) - if err != nil { - t.Fatalf("Error loading ECert: %v", err) - } - ecert := cert.Raw - - sock, acaP, err := GetACAClient() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - defer sock.Close() - - var attributes = make([]*pb.TCertAttribute, 0) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "company"}) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "position"}) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "identity-number"}) - - req := &pb.ACAAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: identity}, - ECert: &pb.Cert{Cert: ecert}, - Attributes: attributes, - Signature: nil} - - var rawReq []byte - rawReq, err = proto.Marshal(req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - var r, s *big.Int - - r, s, err = primitives.ECDSASignDirect(tca.priv, rawReq) - - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - req.Signature = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err := acaP.RequestAttributes(context.Background(), req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status == pb.ACAAttrResp_FAILURE { - t.Fatalf("Error executing test: %v", err) - } - - aCert, err := primitives.DERToX509Certificate(resp.Cert.Cert) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - valueMap := make(map[string]string) - for _, eachExtension := range aCert.Extensions { - if IsAttributeOID(eachExtension.Id) { - var attribute pb.ACAAttribute - proto.Unmarshal(eachExtension.Value, &attribute) - valueMap[attribute.AttributeName] = string(attribute.AttributeValue) - } - } - - if valueMap["company"] != "ACompany" { - t.Fatal("Test failed 'company' attribute don't found.") - } - - if valueMap["position"] != "Software Engineer" { - t.Fatal("Test failed 'position' attribute don't found.") - } -} - -func TestRequestAttributes_AttributesMismatch(t *testing.T) { - - cert, err := loadECert(identity) - if err != nil { - t.Fatalf("Error loading ECert: %v", err) - } - ecert := cert.Raw - - sock, acaP, err := GetACAClient() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - defer sock.Close() - - var attributes = make([]*pb.TCertAttribute, 0) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "account"}) - - req := &pb.ACAAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: identity}, - ECert: &pb.Cert{Cert: ecert}, - Attributes: attributes, - Signature: nil} - - var rawReq []byte - rawReq, err = proto.Marshal(req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - var r, s *big.Int - - r, s, err = primitives.ECDSASignDirect(tca.priv, rawReq) - - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - req.Signature = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err := acaP.RequestAttributes(context.Background(), req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status == pb.ACAAttrResp_FAILURE { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status != pb.ACAAttrResp_NO_ATTRIBUTES_FOUND { - t.Fatal("Test failed 'account' attribute shouldn't be found.") - } - -} - -func TestRequestAttributes_MissingSignature(t *testing.T) { - - cert, err := loadECert(identity) - if err != nil { - t.Fatalf("Error loading ECert: %v", err) - } - ecert := cert.Raw - - sock, acaP, err := GetACAClient() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - defer sock.Close() - - var attributes = make([]*pb.TCertAttribute, 0) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "company"}) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "position"}) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "identity-number"}) - - req := &pb.ACAAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: identity}, - ECert: &pb.Cert{Cert: ecert}, - Attributes: attributes, - Signature: nil} - - resp, err := acaP.RequestAttributes(context.Background(), req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status < pb.ACAAttrResp_FAILURE_MINVAL || resp.Status > pb.ACAAttrResp_FAILURE_MAXVAL { - t.Fatalf("Requesting attributes without a signature should fail") - } -} - -func TestRequestAttributes_DuplicatedAttributes(t *testing.T) { - - cert, err := loadECert(identity) - if err != nil { - t.Fatalf("Error loading ECert: %v", err) - } - ecert := cert.Raw - - sock, acaP, err := GetACAClient() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - defer sock.Close() - - var attributes = make([]*pb.TCertAttribute, 0) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "company"}) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "company"}) - - req := &pb.ACAAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: identity}, - ECert: &pb.Cert{Cert: ecert}, - Attributes: attributes, - Signature: nil} - - var rawReq []byte - rawReq, err = proto.Marshal(req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - var r, s *big.Int - - r, s, err = primitives.ECDSASignDirect(tca.priv, rawReq) - - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - req.Signature = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err := acaP.RequestAttributes(context.Background(), req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status < pb.ACAAttrResp_FAILURE_MINVAL || resp.Status > pb.ACAAttrResp_FAILURE_MAXVAL { - t.Fatalf("Requesting attributes with multiple values should fail") - } -} - -func TestRequestAttributes_FullAttributes(t *testing.T) { - - cert, err := loadECert(identity) - if err != nil { - t.Fatalf("Error loading ECert: %v", err) - } - ecert := cert.Raw - - sock, acaP, err := GetACAClient() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - defer sock.Close() - - var attributes []*pb.TCertAttribute - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "company"}) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "business_unit"}) - - req := &pb.ACAAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: identity}, - ECert: &pb.Cert{Cert: ecert}, - Attributes: attributes, - Signature: nil} - - var rawReq []byte - rawReq, err = proto.Marshal(req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - var r, s *big.Int - - r, s, err = primitives.ECDSASignDirect(tca.priv, rawReq) - - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - req.Signature = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err := acaP.RequestAttributes(context.Background(), req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status == pb.ACAAttrResp_FAILURE { - t.Fatalf("Error executing test: %v", err) - } - - aCert, err := primitives.DERToX509Certificate(resp.Cert.Cert) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - valueMap := make(map[string]string) - for _, eachExtension := range aCert.Extensions { - if IsAttributeOID(eachExtension.Id) { - var attribute pb.ACAAttribute - proto.Unmarshal(eachExtension.Value, &attribute) - valueMap[attribute.AttributeName] = string(attribute.AttributeValue) - } - } - - if valueMap["company"] != "ACompany" { - t.Fatalf("The attribute should have coincided.") - } - - if valueMap["business_unit"] != "Sales" { - t.Fatalf("The attribute should have coincided.") - } - - if resp.Status != pb.ACAAttrResp_FULL_SUCCESSFUL { - t.Fatalf("All attributes in the query should have coincided.") - } -} - -func TestRequestAttributes_PartialAttributes(t *testing.T) { - - cert, err := loadECert(identity) - if err != nil { - t.Fatalf("Error loading ECert: %v", err) - } - ecert := cert.Raw - - sock, acaP, err := GetACAClient() - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - defer sock.Close() - - var attributes []*pb.TCertAttribute - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "company"}) - attributes = append(attributes, &pb.TCertAttribute{AttributeName: "credit_card"}) - - req := &pb.ACAAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: identity}, - ECert: &pb.Cert{Cert: ecert}, - Attributes: attributes, - Signature: nil} - - var rawReq []byte - rawReq, err = proto.Marshal(req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - var r, s *big.Int - - r, s, err = primitives.ECDSASignDirect(tca.priv, rawReq) - - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - req.Signature = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err := acaP.RequestAttributes(context.Background(), req) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - if resp.Status == pb.ACAAttrResp_FAILURE { - t.Fatalf("Error executing test: %v", err) - } - - aCert, err := primitives.DERToX509Certificate(resp.Cert.Cert) - if err != nil { - t.Fatalf("Error executing test: %v", err) - } - - valueMap := make(map[string]string) - for _, eachExtension := range aCert.Extensions { - if IsAttributeOID(eachExtension.Id) { - var attribute pb.ACAAttribute - proto.Unmarshal(eachExtension.Value, &attribute) - valueMap[attribute.AttributeName] = string(attribute.AttributeValue) - } - } - - if valueMap["company"] != "ACompany" { - t.Fatalf("The attribute should have coincided.") - } - - if valueMap["credit_card"] != "" { - t.Fatalf("The Attribute should be blank.") - } - - if resp.Status == pb.ACAAttrResp_NO_ATTRIBUTES_FOUND { - t.Fatalf("At least one attribute must be conincided") - } - - if resp.Status != pb.ACAAttrResp_PARTIAL_SUCCESSFUL { - t.Fatalf("All attributes in the query should have coincided.") - } -} - -func contains(s []string, e string) bool { - for _, a := range s { - if a == e { - return true - } - } - return false -} diff --git a/membersrvc/ca/acap.go b/membersrvc/ca/acap.go deleted file mode 100644 index 4ab6114c763..00000000000 --- a/membersrvc/ca/acap.go +++ /dev/null @@ -1,234 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "encoding/asn1" - "errors" - "math/big" - - "crypto/ecdsa" - "crypto/x509" - "crypto/x509/pkix" - - "github.com/golang/protobuf/proto" - "github.com/op/go-logging" - "golang.org/x/net/context" - - "github.com/hyperledger/fabric/core/crypto/primitives" - pb "github.com/hyperledger/fabric/membersrvc/protos" -) - -var acapLogger = logging.MustGetLogger("acap") - -// ACAP serves the public GRPC interface of the ACA. -// -type ACAP struct { - aca *ACA -} - -// FetchAttributes fetchs the attributes from the outside world and populate them into the database. -func (acap *ACAP) FetchAttributes(ctx context.Context, in *pb.ACAFetchAttrReq) (*pb.ACAFetchAttrResp, error) { - acapLogger.Debug("grpc ACAP:FetchAttributes") - - if in.Ts == nil || in.ECert == nil || in.Signature == nil { - return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE, Msg: "Bad request"}, nil - } - - cert, err := acap.aca.getECACertificate() - if err != nil { - return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE}, errors.New("Error getting ECA certificate.") - } - - ecaPub := cert.PublicKey.(*ecdsa.PublicKey) - r, s := big.NewInt(0), big.NewInt(0) - r.UnmarshalText(in.Signature.R) - s.UnmarshalText(in.Signature.S) - - in.Signature = nil - - hash := primitives.NewHash() - raw, _ := proto.Marshal(in) - hash.Write(raw) - - if ecdsa.Verify(ecaPub, hash.Sum(nil), r, s) == false { - return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE, Msg: "Signature does not verify"}, nil - } - - cert, err = x509.ParseCertificate(in.ECert.Cert) - if err != nil { - return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE}, err - } - - var id, affiliation string - id, affiliation, err = acap.aca.parseEnrollID(cert.Subject.CommonName) - if err != nil { - return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE}, err - } - - err = acap.aca.fetchAndPopulateAttributes(id, affiliation) - if err != nil { - return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_FAILURE}, err - } - - return &pb.ACAFetchAttrResp{Status: pb.ACAFetchAttrResp_SUCCESS}, nil -} - -func (acap *ACAP) createRequestAttributeResponse(status pb.ACAAttrResp_StatusCode, cert *pb.Cert) *pb.ACAAttrResp { - resp := &pb.ACAAttrResp{Status: status, Cert: cert, Signature: nil} - rawReq, err := proto.Marshal(resp) - if err != nil { - return &pb.ACAAttrResp{Status: pb.ACAAttrResp_FAILURE, Cert: nil, Signature: nil} - } - - r, s, err := primitives.ECDSASignDirect(acap.aca.priv, rawReq) - if err != nil { - return &pb.ACAAttrResp{Status: pb.ACAAttrResp_FAILURE, Cert: nil, Signature: nil} - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - resp.Signature = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - return resp -} - -// RequestAttributes lookups the atributes in the database and return a certificate with attributes included in the request and found in the database. -func (acap *ACAP) RequestAttributes(ctx context.Context, in *pb.ACAAttrReq) (*pb.ACAAttrResp, error) { - acapLogger.Debug("grpc ACAP:RequestAttributes") - - fail := pb.ACAAttrResp_FULL_SUCCESSFUL // else explicit which-param-failed error - if nil == in.Ts { - fail = pb.ACAAttrResp_FAIL_NIL_TS - } else if nil == in.Id { - fail = pb.ACAAttrResp_FAIL_NIL_ID - } else if nil == in.ECert { - fail = pb.ACAAttrResp_FAIL_NIL_ECERT - } else if nil == in.Signature { - fail = pb.ACAAttrResp_FAIL_NIL_SIGNATURE - } - - if pb.ACAAttrResp_FULL_SUCCESSFUL != fail { - return acap.createRequestAttributeResponse(fail, nil), nil - } - - if in.Attributes == nil { - in.Attributes = []*pb.TCertAttribute{} - } - - attrs := make(map[string]bool) - for _, attrPair := range in.Attributes { - if attrs[attrPair.AttributeName] { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_BAD_REQUEST, nil), nil - } - attrs[attrPair.AttributeName] = true - } - - cert, err := acap.aca.getTCACertificate() - if err != nil { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), errors.New("Error getting TCA certificate.") - } - - tcaPub := cert.PublicKey.(*ecdsa.PublicKey) - r, s := big.NewInt(0), big.NewInt(0) - r.UnmarshalText(in.Signature.R) - s.UnmarshalText(in.Signature.S) - - in.Signature = nil - - hash := primitives.NewHash() - raw, _ := proto.Marshal(in) - hash.Write(raw) - if ecdsa.Verify(tcaPub, hash.Sum(nil), r, s) == false { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), errors.New("Signature does not verify") - } - - cert, err = x509.ParseCertificate(in.ECert.Cert) - - if err != nil { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err - } - var id, affiliation string - id, affiliation, err = acap.aca.parseEnrollID(cert.Subject.CommonName) - if err != nil { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err - } - //Before continue with the request we perform a refresh of the attributes. - err = acap.aca.fetchAndPopulateAttributes(id, affiliation) - if err != nil { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err - } - - var verifyCounter int - var attributes = make([]AttributePair, 0) - owner := &AttributeOwner{id, affiliation} - for _, attrPair := range in.Attributes { - verifiedPair, _ := acap.aca.findAttribute(owner, attrPair.AttributeName) - if verifiedPair != nil { - verifyCounter++ - attributes = append(attributes, *verifiedPair) - } - } - - var extensions = make([]pkix.Extension, 0) - extensions, err = acap.addAttributesToExtensions(&attributes, extensions) - if err != nil { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err - } - - spec := NewDefaultCertificateSpec(id, cert.PublicKey, cert.KeyUsage, extensions...) - raw, err = acap.aca.newCertificateFromSpec(spec) - if err != nil { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_FAILURE, nil), err - } - - if verifyCounter == 0 { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_NO_ATTRIBUTES_FOUND, &pb.Cert{Cert: raw}), nil - } - - count := len(in.Attributes) - - if count == verifyCounter { - return acap.createRequestAttributeResponse(pb.ACAAttrResp_FULL_SUCCESSFUL, &pb.Cert{Cert: raw}), nil - } - return acap.createRequestAttributeResponse(pb.ACAAttrResp_PARTIAL_SUCCESSFUL, &pb.Cert{Cert: raw}), nil -} - -func (acap *ACAP) addAttributesToExtensions(attributes *[]AttributePair, extensions []pkix.Extension) ([]pkix.Extension, error) { - count := 11 - exts := extensions - for _, a := range *attributes { - //Save the position of the attribute extension on the header. - att := a.ToACAAttribute() - raw, err := proto.Marshal(att) - if err != nil { - continue - } - exts = append(exts, pkix.Extension{Id: asn1.ObjectIdentifier{1, 2, 3, 4, 5, 6, count}, Critical: false, Value: raw}) - count++ - } - return exts, nil -} - -// ReadCACertificate reads the certificate of the ACA. -// -func (acap *ACAP) ReadCACertificate(ctx context.Context, in *pb.Empty) (*pb.Cert, error) { - acapLogger.Debug("grpc ACAP:ReadCACertificate") - - return &pb.Cert{Cert: acap.aca.raw}, nil -} diff --git a/membersrvc/ca/ca.go b/membersrvc/ca/ca.go deleted file mode 100644 index 3698d9b1f7c..00000000000 --- a/membersrvc/ca/ca.go +++ /dev/null @@ -1,990 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "crypto/ecdsa" - "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "database/sql" - "encoding/json" - "encoding/pem" - "errors" - "fmt" - "io/ioutil" - "math/big" - "os" - "path/filepath" - "strconv" - "strings" - "sync" - "time" - - gp "google/protobuf" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/flogging" - pb "github.com/hyperledger/fabric/membersrvc/protos" - _ "github.com/mattn/go-sqlite3" // This blank import is required to load sqlite3 driver - "github.com/op/go-logging" - "github.com/spf13/viper" -) - -var caLogger = logging.MustGetLogger("ca") - -// CA is the base certificate authority. -type CA struct { - db *sql.DB - - path string - - priv *ecdsa.PrivateKey - cert *x509.Certificate - raw []byte -} - -// CertificateSpec defines the parameter used to create a new certificate. -type CertificateSpec struct { - id string - commonName string - serialNumber *big.Int - pub interface{} - usage x509.KeyUsage - NotBefore *time.Time - NotAfter *time.Time - ext *[]pkix.Extension -} - -// AffiliationGroup struct -type AffiliationGroup struct { - name string - parentID int64 - parent *AffiliationGroup - preKey []byte -} - -var ( - mutex = &sync.RWMutex{} - caOrganization string - caCountry string - rootPath string - caDir string -) - -// NewCertificateSpec creates a new certificate spec -func NewCertificateSpec(id string, commonName string, serialNumber *big.Int, pub interface{}, usage x509.KeyUsage, notBefore *time.Time, notAfter *time.Time, opt ...pkix.Extension) *CertificateSpec { - spec := new(CertificateSpec) - spec.id = id - spec.commonName = commonName - spec.serialNumber = serialNumber - spec.pub = pub - spec.usage = usage - spec.NotBefore = notBefore - spec.NotAfter = notAfter - spec.ext = &opt - return spec -} - -// NewDefaultPeriodCertificateSpec creates a new certificate spec with notBefore a minute ago and not after 90 days from notBefore. -// -func NewDefaultPeriodCertificateSpec(id string, serialNumber *big.Int, pub interface{}, usage x509.KeyUsage, opt ...pkix.Extension) *CertificateSpec { - return NewDefaultPeriodCertificateSpecWithCommonName(id, id, serialNumber, pub, usage, opt...) -} - -// NewDefaultPeriodCertificateSpecWithCommonName creates a new certificate spec with notBefore a minute ago and not after 90 days from notBefore and a specifc commonName. -// -func NewDefaultPeriodCertificateSpecWithCommonName(id string, commonName string, serialNumber *big.Int, pub interface{}, usage x509.KeyUsage, opt ...pkix.Extension) *CertificateSpec { - notBefore := time.Now().Add(-1 * time.Minute) - notAfter := notBefore.Add(time.Hour * 24 * 90) - return NewCertificateSpec(id, commonName, serialNumber, pub, usage, ¬Before, ¬After, opt...) -} - -// NewDefaultCertificateSpec creates a new certificate spec with serialNumber = 1, notBefore a minute ago and not after 90 days from notBefore. -// -func NewDefaultCertificateSpec(id string, pub interface{}, usage x509.KeyUsage, opt ...pkix.Extension) *CertificateSpec { - serialNumber := big.NewInt(1) - return NewDefaultPeriodCertificateSpec(id, serialNumber, pub, usage, opt...) -} - -// NewDefaultCertificateSpecWithCommonName creates a new certificate spec with serialNumber = 1, notBefore a minute ago and not after 90 days from notBefore and a specific commonName. -// -func NewDefaultCertificateSpecWithCommonName(id string, commonName string, pub interface{}, usage x509.KeyUsage, opt ...pkix.Extension) *CertificateSpec { - serialNumber := big.NewInt(1) - return NewDefaultPeriodCertificateSpecWithCommonName(id, commonName, serialNumber, pub, usage, opt...) -} - -// CacheConfiguration caches the viper configuration -func CacheConfiguration() { - caOrganization = viper.GetString("pki.ca.subject.organization") - caCountry = viper.GetString("pki.ca.subject.country") - rootPath = viper.GetString("server.rootpath") - caDir = viper.GetString("server.cadir") -} - -// GetID returns the spec's ID field/value -// -func (spec *CertificateSpec) GetID() string { - return spec.id -} - -// GetCommonName returns the spec's Common Name field/value -// -func (spec *CertificateSpec) GetCommonName() string { - return spec.commonName -} - -// GetSerialNumber returns the spec's Serial Number field/value -// -func (spec *CertificateSpec) GetSerialNumber() *big.Int { - return spec.serialNumber -} - -// GetPublicKey returns the spec's Public Key field/value -// -func (spec *CertificateSpec) GetPublicKey() interface{} { - return spec.pub -} - -// GetUsage returns the spec's usage (which is the x509.KeyUsage) field/value -// -func (spec *CertificateSpec) GetUsage() x509.KeyUsage { - return spec.usage -} - -// GetNotBefore returns the spec NotBefore (time.Time) field/value -// -func (spec *CertificateSpec) GetNotBefore() *time.Time { - return spec.NotBefore -} - -// GetNotAfter returns the spec NotAfter (time.Time) field/value -// -func (spec *CertificateSpec) GetNotAfter() *time.Time { - return spec.NotAfter -} - -// GetOrganization returns the spec's Organization field/value -// -func (spec *CertificateSpec) GetOrganization() string { - return caOrganization -} - -// GetCountry returns the spec's Country field/value -// -func (spec *CertificateSpec) GetCountry() string { - return caCountry -} - -// GetSubjectKeyID returns the spec's subject KeyID -// -func (spec *CertificateSpec) GetSubjectKeyID() *[]byte { - return &[]byte{1, 2, 3, 4} -} - -// GetSignatureAlgorithm returns the X509.SignatureAlgorithm field/value -// -func (spec *CertificateSpec) GetSignatureAlgorithm() x509.SignatureAlgorithm { - return x509.ECDSAWithSHA384 -} - -// GetExtensions returns the sepc's extensions -// -func (spec *CertificateSpec) GetExtensions() *[]pkix.Extension { - return spec.ext -} - -// TableInitializer is a function type for table initialization -type TableInitializer func(*sql.DB) error - -func initializeCommonTables(db *sql.DB) error { - if _, err := db.Exec("CREATE TABLE IF NOT EXISTS Certificates (row INTEGER PRIMARY KEY, id VARCHAR(64), timestamp INTEGER, usage INTEGER, cert BLOB, hash BLOB, kdfkey BLOB)"); err != nil { - return err - } - if _, err := db.Exec("CREATE TABLE IF NOT EXISTS Users (row INTEGER PRIMARY KEY, id VARCHAR(64), enrollmentId VARCHAR(100), role INTEGER, metadata VARCHAR(256), token BLOB, state INTEGER, key BLOB)"); err != nil { - return err - } - if _, err := db.Exec("CREATE TABLE IF NOT EXISTS AffiliationGroups (row INTEGER PRIMARY KEY, name VARCHAR(64), parent INTEGER, FOREIGN KEY(parent) REFERENCES AffiliationGroups(row))"); err != nil { - return err - } - return nil -} - -// NewCA sets up a new CA. -func NewCA(name string, initTables TableInitializer) *CA { - ca := new(CA) - flogging.LoggingInit("ca") - ca.path = filepath.Join(rootPath, caDir) - - if _, err := os.Stat(ca.path); err != nil { - caLogger.Info("Fresh start; creating databases, key pairs, and certificates.") - - if err := os.MkdirAll(ca.path, 0755); err != nil { - caLogger.Panic(err) - } - } - - // open or create certificate database - db, err := sql.Open("sqlite3", ca.path+"/"+name+".db") - if err != nil { - caLogger.Panic(err) - } - - if err = db.Ping(); err != nil { - caLogger.Panic(err) - } - - if err = initTables(db); err != nil { - caLogger.Panic(err) - } - ca.db = db - - // read or create signing key pair - priv, err := ca.readCAPrivateKey(name) - if err != nil { - priv = ca.createCAKeyPair(name) - } - ca.priv = priv - - // read CA certificate, or create a self-signed CA certificate - raw, err := ca.readCACertificate(name) - if err != nil { - raw = ca.createCACertificate(name, &ca.priv.PublicKey) - } - cert, err := x509.ParseCertificate(raw) - if err != nil { - caLogger.Panic(err) - } - - ca.raw = raw - ca.cert = cert - - return ca -} - -// Stop Close closes down the CA. -func (ca *CA) Stop() error { - err := ca.db.Close() - if err == nil { - caLogger.Debug("Shutting down CA - Successfully") - } else { - caLogger.Debug(fmt.Sprintf("Shutting down CA - Error closing DB [%s]", err)) - } - return err -} - -func (ca *CA) createCAKeyPair(name string) *ecdsa.PrivateKey { - caLogger.Debug("Creating CA key pair.") - - curve := primitives.GetDefaultCurve() - - priv, err := ecdsa.GenerateKey(curve, rand.Reader) - if err == nil { - raw, _ := x509.MarshalECPrivateKey(priv) - cooked := pem.EncodeToMemory( - &pem.Block{ - Type: "ECDSA PRIVATE KEY", - Bytes: raw, - }) - err = ioutil.WriteFile(ca.path+"/"+name+".priv", cooked, 0644) - if err != nil { - caLogger.Panic(err) - } - - raw, _ = x509.MarshalPKIXPublicKey(&priv.PublicKey) - cooked = pem.EncodeToMemory( - &pem.Block{ - Type: "ECDSA PUBLIC KEY", - Bytes: raw, - }) - err = ioutil.WriteFile(ca.path+"/"+name+".pub", cooked, 0644) - if err != nil { - caLogger.Panic(err) - } - } - if err != nil { - caLogger.Panic(err) - } - - return priv -} - -func (ca *CA) readCAPrivateKey(name string) (*ecdsa.PrivateKey, error) { - caLogger.Debug("Reading CA private key.") - - cooked, err := ioutil.ReadFile(ca.path + "/" + name + ".priv") - if err != nil { - return nil, err - } - - block, _ := pem.Decode(cooked) - return x509.ParseECPrivateKey(block.Bytes) -} - -func (ca *CA) createCACertificate(name string, pub *ecdsa.PublicKey) []byte { - caLogger.Debug("Creating CA certificate.") - - raw, err := ca.newCertificate(name, pub, x509.KeyUsageDigitalSignature|x509.KeyUsageCertSign, nil) - if err != nil { - caLogger.Panic(err) - } - - cooked := pem.EncodeToMemory( - &pem.Block{ - Type: "CERTIFICATE", - Bytes: raw, - }) - err = ioutil.WriteFile(ca.path+"/"+name+".cert", cooked, 0644) - if err != nil { - caLogger.Panic(err) - } - - return raw -} - -func (ca *CA) readCACertificate(name string) ([]byte, error) { - caLogger.Debug("Reading CA certificate.") - - cooked, err := ioutil.ReadFile(ca.path + "/" + name + ".cert") - if err != nil { - return nil, err - } - - block, _ := pem.Decode(cooked) - return block.Bytes, nil -} - -func (ca *CA) createCertificate(id string, pub interface{}, usage x509.KeyUsage, timestamp int64, kdfKey []byte, opt ...pkix.Extension) ([]byte, error) { - spec := NewDefaultCertificateSpec(id, pub, usage, opt...) - return ca.createCertificateFromSpec(spec, timestamp, kdfKey, true) -} - -func (ca *CA) createCertificateFromSpec(spec *CertificateSpec, timestamp int64, kdfKey []byte, persist bool) ([]byte, error) { - caLogger.Debug("Creating certificate for " + spec.GetID() + ".") - - raw, err := ca.newCertificateFromSpec(spec) - if err != nil { - caLogger.Error(err) - return nil, err - } - - if persist { - err = ca.persistCertificate(spec.GetID(), timestamp, spec.GetUsage(), raw, kdfKey) - } - - return raw, err -} - -func (ca *CA) persistCertificate(id string, timestamp int64, usage x509.KeyUsage, certRaw []byte, kdfKey []byte) error { - mutex.Lock() - defer mutex.Unlock() - - hash := primitives.NewHash() - hash.Write(certRaw) - var err error - - if _, err = ca.db.Exec("INSERT INTO Certificates (id, timestamp, usage, cert, hash, kdfkey) VALUES (?, ?, ?, ?, ?, ?)", id, timestamp, usage, certRaw, hash.Sum(nil), kdfKey); err != nil { - caLogger.Error(err) - } - return err -} - -func (ca *CA) newCertificate(id string, pub interface{}, usage x509.KeyUsage, ext []pkix.Extension) ([]byte, error) { - spec := NewDefaultCertificateSpec(id, pub, usage, ext...) - return ca.newCertificateFromSpec(spec) -} - -func (ca *CA) newCertificateFromSpec(spec *CertificateSpec) ([]byte, error) { - notBefore := spec.GetNotBefore() - notAfter := spec.GetNotAfter() - - parent := ca.cert - isCA := parent == nil - - tmpl := x509.Certificate{ - SerialNumber: spec.GetSerialNumber(), - Subject: pkix.Name{ - CommonName: spec.GetCommonName(), - Organization: []string{spec.GetOrganization()}, - Country: []string{spec.GetCountry()}, - }, - NotBefore: *notBefore, - NotAfter: *notAfter, - - SubjectKeyId: *spec.GetSubjectKeyID(), - SignatureAlgorithm: spec.GetSignatureAlgorithm(), - KeyUsage: spec.GetUsage(), - - BasicConstraintsValid: true, - IsCA: isCA, - } - - if len(*spec.GetExtensions()) > 0 { - tmpl.Extensions = *spec.GetExtensions() - tmpl.ExtraExtensions = *spec.GetExtensions() - } - if isCA { - parent = &tmpl - } - - raw, err := x509.CreateCertificate( - rand.Reader, - &tmpl, - parent, - spec.GetPublicKey(), - ca.priv, - ) - if isCA && err != nil { - caLogger.Panic(err) - } - - return raw, err -} - -func (ca *CA) readCertificateByKeyUsage(id string, usage x509.KeyUsage) ([]byte, error) { - caLogger.Debugf("Reading certificate for %s and usage %v", id, usage) - - mutex.RLock() - defer mutex.RUnlock() - - var raw []byte - err := ca.db.QueryRow("SELECT cert FROM Certificates WHERE id=? AND usage=?", id, usage).Scan(&raw) - - if err != nil { - caLogger.Debugf("readCertificateByKeyUsage() Error: %v", err) - } - - return raw, err -} - -func (ca *CA) readCertificateByTimestamp(id string, ts int64) ([]byte, error) { - caLogger.Debug("Reading certificate for " + id + ".") - - mutex.RLock() - defer mutex.RUnlock() - - var raw []byte - err := ca.db.QueryRow("SELECT cert FROM Certificates WHERE id=? AND timestamp=?", id, ts).Scan(&raw) - - return raw, err -} - -func (ca *CA) readCertificates(id string, opt ...int64) (*sql.Rows, error) { - caLogger.Debug("Reading certificatess for " + id + ".") - - mutex.RLock() - defer mutex.RUnlock() - - if len(opt) > 0 && opt[0] != 0 { - return ca.db.Query("SELECT cert, kdfkey FROM Certificates WHERE id=? AND timestamp=? ORDER BY usage", id, opt[0]) - } - - return ca.db.Query("SELECT cert, kdfkey FROM Certificates WHERE id=?", id) -} - -func (ca *CA) readCertificateSets(id string, start, end int64) (*sql.Rows, error) { - caLogger.Debug("Reading certificate sets for " + id + ".") - - mutex.RLock() - defer mutex.RUnlock() - - return ca.db.Query("SELECT cert, kdfKey, timestamp FROM Certificates WHERE id=? AND timestamp BETWEEN ? AND ? ORDER BY timestamp", id, start, end) -} - -func (ca *CA) readCertificateByHash(hash []byte) ([]byte, error) { - caLogger.Debug("Reading certificate for hash " + string(hash) + ".") - - mutex.RLock() - defer mutex.RUnlock() - - var raw []byte - row := ca.db.QueryRow("SELECT cert FROM Certificates WHERE hash=?", hash) - err := row.Scan(&raw) - - return raw, err -} - -func (ca *CA) isValidAffiliation(affiliation string) (bool, error) { - caLogger.Debug("Validating affiliation: " + affiliation) - - mutex.RLock() - defer mutex.RUnlock() - - var count int - var err error - err = ca.db.QueryRow("SELECT count(row) FROM AffiliationGroups WHERE name=?", affiliation).Scan(&count) - if err != nil { - caLogger.Debug("Affiliation <" + affiliation + "> is INVALID.") - - return false, err - } - caLogger.Debug("Affiliation <" + affiliation + "> is VALID.") - - return count == 1, nil -} - -// -// Determine if affiliation is required for a given registration request. -// -// Affiliation is required if the role is client or peer. -// Affiliation is not required if the role is validator or auditor. -// 1: client, 2: peer, 4: validator, 8: auditor -// - -func (ca *CA) requireAffiliation(role pb.Role) bool { - roleStr, _ := MemberRoleToString(role) - caLogger.Debug("Assigned role is: " + roleStr + ".") - - return role != pb.Role_VALIDATOR && role != pb.Role_AUDITOR -} - -// validateAndGenerateEnrollID validates the affiliation subject -func (ca *CA) validateAndGenerateEnrollID(id, affiliation string, role pb.Role) (string, error) { - roleStr, _ := MemberRoleToString(role) - caLogger.Debug("Validating and generating enrollID for user id: " + id + ", affiliation: " + affiliation + ", role: " + roleStr + ".") - - // Check whether the affiliation is required for the current user. - // - // Affiliation is required if the role is client or peer. - // Affiliation is not required if the role is validator or auditor. - if ca.requireAffiliation(role) { - valid, err := ca.isValidAffiliation(affiliation) - if err != nil { - return "", err - } - - if !valid { - caLogger.Debug("Invalid affiliation group: ") - return "", errors.New("Invalid affiliation group " + affiliation) - } - - return ca.generateEnrollID(id, affiliation) - } - - return "", nil -} - -// registerUser registers a new member with the CA -// -func (ca *CA) registerUser(id, affiliation string, role pb.Role, attrs []*pb.Attribute, aca *ACA, registrar, memberMetadata string, opt ...string) (string, error) { - memberMetadata = removeQuotes(memberMetadata) - roleStr, _ := MemberRoleToString(role) - caLogger.Debugf("Received request to register user with id: %s, affiliation: %s, role: %s, attrs: %+v, registrar: %s, memberMetadata: %s\n", - id, affiliation, roleStr, attrs, registrar, memberMetadata) - - var enrollID, tok string - var err error - - // There are two ways that registerUser can be called: - // 1) At initialization time from eca.users in the YAML file - // In this case, 'registrar' may be nil but we still register the users from the YAML file - // 2) At runtime via the GRPC ECA.RegisterUser handler (see RegisterUser in eca.go) - // In this case, 'registrar' must never be nil and furthermore the caller must have been authenticated - // to actually be the 'registrar' identity - // This means we trust what is in the YAML file but not what comes over the network - if registrar != "" { - // Check the permission of member named 'registrar' to perform this registration - err = ca.canRegister(registrar, role2String(int(role)), memberMetadata) - if err != nil { - return "", err - } - } - - enrollID, err = ca.validateAndGenerateEnrollID(id, affiliation, role) - if err != nil { - return "", err - } - - tok, err = ca.registerUserWithEnrollID(id, enrollID, role, memberMetadata, opt...) - if err != nil { - return "", err - } - - if attrs != nil && aca != nil { - var pairs []*AttributePair - pairs, err = toAttributePairs(id, affiliation, attrs) - if err == nil { - err = aca.PopulateAttributes(pairs) - } - } - - return tok, err -} - -// registerUserWithEnrollID registers a new user and its enrollmentID, role and state -// -func (ca *CA) registerUserWithEnrollID(id string, enrollID string, role pb.Role, memberMetadata string, opt ...string) (string, error) { - mutex.Lock() - defer mutex.Unlock() - - roleStr, _ := MemberRoleToString(role) - caLogger.Debugf("Registering user %s as %s with memberMetadata %s\n", id, roleStr, memberMetadata) - - var tok string - if len(opt) > 0 && len(opt[0]) > 0 { - tok = opt[0] - } else { - tok = randomString(12) - } - - var row int - err := ca.db.QueryRow("SELECT row FROM Users WHERE id=?", id).Scan(&row) - if err == nil { - return "", errors.New("User is already registered") - } - - _, err = ca.db.Exec("INSERT INTO Users (id, enrollmentId, token, role, metadata, state) VALUES (?, ?, ?, ?, ?, ?)", id, enrollID, tok, role, memberMetadata, 0) - - if err != nil { - caLogger.Error(err) - } - - return tok, err -} - -// registerAffiliationGroup registers a new affiliation group -// -func (ca *CA) registerAffiliationGroup(name string, parentName string) error { - mutex.Lock() - defer mutex.Unlock() - - caLogger.Debug("Registering affiliation group " + name + " parent " + parentName + ".") - - var parentID int - var err error - var count int - err = ca.db.QueryRow("SELECT count(row) FROM AffiliationGroups WHERE name=?", name).Scan(&count) - if err != nil { - return err - } - if count > 0 { - return errors.New("Affiliation group is already registered") - } - - if strings.Compare(parentName, "") != 0 { - err = ca.db.QueryRow("SELECT row FROM AffiliationGroups WHERE name=?", parentName).Scan(&parentID) - if err != nil { - return err - } - } - - _, err = ca.db.Exec("INSERT INTO AffiliationGroups (name, parent) VALUES (?, ?)", name, parentID) - - if err != nil { - caLogger.Error(err) - } - - return err - -} - -// deleteUser deletes a user given a name -// -func (ca *CA) deleteUser(id string) error { - caLogger.Debug("Deleting user " + id + ".") - - mutex.Lock() - defer mutex.Unlock() - - var row int - err := ca.db.QueryRow("SELECT row FROM Users WHERE id=?", id).Scan(&row) - if err == nil { - _, err = ca.db.Exec("DELETE FROM Certificates Where id=?", id) - if err != nil { - caLogger.Error(err) - } - - _, err = ca.db.Exec("DELETE FROM Users WHERE row=?", row) - if err != nil { - caLogger.Error(err) - } - } - - return err -} - -// readUser reads a token given an id -// -func (ca *CA) readUser(id string) *sql.Row { - caLogger.Debug("Reading token for " + id + ".") - - mutex.RLock() - defer mutex.RUnlock() - - return ca.db.QueryRow("SELECT role, token, state, key, enrollmentId FROM Users WHERE id=?", id) -} - -// readUsers reads users of a given Role -// -func (ca *CA) readUsers(role int) (*sql.Rows, error) { - caLogger.Debug("Reading users matching role " + strconv.FormatInt(int64(role), 2) + ".") - - return ca.db.Query("SELECT id, role FROM Users WHERE role&?!=0", role) -} - -// readRole returns the user Role given a user id -// -func (ca *CA) readRole(id string) int { - caLogger.Debug("Reading role for " + id + ".") - - mutex.RLock() - defer mutex.RUnlock() - - var role int - ca.db.QueryRow("SELECT role FROM Users WHERE id=?", id).Scan(&role) - - return role -} - -func (ca *CA) readAffiliationGroups() ([]*AffiliationGroup, error) { - caLogger.Debug("Reading affilition groups.") - - rows, err := ca.db.Query("SELECT row, name, parent FROM AffiliationGroups") - if err != nil { - return nil, err - } - defer rows.Close() - groups := make(map[int64]*AffiliationGroup) - - for rows.Next() { - group := new(AffiliationGroup) - var id int64 - if e := rows.Scan(&id, &group.name, &group.parentID); e != nil { - return nil, err - } - groups[id] = group - } - - groupList := make([]*AffiliationGroup, len(groups)) - idx := 0 - for _, eachGroup := range groups { - eachGroup.parent = groups[eachGroup.parentID] - groupList[idx] = eachGroup - idx++ - } - - return groupList, nil -} - -func (ca *CA) generateEnrollID(id string, affiliation string) (string, error) { - if id == "" || affiliation == "" { - return "", errors.New("Please provide all the input parameters, id and role") - } - - if strings.Contains(id, "\\") || strings.Contains(affiliation, "\\") { - return "", errors.New("Do not include the escape character \\ as part of the values") - } - - return id + "\\" + affiliation, nil -} - -func (ca *CA) parseEnrollID(enrollID string) (id string, affiliation string, err error) { - - if enrollID == "" { - return "", "", errors.New("Input parameter missing") - } - - enrollIDSections := strings.Split(enrollID, "\\") - - if len(enrollIDSections) != 2 { - return "", "", errors.New("Either the userId or affiliation is missing from the enrollmentID. EnrollID was " + enrollID) - } - - id = enrollIDSections[0] - affiliation = enrollIDSections[1] - err = nil - return -} - -// Check to see if member 'registrar' can register a new member of type 'newMemberRole' -// and with metadata associated with 'newMemberMetadataStr' -// Return nil if allowed, or an error if not allowed -func (ca *CA) canRegister(registrar string, newMemberRole string, newMemberMetadataStr string) error { - mutex.RLock() - defer mutex.RUnlock() - - // Read the user metadata associated with 'registrar' - var registrarMetadataStr string - err := ca.db.QueryRow("SELECT metadata FROM Users WHERE id=?", registrar).Scan(®istrarMetadataStr) - if err != nil { - caLogger.Debugf("CA.canRegister: db error: %s\n", err.Error()) - return err - } - caLogger.Debugf("CA.canRegister: registrar=%s, registrarMD=%s, newMemberRole=%s, newMemberMD=%s", - registrar, registrarMetadataStr, newMemberRole, newMemberMetadataStr) - // If isn't a registrar at all, then error - if registrarMetadataStr == "" { - caLogger.Debug("canRegister: member " + registrar + " is not a registrar") - return errors.New("member " + registrar + " is not a registrar") - } - // Get the registrar's metadata - caLogger.Debug("CA.canRegister: parsing registrar's metadata") - registrarMetadata, err := newMemberMetadata(registrarMetadataStr) - if err != nil { - return err - } - // Convert the user's meta to an object - caLogger.Debug("CA.canRegister: parsing new member's metadata") - newMemberMetadata, err := newMemberMetadata(newMemberMetadataStr) - if err != nil { - return err - } - // See if the metadata to be registered is acceptable for the registrar - return registrarMetadata.canRegister(registrar, newMemberRole, newMemberMetadata) -} - -// Convert a string to a MemberMetadata -func newMemberMetadata(metadata string) (*MemberMetadata, error) { - if metadata == "" { - caLogger.Debug("newMemberMetadata: nil") - return nil, nil - } - var mm MemberMetadata - err := json.Unmarshal([]byte(metadata), &mm) - if err != nil { - caLogger.Debugf("newMemberMetadata: error: %s, metadata: %s\n", err.Error(), metadata) - } - caLogger.Debugf("newMemberMetadata: metadata=%s, object=%+v\n", metadata, mm) - return &mm, err -} - -// MemberMetadata Additional member metadata -type MemberMetadata struct { - Registrar Registrar `json:"registrar"` -} - -// Registrar metadata -type Registrar struct { - Roles []string `json:"roles"` - DelegateRoles []string `json:"delegateRoles"` -} - -// See if member 'registrar' can register a member of type 'newRole' -// with MemberMetadata of 'newMemberMetadata' -func (mm *MemberMetadata) canRegister(registrar string, newRole string, newMemberMetadata *MemberMetadata) error { - // Can register a member of this type? - caLogger.Debugf("MM.canRegister registrar=%s, newRole=%s\n", registrar, newRole) - if !strContained(newRole, mm.Registrar.Roles) { - caLogger.Debugf("MM.canRegister: role %s can't be registered by %s\n", newRole, registrar) - return errors.New("member " + registrar + " may not register member of type " + newRole) - } - - // The registrar privileges that are being registered must not be larger than the registrar's - if newMemberMetadata == nil { - // Not requesting registrar privileges for this member, so we are OK - caLogger.Debug("MM.canRegister: not requesting registrar privileges") - return nil - } - - // Make sure this registrar is not delegating an invalid role - err := checkDelegateRoles(newMemberMetadata.Registrar.Roles, mm.Registrar.DelegateRoles, registrar) - if err != nil { - caLogger.Debug("MM.canRegister: checkDelegateRoles failure") - return err - } - - // Can register OK - caLogger.Debug("MM.canRegister: OK") - return nil -} - -// Return an error if all strings in 'strs1' are not contained in 'strs2' -func checkDelegateRoles(strs1 []string, strs2 []string, registrar string) error { - caLogger.Debugf("CA.checkDelegateRoles: registrar=%s, strs1=%+v, strs2=%+v\n", registrar, strs1, strs2) - for _, s := range strs1 { - if !strContained(s, strs2) { - caLogger.Debugf("CA.checkDelegateRoles: no: %s not in %+v\n", s, strs2) - return errors.New("user " + registrar + " may not register delegateRoles " + s) - } - } - caLogger.Debug("CA.checkDelegateRoles: ok") - return nil -} - -// Return true if 'str' is in 'strs'; otherwise return false -func strContained(str string, strs []string) bool { - for _, s := range strs { - if s == str { - return true - } - } - return false -} - -// Return true if 'str' is prefixed by any string in 'strs'; otherwise return false -func isPrefixed(str string, strs []string) bool { - for _, s := range strs { - if strings.HasPrefix(str, s) { - return true - } - } - return false -} - -// convert a role to a string -func role2String(role int) string { - if role == int(pb.Role_CLIENT) { - return "client" - } else if role == int(pb.Role_PEER) { - return "peer" - } else if role == int(pb.Role_VALIDATOR) { - return "validator" - } else if role == int(pb.Role_AUDITOR) { - return "auditor" - } - return "" -} - -// Remove outer quotes from a string if necessary -func removeQuotes(str string) string { - if str == "" { - return str - } - if (strings.HasPrefix(str, "'") && strings.HasSuffix(str, "'")) || - (strings.HasPrefix(str, "\"") && strings.HasSuffix(str, "\"")) { - str = str[1 : len(str)-1] - } - caLogger.Debugf("removeQuotes: %s\n", str) - return str -} - -// Convert the protobuf array of attributes to the AttributePair array format -// as required by the ACA code to populate the table -func toAttributePairs(id, affiliation string, attrs []*pb.Attribute) ([]*AttributePair, error) { - var pairs = make([]*AttributePair, 0) - for _, attr := range attrs { - vals := []string{id, affiliation, attr.Name, attr.Value, attr.NotBefore, attr.NotAfter} - pair, err := NewAttributePair(vals, nil) - if err != nil { - return nil, err - } - pairs = append(pairs, pair) - } - caLogger.Debugf("toAttributePairs: id=%s, affiliation=%s, attrs=%v, pairs=%v\n", - id, affiliation, attrs, pairs) - return pairs, nil -} - -func convertTime(ts *gp.Timestamp) time.Time { - var t time.Time - if ts == nil { - t = time.Unix(0, 0).UTC() - } else { - t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() - } - return t -} diff --git a/membersrvc/ca/ca_test.go b/membersrvc/ca/ca_test.go deleted file mode 100644 index 9bcc114b387..00000000000 --- a/membersrvc/ca/ca_test.go +++ /dev/null @@ -1,98 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "io/ioutil" - "os" - "testing" - - "database/sql" - - "github.com/hyperledger/fabric/core/crypto" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/spf13/viper" -) - -const ( - name = "TestCA" -) - -var ( - ca *CA - caFiles = [4]string{name + ".cert", name + ".db", name + ".priv", name + ".pub"} -) - -func TestNewCA(t *testing.T) { - - //init the crypto layer - if err := crypto.Init(); err != nil { - t.Errorf("Failed initializing the crypto layer [%s]", err) - } - - //initialize logging to avoid panics in the current code - CacheConfiguration() // Cache configuration - - //Create new CA - ca := NewCA(name, initializeTables) - if ca == nil { - t.Error("could not create new CA") - } - - missing := 0 - //check to see that the expected files were created - for _, file := range caFiles { - if _, err := os.Stat(ca.path + "/" + file); err != nil { - missing++ - t.Logf("failed to find file [%s]", file) - } - } - - if missing > 0 { - t.FailNow() - } - - //check CA certificate for correct properties - pem, err := ioutil.ReadFile(ca.path + "/" + name + ".cert") - if err != nil { - t.Fatalf("could not read CA X509 certificate [%s]", name+".cert") - } - - cacert, err := primitives.PEMtoCertificate(pem) - if err != nil { - t.Fatalf("could not parse CA X509 certificate [%s]", name+".cert") - } - - //check that commonname, organization and country match config - org := viper.GetString("pki.ca.subject.organization") - if cacert.Subject.Organization[0] != org { - t.Fatalf("ca cert subject organization [%s] did not match configuration [%s]", - cacert.Subject.Organization, org) - } - - country := viper.GetString("pki.ca.subject.country") - if cacert.Subject.Country[0] != country { - t.Fatalf("ca cert subject country [%s] did not match configuration [%s]", - cacert.Subject.Country, country) - } - -} - -// Empty initializer for CA -func initializeTables(db *sql.DB) error { - return nil -} diff --git a/membersrvc/ca/ca_test.yaml b/membersrvc/ca/ca_test.yaml deleted file mode 100644 index 3b3e68a7587..00000000000 --- a/membersrvc/ca/ca_test.yaml +++ /dev/null @@ -1,354 +0,0 @@ ---- -server: - version: "0.1" - rootpath: "." - cadir: ".ca" - port: ":7056" - - tls: - cert: - file: ".ca/tlsca.cert" - key: - file: ".ca/tlsca.priv" - -############################################################################### -# -# CLI section -# -############################################################################### -cli: - - # The address that the cli process will use for callbacks from chaincodes - address: 0.0.0.0:7052 - - - -############################################################################### -# -# REST section -# -############################################################################### -rest: - - # The address that the REST service will listen on for incoming requests. - address: 0.0.0.0:7050 - - - - -############################################################################### -# -# Peer section -# -############################################################################### -peer: - - # Peer Version following version semantics as described here http://semver.org/ - # The Peer supplies this version in communications with other Peers - version: 0.1.0 - - # The Peer id is used for identifying this Peer instance. - id: jdoe - - # The privateKey to be used by this peer - privateKey: 794ef087680e2494fa4918fd8fb80fb284b50b57d321a31423fe42b9ccf6216047cea0b66fe8365a8e3f2a8140c6866cc45852e63124668bee1daa9c97da0c2a - - # The networkId allows for logical seperation of networks - # networkId: dev - # networkId: test - networkId: dev - - Dockerfile: | - from hyperledger/fabric-baseimage:latest - # Copy GOPATH src and install Peer - COPY src $GOPATH/src - RUN mkdir -p /var/hyperledger/db - WORKDIR $GOPATH/src/github.com/hyperledger/fabric/peer/ - RUN CGO_CFLAGS=" " CGO_LDFLAGS="-lrocksdb -lstdc++ -lm -lz -lbz2 -lsnappy" go install && cp $GOPATH/src/github.com/hyperledger/fabric/peer/core.yaml $GOPATH/bin - - # The Address this Peer will listen on - listenAddress: 0.0.0.0:7051 - # The Address this Peer will bind to for providing services - address: 0.0.0.0:7051 - # Whether the Peer should programmatically determine the address to bind to. This case is useful for docker containers. - addressAutoDetect: false - - - # Logging settings - logging: - # Logging level, can be one of [error|warning|info|debug] - # One of: CRITICAL | ERROR | WARNING | NOTICE | INFO | DEBUG - level: DEBUG - - # Peer port to accept connections on - port: 7051 - # Peer's setting for GOMAXPROCS - gomaxprocs: 2 - workers: 2 - - # Sync related configuration - sync: - blocks: - # Channel size for readonly SyncBlocks messages channel for receiving blocks from oppositie Peer Endpoints. - # NOTE: currently messages are not stored and forwarded, but rather lost if the channel write blocks. - channelSize: 1 - state: - snapshot: - # Channel size for readonly syncStateSnapshot messages channel for receiving state deltas for snapshot from oppositie Peer Endpoints. - # NOTE: currently messages are not stored and forwarded, but rather lost if the channel write blocks. - channelSize: 50 - - # Validator defines whether this peer is a validating peer or not, and if - # it is enabled, what consensus plugin to load - validator: - enabled: true - - # Consensus plugin to use. The value is the name of the plugin, e.g. pbft, noops - consensus: noops - - # List of validating peers. For MVP, assume list is static. - replicas: 172.17.0.2:7051 172.17.0.3:7051 172.17.0.4:7051 172.17.0.5:7051 - - events: - # The address that the Event service will be enabled on the validator - address: 0.0.0.0:7053 - - # total number of events that could be buffered without blocking the validator sends - buffersize: 100 - - # milliseconds timeout for producer to send an event. - # if < 0, if buffer full, unblocks immediately and not send - # if 0, if buffer full, will block and guarantee the event will be sent out - # if > 0, if buffer full, blocks till timeout - timeout: 10 - - - # TLS Settings for p2p communications - tls: - enabled: false - cert: - file: testdata/server1.pem - key: - file: testdata/server1.key - # The server name use to verify the hostname returned by TLS handshake - serverhostoverride: - - # PKI member services properties - pki: - eca: - paddr: localhost:7054 - tca: - paddr: localhost:7055 - tlsca: - paddr: localhost:7056 - - # Peer discovery settings. Controls how this peer discovers other peers - discovery: - - # The root nodes are used for bootstrapping purposes, and generally supplied through ENV variables - rootnode: - - # The duration of time between attempts to asks peers for their connected peers - period: 5s - - ## leaving this in for example of sub map entry - # testNodes: - # - node : 1 - # ip : 127.0.0.1 - # port : 7051 - # - node : 2 - # ip : 127.0.0.1 - # port : 7051 - - # Should the discovered nodes and their reputations - # be stored in DB and persisted between restarts - persist: true - - # if peer discovery is off - # the peer window will show - # only what retrieved by active - # peer [true/false] - enabled: true - - # number of workers that - # tastes the peers for being - # online [1..10] - workers: 8 - - # the period in seconds with which the discovery - # tries to reconnect to successful nodes - # 0 means the nodes are not reconnected - touchPeriod: 600 - - # the maximum nuber of nodes to reconnect to - # -1 for unlimited - touchMaxNodes: 100 - - # Path on the file system where peer will store data - fileSystemPath: /var/hyperledger/test - -### NOTE: The validator section below is not needed and will be removed - BN -############################################################################### -# -# Validator section -# -############################################################################### -validator: - enabled: false - address: 0.0.0.0:7052 - # TLS Settings for p2p communications - tls: - enabled: false - cert: - file: testdata/server1.pem - key: - file: testdata/server1.key - # The server name use to verify the hostname returned by TLS handshake - serverhostoverride: - # Peer discovery settings. Controls how this peer discovers other peers - discovery: - - # The root nodes are used for bootstrapping purposes, and generally supplied through ENV variables - rootnode: - -############################################################################### -# -# VM section -# -############################################################################### -vm: - - # Endpoint of the vm management system. For docker can be one of the following in general - # unix:///var/run/docker.sock - # http://localhost:2375 - endpoint: unix:///var/run/docker.sock - - -############################################################################### -# -# Chaincode section -# -############################################################################### -chaincode: - - # The id is used by the Chaincode stub to register the executing ChaincodeID with the Peerand is generally supplied through ENV variables - id: - url: - version: - - golang: - - # This is the basis for the Golang Dockerfile. Additional commands will be appended depedendent upon the chaincode specification. - Dockerfile: | - FROM hyperledger/fabric-ccenv:$(ARCH)-$(PROJECT_VERSION) - COPY src $GOPATH/src - WORKDIR $GOPATH - - #timeout in millisecs for starting up a container and waiting for Register to come through. 1sec should be plenty for chaincode unit tests - startuptimeout: 1000 - - #mode - options are "dev", "net" - #dev - in dev mode, user runs the chaincode after starting validator from command line on local machine - #net - in net mode validator will run chaincode in a docker container - - mode: net - - installpath: /opt/gopath/bin/ - -############################################################################### -# -# Ledger section - ledger configuration encompases both the blockchain -# and the state -# -############################################################################### -ledger: - - blockchain: - - state: - - # Control the number state deltas that are maintained. This takes additional - # disk space, but allow the state to be rolled backwards and forwards - # without the need to replay transactions. - deltaHistorySize: 500 - - # The data structure in which the state will be stored. Different data - # structures may offer different performance characteristics. Options are - # 'buckettree' and 'trie'. If not set, the default data structure is the - # 'buckettree'. This CANNOT be changed after the DB has been created. - dataStructure: buckettree - - deploy-system-chaincode: true -############################################################################### -# -# Security section - -# -############################################################################### -security: - enabled: false - # To enroll NVP or VP with Member Services PKI. These parameters are for - # 1 time use. They will not be valid the subsequent times without un-enroll - enrollID: nepumuk - enrollSecret: 9gvZQRwhUq9q - # To enable privacy and confidentiality of transactions (requires security to be enabled) - privacy: false - -ports: - ecaP: ":7054" - ecaA: ":7055" - tcaP: ":7056" - tcaA: ":7057" - tlscaP: ":7058" - tlscaA: ":7059" - -hosts: - eca: localhost - tca: localhost - tlsca: localhost - -tca: - attribute-encryption: - enabled: true - -eca: - affiliations: - banks_and_institutions: - banks: - - bank_a - - bank_b - - bank_c - institutions: - - institution_a - users: - # : - admin: 1 Xurw3yU9zI0l institution_a '{"registrar":{"roles":["client","peer","validator","auditor"],"delegateRoles":["client"]}}' - WebAppAdmin: 1 DJY27pEnl16d institution_a '{"registrar":{"roles":["client"]}}' - system_chaincode_invoker: 1 DRJ20pEql15a institution_a - jim: 1 6avZQLwcUe9b bank_a - lukas: 1 NPKYL39uKbkj bank_a - - test_user0: 1 MS9qrN8hFjlE bank_a - test_user1: 1 jGlNl6ImkuDo institution_a - test_user2: 1 zMflqOKezFiA bank_c - test_user3: 1 vWdLCE00vJy0 bank_a - test_user4: 1 4nXSrfoYGFCP institution_a - test_user5: 1 yg5DVhm0er1z bank_b - test_user6: 1 b7pmSxzKNFiw bank_a - test_user7: 1 YsWZD4qQmYxo institution_a - test_user8: 1 W8G0usrU7jRk bank_a - test_user9: 1 H80SiB5ODKKQ institution_a -aca: - attributes: - attribute-entry-0: test_user0;bank_a;company;ACompany;2015-01-01T00:00:00-03:00;; - attribute-entry-1: test_user0;bank_a;position;Software Staff;2015-01-01T00:00:00-03:00;2015-07-12T23:59:59-03:00; - attribute-entry-2: test_user0;bank_a;position;Software Engineer;2015-07-13T00:00:00-03:00;; - attribute-entry-3: test_user0;bank_a;business_unit;Sales;2015-06-24T00:00:00-03:00;; - address: localhost:7056 - server-name: acap - enabled: true - -pki: - ca: - subject: - organization: Hyperledger - country: US diff --git a/membersrvc/ca/client_grpc.go b/membersrvc/ca/client_grpc.go deleted file mode 100644 index f5a78097cc5..00000000000 --- a/membersrvc/ca/client_grpc.go +++ /dev/null @@ -1,138 +0,0 @@ -package ca - -import ( - "crypto/tls" - "crypto/x509" - "encoding/pem" - "io/ioutil" - "time" - - pb "github.com/hyperledger/fabric/membersrvc/protos" - "github.com/spf13/viper" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -/** Performs Certificate type validation **/ -/* -* Checks for valid Cert format type -* Cert expiration -* - */ -func isValidCertFormatted(certLocation string) bool { - - var isvalidCert = false - certificate, err := ioutil.ReadFile(certLocation) - if err != nil { - return false - } - block, _ := pem.Decode(certificate) - if block == nil { - certificates, err := x509.ParseCertificates(certificate) - if err != nil { - caLogger.Error("Not a valid Certificate") - } else { - validCert := validateCert(certificates[0]) - if !validCert { - caLogger.Error("Certificate has expired") - } - return validCert - } - } else { - certificates, err := x509.ParseCertificates(block.Bytes) - if err != nil { - caLogger.Error("Not a valid Certificate") - } else { - validCert := validateCert(certificates[0]) - if !validCert { - caLogger.Error("Certificate has expired") - } - return validCert - } - } - - return isvalidCert - -} - -/** Given the cert , it checks for expiry -* Does not check for revocation - */ -func validateCert(cert *x509.Certificate) bool { - - notBefore := cert.NotBefore - notAfter := cert.NotAfter - - currentTime := time.Now() - diffFromExpiry := notAfter.Sub(currentTime) - diffFromStart := currentTime.Sub(notBefore) - - return ((diffFromExpiry > 0) && (diffFromStart > 0)) - -} - -// NewClientTLSFromFile creates Client TLS connection credentials -// @certFile : TLS Server Certificate in PEM format -// @serverNameOverride : Common Name (CN) of the TLS Server Certificate -// returns Secure Transport Credentials -// -func NewClientTLSFromFile(certFile, serverNameOverride string) (credentials.TransportCredentials, error) { - caLogger.Debug("upgrading to TLS1.2") - b, err := ioutil.ReadFile(certFile) - - if err != nil { - caLogger.Errorf("Certificate could not be found in the [%s] path", certFile) - return nil, err - } - - if !isValidCertFormatted(certFile) { - return nil, nil - } - - cp := x509.NewCertPool() - - ok := cp.AppendCertsFromPEM(b) - if !ok { - caLogger.Error("credentials: failed to append certificates: ") - return nil, nil - } - return credentials.NewTLS(&tls.Config{ServerName: serverNameOverride, RootCAs: cp, MinVersion: 0, MaxVersion: 0}), nil -} - -//GetClientConn returns a connection to the server located on *address*. -func GetClientConn(address string, serverName string) (*grpc.ClientConn, error) { - - caLogger.Debug("GetACAClient: using the given gRPC client connection to return a new ACA client") - var opts []grpc.DialOption - - if viper.GetBool("security.tls_enabled") { - caLogger.Debug("TLS was enabled [security.tls_enabled == true]") - - creds, err := NewClientTLSFromFile(viper.GetString("security.client.cert.file"), viper.GetString("security.serverhostoverride")) - - if err != nil { - caLogger.Error("Could not establish TLS client connection in GetClientConn while getting creds:") - caLogger.Error(err) - return nil, err - } - opts = append(opts, grpc.WithTransportCredentials(creds)) - } else { - caLogger.Debug("TLS was not enabled [security.tls_enabled == false]") - opts = append(opts, grpc.WithInsecure()) - } - opts = append(opts, grpc.WithTimeout(time.Second*3)) - return grpc.Dial(address, opts...) -} - -//GetACAClient returns a client to Attribute Certificate Authority. -func GetACAClient() (*grpc.ClientConn, pb.ACAPClient, error) { - caLogger.Debug("GetACAClient: Trying to create a new ACA Client from the connection provided") - conn, err := GetClientConn(viper.GetString("aca.address"), viper.GetString("aca.server-name")) - if err != nil { - return nil, nil, err - } - - client := pb.NewACAPClient(conn) - - return conn, client, nil -} diff --git a/membersrvc/ca/eca.go b/membersrvc/ca/eca.go deleted file mode 100644 index 43ec9522621..00000000000 --- a/membersrvc/ca/eca.go +++ /dev/null @@ -1,223 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "crypto/ecdsa" - "crypto/rand" - "crypto/x509" - "database/sql" - "encoding/asn1" - "encoding/base64" - "encoding/pem" - "io/ioutil" - "strconv" - "strings" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/flogging" - pb "github.com/hyperledger/fabric/membersrvc/protos" - "github.com/op/go-logging" - "github.com/spf13/viper" - "google.golang.org/grpc" -) - -var ecaLogger = logging.MustGetLogger("eca") - -var ( - // ECertSubjectRole is the ASN1 object identifier of the subject's role. - // - ECertSubjectRole = asn1.ObjectIdentifier{2, 1, 3, 4, 5, 6, 7} -) - -// ECA is the enrollment certificate authority. -// -type ECA struct { - *CA - aca *ACA - obcKey []byte - obcPriv, obcPub []byte - gRPCServer *grpc.Server -} - -func initializeECATables(db *sql.DB) error { - return initializeCommonTables(db) -} - -// NewECA sets up a new ECA. -// -func NewECA(aca *ACA) *ECA { - eca := &ECA{CA: NewCA("eca", initializeECATables), aca: aca} - flogging.LoggingInit("eca") - - { - // read or create global symmetric encryption key - var cooked string - var l = logging.MustGetLogger("ECA") - - raw, err := ioutil.ReadFile(eca.path + "/obc.aes") - if err != nil { - rand := rand.Reader - key := make([]byte, 32) // AES-256 - rand.Read(key) - cooked = base64.StdEncoding.EncodeToString(key) - - err = ioutil.WriteFile(eca.path+"/obc.aes", []byte(cooked), 0644) - if err != nil { - l.Panic(err) - } - } else { - cooked = string(raw) - } - - eca.obcKey, err = base64.StdEncoding.DecodeString(cooked) - if err != nil { - l.Panic(err) - } - } - - { - // read or create global ECDSA key pair for ECIES - var priv *ecdsa.PrivateKey - cooked, err := ioutil.ReadFile(eca.path + "/obc.ecies") - if err == nil { - block, _ := pem.Decode(cooked) - priv, err = x509.ParseECPrivateKey(block.Bytes) - if err != nil { - ecaLogger.Panic(err) - } - } else { - priv, err = ecdsa.GenerateKey(primitives.GetDefaultCurve(), rand.Reader) - if err != nil { - ecaLogger.Panic(err) - } - - raw, _ := x509.MarshalECPrivateKey(priv) - cooked = pem.EncodeToMemory( - &pem.Block{ - Type: "ECDSA PRIVATE KEY", - Bytes: raw, - }) - err := ioutil.WriteFile(eca.path+"/obc.ecies", cooked, 0644) - if err != nil { - ecaLogger.Panic(err) - } - } - - eca.obcPriv = cooked - raw, _ := x509.MarshalPKIXPublicKey(&priv.PublicKey) - eca.obcPub = pem.EncodeToMemory( - &pem.Block{ - Type: "ECDSA PUBLIC KEY", - Bytes: raw, - }) - } - - eca.populateAffiliationGroupsTable() - eca.populateUsersTable() - return eca -} - -// populateUsersTable populates the users table. -// -func (eca *ECA) populateUsersTable() { - // populate user table - users := viper.GetStringMapString("eca.users") - for id, flds := range users { - vals := strings.Fields(flds) - role, err := strconv.Atoi(vals[0]) - if err != nil { - ecaLogger.Panic(err) - } - var affiliation, memberMetadata, registrar string - if len(vals) >= 3 { - affiliation = vals[2] - if len(vals) >= 4 { - memberMetadata = vals[3] - if len(vals) >= 5 { - registrar = vals[4] - } - } - } - eca.registerUser(id, affiliation, pb.Role(role), nil, eca.aca, registrar, memberMetadata, vals[1]) - } -} - -// populateAffiliationGroup populates the affiliation groups table. -// -func (eca *ECA) populateAffiliationGroup(name, parent, key string, level int) { - eca.registerAffiliationGroup(name, parent) - newKey := key + "." + name - - if level == 0 { - affiliationGroups := viper.GetStringSlice(newKey) - for ci := range affiliationGroups { - eca.registerAffiliationGroup(affiliationGroups[ci], name) - } - } else { - affiliationGroups := viper.GetStringMapString(newKey) - for childName := range affiliationGroups { - eca.populateAffiliationGroup(childName, name, newKey, level-1) - } - } -} - -// populateAffiliationGroupsTable populates affiliation groups table. -// -func (eca *ECA) populateAffiliationGroupsTable() { - key := "eca.affiliations" - affiliationGroups := viper.GetStringMapString(key) - for name := range affiliationGroups { - eca.populateAffiliationGroup(name, "", key, 1) - } -} - -// Start starts the ECA. -// -func (eca *ECA) Start(srv *grpc.Server) { - ecaLogger.Info("Starting ECA...") - - eca.startECAP(srv) - eca.startECAA(srv) - eca.gRPCServer = srv - - ecaLogger.Info("ECA started.") -} - -// Stop stops the ECA services. -func (eca *ECA) Stop() { - ecaLogger.Info("Stopping ECA services...") - if eca.gRPCServer != nil { - eca.gRPCServer.Stop() - } - err := eca.CA.Stop() - if err != nil { - ecaLogger.Errorf("ECA Error stopping services: %s", err) - } else { - ecaLogger.Info("ECA stopped") - } -} - -func (eca *ECA) startECAP(srv *grpc.Server) { - pb.RegisterECAPServer(srv, &ECAP{eca}) - ecaLogger.Info("ECA PUBLIC gRPC API server started") -} - -func (eca *ECA) startECAA(srv *grpc.Server) { - pb.RegisterECAAServer(srv, &ECAA{eca}) - ecaLogger.Info("ECA ADMIN gRPC API server started") -} diff --git a/membersrvc/ca/eca_test.go b/membersrvc/ca/eca_test.go deleted file mode 100644 index a0f81c6be3a..00000000000 --- a/membersrvc/ca/eca_test.go +++ /dev/null @@ -1,571 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "crypto/ecdsa" - "crypto/rand" - "crypto/x509" - "errors" - "os" - "testing" - "time" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/crypto/primitives/ecies" - pb "github.com/hyperledger/fabric/membersrvc/protos" - "golang.org/x/net/context" -) - -type User struct { - enrollID string - enrollPwd []byte - enrollPrivKey *ecdsa.PrivateKey - role int - affiliation string - registrarRoles []string - registrarDelegateRoles []string -} - -var ( - ecaFiles = [6]string{"eca.cert", "eca.db", "eca.priv", "eca.pub", "obc.aes", "obc.ecies"} - testAdmin = User{enrollID: "admin", enrollPwd: []byte("Xurw3yU9zI0l")} - testUser = User{enrollID: "testUser", role: 1, affiliation: "institution_a"} - testUser2 = User{enrollID: "testUser2", role: 1, affiliation: "institution_a"} - testAuditor = User{enrollID: "testAuditor", role: 8} - testClient1 = User{enrollID: "testClient1", role: 1, affiliation: "institution_a", - registrarRoles: []string{"client"}, registrarDelegateRoles: []string{"client"}} - testClient2 = User{enrollID: "testClient2", role: 1, affiliation: "institution_a", - registrarRoles: []string{"client"}} - testClient3 = User{enrollID: "testClient2", role: 1, affiliation: "institution_a", - registrarRoles: []string{"client"}} - testPeer = User{enrollID: "testPeer", role: 2, affiliation: "institution_a", - registrarRoles: []string{"peer"}} -) - -//helper function for multiple tests -func enrollUser(user *User) error { - - ecap := &ECAP{eca} - - // Phase 1 of the protocol: Generate crypto material - signPriv, err := primitives.NewECDSAKey() - user.enrollPrivKey = signPriv - if err != nil { - return err - } - signPub, err := x509.MarshalPKIXPublicKey(&signPriv.PublicKey) - if err != nil { - return err - } - - encPriv, err := primitives.NewECDSAKey() - if err != nil { - return err - } - encPub, err := x509.MarshalPKIXPublicKey(&encPriv.PublicKey) - if err != nil { - return err - } - - req := &pb.ECertCreateReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: user.enrollID}, - Tok: &pb.Token{Tok: user.enrollPwd}, - Sign: &pb.PublicKey{Type: pb.CryptoType_ECDSA, Key: signPub}, - Enc: &pb.PublicKey{Type: pb.CryptoType_ECDSA, Key: encPub}, - Sig: nil} - - resp, err := ecap.CreateCertificatePair(context.Background(), req) - if err != nil { - return err - } - - //Phase 2 of the protocol - spi := ecies.NewSPI() - eciesKey, err := spi.NewPrivateKey(nil, encPriv) - if err != nil { - return err - } - - ecies, err := spi.NewAsymmetricCipherFromPublicKey(eciesKey) - if err != nil { - return err - } - - out, err := ecies.Process(resp.Tok.Tok) - if err != nil { - return err - } - - req.Tok.Tok = out - req.Sig = nil - - hash := primitives.NewHash() - raw, _ := proto.Marshal(req) - hash.Write(raw) - - r, s, err := ecdsa.Sign(rand.Reader, signPriv, hash.Sum(nil)) - if err != nil { - return err - } - R, _ := r.MarshalText() - S, _ := s.MarshalText() - req.Sig = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err = ecap.CreateCertificatePair(context.Background(), req) - if err != nil { - return err - } - - // Verify we got valid crypto material back - x509SignCert, err := primitives.DERToX509Certificate(resp.Certs.Sign) - if err != nil { - return err - } - - _, err = primitives.GetCriticalExtension(x509SignCert, ECertSubjectRole) - if err != nil { - return err - } - - x509EncCert, err := primitives.DERToX509Certificate(resp.Certs.Enc) - if err != nil { - return err - } - - _, err = primitives.GetCriticalExtension(x509EncCert, ECertSubjectRole) - if err != nil { - return err - } - - return nil -} - -func registerUser(registrar User, user *User) error { - - ecaa := &ECAA{eca} - - //create req - req := &pb.RegisterUserReq{ - Id: &pb.Identity{Id: user.enrollID}, - Role: pb.Role(user.role), - Affiliation: user.affiliation, - Registrar: &pb.Registrar{ - Id: &pb.Identity{Id: registrar.enrollID}, - Roles: user.registrarRoles, - DelegateRoles: user.registrarDelegateRoles, - }, - Sig: nil} - - //sign the req - hash := primitives.NewHash() - raw, _ := proto.Marshal(req) - hash.Write(raw) - - r, s, err := ecdsa.Sign(rand.Reader, registrar.enrollPrivKey, hash.Sum(nil)) - if err != nil { - msg := "Failed to register user. Error (ECDSA) signing request: " + err.Error() - return errors.New(msg) - } - R, _ := r.MarshalText() - S, _ := s.MarshalText() - req.Sig = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - token, err := ecaa.RegisterUser(context.Background(), req) - if err != nil { - return err - } - - if token == nil { - return errors.New("Failed to obtain token") - } - - //need the token for later tests - user.enrollPwd = token.Tok - - return nil -} - -//check that the ECA was created / initialized -func TestNewECA(t *testing.T) { - - //initialization was handled in TestMain - //check to see if ECA exists - if eca == nil { - t.Fatal("Failed to create ECA") - } - - missing := 0 - - //check to see that the expected files were created - for _, file := range ecaFiles { - if _, err := os.Stat(eca.CA.path + "/" + file); err != nil { - missing++ - t.Logf("Failed to find file: [%s]", file) - } - } - - if missing > 0 { - t.Fail() - } -} - -/** -* Test the CreateCertificatePair function by enolling a preloaded admin -* we can use to register additional users in later tests - */ -func TestCreateCertificatePairAdmin(t *testing.T) { - //enroll testAdmin - err := enrollUser(&testAdmin) - - if err != nil { - t.Fatalf("Failed to enroll testAdmin: [%s]", err.Error()) - } -} - -//register testUser using testAdmin as the registrar -func TestRegisterUser(t *testing.T) { - - err := registerUser(testAdmin, &testUser) - - if err != nil { - t.Fatal(err.Error()) - } - -} - -//now see if we can enroll testUser -func TestCreateCertificatePairTestUser(t *testing.T) { - - err := enrollUser(&testUser) - - if err != nil { - t.Fatalf("Failed to enroll testUser: [%s]", err.Error()) - } -} - -//register testUser again - should get error -func TestRegisterDuplicateUser(t *testing.T) { - - err := registerUser(testAdmin, &testUser) - - if err == nil { - t.Fatal("Expected an error when registering the same user twice") - } - - if err.Error() != "User is already registered" { - t.Fatalf("Expected error was not returned when registering user twice: [%s]", err.Error()) - } -} - -//register testAuditor with testAdmin as registrar -//register testUser again - should get error -func TestRegisterAuditor(t *testing.T) { - - err := registerUser(testAdmin, &testAuditor) - - if err != nil { - t.Fatal(err.Error()) - } -} - -/** -* A user with no registrar metadata should not be able to register a new user - */ -func TestRegisterUserNonRegistrar(t *testing.T) { - - //testUser has no registrar metadata - err := registerUser(testUser, &testUser2) - - if err == nil { - t.Fatal("User without registrar metadata should not be able to register a new user") - } - t.Logf("Expected an error and indeed received: [%s]", err.Error()) -} - -//testAdmin should NOT be able to register testPeer since testAdmin's -//delegateRoles field DOES NOT contain the value "peer" -func TestRegisterUserPeer(t *testing.T) { - - err := registerUser(testAdmin, &testPeer) - - if err == nil { - t.Fatal("User without appropriate delegateRoles should not be able to register a new user") - } - t.Logf("Expected an error and indeed received: [%s]", err.Error()) -} - -//testAdmin should be able to register testClient1 since testAdmin's -//delegateRoles field contains the value "client" -func TestRegisterUserClient(t *testing.T) { - - err := registerUser(testAdmin, &testClient1) - - if err != nil { - t.Error(err.Error()) - } -} - -//testClient1 registered in the previous test should be able to enroll -func TestCreateCertificatePairClient(t *testing.T) { - - err := enrollUser(&testClient1) - - if err != nil { - t.Fatalf("Failed to enroll testClient1: [%s]", err.Error()) - } -} - -//testClient1 should be able to register testClient2 since testClient1's -//delegateRoles field contains the value "client" -func TestRegisterUserClientAsRegistrar(t *testing.T) { - - err := registerUser(testClient1, &testClient2) - - if err != nil { - t.Error(err.Error()) - } - -} - -//testClient2 should NOT be able to register testClient3 since testClient2's -//delegateRoles field is empty -func TestRegisterUserNoDelegateRoles(t *testing.T) { - - err := enrollUser(&testClient2) - - if err != nil { - t.Fatalf("Failed to enroll testClient2: [%s]", err.Error()) - } - - err = registerUser(testClient2, &testClient3) - - if err == nil { - t.Fatal("User without delegateRoles should not be able to register a new user") - } - - t.Logf("Expected an error and indeed received: [%s]", err.Error()) -} - -func TestReadCACertificate(t *testing.T) { - ecap := &ECAP{eca} - _, err := ecap.ReadCACertificate(context.Background(), &pb.Empty{}) - - if err != nil { - t.Fatalf("Failed to read the CA certificate of the ECA: [%s]: ", err.Error()) - } -} - -func TestReadCertificatePair(t *testing.T) { - - ecap := &ECAP{eca} - - req := &pb.ECertReadReq{Id: &pb.Identity{Id: testUser.enrollID}} - - _, err := ecap.ReadCertificatePair(context.Background(), req) - - if err != nil { - t.Fatalf("Failed to read certificate pair: [%s]", err.Error()) - } -} - -func TestReadCertificatePairBadIdentity(t *testing.T) { - ecap := &ECAP{eca} - - req := &pb.ECertReadReq{Id: &pb.Identity{Id: "badUser"}} - - _, err := ecap.ReadCertificatePair(context.Background(), req) - - if err == nil { - t.Error("The query result searching by an invalid user identity should have been empty. ") - } - -} - -func TestReadCertificateByHash(t *testing.T) { - ecap := &ECAP{eca} - - req := &pb.ECertReadReq{Id: &pb.Identity{Id: testUser.enrollID}} - - cert, err := ecap.ReadCertificatePair(context.Background(), req) - - if err != nil { - t.Fatalf("Failed to read certificate pair: [%s]", err.Error()) - } - - hash := primitives.NewHash() - raw, _ := proto.Marshal(cert) - hash.Write(raw) - - hashReq := &pb.Hash{Hash: hash.Sum(nil)} - - certByHash, _ := ecap.ReadCertificateByHash(context.Background(), hashReq) - - if certByHash == nil { - t.Error("A. ") - } - -} - -func TestReadCertificateByInvalidHash(t *testing.T) { - ecap := &ECAP{eca} - - req := &pb.Hash{Hash: nil} - - _, err := ecap.ReadCertificateByHash(context.Background(), req) - - if err == nil { - t.Error("The query result searching by an invalid hash value should have been empty. ") - } - -} - -func TestReadUserSet(t *testing.T) { - - //enroll Auditor - err := enrollUser(&testAuditor) - - if err != nil { - t.Fatalf("Failed to read user set [%s]", err.Error()) - } - - ecaa := &ECAA{eca} - - req := &pb.ReadUserSetReq{ - Req: &pb.Identity{Id: testAuditor.enrollID}, - Role: 1, - Sig: nil} - - //sign the req - hash := primitives.NewHash() - raw, _ := proto.Marshal(req) - hash.Write(raw) - - r, s, err := ecdsa.Sign(rand.Reader, testAuditor.enrollPrivKey, hash.Sum(nil)) - if err != nil { - t.Fatalf("Failed (ECDSA) signing [%s]", err.Error()) - } - R, _ := r.MarshalText() - S, _ := s.MarshalText() - req.Sig = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err := ecaa.ReadUserSet(context.Background(), req) - - if err != nil { - t.Fatalf("Failed to read user set [%s]", err.Error()) - } - t.Log("number of users: ", len(resp.Users)) -} - -func TestReadUserSetNonAuditor(t *testing.T) { - - ecaa := &ECAA{eca} - - req := &pb.ReadUserSetReq{ - Req: &pb.Identity{Id: testUser.enrollID}, - Role: 1, - Sig: nil} - - //sign the req - hash := primitives.NewHash() - raw, _ := proto.Marshal(req) - hash.Write(raw) - - r, s, err := ecdsa.Sign(rand.Reader, testUser.enrollPrivKey, hash.Sum(nil)) - if err != nil { - t.Fatalf("Failed (ECDSA) signing [%s]", err.Error()) - } - R, _ := r.MarshalText() - S, _ := s.MarshalText() - req.Sig = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - _, err = ecaa.ReadUserSet(context.Background(), req) - - if err == nil { - t.Fatal("Only auditors should be able to call ReadUserSet") - } - -} - -func TestCreateCertificatePairBadIdentity(t *testing.T) { - - ecap := &ECAP{eca} - - req := &pb.ECertCreateReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: "badIdentity"}, - Tok: &pb.Token{Tok: testUser.enrollPwd}, - Sign: &pb.PublicKey{Type: pb.CryptoType_ECDSA, Key: []byte{0}}, - Enc: &pb.PublicKey{Type: pb.CryptoType_ECDSA, Key: []byte{0}}, - Sig: nil} - - _, err := ecap.CreateCertificatePair(context.Background(), req) - if err.Error() != "Identity lookup error: sql: no rows in result set" { - t.Log(err.Error()) - t.Fatal("The expected error of 'Identity lookup error: sql: no rows in result set' was not returned for bad identity") - } -} - -func TestCreateCertificatePairBadToken(t *testing.T) { - - ecap := &ECAP{eca} - - req := &pb.ECertCreateReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: testUser.enrollID}, - Tok: &pb.Token{Tok: []byte("badPassword")}, - Sign: &pb.PublicKey{Type: pb.CryptoType_ECDSA, Key: []byte{0}}, - Enc: &pb.PublicKey{Type: pb.CryptoType_ECDSA, Key: []byte{0}}, - Sig: nil} - - _, err := ecap.CreateCertificatePair(context.Background(), req) - if err.Error() != "Identity or token does not match." { - t.Fatal("Expected error was not returned for bad password") - } -} - -func TestRevokeCertificatePair(t *testing.T) { - - ecap := &ECAP{eca} - - _, err := ecap.RevokeCertificatePair(context.Background(), &pb.ECertRevokeReq{}) - if err.Error() != "ECAP:RevokeCertificate method not (yet) implemented" { - t.Fatalf("Expected error was not returned: [%s]", err.Error()) - } -} - -func TestRevokeCertificate(t *testing.T) { - - ecaa := &ECAA{eca} - - _, err := ecaa.RevokeCertificate(context.Background(), &pb.ECertRevokeReq{}) - if err.Error() != "ECAA:RevokeCertificate method not (yet) implemented" { - t.Fatalf("Expected error was not returned: [%s]", err.Error()) - } -} - -func TestPublishCRL(t *testing.T) { - ecaa := &ECAA{eca} - - _, err := ecaa.PublishCRL(context.Background(), &pb.ECertCRLReq{}) - if err.Error() != "ECAA:PublishCRL method not (yet) implemented" { - t.Fatalf("Expected error was not returned: [%s]", err.Error()) - } -} diff --git a/membersrvc/ca/ecaa.go b/membersrvc/ca/ecaa.go deleted file mode 100644 index 15cd3e6f0ed..00000000000 --- a/membersrvc/ca/ecaa.go +++ /dev/null @@ -1,185 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "crypto/ecdsa" - "crypto/x509" - "encoding/json" - "errors" - "math/big" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/core/crypto/primitives" - pb "github.com/hyperledger/fabric/membersrvc/protos" - "github.com/op/go-logging" - "golang.org/x/net/context" -) - -var ecaaLogger = logging.MustGetLogger("ecaa") - -// ECAA serves the administrator GRPC interface of the ECA. -// -type ECAA struct { - eca *ECA -} - -// RegisterUser registers a new user with the ECA. If the user had been registered before -// an error is returned. -// -func (ecaa *ECAA) RegisterUser(ctx context.Context, in *pb.RegisterUserReq) (*pb.Token, error) { - ecaaLogger.Debug("gRPC ECAA:RegisterUser") - - // Check the signature - err := ecaa.checkRegistrarSignature(in) - if err != nil { - return nil, err - } - - // Register the user - registrarID := in.Registrar.Id.Id - in.Registrar.Id = nil - registrar := pb.RegisterUserReq{Registrar: in.Registrar} - json, err := json.Marshal(registrar) - if err != nil { - return nil, err - } - jsonStr := string(json) - ecaaLogger.Debugf("gRPC ECAA:RegisterUser: json=%s", jsonStr) - tok, err := ecaa.eca.registerUser(in.Id.Id, in.Affiliation, in.Role, in.Attributes, ecaa.eca.aca, registrarID, jsonStr) - - // Return the one-time password - return &pb.Token{Tok: []byte(tok)}, err - -} - -func (ecaa *ECAA) checkRegistrarSignature(in *pb.RegisterUserReq) error { - ecaaLogger.Debug("ECAA.checkRegistrarSignature") - - // If no registrar was specified - if in.Registrar == nil || in.Registrar.Id == nil || in.Registrar.Id.Id == "" { - ecaaLogger.Debug("gRPC ECAA:checkRegistrarSignature: no registrar was specified") - return errors.New("no registrar was specified") - } - - // Get the raw cert for the registrar - registrar := in.Registrar.Id.Id - raw, err := ecaa.eca.readCertificateByKeyUsage(registrar, x509.KeyUsageDigitalSignature) - if err != nil { - return err - } - - // Parse the cert - cert, err := x509.ParseCertificate(raw) - if err != nil { - return err - } - - // Remove the signature - sig := in.Sig - in.Sig = nil - - // Marshall the raw bytes - r, s := big.NewInt(0), big.NewInt(0) - r.UnmarshalText(sig.R) - s.UnmarshalText(sig.S) - - hash := primitives.NewHash() - raw, _ = proto.Marshal(in) - hash.Write(raw) - - // Check the signature - if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { - // Signature verification failure - ecaaLogger.Debugf("ECAA.checkRegistrarSignature: failure for %s (len=%d): %+v", registrar, len(raw), in) - return errors.New("Signature verification failed.") - } - - // Signature verification was successful - ecaaLogger.Debugf("ECAA.checkRegistrarSignature: success for %s", registrar) - return nil -} - -// ReadUserSet returns a list of users matching the parameters set in the read request. -// -func (ecaa *ECAA) ReadUserSet(ctx context.Context, in *pb.ReadUserSetReq) (*pb.UserSet, error) { - ecaaLogger.Debug("gRPC ECAA:ReadUserSet") - - req := in.Req.Id - if ecaa.eca.readRole(req)&int(pb.Role_AUDITOR) == 0 { - return nil, errors.New("Access denied.") - } - - raw, err := ecaa.eca.readCertificateByKeyUsage(req, x509.KeyUsageDigitalSignature) - if err != nil { - return nil, err - } - cert, err := x509.ParseCertificate(raw) - if err != nil { - return nil, err - } - - sig := in.Sig - in.Sig = nil - - r, s := big.NewInt(0), big.NewInt(0) - r.UnmarshalText(sig.R) - s.UnmarshalText(sig.S) - - hash := primitives.NewHash() - raw, _ = proto.Marshal(in) - hash.Write(raw) - if ecdsa.Verify(cert.PublicKey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { - return nil, errors.New("Signature verification failed.") - } - - rows, err := ecaa.eca.readUsers(int(in.Role)) - if err != nil { - return nil, err - } - defer rows.Close() - - var users []*pb.User - if err == nil { - for rows.Next() { - var id string - var role int - - err = rows.Scan(&id, &role) - users = append(users, &pb.User{Id: &pb.Identity{Id: id}, Role: pb.Role(role)}) - } - err = rows.Err() - } - - return &pb.UserSet{Users: users}, err -} - -// RevokeCertificate revokes a certificate from the ECA. Not yet implemented. -// -func (ecaa *ECAA) RevokeCertificate(context.Context, *pb.ECertRevokeReq) (*pb.CAStatus, error) { - ecaaLogger.Debug("gRPC ECAA:RevokeCertificate") - - return nil, errors.New("ECAA:RevokeCertificate method not (yet) implemented") -} - -// PublishCRL requests the creation of a certificate revocation list from the ECA. Not yet implemented. -// -func (ecaa *ECAA) PublishCRL(context.Context, *pb.ECertCRLReq) (*pb.CAStatus, error) { - ecaaLogger.Debug("gRPC ECAA:CreateCRL") - - return nil, errors.New("ECAA:PublishCRL method not (yet) implemented") -} diff --git a/membersrvc/ca/ecap.go b/membersrvc/ca/ecap.go deleted file mode 100644 index ad01fda4e7a..00000000000 --- a/membersrvc/ca/ecap.go +++ /dev/null @@ -1,285 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "bytes" - "crypto/ecdsa" - "crypto/subtle" - "crypto/x509" - "crypto/x509/pkix" - "errors" - "io/ioutil" - "math/big" - "strconv" - "time" - - "github.com/hyperledger/fabric/core/crypto/primitives/ecies" - "github.com/op/go-logging" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/hyperledger/fabric/core/crypto/primitives" - pb "github.com/hyperledger/fabric/membersrvc/protos" - "github.com/spf13/viper" - "golang.org/x/net/context" -) - -var ecapLogger = logging.MustGetLogger("ecap") - -// ECAP serves the public GRPC interface of the ECA. -// -type ECAP struct { - eca *ECA -} - -// ReadCACertificate reads the certificate of the ECA. -// -func (ecap *ECAP) ReadCACertificate(ctx context.Context, in *pb.Empty) (*pb.Cert, error) { - ecapLogger.Debug("gRPC ECAP:ReadCACertificate") - - return &pb.Cert{Cert: ecap.eca.raw}, nil -} - -func (ecap *ECAP) fetchAttributes(cert *pb.Cert) error { - //TODO we are creating a new client connection per each ecert request. We should implement a connections pool. - sock, acaP, err := GetACAClient() - if err != nil { - return err - } - defer sock.Close() - - req := &pb.ACAFetchAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - ECert: cert, - Signature: nil} - - var rawReq []byte - rawReq, err = proto.Marshal(req) - if err != nil { - return err - } - - var r, s *big.Int - - r, s, err = primitives.ECDSASignDirect(ecap.eca.priv, rawReq) - - if err != nil { - return err - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - req.Signature = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err := acaP.FetchAttributes(context.Background(), req) - if err != nil { - return err - } - - if resp.Status != pb.ACAFetchAttrResp_FAILURE { - return nil - } - return errors.New("Error fetching attributes.") -} - -// CreateCertificatePair requests the creation of a new enrollment certificate pair by the ECA. -// -func (ecap *ECAP) CreateCertificatePair(ctx context.Context, in *pb.ECertCreateReq) (*pb.ECertCreateResp, error) { - ecapLogger.Debug("gRPC ECAP:CreateCertificate") - - // validate token - var tok, prev []byte - var role, state int - var enrollID string - - id := in.Id.Id - err := ecap.eca.readUser(id).Scan(&role, &tok, &state, &prev, &enrollID) - - if err != nil { - errMsg := "Identity lookup error: " + err.Error() - ecapLogger.Debug(errMsg) - return nil, errors.New(errMsg) - } - if !bytes.Equal(tok, in.Tok.Tok) { - ecapLogger.Debugf("id or token mismatch: id=%s", id) - return nil, errors.New("Identity or token does not match.") - } - - ekey, err := x509.ParsePKIXPublicKey(in.Enc.Key) - if err != nil { - return nil, err - } - - fetchResult := pb.FetchAttrsResult{Status: pb.FetchAttrsResult_SUCCESS, Msg: ""} - switch { - case state == 0: - // initial request, create encryption challenge - tok = []byte(randomString(12)) - - mutex.Lock() - _, err = ecap.eca.db.Exec("UPDATE Users SET token=?, state=?, key=? WHERE id=?", tok, 1, in.Enc.Key, id) - mutex.Unlock() - - if err != nil { - ecapLogger.Error(err) - return nil, err - } - - spi := ecies.NewSPI() - eciesKey, err := spi.NewPublicKey(nil, ekey.(*ecdsa.PublicKey)) - if err != nil { - return nil, err - } - - ecies, err := spi.NewAsymmetricCipherFromPublicKey(eciesKey) - if err != nil { - return nil, err - } - - out, err := ecies.Process(tok) - - return &pb.ECertCreateResp{Certs: nil, Chain: nil, Pkchain: nil, Tok: &pb.Token{Tok: out}}, err - - case state == 1: - // ensure that the same encryption key is signed that has been used for the challenge - if subtle.ConstantTimeCompare(in.Enc.Key, prev) != 1 { - return nil, errors.New("Encryption keys do not match.") - } - - // validate request signature - sig := in.Sig - in.Sig = nil - - r, s := big.NewInt(0), big.NewInt(0) - r.UnmarshalText(sig.R) - s.UnmarshalText(sig.S) - - if in.Sign.Type != pb.CryptoType_ECDSA { - return nil, errors.New("Unsupported (signing) key type.") - } - skey, err := x509.ParsePKIXPublicKey(in.Sign.Key) - if err != nil { - return nil, err - } - - hash := primitives.NewHash() - raw, _ := proto.Marshal(in) - hash.Write(raw) - if ecdsa.Verify(skey.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { - return nil, errors.New("Signature verification failed.") - } - - // create new certificate pair - ts := time.Now().Add(-1 * time.Minute).UnixNano() - - spec := NewDefaultCertificateSpecWithCommonName(id, enrollID, skey.(*ecdsa.PublicKey), x509.KeyUsageDigitalSignature, pkix.Extension{Id: ECertSubjectRole, Critical: true, Value: []byte(strconv.Itoa(ecap.eca.readRole(id)))}) - sraw, err := ecap.eca.createCertificateFromSpec(spec, ts, nil, true) - if err != nil { - ecapLogger.Error(err) - return nil, err - } - - _ = ioutil.WriteFile("/tmp/ecert_"+id, sraw, 0644) - - spec = NewDefaultCertificateSpecWithCommonName(id, enrollID, ekey.(*ecdsa.PublicKey), x509.KeyUsageDataEncipherment, pkix.Extension{Id: ECertSubjectRole, Critical: true, Value: []byte(strconv.Itoa(ecap.eca.readRole(id)))}) - eraw, err := ecap.eca.createCertificateFromSpec(spec, ts, nil, true) - if err != nil { - mutex.Lock() - ecap.eca.db.Exec("DELETE FROM Certificates Where id=?", id) - mutex.Unlock() - ecapLogger.Error(err) - return nil, err - } - - mutex.Lock() - _, err = ecap.eca.db.Exec("UPDATE Users SET state=? WHERE id=?", 2, id) - mutex.Unlock() - if err != nil { - mutex.Lock() - ecap.eca.db.Exec("DELETE FROM Certificates Where id=?", id) - mutex.Unlock() - ecapLogger.Error(err) - return nil, err - } - - var obcECKey []byte - if role == int(pb.Role_VALIDATOR) { - obcECKey = ecap.eca.obcPriv - } else { - obcECKey = ecap.eca.obcPub - } - if role == int(pb.Role_CLIENT) { - //Only client have to fetch attributes. - if viper.GetBool("aca.enabled") { - err = ecap.fetchAttributes(&pb.Cert{Cert: sraw}) - if err != nil { - fetchResult = pb.FetchAttrsResult{Status: pb.FetchAttrsResult_FAILURE, Msg: err.Error()} - - } - } - } - - return &pb.ECertCreateResp{Certs: &pb.CertPair{Sign: sraw, Enc: eraw}, Chain: &pb.Token{Tok: ecap.eca.obcKey}, Pkchain: obcECKey, Tok: nil, FetchResult: &fetchResult}, nil - } - - return nil, errors.New("Invalid (=expired) certificate creation token provided.") -} - -// ReadCertificatePair reads an enrollment certificate pair from the ECA. -// -func (ecap *ECAP) ReadCertificatePair(ctx context.Context, in *pb.ECertReadReq) (*pb.CertPair, error) { - ecapLogger.Debug("gRPC ECAP:ReadCertificate") - - rows, err := ecap.eca.readCertificates(in.Id.Id) - defer rows.Close() - - hasResults := false - var certs [][]byte - if err == nil { - for rows.Next() { - hasResults = true - var raw []byte - err = rows.Scan(&raw) - certs = append(certs, raw) - } - err = rows.Err() - } - - if !hasResults { - return nil, errors.New("No certificates for the given identity were found.") - } - return &pb.CertPair{Sign: certs[0], Enc: certs[1]}, err -} - -// ReadCertificateByHash reads a single enrollment certificate by hash from the ECA. -// -func (ecap *ECAP) ReadCertificateByHash(ctx context.Context, hash *pb.Hash) (*pb.Cert, error) { - ecapLogger.Debug("gRPC ECAP:ReadCertificateByHash") - - raw, err := ecap.eca.readCertificateByHash(hash.Hash) - return &pb.Cert{Cert: raw}, err -} - -// RevokeCertificatePair revokes a certificate pair from the ECA. Not yet implemented. -// -func (ecap *ECAP) RevokeCertificatePair(context.Context, *pb.ECertRevokeReq) (*pb.CAStatus, error) { - ecapLogger.Debug("gRPC ECAP:RevokeCertificate") - - return nil, errors.New("ECAP:RevokeCertificate method not (yet) implemented") -} diff --git a/membersrvc/ca/membersrvc_test.go b/membersrvc/ca/membersrvc_test.go deleted file mode 100644 index a294f252663..00000000000 --- a/membersrvc/ca/membersrvc_test.go +++ /dev/null @@ -1,114 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "net" - "os" - "testing" - - "github.com/spf13/viper" - - "fmt" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "google.golang.org/grpc" - - "time" -) - -var ( - aca *ACA - eca *ECA - tca *TCA - server *grpc.Server -) - -func TestMain(m *testing.M) { - setupTestConfig() - curve := primitives.GetDefaultCurve() - fmt.Printf("Default Curve %v \n", curve) - // Init PKI - initPKI() - go startPKI() - defer cleanup() - time.Sleep(time.Second * 10) - fmt.Println("Running tests....") - ret := m.Run() - fmt.Println("End running tests....") - cleanupFiles() - os.Exit(ret) - -} - -func setupTestConfig() { - primitives.SetSecurityLevel("SHA3", 256) - viper.AutomaticEnv() - viper.SetConfigName("ca_test") // name of config file (without extension) - viper.AddConfigPath("./") // path to look for the config file in - viper.AddConfigPath("./..") // path to look for the config file in - err := viper.ReadInConfig() // Find and read the config file - if err != nil { // Handle errors reading the config file - panic(fmt.Errorf("Fatal error config file: %s \n", err)) - } -} - -func initPKI() { - CacheConfiguration() // Cache configuration - aca = NewACA() - eca = NewECA(aca) - tca = NewTCA(eca) -} - -func startPKI() { - var opts []grpc.ServerOption - fmt.Printf("open socket...\n") - sockp, err := net.Listen("tcp", viper.GetString("server.port")) - if err != nil { - panic("Cannot open port: " + err.Error()) - } - fmt.Printf("open socket...done\n") - - server = grpc.NewServer(opts...) - aca.Start(server) - eca.Start(server) - tca.Start(server) - fmt.Printf("start serving...\n") - server.Serve(sockp) -} - -func cleanup() { - fmt.Println("Cleanup...") - stopPKI() - fmt.Println("Cleanup...done!") -} - -func cleanupFiles() { - //cleanup files - path := viper.GetString("server.cadir") - err := os.RemoveAll("./" + path) - if err != nil { - fmt.Printf("Failed removing [%s] [%s]\n", path, err) - } -} - -func stopPKI() { - aca.Stop() - eca.Stop() - tca.Stop() - server.Stop() -} diff --git a/membersrvc/ca/tca.go b/membersrvc/ca/tca.go deleted file mode 100644 index 4c375e2da11..00000000000 --- a/membersrvc/ca/tca.go +++ /dev/null @@ -1,293 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "crypto/hmac" - "crypto/rand" - "crypto/x509" - "database/sql" - "encoding/asn1" - "encoding/base64" - "errors" - "io/ioutil" - - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/flogging" - pb "github.com/hyperledger/fabric/membersrvc/protos" - "github.com/op/go-logging" - "google.golang.org/grpc" -) - -var tcaLogger = logging.MustGetLogger("tca") - -var ( - // TCertEncTCertIndex is the ASN1 object identifier of the TCert index. - TCertEncTCertIndex = asn1.ObjectIdentifier{1, 2, 3, 4, 5, 6, 7} - - // TCertEncEnrollmentID is the ASN1 object identifier of the enrollment id. - TCertEncEnrollmentID = asn1.ObjectIdentifier{1, 2, 3, 4, 5, 6, 8} - - // TCertAttributesHeaders is the ASN1 object identifier of attributes header. - TCertAttributesHeaders = asn1.ObjectIdentifier{1, 2, 3, 4, 5, 6, 9} - - // Padding for encryption. - Padding = []byte{255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} - - // RootPreKeySize for attribute encryption keys derivation - RootPreKeySize = 48 -) - -// TCA is the transaction certificate authority. -type TCA struct { - *CA - eca *ECA - hmacKey []byte - rootPreKey []byte - preKeys map[string][]byte - gRPCServer *grpc.Server -} - -// TCertSet contains relevant information of a set of tcerts -type TCertSet struct { - Ts int64 - EnrollmentID string - Nonce []byte - Key []byte -} - -func initializeTCATables(db *sql.DB) error { - var err error - - err = initializeCommonTables(db) - if err != nil { - return err - } - - if _, err = db.Exec("CREATE TABLE IF NOT EXISTS TCertificateSets (row INTEGER PRIMARY KEY, enrollmentID VARCHAR(64), timestamp INTEGER, nonce BLOB, kdfkey BLOB)"); err != nil { - return err - } - - return err -} - -// NewTCA sets up a new TCA. -func NewTCA(eca *ECA) *TCA { - tca := &TCA{NewCA("tca", initializeTCATables), eca, nil, nil, nil, nil} - flogging.LoggingInit("tca") - - err := tca.readHmacKey() - if err != nil { - tcaLogger.Panic(err) - } - - err = tca.readRootPreKey() - if err != nil { - tcaLogger.Panic(err) - } - - err = tca.initializePreKeyTree() - if err != nil { - tcaLogger.Panic(err) - } - return tca -} - -// Read the hcmac key from the file system. -func (tca *TCA) readHmacKey() error { - var cooked string - raw, err := ioutil.ReadFile(tca.path + "/tca.hmac") - if err != nil { - key := make([]byte, 49) - rand.Reader.Read(key) - cooked = base64.StdEncoding.EncodeToString(key) - - err = ioutil.WriteFile(tca.path+"/tca.hmac", []byte(cooked), 0644) - if err != nil { - tcaLogger.Panic(err) - } - } else { - cooked = string(raw) - } - - tca.hmacKey, err = base64.StdEncoding.DecodeString(cooked) - return err -} - -// Read the root pre key from the file system. -func (tca *TCA) readRootPreKey() error { - var cooked string - raw, err := ioutil.ReadFile(tca.path + "/root_pk.hmac") - if err != nil { - key := make([]byte, RootPreKeySize) - rand.Reader.Read(key) - cooked = base64.StdEncoding.EncodeToString(key) - - err = ioutil.WriteFile(tca.path+"/root_pk.hmac", []byte(cooked), 0644) - if err != nil { - tcaLogger.Panic(err) - } - } else { - cooked = string(raw) - } - - tca.rootPreKey, err = base64.StdEncoding.DecodeString(cooked) - return err -} - -func (tca *TCA) calculatePreKey(variant []byte, preKey []byte) ([]byte, error) { - mac := hmac.New(primitives.GetDefaultHash(), preKey) - _, err := mac.Write(variant) - if err != nil { - return nil, err - } - return mac.Sum(nil), nil -} - -func (tca *TCA) initializePreKeyNonRootGroup(group *AffiliationGroup) error { - if group.parent.preKey == nil { - //Initialize parent if it is not initialized yet. - tca.initializePreKeyGroup(group.parent) - } - var err error - group.preKey, err = tca.calculatePreKey([]byte(group.name), group.parent.preKey) - return err -} - -func (tca *TCA) initializePreKeyGroup(group *AffiliationGroup) error { - if group.parentID == 0 { - //This group is root - group.preKey = tca.rootPreKey - return nil - } - return tca.initializePreKeyNonRootGroup(group) -} - -func (tca *TCA) initializePreKeyTree() error { - tcaLogger.Debug("Initializing PreKeys.") - groups, err := tca.eca.readAffiliationGroups() - if err != nil { - return err - } - tca.preKeys = make(map[string][]byte) - for _, group := range groups { - if group.preKey == nil { - err = tca.initializePreKeyGroup(group) - if err != nil { - return err - } - } - tcaLogger.Debug("Initializing PK group ", group.name) - tca.preKeys[group.name] = group.preKey - } - - return nil -} - -func (tca *TCA) getPreKFrom(enrollmentCertificate *x509.Certificate) ([]byte, error) { - _, affiliation, err := tca.eca.parseEnrollID(enrollmentCertificate.Subject.CommonName) - if err != nil { - return nil, err - } - preK := tca.preKeys[affiliation] - if preK == nil { - return nil, errors.New("Could not be found a pre-k to the affiliation group " + affiliation + ".") - } - return preK, nil -} - -// Start starts the TCA. -func (tca *TCA) Start(srv *grpc.Server) { - tcaLogger.Info("Staring TCA services...") - tca.startTCAP(srv) - tca.startTCAA(srv) - tca.gRPCServer = srv - tcaLogger.Info("TCA started.") -} - -// Stop stops the TCA services. -func (tca *TCA) Stop() error { - tcaLogger.Info("Stopping the TCA services...") - if tca.gRPCServer != nil { - tca.gRPCServer.Stop() - } - err := tca.CA.Stop() - if err != nil { - tcaLogger.Errorf("Error stopping TCA services: %s", err) - } else { - tcaLogger.Info("TCA services stopped") - } - return err -} - -func (tca *TCA) startTCAP(srv *grpc.Server) { - pb.RegisterTCAPServer(srv, &TCAP{tca}) - tcaLogger.Info("TCA PUBLIC gRPC API server started") -} - -func (tca *TCA) startTCAA(srv *grpc.Server) { - pb.RegisterTCAAServer(srv, &TCAA{tca}) - tcaLogger.Info("TCA ADMIN gRPC API server started") -} - -func (tca *TCA) getCertificateSets(enrollmentID string) ([]*TCertSet, error) { - mutex.RLock() - defer mutex.RUnlock() - - var sets = []*TCertSet{} - var err error - - var rows *sql.Rows - rows, err = tca.retrieveCertificateSets(enrollmentID) - if err != nil { - return nil, err - } - defer rows.Close() - - var enrollID string - var timestamp int64 - var nonce []byte - var kdfKey []byte - - for rows.Next() { - if err = rows.Scan(&enrollID, ×tamp, &nonce, &kdfKey); err != nil { - return nil, err - } - sets = append(sets, &TCertSet{Ts: timestamp, EnrollmentID: enrollID, Key: kdfKey}) - } - if err = rows.Err(); err != nil { - return nil, err - } - - return sets, nil -} - -func (tca *TCA) persistCertificateSet(enrollmentID string, timestamp int64, nonce []byte, kdfKey []byte) error { - mutex.Lock() - defer mutex.Unlock() - - var err error - - if _, err = tca.db.Exec("INSERT INTO TCertificateSets (enrollmentID, timestamp, nonce, kdfkey) VALUES (?, ?, ?, ?)", enrollmentID, timestamp, nonce, kdfKey); err != nil { - tcaLogger.Error(err) - } - return err -} - -func (tca *TCA) retrieveCertificateSets(enrollmentID string) (*sql.Rows, error) { - return tca.db.Query("SELECT enrollmentID, timestamp, nonce, kdfkey FROM TCertificateSets WHERE enrollmentID=?", enrollmentID) -} diff --git a/membersrvc/ca/tca_test.go b/membersrvc/ca/tca_test.go deleted file mode 100644 index dbbf75c9861..00000000000 --- a/membersrvc/ca/tca_test.go +++ /dev/null @@ -1,209 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "crypto/ecdsa" - "crypto/x509" - "encoding/pem" - "fmt" - "io/ioutil" - "testing" - "time" - - "golang.org/x/net/context" - - "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/timestamp" - "github.com/hyperledger/fabric/core/crypto" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/membersrvc/protos" -) - -func TestNewTCA(t *testing.T) { - tca, err := initTCA() - if err != nil { - t.Fatal(err) - } - - if tca.hmacKey == nil || len(tca.hmacKey) == 0 { - t.Fatal("Could not read hmacKey from TCA") - } - - if tca.rootPreKey == nil || len(tca.rootPreKey) == 0 { - t.Fatal("Could not read rootPreKey from TCA") - } - - if tca.preKeys == nil || len(tca.preKeys) == 0 { - t.Fatal("Could not read preKeys from TCA") - } -} - -func TestCreateCertificateSet(t *testing.T) { - tca, err := initTCA() - if err != nil { - t.Fatal(err) - } - - enrollmentID := "test_user0" - enrollmentPassword := "MS9qrN8hFjlE" - - ecertRaw, priv, err := loadECertAndEnrollmentPrivateKey(enrollmentID, enrollmentPassword) - if err != nil { - t.Fatal(err) - } - - const expectedTcertSubjectCommonNameValue string = "Transaction Certificate" - ncerts := 1 - for nattributes := -1; nattributes < 1; nattributes++ { - certificateSetRequest, err := buildCertificateSetRequest(enrollmentID, priv, ncerts, nattributes) - if err != nil { - t.Fatal(err) - } - - var certSets []*TCertSet - certSets, err = tca.getCertificateSets(enrollmentID) - if err != nil { - t.Fatal(err) - } - - certSetsCountBefore := len(certSets) - - tcap := &TCAP{tca} - response, err := tcap.createCertificateSet(context.Background(), ecertRaw, certificateSetRequest) - if err != nil { - t.Fatal(err) - } - - certSets, err = tca.getCertificateSets(enrollmentID) - if err != nil { - t.Fatal(err) - } - certSetsCountAfter := len(certSets) - - if certSetsCountBefore != certSetsCountAfter-1 { - t.Fatal("TCertSets count should be increased by 1 after requesting a new set of TCerts") - } - - tcerts := response.GetCerts() - if len(tcerts.Certs) != ncerts { - t.Fatal(fmt.Errorf("Invalid tcert size. Expected: %v, Actual: %v", ncerts, len(tcerts.Certs))) - } - - for pos, eachTCert := range tcerts.Certs { - tcert, err := x509.ParseCertificate(eachTCert.Cert) - if err != nil { - t.Fatalf("Error: %v\nCould not x509.ParseCertificate %v", err, eachTCert.Cert) - } - - t.Logf("Examining TCert[%d]'s Subject: %v", pos, tcert.Subject) - if tcert.Subject.CommonName != expectedTcertSubjectCommonNameValue { - t.Fatalf("The TCert's Subject.CommonName is '%s' which is different than '%s'", tcert.Subject.CommonName, expectedTcertSubjectCommonNameValue) - } - t.Logf("Successfully verified that TCert[%d].Subject.CommonName == '%s'", pos, tcert.Subject.CommonName) - } - } -} - -func loadECertAndEnrollmentPrivateKey(enrollmentID string, password string) ([]byte, *ecdsa.PrivateKey, error) { - cooked, err := ioutil.ReadFile("./test_resources/key_" + enrollmentID + ".dump") - if err != nil { - return nil, nil, err - } - - block, _ := pem.Decode(cooked) - decryptedBlock, err := x509.DecryptPEMBlock(block, []byte(password)) - if err != nil { - return nil, nil, err - } - - enrollmentPrivateKey, err := x509.ParseECPrivateKey(decryptedBlock) - if err != nil { - return nil, nil, err - } - - if err != nil { - return nil, nil, err - } - - ecertRaw, err := ioutil.ReadFile("./test_resources/ecert_" + enrollmentID + ".dump") - if err != nil { - return nil, nil, err - } - - return ecertRaw, enrollmentPrivateKey, nil -} - -func initTCA() (*TCA, error) { - //init the crypto layer - if err := crypto.Init(); err != nil { - return nil, fmt.Errorf("Failed initializing the crypto layer [%v]", err) - } - - CacheConfiguration() // Cache configuration - - aca := NewACA() - if aca == nil { - return nil, fmt.Errorf("Could not create a new ACA") - } - - eca := NewECA(aca) - if eca == nil { - return nil, fmt.Errorf("Could not create a new ECA") - } - - tca := NewTCA(eca) - if tca == nil { - return nil, fmt.Errorf("Could not create a new TCA") - } - - return tca, nil -} - -func buildCertificateSetRequest(enrollID string, enrollmentPrivKey *ecdsa.PrivateKey, num, numattrs int) (*protos.TCertCreateSetReq, error) { - now := time.Now() - timestamp := timestamp.Timestamp{Seconds: int64(now.Second()), Nanos: int32(now.Nanosecond())} - - var attributes []*protos.TCertAttribute - if numattrs >= 0 { // else negative means use nil from above - attributes = make([]*protos.TCertAttribute, numattrs) - } - - req := &protos.TCertCreateSetReq{ - Ts: ×tamp, - Id: &protos.Identity{Id: enrollID}, - Num: uint32(num), - Attributes: attributes, - Sig: nil, - } - - rawReq, err := proto.Marshal(req) - if err != nil { - return nil, fmt.Errorf("Failed marshaling request [%v].", err) - } - - r, s, err := primitives.ECDSASignDirect(enrollmentPrivKey, rawReq) - if err != nil { - return nil, fmt.Errorf("Failed creating signature for [%v]: [%v].", rawReq, err) - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - req.Sig = &protos.Signature{Type: protos.CryptoType_ECDSA, R: R, S: S} - return req, nil -} diff --git a/membersrvc/ca/tcaa.go b/membersrvc/ca/tcaa.go deleted file mode 100644 index b1e80b12acf..00000000000 --- a/membersrvc/ca/tcaa.go +++ /dev/null @@ -1,53 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "errors" - - pb "github.com/hyperledger/fabric/membersrvc/protos" - "github.com/op/go-logging" - "golang.org/x/net/context" -) - -var tcaaLogger = logging.MustGetLogger("tcaa") - -// TCAA serves the administrator GRPC interface of the TCA. -type TCAA struct { - tca *TCA -} - -// RevokeCertificate revokes a certificate from the TCA. Not yet implemented. -func (tcaa *TCAA) RevokeCertificate(context.Context, *pb.TCertRevokeReq) (*pb.CAStatus, error) { - tcaaLogger.Debug("grpc TCAA:RevokeCertificate") - - return nil, errors.New("not yet implemented") -} - -// RevokeCertificateSet revokes a certificate set from the TCA. Not yet implemented. -func (tcaa *TCAA) RevokeCertificateSet(context.Context, *pb.TCertRevokeSetReq) (*pb.CAStatus, error) { - tcaaLogger.Debug("grpc TCAA:RevokeCertificateSet") - - return nil, errors.New("not yet implemented") -} - -// PublishCRL requests the creation of a certificate revocation list from the TCA. Not yet implemented. -func (tcaa *TCAA) PublishCRL(context.Context, *pb.TCertCRLReq) (*pb.CAStatus, error) { - tcaaLogger.Debug("grpc TCAA:CreateCRL") - - return nil, errors.New("not yet implemented") -} diff --git a/membersrvc/ca/tcap.go b/membersrvc/ca/tcap.go deleted file mode 100644 index da503111734..00000000000 --- a/membersrvc/ca/tcap.go +++ /dev/null @@ -1,365 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "crypto/ecdsa" - "crypto/hmac" - "crypto/rand" - "crypto/x509" - "crypto/x509/pkix" - "encoding/asn1" - "encoding/binary" - "errors" - "fmt" - "math/big" - "strconv" - "time" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/core/crypto/attributes" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/util" - pb "github.com/hyperledger/fabric/membersrvc/protos" - "github.com/op/go-logging" - "github.com/spf13/viper" - "golang.org/x/net/context" - - "github.com/golang/protobuf/ptypes/timestamp" -) - -var tcapLogger = logging.MustGetLogger("tcap") - -// TCAP serves the public GRPC interface of the TCA. -type TCAP struct { - tca *TCA -} - -// ReadCACertificate reads the certificate of the TCA. -func (tcap *TCAP) ReadCACertificate(ctx context.Context, in *pb.Empty) (*pb.Cert, error) { - tcapLogger.Debugf("grpc TCAP:ReadCACertificate") - - return &pb.Cert{Cert: tcap.tca.raw}, nil -} - -func (tcap *TCAP) selectValidAttributes(certRaw []byte) ([]*pb.ACAAttribute, error) { - cert, err := x509.ParseCertificate(certRaw) - if err != nil { - return nil, err - } - - var ans []*pb.ACAAttribute - - if cert.Extensions == nil { - return ans, nil - } - currentTime := time.Now() - for _, extension := range cert.Extensions { - acaAtt := &pb.ACAAttribute{AttributeName: "", AttributeValue: nil, ValidFrom: ×tamp.Timestamp{Seconds: 0, Nanos: 0}, ValidTo: ×tamp.Timestamp{Seconds: 0, Nanos: 0}} - - if IsAttributeOID(extension.Id) { - if err := proto.Unmarshal(extension.Value, acaAtt); err != nil { - continue - } - - if acaAtt.AttributeName == "" { - continue - } - var from, to time.Time - if acaAtt.ValidFrom != nil { - from = time.Unix(acaAtt.ValidFrom.Seconds, int64(acaAtt.ValidFrom.Nanos)) - } - if acaAtt.ValidTo != nil { - to = time.Unix(acaAtt.ValidTo.Seconds, int64(acaAtt.ValidTo.Nanos)) - } - - //Check if the attribute still being valid. - if (from.Before(currentTime) || from.Equal(currentTime)) && (to.IsZero() || to.After(currentTime)) { - ans = append(ans, acaAtt) - } - } - } - return ans, nil -} - -func (tcap *TCAP) requestAttributes(id string, ecert []byte, attrs []*pb.TCertAttribute) ([]*pb.ACAAttribute, error) { - //TODO we are creation a new client connection per each ecer request. We should be implement a connections pool. - sock, acaP, err := GetACAClient() - if err != nil { - return nil, err - } - defer sock.Close() - var attrNames []*pb.TCertAttribute - - for _, att := range attrs { - attrName := pb.TCertAttribute{AttributeName: att.AttributeName} - attrNames = append(attrNames, &attrName) - } - - req := &pb.ACAAttrReq{ - Ts: ×tamp.Timestamp{Seconds: time.Now().Unix(), Nanos: 0}, - Id: &pb.Identity{Id: id}, - ECert: &pb.Cert{Cert: ecert}, - Attributes: attrNames, - Signature: nil} - - var rawReq []byte - rawReq, err = proto.Marshal(req) - if err != nil { - return nil, err - } - - var r, s *big.Int - - r, s, err = primitives.ECDSASignDirect(tcap.tca.priv, rawReq) - - if err != nil { - return nil, err - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - - req.Signature = &pb.Signature{Type: pb.CryptoType_ECDSA, R: R, S: S} - - resp, err := acaP.RequestAttributes(context.Background(), req) - if err != nil { - return nil, err - } - - if resp.Status >= pb.ACAAttrResp_FAILURE_MINVAL && resp.Status <= pb.ACAAttrResp_FAILURE_MAXVAL { - return nil, fmt.Errorf("Error fetching attributes = %s", resp.Status) - } - - return tcap.selectValidAttributes(resp.Cert.Cert) -} - -// CreateCertificateSet requests the creation of a new transaction certificate set by the TCA. -func (tcap *TCAP) CreateCertificateSet(ctx context.Context, in *pb.TCertCreateSetReq) (*pb.TCertCreateSetResp, error) { - tcapLogger.Debugf("grpc TCAP:CreateCertificateSet") - - id := in.Id.Id - raw, err := tcap.tca.eca.readCertificateByKeyUsage(id, x509.KeyUsageDigitalSignature) - if err != nil { - return nil, err - } - - return tcap.createCertificateSet(ctx, raw, in) -} - -func (tcap *TCAP) createCertificateSet(ctx context.Context, raw []byte, in *pb.TCertCreateSetReq) (*pb.TCertCreateSetResp, error) { - var attrs = []*pb.ACAAttribute{} - var err error - var id = in.Id.Id - var timestamp = in.Ts.Seconds - const tcertSubjectCommonNameValue string = "Transaction Certificate" - - if in.Attributes != nil && viper.GetBool("aca.enabled") { - attrs, err = tcap.requestAttributes(id, raw, in.Attributes) - if err != nil { - return nil, err - } - } - - cert, err := x509.ParseCertificate(raw) - if err != nil { - return nil, err - } - - pub := cert.PublicKey.(*ecdsa.PublicKey) - - r, s := big.NewInt(0), big.NewInt(0) - r.UnmarshalText(in.Sig.R) - s.UnmarshalText(in.Sig.S) - - //sig := in.Sig - in.Sig = nil - - hash := primitives.NewHash() - raw, _ = proto.Marshal(in) - hash.Write(raw) - if ecdsa.Verify(pub, hash.Sum(nil), r, s) == false { - return nil, errors.New("signature does not verify") - } - - // Generate nonce for TCertIndex - nonce := make([]byte, 16) // 8 bytes rand, 8 bytes timestamp - rand.Reader.Read(nonce[:8]) - binary.LittleEndian.PutUint64(nonce[8:], uint64(in.Ts.Seconds)) - - mac := hmac.New(primitives.GetDefaultHash(), tcap.tca.hmacKey) - raw, _ = x509.MarshalPKIXPublicKey(pub) - mac.Write(raw) - kdfKey := mac.Sum(nil) - - num := int(in.Num) - if num == 0 { - num = 1 - } - - // the batch of TCerts - var set []*pb.TCert - - for i := 0; i < num; i++ { - tcertid := util.GenerateIntUUID() - - // Compute TCertIndex - tidx := []byte(strconv.Itoa(2*i + 1)) - tidx = append(tidx[:], nonce[:]...) - tidx = append(tidx[:], Padding...) - - mac := hmac.New(primitives.GetDefaultHash(), kdfKey) - mac.Write([]byte{1}) - extKey := mac.Sum(nil)[:32] - - mac = hmac.New(primitives.GetDefaultHash(), kdfKey) - mac.Write([]byte{2}) - mac = hmac.New(primitives.GetDefaultHash(), mac.Sum(nil)) - mac.Write(tidx) - - one := new(big.Int).SetInt64(1) - k := new(big.Int).SetBytes(mac.Sum(nil)) - k.Mod(k, new(big.Int).Sub(pub.Curve.Params().N, one)) - k.Add(k, one) - - tmpX, tmpY := pub.ScalarBaseMult(k.Bytes()) - txX, txY := pub.Curve.Add(pub.X, pub.Y, tmpX, tmpY) - txPub := ecdsa.PublicKey{Curve: pub.Curve, X: txX, Y: txY} - - // Compute encrypted TCertIndex - encryptedTidx, err := primitives.CBCPKCS7Encrypt(extKey, tidx) - if err != nil { - return nil, err - } - - extensions, preK0, err := tcap.generateExtensions(tcertid, encryptedTidx, cert, attrs) - - if err != nil { - return nil, err - } - - spec := NewDefaultPeriodCertificateSpecWithCommonName(id, tcertSubjectCommonNameValue, tcertid, &txPub, x509.KeyUsageDigitalSignature, extensions...) - if raw, err = tcap.tca.createCertificateFromSpec(spec, timestamp, kdfKey, false); err != nil { - tcapLogger.Error(err) - return nil, err - } - - set = append(set, &pb.TCert{Cert: raw, Prek0: preK0}) - } - - tcap.tca.persistCertificateSet(id, timestamp, nonce, kdfKey) - - return &pb.TCertCreateSetResp{Certs: &pb.CertSet{Ts: in.Ts, Id: in.Id, Key: kdfKey, Certs: set}}, nil -} - -// Generate encrypted extensions to be included into the TCert (TCertIndex, EnrollmentID and attributes). -func (tcap *TCAP) generateExtensions(tcertid *big.Int, tidx []byte, enrollmentCert *x509.Certificate, attrs []*pb.ACAAttribute) ([]pkix.Extension, []byte, error) { - // For each TCert we need to store and retrieve to the user the list of Ks used to encrypt the EnrollmentID and the attributes. - extensions := make([]pkix.Extension, len(attrs)) - - // Compute preK_1 to encrypt attributes and enrollment ID - preK1, err := tcap.tca.getPreKFrom(enrollmentCert) - if err != nil { - return nil, nil, err - } - - mac := hmac.New(primitives.GetDefaultHash(), preK1) - mac.Write(tcertid.Bytes()) - preK0 := mac.Sum(nil) - - // Compute encrypted EnrollmentID - mac = hmac.New(primitives.GetDefaultHash(), preK0) - mac.Write([]byte("enrollmentID")) - enrollmentIDKey := mac.Sum(nil)[:32] - - enrollmentID := []byte(enrollmentCert.Subject.CommonName) - enrollmentID = append(enrollmentID, Padding...) - - encEnrollmentID, err := primitives.CBCPKCS7Encrypt(enrollmentIDKey, enrollmentID) - if err != nil { - return nil, nil, err - } - - attributeIdentifierIndex := 9 - count := 0 - attrsHeader := make(map[string]int) - // Encrypt and append attrs to the extensions slice - for _, a := range attrs { - count++ - - value := []byte(a.AttributeValue) - - //Save the position of the attribute extension on the header. - attrsHeader[a.AttributeName] = count - - if isEnabledAttributesEncryption() { - value, err = attributes.EncryptAttributeValuePK0(preK0, a.AttributeName, value) - if err != nil { - return nil, nil, err - } - } - - // Generate an ObjectIdentifier for the extension holding the attribute - TCertEncAttributes := asn1.ObjectIdentifier{1, 2, 3, 4, 5, 6, attributeIdentifierIndex + count} - - // Add the attribute extension to the extensions array - extensions[count-1] = pkix.Extension{Id: TCertEncAttributes, Critical: false, Value: value} - } - - // Append the TCertIndex to the extensions - extensions = append(extensions, pkix.Extension{Id: TCertEncTCertIndex, Critical: true, Value: tidx}) - - // Append the encrypted EnrollmentID to the extensions - extensions = append(extensions, pkix.Extension{Id: TCertEncEnrollmentID, Critical: false, Value: encEnrollmentID}) - - // Append the attributes header if there was attributes to include in the TCert - if len(attrs) > 0 { - headerValue, err := attributes.BuildAttributesHeader(attrsHeader) - if err != nil { - return nil, nil, err - } - if isEnabledAttributesEncryption() { - headerValue, err = attributes.EncryptAttributeValuePK0(preK0, attributes.HeaderAttributeName, headerValue) - if err != nil { - return nil, nil, err - } - } - extensions = append(extensions, pkix.Extension{Id: TCertAttributesHeaders, Critical: false, Value: headerValue}) - } - - return extensions, preK0, nil -} - -// RevokeCertificate revokes a certificate from the TCA. Not yet implemented. -func (tcap *TCAP) RevokeCertificate(context.Context, *pb.TCertRevokeReq) (*pb.CAStatus, error) { - tcapLogger.Debugf("grpc TCAP:RevokeCertificate") - - return nil, errors.New("not yet implemented") -} - -// RevokeCertificateSet revokes a certificate set from the TCA. Not yet implemented. -func (tcap *TCAP) RevokeCertificateSet(context.Context, *pb.TCertRevokeSetReq) (*pb.CAStatus, error) { - tcapLogger.Debugf("grpc TCAP:RevokeCertificateSet") - - return nil, errors.New("not yet implemented") -} - -func isEnabledAttributesEncryption() bool { - //TODO this code is commented because attributes encryption is not yet implemented. - //return viper.GetBool("tca.attribute-encryption.enabled") - return false -} diff --git a/membersrvc/ca/test_resources/ecert_test_user0.dump b/membersrvc/ca/test_resources/ecert_test_user0.dump deleted file mode 100755 index b149810531c..00000000000 Binary files a/membersrvc/ca/test_resources/ecert_test_user0.dump and /dev/null differ diff --git a/membersrvc/ca/test_resources/ecert_test_user1.dump b/membersrvc/ca/test_resources/ecert_test_user1.dump deleted file mode 100755 index ff27bf0c17a..00000000000 Binary files a/membersrvc/ca/test_resources/ecert_test_user1.dump and /dev/null differ diff --git a/membersrvc/ca/test_resources/ecert_test_user2.dump b/membersrvc/ca/test_resources/ecert_test_user2.dump deleted file mode 100755 index b75506c6d9c..00000000000 Binary files a/membersrvc/ca/test_resources/ecert_test_user2.dump and /dev/null differ diff --git a/membersrvc/ca/test_resources/key_test_user0.dump b/membersrvc/ca/test_resources/key_test_user0.dump deleted file mode 100755 index 42b46a7ad43..00000000000 --- a/membersrvc/ca/test_resources/key_test_user0.dump +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN ECDSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-256-CBC,7af376757b4a587ac1d7a187192eb5e9 - -zZCWUTmd7IVh+3Vp0XlRTh1rOGWjVkMb2HG4JIY1IUue4vbZP+HyxQZ424WsOP3w -lBqdksRY1oHN+KFU6RRvGH54qOuI2MULGRMK80d5Q0eqGX09FaO1pBPbQiNud0n5 -uk4jlt6b+4RLKfBghbqk0UqBMeg9gECU5zF5MH3/+H8= ------END ECDSA PRIVATE KEY----- diff --git a/membersrvc/ca/test_resources/key_test_user1.dump b/membersrvc/ca/test_resources/key_test_user1.dump deleted file mode 100755 index c63fce6fd01..00000000000 --- a/membersrvc/ca/test_resources/key_test_user1.dump +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN ECDSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-256-CBC,54fe446e7249adc2b762039808a5a434 - -OM4MzGtsERUCRN6P4c0uKOcNFvkcm6Z3rjpa4b37k3FB5tB2r699I2XghEnr2ifq -1L1LDuRHS2SqayTjeAHCty86mw9aBjKeCBqyZPPUGw0s8AvxUw1cr0YXiqIbveXt -5pDRPd39T1baJWGGLtNyTlnsyCTaBs8SPYi7wjyvXpo= ------END ECDSA PRIVATE KEY----- diff --git a/membersrvc/ca/test_resources/key_test_user2.dump b/membersrvc/ca/test_resources/key_test_user2.dump deleted file mode 100755 index f3fa0364083..00000000000 --- a/membersrvc/ca/test_resources/key_test_user2.dump +++ /dev/null @@ -1,8 +0,0 @@ ------BEGIN ECDSA PRIVATE KEY----- -Proc-Type: 4,ENCRYPTED -DEK-Info: AES-256-CBC,97b5487e373a4728f206bb4fb81ba331 - -nhNzsdwpN8HHclaYvEHL8sjesdTnEavIzX5H/X2HSqigKEyNJFV56fzHrkGIrd5r -dKAn/966dPD+PIaJTkVY1hXUpaXeJf58v/ZefW8soZxJAw1scOsTDWRuzobIuC60 -pr6mIeFHRSdb/39gLBznjpI6FVJApQQTJJt9ODpbaUE= ------END ECDSA PRIVATE KEY----- diff --git a/membersrvc/ca/tlsca.go b/membersrvc/ca/tlsca.go deleted file mode 100644 index 9106d9ac1b5..00000000000 --- a/membersrvc/ca/tlsca.go +++ /dev/null @@ -1,175 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "crypto/ecdsa" - "crypto/x509" - "database/sql" - "errors" - "math/big" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/flogging" - pb "github.com/hyperledger/fabric/membersrvc/protos" - "github.com/op/go-logging" - "golang.org/x/net/context" - "google.golang.org/grpc" -) - -var tlscaLogger = logging.MustGetLogger("tlsca") - -// TLSCA is the tls certificate authority. -// -type TLSCA struct { - *CA - eca *ECA - gRPCServer *grpc.Server -} - -// TLSCAP serves the public GRPC interface of the TLSCA. -// -type TLSCAP struct { - tlsca *TLSCA -} - -// TLSCAA serves the administrator GRPC interface of the TLS. -// -type TLSCAA struct { - tlsca *TLSCA -} - -func initializeTLSCATables(db *sql.DB) error { - return initializeCommonTables(db) -} - -// NewTLSCA sets up a new TLSCA. -// -func NewTLSCA(eca *ECA) *TLSCA { - tlsca := &TLSCA{NewCA("tlsca", initializeTLSCATables), eca, nil} - flogging.LoggingInit("tlsca") - - return tlsca -} - -// Start starts the TLSCA. -// -func (tlsca *TLSCA) Start(srv *grpc.Server) { - tlsca.startTLSCAP(srv) - tlsca.startTLSCAA(srv) - - tlscaLogger.Info("TLSCA started.") -} - -func (tlsca *TLSCA) startTLSCAP(srv *grpc.Server) { - pb.RegisterTLSCAPServer(srv, &TLSCAP{tlsca}) -} - -func (tlsca *TLSCA) startTLSCAA(srv *grpc.Server) { - pb.RegisterTLSCAAServer(srv, &TLSCAA{tlsca}) -} - -// Stop stops the TCA services. -func (tlsca *TLSCA) Stop() error { - tlscaLogger.Info("Stopping the TLSCA services...") - if tlsca.gRPCServer != nil { - tlsca.gRPCServer.Stop() - } - err := tlsca.CA.Stop() - if err != nil { - tlscaLogger.Errorf("Error stopping the TLSCA services: %s", err) - } else { - tlscaLogger.Info("TLSCA services stopped") - } - return err -} - -// ReadCACertificate reads the certificate of the TLSCA. -// -func (tlscap *TLSCAP) ReadCACertificate(ctx context.Context, in *pb.Empty) (*pb.Cert, error) { - tlscaLogger.Debug("grpc TLSCAP:ReadCACertificate") - - return &pb.Cert{Cert: tlscap.tlsca.raw}, nil -} - -// CreateCertificate requests the creation of a new enrollment certificate by the TLSCA. -// -func (tlscap *TLSCAP) CreateCertificate(ctx context.Context, in *pb.TLSCertCreateReq) (*pb.TLSCertCreateResp, error) { - tlscaLogger.Debug("grpc TLSCAP:CreateCertificate") - - id := in.Id.Id - - sig := in.Sig - in.Sig = nil - - r, s := big.NewInt(0), big.NewInt(0) - r.UnmarshalText(sig.R) - s.UnmarshalText(sig.S) - - raw := in.Pub.Key - if in.Pub.Type != pb.CryptoType_ECDSA { - return nil, errors.New("unsupported key type") - } - pub, err := x509.ParsePKIXPublicKey(in.Pub.Key) - if err != nil { - return nil, err - } - - hash := primitives.NewHash() - raw, _ = proto.Marshal(in) - hash.Write(raw) - if ecdsa.Verify(pub.(*ecdsa.PublicKey), hash.Sum(nil), r, s) == false { - return nil, errors.New("signature does not verify") - } - - if raw, err = tlscap.tlsca.createCertificate(id, pub.(*ecdsa.PublicKey), x509.KeyUsageDigitalSignature, in.Ts.Seconds, nil); err != nil { - tlscaLogger.Error(err) - return nil, err - } - - return &pb.TLSCertCreateResp{Cert: &pb.Cert{Cert: raw}, RootCert: &pb.Cert{Cert: tlscap.tlsca.raw}}, nil -} - -// ReadCertificate reads an enrollment certificate from the TLSCA. -// -func (tlscap *TLSCAP) ReadCertificate(ctx context.Context, in *pb.TLSCertReadReq) (*pb.Cert, error) { - tlscaLogger.Debug("grpc TLSCAP:ReadCertificate") - - raw, err := tlscap.tlsca.readCertificateByKeyUsage(in.Id.Id, x509.KeyUsageKeyAgreement) - if err != nil { - return nil, err - } - - return &pb.Cert{Cert: raw}, nil -} - -// RevokeCertificate revokes a certificate from the TLSCA. Not yet implemented. -// -func (tlscap *TLSCAP) RevokeCertificate(context.Context, *pb.TLSCertRevokeReq) (*pb.CAStatus, error) { - tlscaLogger.Debug("grpc TLSCAP:RevokeCertificate") - - return nil, errors.New("not yet implemented") -} - -// RevokeCertificate revokes a certificate from the TLSCA. Not yet implemented. -// -func (tlscaa *TLSCAA) RevokeCertificate(context.Context, *pb.TLSCertRevokeReq) (*pb.CAStatus, error) { - tlscaLogger.Debug("grpc TLSCAA:RevokeCertificate") - - return nil, errors.New("not yet implemented") -} diff --git a/membersrvc/ca/tlsca_test.go b/membersrvc/ca/tlsca_test.go deleted file mode 100644 index 6fa0d80b5c9..00000000000 --- a/membersrvc/ca/tlsca_test.go +++ /dev/null @@ -1,183 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "io/ioutil" - "net" - "testing" - "time" - - "golang.org/x/net/context" - - "github.com/spf13/viper" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" - - "crypto/ecdsa" - "crypto/rand" - "crypto/x509" - "path/filepath" - - "github.com/golang/protobuf/proto" - "github.com/hyperledger/fabric/core/crypto/primitives" - "github.com/hyperledger/fabric/core/util" - membersrvc "github.com/hyperledger/fabric/membersrvc/protos" - - _ "fmt" - - "github.com/golang/protobuf/ptypes/timestamp" -) - -var ( - ecaS *ECA - tlscaS *TLSCA - srv *grpc.Server -) - -func TestTLS(t *testing.T) { - // Skipping test for now, this is just to try tls connections - t.Skip() - - go startTLSCA(t) - - time.Sleep(time.Second * 10) - - requestTLSCertificate(t) - - stopTLSCA(t) -} - -func startTLSCA(t *testing.T) { - CacheConfiguration() // Cache configuration - ecaS = NewECA(nil) - tlscaS = NewTLSCA(ecaS) - - var opts []grpc.ServerOption - creds, err := credentials.NewServerTLSFromFile(viper.GetString("server.tls.cert.file"), viper.GetString("server.tls.key.file")) - if err != nil { - t.Logf("Failed creating credentials for TLS-CA service: %s", err) - t.Fail() - } - - opts = []grpc.ServerOption{grpc.Creds(creds)} - - srv = grpc.NewServer(opts...) - - ecaS.Start(srv) - tlscaS.Start(srv) - - sock, err := net.Listen("tcp", viper.GetString("server.port")) - if err != nil { - t.Logf("Failed to start TLS-CA service: %s", err) - t.Fail() - } - - srv.Serve(sock) -} - -func requestTLSCertificate(t *testing.T) { - var opts []grpc.DialOption - - creds, err := credentials.NewClientTLSFromFile(viper.GetString("server.tls.cert.file"), "tlsca") - if err != nil { - t.Logf("Failed creating credentials for TLS-CA client: %s", err) - t.Fail() - } - - opts = append(opts, grpc.WithTransportCredentials(creds)) - sockP, err := grpc.Dial(viper.GetString("peer.pki.tlsca.paddr"), opts...) - if err != nil { - t.Logf("Failed dialing in: %s", err) - t.Fail() - } - - defer sockP.Close() - - tlscaP := membersrvc.NewTLSCAPClient(sockP) - - // Prepare the request - id := "peer" - priv, err := primitives.NewECDSAKey() - - if err != nil { - t.Logf("Failed generating key: %s", err) - t.Fail() - } - - uuid := util.GenerateUUID() - - pubraw, _ := x509.MarshalPKIXPublicKey(&priv.PublicKey) - now := time.Now() - timestamp := timestamp.Timestamp{Seconds: int64(now.Second()), Nanos: int32(now.Nanosecond())} - - req := &membersrvc.TLSCertCreateReq{ - Ts: ×tamp, - Id: &membersrvc.Identity{Id: id + "-" + uuid}, - Pub: &membersrvc.PublicKey{ - Type: membersrvc.CryptoType_ECDSA, - Key: pubraw, - }, Sig: nil} - - rawreq, _ := proto.Marshal(req) - r, s, err := ecdsa.Sign(rand.Reader, priv, primitives.Hash(rawreq)) - - if err != nil { - t.Logf("Failed signing the request: %s", err) - t.Fail() - } - - R, _ := r.MarshalText() - S, _ := s.MarshalText() - req.Sig = &membersrvc.Signature{Type: membersrvc.CryptoType_ECDSA, R: R, S: S} - - resp, err := tlscaP.CreateCertificate(context.Background(), req) - if err != nil { - t.Logf("Failed requesting tls certificate: %s", err) - t.Fail() - } - - storePrivateKeyInClear("tls_peer.priv", priv, t) - storeCert("tls_peer.cert", resp.Cert.Cert, t) - storeCert("tls_peer.ca", resp.RootCert.Cert, t) -} - -func stopTLSCA(t *testing.T) { - srv.Stop() -} - -func storePrivateKeyInClear(alias string, privateKey interface{}, t *testing.T) { - rawKey, err := primitives.PrivateKeyToPEM(privateKey, nil) - if err != nil { - t.Logf("Failed converting private key to PEM [%s]: [%s]", alias, err) - t.Fail() - } - - err = ioutil.WriteFile(filepath.Join(".membersrvc/", alias), rawKey, 0700) - if err != nil { - t.Logf("Failed storing private key [%s]: [%s]", alias, err) - t.Fail() - } -} - -func storeCert(alias string, der []byte, t *testing.T) { - err := ioutil.WriteFile(filepath.Join(".membersrvc/", alias), primitives.DERCertToPEM(der), 0700) - if err != nil { - t.Logf("Failed storing certificate [%s]: [%s]", alias, err) - t.Fail() - } -} diff --git a/membersrvc/ca/util.go b/membersrvc/ca/util.go deleted file mode 100644 index 54c297132da..00000000000 --- a/membersrvc/ca/util.go +++ /dev/null @@ -1,67 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "errors" - mrand "math/rand" - "time" - - pb "github.com/hyperledger/fabric/membersrvc/protos" -) - -const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" -const ( - letterIdxBits = 6 // 6 bits to represent a letter index - letterIdxMask = 1<= 0; { - if remain == 0 { - cache, remain = rnd.Int63(), letterIdxMax - } - if idx := int(cache & letterIdxMask); idx < len(letterBytes) { - b[i] = letterBytes[idx] - i-- - } - cache >>= letterIdxBits - remain-- - } - - return string(b) -} - -// -// MemberRoleToString converts a member role representation from int32 to a string, -// according to the Role enum defined in ca.proto. -// -func MemberRoleToString(role pb.Role) (string, error) { - roleMap := pb.Role_name - - roleStr := roleMap[int32(role)] - if roleStr == "" { - return "", errors.New("Undefined user role passed.") - } - - return roleStr, nil -} diff --git a/membersrvc/ca/util_test.go b/membersrvc/ca/util_test.go deleted file mode 100644 index 9a5c14dfd5b..00000000000 --- a/membersrvc/ca/util_test.go +++ /dev/null @@ -1,50 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package ca - -import ( - "reflect" - "testing" - - pb "github.com/hyperledger/fabric/membersrvc/protos" -) - -func TestRandomString(t *testing.T) { - - rand := randomString(100) - if rand == "" { - t.Error("The randomString function must return a non nil value.") - } - - if reflect.TypeOf(rand).String() != "string" { - t.Error("The randomString function must returns a string type value.") - } -} - -func TestMemberRoleToStringNone(t *testing.T) { - - var role, err = MemberRoleToString(pb.Role_NONE) - - if err != nil { - t.Errorf("Error converting member role to string, result: %s", role) - } - - if role != pb.Role_name[int32(pb.Role_NONE)] { - t.Errorf("The role string returned should have been %s", "NONE") - } - -} diff --git a/membersrvc/membersrvc.yaml b/membersrvc/membersrvc.yaml deleted file mode 100644 index 84ef66d74d9..00000000000 --- a/membersrvc/membersrvc.yaml +++ /dev/null @@ -1,195 +0,0 @@ -# CA server parameters -# -server: - - # limits the number of operating system threads used by the CA - # set to negative to use the system default setting - gomaxprocs: -1 - - # path to the OBC state directory and CA state subdirectory - rootpath: "/var/hyperledger/production" - cadir: ".membersrvc" - - # port the CA services are listening on - port: ":7054" - - # TLS certificate and key file paths - tls: - cert: - file: - key: - file: - -security: - # Either 256 or 384 (note: must be the exact same value as specified in the core.yaml file) - level: 256 - - # Either SHA2 or SHA3 (note: must be the exact same value as specified in the core.yaml file) - hashAlgorithm: SHA3 - - # The server host CN (Common Name) to be used (needs to match the TLS Server Certificate) - serverhostoverride: - - # Boolean (true/false) value indicating whether TLS should be used between the client and - # the various CA services (ECA, TCA, TLSCA, ACA) - tls_enabled: false - - # A PEM-encoded (X509 v3, Base64) certificate to use for establishing the TLS connection - # between the client and the ACA service - client: - cert: - file: - - -# Enabling/disabling different logging levels of the CA. -# -logging: - -# Please see fabric/docs/Setup/logging-control.md for more -# options. - server: warning - ca: warning - eca: warning - ecap: warning - ecaa: warning - aca: warning - acap: warning - tca: warning - tcap: warning - tcaa: warning - tlsca: warning - -# Default users to be registered with the CA on first launch. The role is a binary OR -# of the different roles a user can have: -# -# - simple client such as a wallet: CLIENT -# - non-validating peer: PEER -# - validating client: VALIDATOR -# - auditing client: AUDITOR -# -eca: - # This hierarchy is used to create the Pre-key tree, affiliations is the top of this hierarchy, 'banks_and_institutions' is used to create the key associated to auditors of both banks and - # institutions, 'banks' is used to create a key associated to auditors of banks, 'bank_a' is used to create a key associated to auditors of bank_a, etc. - affiliations: - banks_and_institutions: - banks: - - bank_a - - bank_b - - bank_c - institutions: - - institution_a - users: - # - # The fields of each user are as follows: - # : - # - # The optional JSON_Metadata field is of the following format: - # { "registrar": { "roles": , "delegateRoles": } } - # The 'registrar' section is used to control access to registration of new users directly via the ECAA.RegisterUser GRPC call. - # (See the 'fabric/membersrvc/protos/ca.proto' file for the definition of ECAA.RegisterUser.) - # Note that this also controls who can register users via the client SDK. - # - # Only users with a 'registrar' section may be a registrar to register other users. In particular, - # 1) the "roles" field specifies which member roles may be registered by this user, and - # 2) the "delegateRoles" field specifies which member roles may become the "roles" field of registered users. - # The valid role names are "client", "peer", "validator", and "auditor". - # - # Example1: - # The 'admin' user below can register clients, peers, validators, or auditors; furthermore, the 'admin' user can register other - # users who can then register clients only. - # - # Example2: - # The 'WebAppAdmin' user below can register clients only, but none of the users registered by this user can register other users. - # - admin: 1 Xurw3yU9zI0l institution_a '{"registrar":{"roles":["client","peer","validator","auditor"],"delegateRoles":["client"]}}' - WebAppAdmin: 1 DJY27pEnl16d institution_a '{"registrar":{"roles":["client"]}}' - lukas: 1 NPKYL39uKbkj bank_a - system_chaincode_invoker: 1 DRJ20pEql15a institution_a - diego: 1 DRJ23pEQl16a institution_a - jim: 1 6avZQLwcUe9b bank_a - binhn: 1 7avZQLwcUe9q institution_a - - # Users for asset transfer with roles test located at - # sdk/node/test/unit/asset-mgmt-with-roles.js - alice: 1 CMS10pEQlB16 bank_a - bob: 1 NOE63pEQbL25 bank_a - assigner: 1 Tc43PeqBl11 bank_a - - vp: 4 f3489fy98ghf - - test_vp0: 4 MwYpmSRjupbT - test_vp1: 4 5wgHK9qqYaPy - test_vp2: 4 vQelbRvja7cJ - test_vp3: 4 9LKqKH5peurL - test_vp4: 4 Pqh90CEW5juZ - test_vp5: 4 FfdvDkAdY81P - test_vp6: 4 QiXJgHyV4t7A - test_vp7: 4 twoKZouEyLyB - test_vp8: 4 BxP7QNh778gI - test_vp9: 4 wu3F1EwJWHvQ - -# Uncomment this section to activate devnet setup as specficied in -# devnet-setup.md -# -# vp0: 4 vp0_secret -# vp1: 4 vp1_secret - - test_user0: 1 MS9qrN8hFjlE bank_a - test_user1: 1 jGlNl6ImkuDo institution_a - test_user2: 1 zMflqOKezFiA bank_c - test_user3: 1 vWdLCE00vJy0 bank_a - test_user4: 1 4nXSrfoYGFCP institution_a - test_user5: 1 yg5DVhm0er1z bank_b - test_user6: 1 b7pmSxzKNFiw bank_a - test_user7: 1 YsWZD4qQmYxo institution_a - test_user8: 1 W8G0usrU7jRk bank_a - test_user9: 1 H80SiB5ODKKQ institution_a - - test_nvp0: 2 iywrPBDEPl0K bank_a - test_nvp1: 2 DcYXuRSocuqd institution_a - test_nvp2: 2 flpChShlY7xt bank_c - test_nvp3: 2 jeruawMomclo bank_a - test_nvp4: 2 RMYVxSZCk370 institution_a - test_nvp5: 2 XHYVCIJGZGK7 bank_b - test_nvp6: 2 4cIn63j8ahYp bank_a - test_nvp7: 2 E7FAJUtWVn2h institution_a - test_nvp8: 2 LJu8DkUilBEH bank_a - test_nvp9: 2 VlEsBsiyXSjw institution_a - -tca: - # Enabling/disabling attributes encryption, currently false is unique possible value due attributes encryption is not yet implemented. - attribute-encryption: - enabled: false -aca: - # Attributes is a list of the valid attributes to each user, attribute certificate authority is emulated temporarily using this file entries. - # In the future an external attribute certificate authority will be invoked. The format to each entry is: - # - # attribute-entry-#:{userid};{affiliation};{attributeName};{attributeValue};{valid from};{valid to} - # - # If valid to is empty the attribute never expire, if the valid from is empty the attribute is valid from the time zero. - attributes: - attribute-entry-0: diego;institution_a;company;ACompany;2015-01-01T00:00:00-03:00;; - attribute-entry-1: diego;institution_a;position;Software Staff;2015-01-01T00:00:00-03:00;2015-07-12T23:59:59-03:00; - attribute-entry-2: diego;institution_a;position;Software Engineer;2015-07-13T00:00:00-03:00;; - attribute-entry-3: jim,;institution_a;company;ACompany;2001-02-02T00:00:00-03:00;; - attribute-entry-4: jim;institution_a;position;Project Manager;2001-02-02T00:00:00-03:00;; - attribute-entry-5: binhn,;institution_a;company;ACompany;2015-01-01T00:00:00-03:00;; - attribute-entry-6: binhn;institution_a;position;Technical Leader;2015-01-01T00:00:00-03:00;; - - # User attributes for asset transfer with roles test located at - #sdk/node/test/unit/asset-mgmt-with-roles.js - attribute-entry-7: alice;bank_a;role;client;2016-01-01T00:00:00-03:00;; - attribute-entry-8: alice;bank_a;account;12345-56789;2016-01-01T00:00:00-03:00;; - attribute-entry-9: bob;bank_a;role;client;2015-02-02T00:00:00-03:00;; - attribute-entry-10: bob;bank_a;account;23456-67890;2015-02-02T00:00:00-03:00;; - attribute-entry-11: assigner;bank_a;role;assigner;2015-01-01T00:00:00-03:00;; - - address: localhost:7054 - server-name: acap - # Enabling/disabling Attribute Certificate Authority, if ACA is enabled attributes will be added into the TCert. - enabled: false -pki: - ca: - subject: - organization: Hyperledger - country: US diff --git a/membersrvc/protos/ca.pb.go b/membersrvc/protos/ca.pb.go deleted file mode 100644 index 589b0b149be..00000000000 --- a/membersrvc/protos/ca.pb.go +++ /dev/null @@ -1,2459 +0,0 @@ -// Code generated by protoc-gen-go. -// source: ca.proto -// DO NOT EDIT! - -/* -Package protos is a generated protocol buffer package. - -It is generated from these files: - ca.proto - -It has these top-level messages: - CAStatus - Empty - Identity - Token - Hash - PublicKey - PrivateKey - Signature - Registrar - RegisterUserReq - Attribute - ReadUserSetReq - User - UserSet - ECertCreateReq - ECertCreateResp - ECertReadReq - ECertRevokeReq - ECertCRLReq - TCertCreateReq - TCertCreateResp - TCertCreateSetReq - TCertAttribute - TCertCreateSetResp - TCertReadSetsReq - TCertRevokeReq - TCertRevokeSetReq - TCertCRLReq - TLSCertCreateReq - TLSCertCreateResp - TLSCertReadReq - TLSCertRevokeReq - Cert - TCert - CertSet - CertSets - CertPair - ACAAttrReq - ACAAttrResp - ACAFetchAttrReq - ACAFetchAttrResp - FetchAttrsResult - ACAAttribute -*/ -package protos - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import google_protobuf "github.com/golang/protobuf/ptypes/timestamp" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// Public/private keys. -type CryptoType int32 - -const ( - CryptoType_ECDSA CryptoType = 0 - CryptoType_RSA CryptoType = 1 - CryptoType_DSA CryptoType = 2 -) - -var CryptoType_name = map[int32]string{ - 0: "ECDSA", - 1: "RSA", - 2: "DSA", -} -var CryptoType_value = map[string]int32{ - "ECDSA": 0, - "RSA": 1, - "DSA": 2, -} - -func (x CryptoType) String() string { - return proto.EnumName(CryptoType_name, int32(x)) -} -func (CryptoType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -// User registration. -// -type Role int32 - -const ( - Role_NONE Role = 0 - Role_CLIENT Role = 1 - Role_PEER Role = 2 - Role_VALIDATOR Role = 4 - Role_AUDITOR Role = 8 - Role_ALL Role = 65535 -) - -var Role_name = map[int32]string{ - 0: "NONE", - 1: "CLIENT", - 2: "PEER", - 4: "VALIDATOR", - 8: "AUDITOR", - 65535: "ALL", -} -var Role_value = map[string]int32{ - "NONE": 0, - "CLIENT": 1, - "PEER": 2, - "VALIDATOR": 4, - "AUDITOR": 8, - "ALL": 65535, -} - -func (x Role) String() string { - return proto.EnumName(Role_name, int32(x)) -} -func (Role) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -type CAStatus_StatusCode int32 - -const ( - CAStatus_OK CAStatus_StatusCode = 0 - CAStatus_UNKNOWN_ERROR CAStatus_StatusCode = 1 -) - -var CAStatus_StatusCode_name = map[int32]string{ - 0: "OK", - 1: "UNKNOWN_ERROR", -} -var CAStatus_StatusCode_value = map[string]int32{ - "OK": 0, - "UNKNOWN_ERROR": 1, -} - -func (x CAStatus_StatusCode) String() string { - return proto.EnumName(CAStatus_StatusCode_name, int32(x)) -} -func (CAStatus_StatusCode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0, 0} } - -type ACAAttrResp_StatusCode int32 - -const ( - // Processed OK and all attributes included. - ACAAttrResp_FULL_SUCCESSFUL ACAAttrResp_StatusCode = 0 - // Processed OK but some attributes included. - ACAAttrResp_PARTIAL_SUCCESSFUL ACAAttrResp_StatusCode = 1 - // Processed OK but no attributes included. - ACAAttrResp_NO_ATTRIBUTES_FOUND ACAAttrResp_StatusCode = 8 - ACAAttrResp_FAILURE_MINVAL ACAAttrResp_StatusCode = 100 - ACAAttrResp_FAILURE ACAAttrResp_StatusCode = 100 - ACAAttrResp_BAD_REQUEST ACAAttrResp_StatusCode = 200 - // Missing parameters - ACAAttrResp_FAIL_NIL_TS ACAAttrResp_StatusCode = 201 - ACAAttrResp_FAIL_NIL_ID ACAAttrResp_StatusCode = 202 - ACAAttrResp_FAIL_NIL_ECERT ACAAttrResp_StatusCode = 203 - ACAAttrResp_FAIL_NIL_SIGNATURE ACAAttrResp_StatusCode = 204 - ACAAttrResp_FAIL_NIL_ATTRIBUTES ACAAttrResp_StatusCode = 205 - ACAAttrResp_FAILURE_MAXVAL ACAAttrResp_StatusCode = 205 -) - -var ACAAttrResp_StatusCode_name = map[int32]string{ - 0: "FULL_SUCCESSFUL", - 1: "PARTIAL_SUCCESSFUL", - 8: "NO_ATTRIBUTES_FOUND", - 100: "FAILURE_MINVAL", - // Duplicate value: 100: "FAILURE", - 200: "BAD_REQUEST", - 201: "FAIL_NIL_TS", - 202: "FAIL_NIL_ID", - 203: "FAIL_NIL_ECERT", - 204: "FAIL_NIL_SIGNATURE", - 205: "FAIL_NIL_ATTRIBUTES", - // Duplicate value: 205: "FAILURE_MAXVAL", -} -var ACAAttrResp_StatusCode_value = map[string]int32{ - "FULL_SUCCESSFUL": 0, - "PARTIAL_SUCCESSFUL": 1, - "NO_ATTRIBUTES_FOUND": 8, - "FAILURE_MINVAL": 100, - "FAILURE": 100, - "BAD_REQUEST": 200, - "FAIL_NIL_TS": 201, - "FAIL_NIL_ID": 202, - "FAIL_NIL_ECERT": 203, - "FAIL_NIL_SIGNATURE": 204, - "FAIL_NIL_ATTRIBUTES": 205, - "FAILURE_MAXVAL": 205, -} - -func (x ACAAttrResp_StatusCode) String() string { - return proto.EnumName(ACAAttrResp_StatusCode_name, int32(x)) -} -func (ACAAttrResp_StatusCode) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{38, 0} } - -type ACAFetchAttrResp_StatusCode int32 - -const ( - // Processed OK - ACAFetchAttrResp_SUCCESS ACAFetchAttrResp_StatusCode = 0 - // Processed with errors. - ACAFetchAttrResp_FAILURE ACAFetchAttrResp_StatusCode = 100 -) - -var ACAFetchAttrResp_StatusCode_name = map[int32]string{ - 0: "SUCCESS", - 100: "FAILURE", -} -var ACAFetchAttrResp_StatusCode_value = map[string]int32{ - "SUCCESS": 0, - "FAILURE": 100, -} - -func (x ACAFetchAttrResp_StatusCode) String() string { - return proto.EnumName(ACAFetchAttrResp_StatusCode_name, int32(x)) -} -func (ACAFetchAttrResp_StatusCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor0, []int{40, 0} -} - -type FetchAttrsResult_StatusCode int32 - -const ( - // Processed OK - FetchAttrsResult_SUCCESS FetchAttrsResult_StatusCode = 0 - // Processed with errors - FetchAttrsResult_FAILURE FetchAttrsResult_StatusCode = 100 -) - -var FetchAttrsResult_StatusCode_name = map[int32]string{ - 0: "SUCCESS", - 100: "FAILURE", -} -var FetchAttrsResult_StatusCode_value = map[string]int32{ - "SUCCESS": 0, - "FAILURE": 100, -} - -func (x FetchAttrsResult_StatusCode) String() string { - return proto.EnumName(FetchAttrsResult_StatusCode_name, int32(x)) -} -func (FetchAttrsResult_StatusCode) EnumDescriptor() ([]byte, []int) { - return fileDescriptor0, []int{41, 0} -} - -// Status codes shared by both CAs. -// -type CAStatus struct { - Status CAStatus_StatusCode `protobuf:"varint,1,opt,name=status,enum=protos.CAStatus_StatusCode" json:"status,omitempty"` -} - -func (m *CAStatus) Reset() { *m = CAStatus{} } -func (m *CAStatus) String() string { return proto.CompactTextString(m) } -func (*CAStatus) ProtoMessage() {} -func (*CAStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -// Empty message. -type Empty struct { -} - -func (m *Empty) Reset() { *m = Empty{} } -func (m *Empty) String() string { return proto.CompactTextString(m) } -func (*Empty) ProtoMessage() {} -func (*Empty) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -// Uniquely identifies a user towards either CA. -type Identity struct { - Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` -} - -func (m *Identity) Reset() { *m = Identity{} } -func (m *Identity) String() string { return proto.CompactTextString(m) } -func (*Identity) ProtoMessage() {} -func (*Identity) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -type Token struct { - Tok []byte `protobuf:"bytes,1,opt,name=tok,proto3" json:"tok,omitempty"` -} - -func (m *Token) Reset() { *m = Token{} } -func (m *Token) String() string { return proto.CompactTextString(m) } -func (*Token) ProtoMessage() {} -func (*Token) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } - -type Hash struct { - Hash []byte `protobuf:"bytes,1,opt,name=hash,proto3" json:"hash,omitempty"` -} - -func (m *Hash) Reset() { *m = Hash{} } -func (m *Hash) String() string { return proto.CompactTextString(m) } -func (*Hash) ProtoMessage() {} -func (*Hash) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } - -type PublicKey struct { - Type CryptoType `protobuf:"varint,1,opt,name=type,enum=protos.CryptoType" json:"type,omitempty"` - Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` -} - -func (m *PublicKey) Reset() { *m = PublicKey{} } -func (m *PublicKey) String() string { return proto.CompactTextString(m) } -func (*PublicKey) ProtoMessage() {} -func (*PublicKey) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } - -type PrivateKey struct { - Type CryptoType `protobuf:"varint,1,opt,name=type,enum=protos.CryptoType" json:"type,omitempty"` - Key []byte `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` -} - -func (m *PrivateKey) Reset() { *m = PrivateKey{} } -func (m *PrivateKey) String() string { return proto.CompactTextString(m) } -func (*PrivateKey) ProtoMessage() {} -func (*PrivateKey) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } - -// Signature. -// -type Signature struct { - Type CryptoType `protobuf:"varint,1,opt,name=type,enum=protos.CryptoType" json:"type,omitempty"` - R []byte `protobuf:"bytes,2,opt,name=r,proto3" json:"r,omitempty"` - S []byte `protobuf:"bytes,3,opt,name=s,proto3" json:"s,omitempty"` -} - -func (m *Signature) Reset() { *m = Signature{} } -func (m *Signature) String() string { return proto.CompactTextString(m) } -func (*Signature) ProtoMessage() {} -func (*Signature) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } - -type Registrar struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Roles []string `protobuf:"bytes,2,rep,name=roles" json:"roles,omitempty"` - DelegateRoles []string `protobuf:"bytes,3,rep,name=delegateRoles" json:"delegateRoles,omitempty"` -} - -func (m *Registrar) Reset() { *m = Registrar{} } -func (m *Registrar) String() string { return proto.CompactTextString(m) } -func (*Registrar) ProtoMessage() {} -func (*Registrar) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} } - -func (m *Registrar) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -type RegisterUserReq struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Role Role `protobuf:"varint,2,opt,name=role,enum=protos.Role" json:"role,omitempty"` - Attributes []*Attribute `protobuf:"bytes,3,rep,name=attributes" json:"attributes,omitempty"` - Affiliation string `protobuf:"bytes,4,opt,name=affiliation" json:"affiliation,omitempty"` - Registrar *Registrar `protobuf:"bytes,5,opt,name=registrar" json:"registrar,omitempty"` - Sig *Signature `protobuf:"bytes,6,opt,name=sig" json:"sig,omitempty"` -} - -func (m *RegisterUserReq) Reset() { *m = RegisterUserReq{} } -func (m *RegisterUserReq) String() string { return proto.CompactTextString(m) } -func (*RegisterUserReq) ProtoMessage() {} -func (*RegisterUserReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} } - -func (m *RegisterUserReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *RegisterUserReq) GetAttributes() []*Attribute { - if m != nil { - return m.Attributes - } - return nil -} - -func (m *RegisterUserReq) GetRegistrar() *Registrar { - if m != nil { - return m.Registrar - } - return nil -} - -func (m *RegisterUserReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type Attribute struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` - NotBefore string `protobuf:"bytes,3,opt,name=notBefore" json:"notBefore,omitempty"` - NotAfter string `protobuf:"bytes,4,opt,name=notAfter" json:"notAfter,omitempty"` -} - -func (m *Attribute) Reset() { *m = Attribute{} } -func (m *Attribute) String() string { return proto.CompactTextString(m) } -func (*Attribute) ProtoMessage() {} -func (*Attribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} } - -type ReadUserSetReq struct { - Req *Identity `protobuf:"bytes,1,opt,name=req" json:"req,omitempty"` - Role Role `protobuf:"varint,2,opt,name=role,enum=protos.Role" json:"role,omitempty"` - Sig *Signature `protobuf:"bytes,3,opt,name=sig" json:"sig,omitempty"` -} - -func (m *ReadUserSetReq) Reset() { *m = ReadUserSetReq{} } -func (m *ReadUserSetReq) String() string { return proto.CompactTextString(m) } -func (*ReadUserSetReq) ProtoMessage() {} -func (*ReadUserSetReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} } - -func (m *ReadUserSetReq) GetReq() *Identity { - if m != nil { - return m.Req - } - return nil -} - -func (m *ReadUserSetReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type User struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Role Role `protobuf:"varint,2,opt,name=role,enum=protos.Role" json:"role,omitempty"` -} - -func (m *User) Reset() { *m = User{} } -func (m *User) String() string { return proto.CompactTextString(m) } -func (*User) ProtoMessage() {} -func (*User) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} } - -func (m *User) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -type UserSet struct { - Users []*User `protobuf:"bytes,1,rep,name=users" json:"users,omitempty"` -} - -func (m *UserSet) Reset() { *m = UserSet{} } -func (m *UserSet) String() string { return proto.CompactTextString(m) } -func (*UserSet) ProtoMessage() {} -func (*UserSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} } - -func (m *UserSet) GetUsers() []*User { - if m != nil { - return m.Users - } - return nil -} - -// Certificate requests. -// -type ECertCreateReq struct { - Ts *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=ts" json:"ts,omitempty"` - Id *Identity `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` - Tok *Token `protobuf:"bytes,3,opt,name=tok" json:"tok,omitempty"` - Sign *PublicKey `protobuf:"bytes,4,opt,name=sign" json:"sign,omitempty"` - Enc *PublicKey `protobuf:"bytes,5,opt,name=enc" json:"enc,omitempty"` - Sig *Signature `protobuf:"bytes,6,opt,name=sig" json:"sig,omitempty"` -} - -func (m *ECertCreateReq) Reset() { *m = ECertCreateReq{} } -func (m *ECertCreateReq) String() string { return proto.CompactTextString(m) } -func (*ECertCreateReq) ProtoMessage() {} -func (*ECertCreateReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} } - -func (m *ECertCreateReq) GetTs() *google_protobuf.Timestamp { - if m != nil { - return m.Ts - } - return nil -} - -func (m *ECertCreateReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *ECertCreateReq) GetTok() *Token { - if m != nil { - return m.Tok - } - return nil -} - -func (m *ECertCreateReq) GetSign() *PublicKey { - if m != nil { - return m.Sign - } - return nil -} - -func (m *ECertCreateReq) GetEnc() *PublicKey { - if m != nil { - return m.Enc - } - return nil -} - -func (m *ECertCreateReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type ECertCreateResp struct { - Certs *CertPair `protobuf:"bytes,1,opt,name=certs" json:"certs,omitempty"` - Chain *Token `protobuf:"bytes,2,opt,name=chain" json:"chain,omitempty"` - Pkchain []byte `protobuf:"bytes,5,opt,name=pkchain,proto3" json:"pkchain,omitempty"` - Tok *Token `protobuf:"bytes,3,opt,name=tok" json:"tok,omitempty"` - FetchResult *FetchAttrsResult `protobuf:"bytes,4,opt,name=fetchResult" json:"fetchResult,omitempty"` -} - -func (m *ECertCreateResp) Reset() { *m = ECertCreateResp{} } -func (m *ECertCreateResp) String() string { return proto.CompactTextString(m) } -func (*ECertCreateResp) ProtoMessage() {} -func (*ECertCreateResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} } - -func (m *ECertCreateResp) GetCerts() *CertPair { - if m != nil { - return m.Certs - } - return nil -} - -func (m *ECertCreateResp) GetChain() *Token { - if m != nil { - return m.Chain - } - return nil -} - -func (m *ECertCreateResp) GetTok() *Token { - if m != nil { - return m.Tok - } - return nil -} - -func (m *ECertCreateResp) GetFetchResult() *FetchAttrsResult { - if m != nil { - return m.FetchResult - } - return nil -} - -type ECertReadReq struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` -} - -func (m *ECertReadReq) Reset() { *m = ECertReadReq{} } -func (m *ECertReadReq) String() string { return proto.CompactTextString(m) } -func (*ECertReadReq) ProtoMessage() {} -func (*ECertReadReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} } - -func (m *ECertReadReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -type ECertRevokeReq struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Cert *Cert `protobuf:"bytes,2,opt,name=cert" json:"cert,omitempty"` - Sig *Signature `protobuf:"bytes,3,opt,name=sig" json:"sig,omitempty"` -} - -func (m *ECertRevokeReq) Reset() { *m = ECertRevokeReq{} } -func (m *ECertRevokeReq) String() string { return proto.CompactTextString(m) } -func (*ECertRevokeReq) ProtoMessage() {} -func (*ECertRevokeReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} } - -func (m *ECertRevokeReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *ECertRevokeReq) GetCert() *Cert { - if m != nil { - return m.Cert - } - return nil -} - -func (m *ECertRevokeReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type ECertCRLReq struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Sig *Signature `protobuf:"bytes,2,opt,name=sig" json:"sig,omitempty"` -} - -func (m *ECertCRLReq) Reset() { *m = ECertCRLReq{} } -func (m *ECertCRLReq) String() string { return proto.CompactTextString(m) } -func (*ECertCRLReq) ProtoMessage() {} -func (*ECertCRLReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} } - -func (m *ECertCRLReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *ECertCRLReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type TCertCreateReq struct { - Ts *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=ts" json:"ts,omitempty"` - Id *Identity `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` - Pub *PublicKey `protobuf:"bytes,3,opt,name=pub" json:"pub,omitempty"` - Sig *Signature `protobuf:"bytes,4,opt,name=sig" json:"sig,omitempty"` -} - -func (m *TCertCreateReq) Reset() { *m = TCertCreateReq{} } -func (m *TCertCreateReq) String() string { return proto.CompactTextString(m) } -func (*TCertCreateReq) ProtoMessage() {} -func (*TCertCreateReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} } - -func (m *TCertCreateReq) GetTs() *google_protobuf.Timestamp { - if m != nil { - return m.Ts - } - return nil -} - -func (m *TCertCreateReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *TCertCreateReq) GetPub() *PublicKey { - if m != nil { - return m.Pub - } - return nil -} - -func (m *TCertCreateReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type TCertCreateResp struct { - Cert *Cert `protobuf:"bytes,1,opt,name=cert" json:"cert,omitempty"` -} - -func (m *TCertCreateResp) Reset() { *m = TCertCreateResp{} } -func (m *TCertCreateResp) String() string { return proto.CompactTextString(m) } -func (*TCertCreateResp) ProtoMessage() {} -func (*TCertCreateResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} } - -func (m *TCertCreateResp) GetCert() *Cert { - if m != nil { - return m.Cert - } - return nil -} - -type TCertCreateSetReq struct { - Ts *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=ts" json:"ts,omitempty"` - Id *Identity `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` - Num uint32 `protobuf:"varint,3,opt,name=num" json:"num,omitempty"` - Attributes []*TCertAttribute `protobuf:"bytes,4,rep,name=attributes" json:"attributes,omitempty"` - Sig *Signature `protobuf:"bytes,5,opt,name=sig" json:"sig,omitempty"` -} - -func (m *TCertCreateSetReq) Reset() { *m = TCertCreateSetReq{} } -func (m *TCertCreateSetReq) String() string { return proto.CompactTextString(m) } -func (*TCertCreateSetReq) ProtoMessage() {} -func (*TCertCreateSetReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} } - -func (m *TCertCreateSetReq) GetTs() *google_protobuf.Timestamp { - if m != nil { - return m.Ts - } - return nil -} - -func (m *TCertCreateSetReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *TCertCreateSetReq) GetAttributes() []*TCertAttribute { - if m != nil { - return m.Attributes - } - return nil -} - -func (m *TCertCreateSetReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type TCertAttribute struct { - AttributeName string `protobuf:"bytes,1,opt,name=attributeName" json:"attributeName,omitempty"` -} - -func (m *TCertAttribute) Reset() { *m = TCertAttribute{} } -func (m *TCertAttribute) String() string { return proto.CompactTextString(m) } -func (*TCertAttribute) ProtoMessage() {} -func (*TCertAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} } - -type TCertCreateSetResp struct { - Certs *CertSet `protobuf:"bytes,1,opt,name=certs" json:"certs,omitempty"` -} - -func (m *TCertCreateSetResp) Reset() { *m = TCertCreateSetResp{} } -func (m *TCertCreateSetResp) String() string { return proto.CompactTextString(m) } -func (*TCertCreateSetResp) ProtoMessage() {} -func (*TCertCreateSetResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} } - -func (m *TCertCreateSetResp) GetCerts() *CertSet { - if m != nil { - return m.Certs - } - return nil -} - -type TCertReadSetsReq struct { - Begin *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=begin" json:"begin,omitempty"` - End *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=end" json:"end,omitempty"` - Req *Identity `protobuf:"bytes,3,opt,name=req" json:"req,omitempty"` - Role Role `protobuf:"varint,4,opt,name=role,enum=protos.Role" json:"role,omitempty"` - Sig *Signature `protobuf:"bytes,5,opt,name=sig" json:"sig,omitempty"` -} - -func (m *TCertReadSetsReq) Reset() { *m = TCertReadSetsReq{} } -func (m *TCertReadSetsReq) String() string { return proto.CompactTextString(m) } -func (*TCertReadSetsReq) ProtoMessage() {} -func (*TCertReadSetsReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} } - -func (m *TCertReadSetsReq) GetBegin() *google_protobuf.Timestamp { - if m != nil { - return m.Begin - } - return nil -} - -func (m *TCertReadSetsReq) GetEnd() *google_protobuf.Timestamp { - if m != nil { - return m.End - } - return nil -} - -func (m *TCertReadSetsReq) GetReq() *Identity { - if m != nil { - return m.Req - } - return nil -} - -func (m *TCertReadSetsReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type TCertRevokeReq struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Cert *Cert `protobuf:"bytes,2,opt,name=cert" json:"cert,omitempty"` - Sig *Signature `protobuf:"bytes,3,opt,name=sig" json:"sig,omitempty"` -} - -func (m *TCertRevokeReq) Reset() { *m = TCertRevokeReq{} } -func (m *TCertRevokeReq) String() string { return proto.CompactTextString(m) } -func (*TCertRevokeReq) ProtoMessage() {} -func (*TCertRevokeReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{25} } - -func (m *TCertRevokeReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *TCertRevokeReq) GetCert() *Cert { - if m != nil { - return m.Cert - } - return nil -} - -func (m *TCertRevokeReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type TCertRevokeSetReq struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Ts *google_protobuf.Timestamp `protobuf:"bytes,2,opt,name=ts" json:"ts,omitempty"` - Sig *Signature `protobuf:"bytes,3,opt,name=sig" json:"sig,omitempty"` -} - -func (m *TCertRevokeSetReq) Reset() { *m = TCertRevokeSetReq{} } -func (m *TCertRevokeSetReq) String() string { return proto.CompactTextString(m) } -func (*TCertRevokeSetReq) ProtoMessage() {} -func (*TCertRevokeSetReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{26} } - -func (m *TCertRevokeSetReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *TCertRevokeSetReq) GetTs() *google_protobuf.Timestamp { - if m != nil { - return m.Ts - } - return nil -} - -func (m *TCertRevokeSetReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type TCertCRLReq struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Sig *Signature `protobuf:"bytes,2,opt,name=sig" json:"sig,omitempty"` -} - -func (m *TCertCRLReq) Reset() { *m = TCertCRLReq{} } -func (m *TCertCRLReq) String() string { return proto.CompactTextString(m) } -func (*TCertCRLReq) ProtoMessage() {} -func (*TCertCRLReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{27} } - -func (m *TCertCRLReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *TCertCRLReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type TLSCertCreateReq struct { - Ts *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=ts" json:"ts,omitempty"` - Id *Identity `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` - Pub *PublicKey `protobuf:"bytes,3,opt,name=pub" json:"pub,omitempty"` - Sig *Signature `protobuf:"bytes,4,opt,name=sig" json:"sig,omitempty"` -} - -func (m *TLSCertCreateReq) Reset() { *m = TLSCertCreateReq{} } -func (m *TLSCertCreateReq) String() string { return proto.CompactTextString(m) } -func (*TLSCertCreateReq) ProtoMessage() {} -func (*TLSCertCreateReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{28} } - -func (m *TLSCertCreateReq) GetTs() *google_protobuf.Timestamp { - if m != nil { - return m.Ts - } - return nil -} - -func (m *TLSCertCreateReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *TLSCertCreateReq) GetPub() *PublicKey { - if m != nil { - return m.Pub - } - return nil -} - -func (m *TLSCertCreateReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -type TLSCertCreateResp struct { - Cert *Cert `protobuf:"bytes,1,opt,name=cert" json:"cert,omitempty"` - RootCert *Cert `protobuf:"bytes,2,opt,name=rootCert" json:"rootCert,omitempty"` -} - -func (m *TLSCertCreateResp) Reset() { *m = TLSCertCreateResp{} } -func (m *TLSCertCreateResp) String() string { return proto.CompactTextString(m) } -func (*TLSCertCreateResp) ProtoMessage() {} -func (*TLSCertCreateResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{29} } - -func (m *TLSCertCreateResp) GetCert() *Cert { - if m != nil { - return m.Cert - } - return nil -} - -func (m *TLSCertCreateResp) GetRootCert() *Cert { - if m != nil { - return m.RootCert - } - return nil -} - -type TLSCertReadReq struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` -} - -func (m *TLSCertReadReq) Reset() { *m = TLSCertReadReq{} } -func (m *TLSCertReadReq) String() string { return proto.CompactTextString(m) } -func (*TLSCertReadReq) ProtoMessage() {} -func (*TLSCertReadReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{30} } - -func (m *TLSCertReadReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -type TLSCertRevokeReq struct { - Id *Identity `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` - Cert *Cert `protobuf:"bytes,2,opt,name=cert" json:"cert,omitempty"` - Sig *Signature `protobuf:"bytes,3,opt,name=sig" json:"sig,omitempty"` -} - -func (m *TLSCertRevokeReq) Reset() { *m = TLSCertRevokeReq{} } -func (m *TLSCertRevokeReq) String() string { return proto.CompactTextString(m) } -func (*TLSCertRevokeReq) ProtoMessage() {} -func (*TLSCertRevokeReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{31} } - -func (m *TLSCertRevokeReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *TLSCertRevokeReq) GetCert() *Cert { - if m != nil { - return m.Cert - } - return nil -} - -func (m *TLSCertRevokeReq) GetSig() *Signature { - if m != nil { - return m.Sig - } - return nil -} - -// Certificate issued by either the ECA or TCA. -// -type Cert struct { - Cert []byte `protobuf:"bytes,1,opt,name=cert,proto3" json:"cert,omitempty"` -} - -func (m *Cert) Reset() { *m = Cert{} } -func (m *Cert) String() string { return proto.CompactTextString(m) } -func (*Cert) ProtoMessage() {} -func (*Cert) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{32} } - -// TCert -// -type TCert struct { - Cert []byte `protobuf:"bytes,1,opt,name=cert,proto3" json:"cert,omitempty"` - Prek0 []byte `protobuf:"bytes,2,opt,name=prek0,proto3" json:"prek0,omitempty"` -} - -func (m *TCert) Reset() { *m = TCert{} } -func (m *TCert) String() string { return proto.CompactTextString(m) } -func (*TCert) ProtoMessage() {} -func (*TCert) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{33} } - -type CertSet struct { - Ts *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=ts" json:"ts,omitempty"` - Id *Identity `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` - Key []byte `protobuf:"bytes,3,opt,name=key,proto3" json:"key,omitempty"` - Certs []*TCert `protobuf:"bytes,4,rep,name=certs" json:"certs,omitempty"` -} - -func (m *CertSet) Reset() { *m = CertSet{} } -func (m *CertSet) String() string { return proto.CompactTextString(m) } -func (*CertSet) ProtoMessage() {} -func (*CertSet) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{34} } - -func (m *CertSet) GetTs() *google_protobuf.Timestamp { - if m != nil { - return m.Ts - } - return nil -} - -func (m *CertSet) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *CertSet) GetCerts() []*TCert { - if m != nil { - return m.Certs - } - return nil -} - -type CertSets struct { - Sets []*CertSet `protobuf:"bytes,1,rep,name=sets" json:"sets,omitempty"` -} - -func (m *CertSets) Reset() { *m = CertSets{} } -func (m *CertSets) String() string { return proto.CompactTextString(m) } -func (*CertSets) ProtoMessage() {} -func (*CertSets) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{35} } - -func (m *CertSets) GetSets() []*CertSet { - if m != nil { - return m.Sets - } - return nil -} - -type CertPair struct { - Sign []byte `protobuf:"bytes,1,opt,name=sign,proto3" json:"sign,omitempty"` - Enc []byte `protobuf:"bytes,2,opt,name=enc,proto3" json:"enc,omitempty"` -} - -func (m *CertPair) Reset() { *m = CertPair{} } -func (m *CertPair) String() string { return proto.CompactTextString(m) } -func (*CertPair) ProtoMessage() {} -func (*CertPair) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{36} } - -// ACAAttrReq is sent to request an ACert (attributes certificate) to the Attribute Certificate Authority (ACA). -type ACAAttrReq struct { - // Request time - Ts *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=ts" json:"ts,omitempty"` - // User identity - Id *Identity `protobuf:"bytes,2,opt,name=id" json:"id,omitempty"` - // Enrollment certificate - ECert *Cert `protobuf:"bytes,3,opt,name=eCert" json:"eCert,omitempty"` - // Collection of requested attributes including the attribute name and its respective value hash. - Attributes []*TCertAttribute `protobuf:"bytes,4,rep,name=attributes" json:"attributes,omitempty"` - // The request is signed by the TCA. - Signature *Signature `protobuf:"bytes,5,opt,name=signature" json:"signature,omitempty"` -} - -func (m *ACAAttrReq) Reset() { *m = ACAAttrReq{} } -func (m *ACAAttrReq) String() string { return proto.CompactTextString(m) } -func (*ACAAttrReq) ProtoMessage() {} -func (*ACAAttrReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{37} } - -func (m *ACAAttrReq) GetTs() *google_protobuf.Timestamp { - if m != nil { - return m.Ts - } - return nil -} - -func (m *ACAAttrReq) GetId() *Identity { - if m != nil { - return m.Id - } - return nil -} - -func (m *ACAAttrReq) GetECert() *Cert { - if m != nil { - return m.ECert - } - return nil -} - -func (m *ACAAttrReq) GetAttributes() []*TCertAttribute { - if m != nil { - return m.Attributes - } - return nil -} - -func (m *ACAAttrReq) GetSignature() *Signature { - if m != nil { - return m.Signature - } - return nil -} - -// ACAAttrResp is the response of Attribute Certificate Authority (ACA) to the attribute request. Is composed by the following fields: -type ACAAttrResp struct { - // Indicates the request process status. - Status ACAAttrResp_StatusCode `protobuf:"varint,1,opt,name=status,enum=protos.ACAAttrResp_StatusCode" json:"status,omitempty"` - // Attribute certificate. Include all the attributes certificated. - Cert *Cert `protobuf:"bytes,2,opt,name=cert" json:"cert,omitempty"` - // The response is signed by the ACA. - Signature *Signature `protobuf:"bytes,3,opt,name=signature" json:"signature,omitempty"` -} - -func (m *ACAAttrResp) Reset() { *m = ACAAttrResp{} } -func (m *ACAAttrResp) String() string { return proto.CompactTextString(m) } -func (*ACAAttrResp) ProtoMessage() {} -func (*ACAAttrResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{38} } - -func (m *ACAAttrResp) GetCert() *Cert { - if m != nil { - return m.Cert - } - return nil -} - -func (m *ACAAttrResp) GetSignature() *Signature { - if m != nil { - return m.Signature - } - return nil -} - -// ACAFetchAttrReq is a request to the Attribute Certificate Authority (ACA) to refresh attributes values from the sources. -type ACAFetchAttrReq struct { - // Request timestamp - Ts *google_protobuf.Timestamp `protobuf:"bytes,1,opt,name=ts" json:"ts,omitempty"` - // Enrollment certificate. - ECert *Cert `protobuf:"bytes,2,opt,name=eCert" json:"eCert,omitempty"` - // The request is signed by the ECA. - Signature *Signature `protobuf:"bytes,3,opt,name=signature" json:"signature,omitempty"` -} - -func (m *ACAFetchAttrReq) Reset() { *m = ACAFetchAttrReq{} } -func (m *ACAFetchAttrReq) String() string { return proto.CompactTextString(m) } -func (*ACAFetchAttrReq) ProtoMessage() {} -func (*ACAFetchAttrReq) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{39} } - -func (m *ACAFetchAttrReq) GetTs() *google_protobuf.Timestamp { - if m != nil { - return m.Ts - } - return nil -} - -func (m *ACAFetchAttrReq) GetECert() *Cert { - if m != nil { - return m.ECert - } - return nil -} - -func (m *ACAFetchAttrReq) GetSignature() *Signature { - if m != nil { - return m.Signature - } - return nil -} - -// ACAFetchAttrReq is the answer of the Attribute Certificate Authority (ACA) to the refresh request. -type ACAFetchAttrResp struct { - // Status of the fetch process. - Status ACAFetchAttrResp_StatusCode `protobuf:"varint,1,opt,name=status,enum=protos.ACAFetchAttrResp_StatusCode" json:"status,omitempty"` - // Error message. - Msg string `protobuf:"bytes,2,opt,name=Msg" json:"Msg,omitempty"` -} - -func (m *ACAFetchAttrResp) Reset() { *m = ACAFetchAttrResp{} } -func (m *ACAFetchAttrResp) String() string { return proto.CompactTextString(m) } -func (*ACAFetchAttrResp) ProtoMessage() {} -func (*ACAFetchAttrResp) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{40} } - -// FetchAttrsResult is returned within the ECertCreateResp indicating the results of the fetch attributes invoked during enroll. -type FetchAttrsResult struct { - // Status of the fetch process. - Status FetchAttrsResult_StatusCode `protobuf:"varint,1,opt,name=status,enum=protos.FetchAttrsResult_StatusCode" json:"status,omitempty"` - // Error message. - Msg string `protobuf:"bytes,2,opt,name=Msg" json:"Msg,omitempty"` -} - -func (m *FetchAttrsResult) Reset() { *m = FetchAttrsResult{} } -func (m *FetchAttrsResult) String() string { return proto.CompactTextString(m) } -func (*FetchAttrsResult) ProtoMessage() {} -func (*FetchAttrsResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{41} } - -// ACAAttribute is an instance of an attribute with the time constraints. Is used to marshal attributes to be stored within the certificate extensions. -type ACAAttribute struct { - // Name of the attribute. - AttributeName string `protobuf:"bytes,1,opt,name=attributeName" json:"attributeName,omitempty"` - // Value of the attribute. - AttributeValue []byte `protobuf:"bytes,2,opt,name=attributeValue,proto3" json:"attributeValue,omitempty"` - // The timestamp which attribute is valid from. - ValidFrom *google_protobuf.Timestamp `protobuf:"bytes,3,opt,name=validFrom" json:"validFrom,omitempty"` - // The timestamp which attribute is valid to. - ValidTo *google_protobuf.Timestamp `protobuf:"bytes,4,opt,name=validTo" json:"validTo,omitempty"` -} - -func (m *ACAAttribute) Reset() { *m = ACAAttribute{} } -func (m *ACAAttribute) String() string { return proto.CompactTextString(m) } -func (*ACAAttribute) ProtoMessage() {} -func (*ACAAttribute) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{42} } - -func (m *ACAAttribute) GetValidFrom() *google_protobuf.Timestamp { - if m != nil { - return m.ValidFrom - } - return nil -} - -func (m *ACAAttribute) GetValidTo() *google_protobuf.Timestamp { - if m != nil { - return m.ValidTo - } - return nil -} - -func init() { - proto.RegisterType((*CAStatus)(nil), "protos.CAStatus") - proto.RegisterType((*Empty)(nil), "protos.Empty") - proto.RegisterType((*Identity)(nil), "protos.Identity") - proto.RegisterType((*Token)(nil), "protos.Token") - proto.RegisterType((*Hash)(nil), "protos.Hash") - proto.RegisterType((*PublicKey)(nil), "protos.PublicKey") - proto.RegisterType((*PrivateKey)(nil), "protos.PrivateKey") - proto.RegisterType((*Signature)(nil), "protos.Signature") - proto.RegisterType((*Registrar)(nil), "protos.Registrar") - proto.RegisterType((*RegisterUserReq)(nil), "protos.RegisterUserReq") - proto.RegisterType((*Attribute)(nil), "protos.Attribute") - proto.RegisterType((*ReadUserSetReq)(nil), "protos.ReadUserSetReq") - proto.RegisterType((*User)(nil), "protos.User") - proto.RegisterType((*UserSet)(nil), "protos.UserSet") - proto.RegisterType((*ECertCreateReq)(nil), "protos.ECertCreateReq") - proto.RegisterType((*ECertCreateResp)(nil), "protos.ECertCreateResp") - proto.RegisterType((*ECertReadReq)(nil), "protos.ECertReadReq") - proto.RegisterType((*ECertRevokeReq)(nil), "protos.ECertRevokeReq") - proto.RegisterType((*ECertCRLReq)(nil), "protos.ECertCRLReq") - proto.RegisterType((*TCertCreateReq)(nil), "protos.TCertCreateReq") - proto.RegisterType((*TCertCreateResp)(nil), "protos.TCertCreateResp") - proto.RegisterType((*TCertCreateSetReq)(nil), "protos.TCertCreateSetReq") - proto.RegisterType((*TCertAttribute)(nil), "protos.TCertAttribute") - proto.RegisterType((*TCertCreateSetResp)(nil), "protos.TCertCreateSetResp") - proto.RegisterType((*TCertReadSetsReq)(nil), "protos.TCertReadSetsReq") - proto.RegisterType((*TCertRevokeReq)(nil), "protos.TCertRevokeReq") - proto.RegisterType((*TCertRevokeSetReq)(nil), "protos.TCertRevokeSetReq") - proto.RegisterType((*TCertCRLReq)(nil), "protos.TCertCRLReq") - proto.RegisterType((*TLSCertCreateReq)(nil), "protos.TLSCertCreateReq") - proto.RegisterType((*TLSCertCreateResp)(nil), "protos.TLSCertCreateResp") - proto.RegisterType((*TLSCertReadReq)(nil), "protos.TLSCertReadReq") - proto.RegisterType((*TLSCertRevokeReq)(nil), "protos.TLSCertRevokeReq") - proto.RegisterType((*Cert)(nil), "protos.Cert") - proto.RegisterType((*TCert)(nil), "protos.TCert") - proto.RegisterType((*CertSet)(nil), "protos.CertSet") - proto.RegisterType((*CertSets)(nil), "protos.CertSets") - proto.RegisterType((*CertPair)(nil), "protos.CertPair") - proto.RegisterType((*ACAAttrReq)(nil), "protos.ACAAttrReq") - proto.RegisterType((*ACAAttrResp)(nil), "protos.ACAAttrResp") - proto.RegisterType((*ACAFetchAttrReq)(nil), "protos.ACAFetchAttrReq") - proto.RegisterType((*ACAFetchAttrResp)(nil), "protos.ACAFetchAttrResp") - proto.RegisterType((*FetchAttrsResult)(nil), "protos.FetchAttrsResult") - proto.RegisterType((*ACAAttribute)(nil), "protos.ACAAttribute") - proto.RegisterEnum("protos.CryptoType", CryptoType_name, CryptoType_value) - proto.RegisterEnum("protos.Role", Role_name, Role_value) - proto.RegisterEnum("protos.CAStatus_StatusCode", CAStatus_StatusCode_name, CAStatus_StatusCode_value) - proto.RegisterEnum("protos.ACAAttrResp_StatusCode", ACAAttrResp_StatusCode_name, ACAAttrResp_StatusCode_value) - proto.RegisterEnum("protos.ACAFetchAttrResp_StatusCode", ACAFetchAttrResp_StatusCode_name, ACAFetchAttrResp_StatusCode_value) - proto.RegisterEnum("protos.FetchAttrsResult_StatusCode", FetchAttrsResult_StatusCode_name, FetchAttrsResult_StatusCode_value) -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion3 - -// Client API for ECAP service - -type ECAPClient interface { - ReadCACertificate(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Cert, error) - CreateCertificatePair(ctx context.Context, in *ECertCreateReq, opts ...grpc.CallOption) (*ECertCreateResp, error) - ReadCertificatePair(ctx context.Context, in *ECertReadReq, opts ...grpc.CallOption) (*CertPair, error) - ReadCertificateByHash(ctx context.Context, in *Hash, opts ...grpc.CallOption) (*Cert, error) - RevokeCertificatePair(ctx context.Context, in *ECertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) -} - -type eCAPClient struct { - cc *grpc.ClientConn -} - -func NewECAPClient(cc *grpc.ClientConn) ECAPClient { - return &eCAPClient{cc} -} - -func (c *eCAPClient) ReadCACertificate(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Cert, error) { - out := new(Cert) - err := grpc.Invoke(ctx, "/protos.ECAP/ReadCACertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *eCAPClient) CreateCertificatePair(ctx context.Context, in *ECertCreateReq, opts ...grpc.CallOption) (*ECertCreateResp, error) { - out := new(ECertCreateResp) - err := grpc.Invoke(ctx, "/protos.ECAP/CreateCertificatePair", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *eCAPClient) ReadCertificatePair(ctx context.Context, in *ECertReadReq, opts ...grpc.CallOption) (*CertPair, error) { - out := new(CertPair) - err := grpc.Invoke(ctx, "/protos.ECAP/ReadCertificatePair", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *eCAPClient) ReadCertificateByHash(ctx context.Context, in *Hash, opts ...grpc.CallOption) (*Cert, error) { - out := new(Cert) - err := grpc.Invoke(ctx, "/protos.ECAP/ReadCertificateByHash", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *eCAPClient) RevokeCertificatePair(ctx context.Context, in *ECertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.ECAP/RevokeCertificatePair", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for ECAP service - -type ECAPServer interface { - ReadCACertificate(context.Context, *Empty) (*Cert, error) - CreateCertificatePair(context.Context, *ECertCreateReq) (*ECertCreateResp, error) - ReadCertificatePair(context.Context, *ECertReadReq) (*CertPair, error) - ReadCertificateByHash(context.Context, *Hash) (*Cert, error) - RevokeCertificatePair(context.Context, *ECertRevokeReq) (*CAStatus, error) -} - -func RegisterECAPServer(s *grpc.Server, srv ECAPServer) { - s.RegisterService(&_ECAP_serviceDesc, srv) -} - -func _ECAP_ReadCACertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ECAPServer).ReadCACertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ECAP/ReadCACertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ECAPServer).ReadCACertificate(ctx, req.(*Empty)) - } - return interceptor(ctx, in, info, handler) -} - -func _ECAP_CreateCertificatePair_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ECertCreateReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ECAPServer).CreateCertificatePair(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ECAP/CreateCertificatePair", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ECAPServer).CreateCertificatePair(ctx, req.(*ECertCreateReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _ECAP_ReadCertificatePair_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ECertReadReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ECAPServer).ReadCertificatePair(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ECAP/ReadCertificatePair", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ECAPServer).ReadCertificatePair(ctx, req.(*ECertReadReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _ECAP_ReadCertificateByHash_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Hash) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ECAPServer).ReadCertificateByHash(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ECAP/ReadCertificateByHash", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ECAPServer).ReadCertificateByHash(ctx, req.(*Hash)) - } - return interceptor(ctx, in, info, handler) -} - -func _ECAP_RevokeCertificatePair_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ECertRevokeReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ECAPServer).RevokeCertificatePair(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ECAP/RevokeCertificatePair", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ECAPServer).RevokeCertificatePair(ctx, req.(*ECertRevokeReq)) - } - return interceptor(ctx, in, info, handler) -} - -var _ECAP_serviceDesc = grpc.ServiceDesc{ - ServiceName: "protos.ECAP", - HandlerType: (*ECAPServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "ReadCACertificate", - Handler: _ECAP_ReadCACertificate_Handler, - }, - { - MethodName: "CreateCertificatePair", - Handler: _ECAP_CreateCertificatePair_Handler, - }, - { - MethodName: "ReadCertificatePair", - Handler: _ECAP_ReadCertificatePair_Handler, - }, - { - MethodName: "ReadCertificateByHash", - Handler: _ECAP_ReadCertificateByHash_Handler, - }, - { - MethodName: "RevokeCertificatePair", - Handler: _ECAP_RevokeCertificatePair_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptor0, -} - -// Client API for ECAA service - -type ECAAClient interface { - RegisterUser(ctx context.Context, in *RegisterUserReq, opts ...grpc.CallOption) (*Token, error) - ReadUserSet(ctx context.Context, in *ReadUserSetReq, opts ...grpc.CallOption) (*UserSet, error) - RevokeCertificate(ctx context.Context, in *ECertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) - PublishCRL(ctx context.Context, in *ECertCRLReq, opts ...grpc.CallOption) (*CAStatus, error) -} - -type eCAAClient struct { - cc *grpc.ClientConn -} - -func NewECAAClient(cc *grpc.ClientConn) ECAAClient { - return &eCAAClient{cc} -} - -func (c *eCAAClient) RegisterUser(ctx context.Context, in *RegisterUserReq, opts ...grpc.CallOption) (*Token, error) { - out := new(Token) - err := grpc.Invoke(ctx, "/protos.ECAA/RegisterUser", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *eCAAClient) ReadUserSet(ctx context.Context, in *ReadUserSetReq, opts ...grpc.CallOption) (*UserSet, error) { - out := new(UserSet) - err := grpc.Invoke(ctx, "/protos.ECAA/ReadUserSet", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *eCAAClient) RevokeCertificate(ctx context.Context, in *ECertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.ECAA/RevokeCertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *eCAAClient) PublishCRL(ctx context.Context, in *ECertCRLReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.ECAA/PublishCRL", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for ECAA service - -type ECAAServer interface { - RegisterUser(context.Context, *RegisterUserReq) (*Token, error) - ReadUserSet(context.Context, *ReadUserSetReq) (*UserSet, error) - RevokeCertificate(context.Context, *ECertRevokeReq) (*CAStatus, error) - PublishCRL(context.Context, *ECertCRLReq) (*CAStatus, error) -} - -func RegisterECAAServer(s *grpc.Server, srv ECAAServer) { - s.RegisterService(&_ECAA_serviceDesc, srv) -} - -func _ECAA_RegisterUser_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(RegisterUserReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ECAAServer).RegisterUser(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ECAA/RegisterUser", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ECAAServer).RegisterUser(ctx, req.(*RegisterUserReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _ECAA_ReadUserSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ReadUserSetReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ECAAServer).ReadUserSet(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ECAA/ReadUserSet", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ECAAServer).ReadUserSet(ctx, req.(*ReadUserSetReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _ECAA_RevokeCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ECertRevokeReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ECAAServer).RevokeCertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ECAA/RevokeCertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ECAAServer).RevokeCertificate(ctx, req.(*ECertRevokeReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _ECAA_PublishCRL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ECertCRLReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ECAAServer).PublishCRL(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ECAA/PublishCRL", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ECAAServer).PublishCRL(ctx, req.(*ECertCRLReq)) - } - return interceptor(ctx, in, info, handler) -} - -var _ECAA_serviceDesc = grpc.ServiceDesc{ - ServiceName: "protos.ECAA", - HandlerType: (*ECAAServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "RegisterUser", - Handler: _ECAA_RegisterUser_Handler, - }, - { - MethodName: "ReadUserSet", - Handler: _ECAA_ReadUserSet_Handler, - }, - { - MethodName: "RevokeCertificate", - Handler: _ECAA_RevokeCertificate_Handler, - }, - { - MethodName: "PublishCRL", - Handler: _ECAA_PublishCRL_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptor0, -} - -// Client API for TCAP service - -type TCAPClient interface { - ReadCACertificate(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Cert, error) - CreateCertificateSet(ctx context.Context, in *TCertCreateSetReq, opts ...grpc.CallOption) (*TCertCreateSetResp, error) - RevokeCertificate(ctx context.Context, in *TCertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) - RevokeCertificateSet(ctx context.Context, in *TCertRevokeSetReq, opts ...grpc.CallOption) (*CAStatus, error) -} - -type tCAPClient struct { - cc *grpc.ClientConn -} - -func NewTCAPClient(cc *grpc.ClientConn) TCAPClient { - return &tCAPClient{cc} -} - -func (c *tCAPClient) ReadCACertificate(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Cert, error) { - out := new(Cert) - err := grpc.Invoke(ctx, "/protos.TCAP/ReadCACertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tCAPClient) CreateCertificateSet(ctx context.Context, in *TCertCreateSetReq, opts ...grpc.CallOption) (*TCertCreateSetResp, error) { - out := new(TCertCreateSetResp) - err := grpc.Invoke(ctx, "/protos.TCAP/CreateCertificateSet", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tCAPClient) RevokeCertificate(ctx context.Context, in *TCertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.TCAP/RevokeCertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tCAPClient) RevokeCertificateSet(ctx context.Context, in *TCertRevokeSetReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.TCAP/RevokeCertificateSet", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for TCAP service - -type TCAPServer interface { - ReadCACertificate(context.Context, *Empty) (*Cert, error) - CreateCertificateSet(context.Context, *TCertCreateSetReq) (*TCertCreateSetResp, error) - RevokeCertificate(context.Context, *TCertRevokeReq) (*CAStatus, error) - RevokeCertificateSet(context.Context, *TCertRevokeSetReq) (*CAStatus, error) -} - -func RegisterTCAPServer(s *grpc.Server, srv TCAPServer) { - s.RegisterService(&_TCAP_serviceDesc, srv) -} - -func _TCAP_ReadCACertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TCAPServer).ReadCACertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TCAP/ReadCACertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TCAPServer).ReadCACertificate(ctx, req.(*Empty)) - } - return interceptor(ctx, in, info, handler) -} - -func _TCAP_CreateCertificateSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TCertCreateSetReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TCAPServer).CreateCertificateSet(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TCAP/CreateCertificateSet", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TCAPServer).CreateCertificateSet(ctx, req.(*TCertCreateSetReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _TCAP_RevokeCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TCertRevokeReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TCAPServer).RevokeCertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TCAP/RevokeCertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TCAPServer).RevokeCertificate(ctx, req.(*TCertRevokeReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _TCAP_RevokeCertificateSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TCertRevokeSetReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TCAPServer).RevokeCertificateSet(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TCAP/RevokeCertificateSet", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TCAPServer).RevokeCertificateSet(ctx, req.(*TCertRevokeSetReq)) - } - return interceptor(ctx, in, info, handler) -} - -var _TCAP_serviceDesc = grpc.ServiceDesc{ - ServiceName: "protos.TCAP", - HandlerType: (*TCAPServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "ReadCACertificate", - Handler: _TCAP_ReadCACertificate_Handler, - }, - { - MethodName: "CreateCertificateSet", - Handler: _TCAP_CreateCertificateSet_Handler, - }, - { - MethodName: "RevokeCertificate", - Handler: _TCAP_RevokeCertificate_Handler, - }, - { - MethodName: "RevokeCertificateSet", - Handler: _TCAP_RevokeCertificateSet_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptor0, -} - -// Client API for TCAA service - -type TCAAClient interface { - RevokeCertificate(ctx context.Context, in *TCertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) - RevokeCertificateSet(ctx context.Context, in *TCertRevokeSetReq, opts ...grpc.CallOption) (*CAStatus, error) - PublishCRL(ctx context.Context, in *TCertCRLReq, opts ...grpc.CallOption) (*CAStatus, error) -} - -type tCAAClient struct { - cc *grpc.ClientConn -} - -func NewTCAAClient(cc *grpc.ClientConn) TCAAClient { - return &tCAAClient{cc} -} - -func (c *tCAAClient) RevokeCertificate(ctx context.Context, in *TCertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.TCAA/RevokeCertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tCAAClient) RevokeCertificateSet(ctx context.Context, in *TCertRevokeSetReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.TCAA/RevokeCertificateSet", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tCAAClient) PublishCRL(ctx context.Context, in *TCertCRLReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.TCAA/PublishCRL", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for TCAA service - -type TCAAServer interface { - RevokeCertificate(context.Context, *TCertRevokeReq) (*CAStatus, error) - RevokeCertificateSet(context.Context, *TCertRevokeSetReq) (*CAStatus, error) - PublishCRL(context.Context, *TCertCRLReq) (*CAStatus, error) -} - -func RegisterTCAAServer(s *grpc.Server, srv TCAAServer) { - s.RegisterService(&_TCAA_serviceDesc, srv) -} - -func _TCAA_RevokeCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TCertRevokeReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TCAAServer).RevokeCertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TCAA/RevokeCertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TCAAServer).RevokeCertificate(ctx, req.(*TCertRevokeReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _TCAA_RevokeCertificateSet_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TCertRevokeSetReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TCAAServer).RevokeCertificateSet(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TCAA/RevokeCertificateSet", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TCAAServer).RevokeCertificateSet(ctx, req.(*TCertRevokeSetReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _TCAA_PublishCRL_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TCertCRLReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TCAAServer).PublishCRL(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TCAA/PublishCRL", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TCAAServer).PublishCRL(ctx, req.(*TCertCRLReq)) - } - return interceptor(ctx, in, info, handler) -} - -var _TCAA_serviceDesc = grpc.ServiceDesc{ - ServiceName: "protos.TCAA", - HandlerType: (*TCAAServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "RevokeCertificate", - Handler: _TCAA_RevokeCertificate_Handler, - }, - { - MethodName: "RevokeCertificateSet", - Handler: _TCAA_RevokeCertificateSet_Handler, - }, - { - MethodName: "PublishCRL", - Handler: _TCAA_PublishCRL_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptor0, -} - -// Client API for TLSCAP service - -type TLSCAPClient interface { - ReadCACertificate(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Cert, error) - CreateCertificate(ctx context.Context, in *TLSCertCreateReq, opts ...grpc.CallOption) (*TLSCertCreateResp, error) - ReadCertificate(ctx context.Context, in *TLSCertReadReq, opts ...grpc.CallOption) (*Cert, error) - RevokeCertificate(ctx context.Context, in *TLSCertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) -} - -type tLSCAPClient struct { - cc *grpc.ClientConn -} - -func NewTLSCAPClient(cc *grpc.ClientConn) TLSCAPClient { - return &tLSCAPClient{cc} -} - -func (c *tLSCAPClient) ReadCACertificate(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Cert, error) { - out := new(Cert) - err := grpc.Invoke(ctx, "/protos.TLSCAP/ReadCACertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tLSCAPClient) CreateCertificate(ctx context.Context, in *TLSCertCreateReq, opts ...grpc.CallOption) (*TLSCertCreateResp, error) { - out := new(TLSCertCreateResp) - err := grpc.Invoke(ctx, "/protos.TLSCAP/CreateCertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tLSCAPClient) ReadCertificate(ctx context.Context, in *TLSCertReadReq, opts ...grpc.CallOption) (*Cert, error) { - out := new(Cert) - err := grpc.Invoke(ctx, "/protos.TLSCAP/ReadCertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *tLSCAPClient) RevokeCertificate(ctx context.Context, in *TLSCertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.TLSCAP/RevokeCertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for TLSCAP service - -type TLSCAPServer interface { - ReadCACertificate(context.Context, *Empty) (*Cert, error) - CreateCertificate(context.Context, *TLSCertCreateReq) (*TLSCertCreateResp, error) - ReadCertificate(context.Context, *TLSCertReadReq) (*Cert, error) - RevokeCertificate(context.Context, *TLSCertRevokeReq) (*CAStatus, error) -} - -func RegisterTLSCAPServer(s *grpc.Server, srv TLSCAPServer) { - s.RegisterService(&_TLSCAP_serviceDesc, srv) -} - -func _TLSCAP_ReadCACertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TLSCAPServer).ReadCACertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TLSCAP/ReadCACertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TLSCAPServer).ReadCACertificate(ctx, req.(*Empty)) - } - return interceptor(ctx, in, info, handler) -} - -func _TLSCAP_CreateCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TLSCertCreateReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TLSCAPServer).CreateCertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TLSCAP/CreateCertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TLSCAPServer).CreateCertificate(ctx, req.(*TLSCertCreateReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _TLSCAP_ReadCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TLSCertReadReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TLSCAPServer).ReadCertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TLSCAP/ReadCertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TLSCAPServer).ReadCertificate(ctx, req.(*TLSCertReadReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _TLSCAP_RevokeCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TLSCertRevokeReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TLSCAPServer).RevokeCertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TLSCAP/RevokeCertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TLSCAPServer).RevokeCertificate(ctx, req.(*TLSCertRevokeReq)) - } - return interceptor(ctx, in, info, handler) -} - -var _TLSCAP_serviceDesc = grpc.ServiceDesc{ - ServiceName: "protos.TLSCAP", - HandlerType: (*TLSCAPServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "ReadCACertificate", - Handler: _TLSCAP_ReadCACertificate_Handler, - }, - { - MethodName: "CreateCertificate", - Handler: _TLSCAP_CreateCertificate_Handler, - }, - { - MethodName: "ReadCertificate", - Handler: _TLSCAP_ReadCertificate_Handler, - }, - { - MethodName: "RevokeCertificate", - Handler: _TLSCAP_RevokeCertificate_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptor0, -} - -// Client API for TLSCAA service - -type TLSCAAClient interface { - RevokeCertificate(ctx context.Context, in *TLSCertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) -} - -type tLSCAAClient struct { - cc *grpc.ClientConn -} - -func NewTLSCAAClient(cc *grpc.ClientConn) TLSCAAClient { - return &tLSCAAClient{cc} -} - -func (c *tLSCAAClient) RevokeCertificate(ctx context.Context, in *TLSCertRevokeReq, opts ...grpc.CallOption) (*CAStatus, error) { - out := new(CAStatus) - err := grpc.Invoke(ctx, "/protos.TLSCAA/RevokeCertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for TLSCAA service - -type TLSCAAServer interface { - RevokeCertificate(context.Context, *TLSCertRevokeReq) (*CAStatus, error) -} - -func RegisterTLSCAAServer(s *grpc.Server, srv TLSCAAServer) { - s.RegisterService(&_TLSCAA_serviceDesc, srv) -} - -func _TLSCAA_RevokeCertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(TLSCertRevokeReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(TLSCAAServer).RevokeCertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.TLSCAA/RevokeCertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(TLSCAAServer).RevokeCertificate(ctx, req.(*TLSCertRevokeReq)) - } - return interceptor(ctx, in, info, handler) -} - -var _TLSCAA_serviceDesc = grpc.ServiceDesc{ - ServiceName: "protos.TLSCAA", - HandlerType: (*TLSCAAServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "RevokeCertificate", - Handler: _TLSCAA_RevokeCertificate_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptor0, -} - -// Client API for ACAP service - -type ACAPClient interface { - ReadCACertificate(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Cert, error) - RequestAttributes(ctx context.Context, in *ACAAttrReq, opts ...grpc.CallOption) (*ACAAttrResp, error) - FetchAttributes(ctx context.Context, in *ACAFetchAttrReq, opts ...grpc.CallOption) (*ACAFetchAttrResp, error) -} - -type aCAPClient struct { - cc *grpc.ClientConn -} - -func NewACAPClient(cc *grpc.ClientConn) ACAPClient { - return &aCAPClient{cc} -} - -func (c *aCAPClient) ReadCACertificate(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*Cert, error) { - out := new(Cert) - err := grpc.Invoke(ctx, "/protos.ACAP/ReadCACertificate", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aCAPClient) RequestAttributes(ctx context.Context, in *ACAAttrReq, opts ...grpc.CallOption) (*ACAAttrResp, error) { - out := new(ACAAttrResp) - err := grpc.Invoke(ctx, "/protos.ACAP/RequestAttributes", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *aCAPClient) FetchAttributes(ctx context.Context, in *ACAFetchAttrReq, opts ...grpc.CallOption) (*ACAFetchAttrResp, error) { - out := new(ACAFetchAttrResp) - err := grpc.Invoke(ctx, "/protos.ACAP/FetchAttributes", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for ACAP service - -type ACAPServer interface { - ReadCACertificate(context.Context, *Empty) (*Cert, error) - RequestAttributes(context.Context, *ACAAttrReq) (*ACAAttrResp, error) - FetchAttributes(context.Context, *ACAFetchAttrReq) (*ACAFetchAttrResp, error) -} - -func RegisterACAPServer(s *grpc.Server, srv ACAPServer) { - s.RegisterService(&_ACAP_serviceDesc, srv) -} - -func _ACAP_ReadCACertificate_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(Empty) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ACAPServer).ReadCACertificate(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ACAP/ReadCACertificate", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ACAPServer).ReadCACertificate(ctx, req.(*Empty)) - } - return interceptor(ctx, in, info, handler) -} - -func _ACAP_RequestAttributes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ACAAttrReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ACAPServer).RequestAttributes(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ACAP/RequestAttributes", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ACAPServer).RequestAttributes(ctx, req.(*ACAAttrReq)) - } - return interceptor(ctx, in, info, handler) -} - -func _ACAP_FetchAttributes_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ACAFetchAttrReq) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ACAPServer).FetchAttributes(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/protos.ACAP/FetchAttributes", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ACAPServer).FetchAttributes(ctx, req.(*ACAFetchAttrReq)) - } - return interceptor(ctx, in, info, handler) -} - -var _ACAP_serviceDesc = grpc.ServiceDesc{ - ServiceName: "protos.ACAP", - HandlerType: (*ACAPServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "ReadCACertificate", - Handler: _ACAP_ReadCACertificate_Handler, - }, - { - MethodName: "RequestAttributes", - Handler: _ACAP_RequestAttributes_Handler, - }, - { - MethodName: "FetchAttributes", - Handler: _ACAP_FetchAttributes_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: fileDescriptor0, -} - -func init() { proto.RegisterFile("ca.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 1888 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xd4, 0x59, 0x4f, 0x6f, 0x23, 0x49, - 0x15, 0x4f, 0xff, 0x71, 0x62, 0x3f, 0x3b, 0x76, 0xa7, 0x32, 0xbb, 0xe3, 0x69, 0x10, 0x1b, 0xf5, - 0xec, 0x0e, 0xc3, 0x08, 0x92, 0x6c, 0x82, 0x02, 0x62, 0x59, 0xa1, 0x1e, 0xa7, 0xc3, 0x9a, 0xf1, - 0x38, 0xa1, 0xdc, 0x1e, 0xb8, 0x59, 0x9d, 0xa4, 0xe2, 0xb4, 0x92, 0xb8, 0x3b, 0xdd, 0xed, 0x91, - 0xac, 0xbd, 0x70, 0x42, 0x02, 0x24, 0x0e, 0x7c, 0x07, 0x24, 0xc4, 0x37, 0x40, 0x42, 0xe2, 0xca, - 0x9f, 0x5d, 0x89, 0x0b, 0x47, 0xce, 0x48, 0x9c, 0xf8, 0x04, 0x2c, 0xaa, 0xea, 0xea, 0x72, 0x77, - 0xfb, 0xcf, 0xf4, 0xcc, 0x06, 0x2d, 0x9c, 0xdc, 0x55, 0xef, 0x55, 0xd5, 0x7b, 0xbf, 0xf7, 0xab, - 0x57, 0xaf, 0xca, 0x50, 0x3e, 0x73, 0xb6, 0xfd, 0xc0, 0x8b, 0x3c, 0xb4, 0xca, 0x7e, 0x42, 0xfd, - 0x9d, 0xa1, 0xe7, 0x0d, 0xaf, 0xc9, 0x0e, 0x6b, 0x9e, 0x8e, 0x2f, 0x76, 0x22, 0xf7, 0x86, 0x84, - 0x91, 0x73, 0xe3, 0xc7, 0x8a, 0xc6, 0x25, 0x94, 0x5b, 0x66, 0x2f, 0x72, 0xa2, 0x71, 0x88, 0xf6, - 0x61, 0x35, 0x64, 0x5f, 0x4d, 0x69, 0x4b, 0x7a, 0x5c, 0xdf, 0xfb, 0x52, 0xac, 0x13, 0x6e, 0x27, - 0x1a, 0xdb, 0xf1, 0x4f, 0xcb, 0x3b, 0x27, 0x98, 0xab, 0x1a, 0x5f, 0x05, 0x98, 0xf6, 0xa2, 0x55, - 0x90, 0x8f, 0x9f, 0x69, 0x2b, 0x68, 0x03, 0xd6, 0xfb, 0xdd, 0x67, 0xdd, 0xe3, 0x1f, 0x75, 0x07, - 0x16, 0xc6, 0xc7, 0x58, 0x93, 0x8c, 0x35, 0x28, 0x59, 0x37, 0x7e, 0x34, 0x31, 0x74, 0x28, 0xb7, - 0xcf, 0xc9, 0x28, 0x72, 0xa3, 0x09, 0xaa, 0x83, 0xec, 0x9e, 0xb3, 0xe5, 0x2a, 0x58, 0x76, 0xcf, - 0x8d, 0x07, 0x50, 0xb2, 0xbd, 0x2b, 0x32, 0x42, 0x1a, 0x28, 0x91, 0x77, 0xc5, 0x24, 0x35, 0x4c, - 0x3f, 0x0d, 0x1d, 0xd4, 0x8f, 0x9c, 0xf0, 0x12, 0x21, 0x50, 0x2f, 0x9d, 0xf0, 0x92, 0x8b, 0xd8, - 0xb7, 0x61, 0x41, 0xe5, 0x64, 0x7c, 0x7a, 0xed, 0x9e, 0x3d, 0x23, 0x13, 0xf4, 0x08, 0xd4, 0x68, - 0xe2, 0x13, 0xee, 0x04, 0x12, 0x4e, 0x04, 0x13, 0x3f, 0xf2, 0xec, 0x89, 0x4f, 0x30, 0x93, 0xd3, - 0x25, 0xae, 0xc8, 0xa4, 0x29, 0xc7, 0x4b, 0x5c, 0x91, 0x89, 0x71, 0x04, 0x70, 0x12, 0xb8, 0x2f, - 0x9d, 0x88, 0x7c, 0xbe, 0x79, 0x8e, 0xa1, 0xd2, 0x73, 0x87, 0x23, 0x27, 0x1a, 0x07, 0xa4, 0xf0, - 0x34, 0x35, 0x90, 0x02, 0x3e, 0x89, 0x14, 0xd0, 0x56, 0xd8, 0x54, 0xe2, 0x56, 0x68, 0xb8, 0x50, - 0xc1, 0x64, 0xe8, 0x86, 0x51, 0xe0, 0x04, 0x68, 0x4b, 0x60, 0x56, 0xdd, 0xd3, 0x92, 0xe9, 0x12, - 0x44, 0x29, 0x8a, 0xe8, 0x1e, 0x94, 0x02, 0xef, 0x9a, 0x84, 0x4d, 0x79, 0x4b, 0x79, 0x5c, 0xc1, - 0x71, 0x03, 0xbd, 0x0b, 0xeb, 0xe7, 0xe4, 0x9a, 0x0c, 0x9d, 0x88, 0x60, 0x26, 0x55, 0x98, 0x34, - 0xdb, 0x69, 0xfc, 0x44, 0x86, 0x46, 0xbc, 0x16, 0x09, 0xfa, 0x21, 0x09, 0x30, 0xb9, 0x2d, 0xb0, - 0xe2, 0x16, 0xa8, 0x74, 0x11, 0x66, 0x7f, 0x7d, 0xaf, 0x96, 0xe8, 0xd0, 0x29, 0x31, 0x93, 0xa0, - 0xf7, 0x01, 0x9c, 0x28, 0x0a, 0xdc, 0xd3, 0x71, 0xc4, 0x97, 0xae, 0xee, 0x6d, 0x24, 0x7a, 0x66, - 0x22, 0xc1, 0x29, 0x25, 0xb4, 0x05, 0x55, 0xe7, 0xe2, 0xc2, 0xbd, 0x76, 0x9d, 0xc8, 0xf5, 0x46, - 0x4d, 0x95, 0xb1, 0x24, 0xdd, 0x85, 0x76, 0xa0, 0x12, 0x24, 0xb8, 0x34, 0x4b, 0xcc, 0x3e, 0x31, - 0xa7, 0x00, 0x0c, 0x4f, 0x75, 0xd0, 0x43, 0x50, 0x42, 0x77, 0xd8, 0x5c, 0xcd, 0xaa, 0x8a, 0x60, - 0x61, 0x2a, 0x35, 0x3c, 0xa8, 0x08, 0x83, 0x28, 0xdd, 0x46, 0xce, 0x0d, 0xe1, 0x1c, 0x65, 0xdf, - 0x14, 0xdf, 0x97, 0xce, 0xf5, 0x38, 0x76, 0xb7, 0x82, 0xe3, 0x06, 0xfa, 0x32, 0x54, 0x46, 0x5e, - 0xf4, 0x94, 0x5c, 0x78, 0x01, 0x61, 0xa1, 0xab, 0xe0, 0x69, 0x07, 0xd2, 0xa1, 0x3c, 0xf2, 0x22, - 0xf3, 0x22, 0x22, 0x01, 0xf7, 0x44, 0xb4, 0x8d, 0x8f, 0xa1, 0x8e, 0x89, 0x73, 0x4e, 0xe1, 0xee, - 0x91, 0x88, 0x22, 0x6e, 0x80, 0x12, 0x90, 0xdb, 0x85, 0x90, 0x53, 0x61, 0x01, 0xcc, 0xb9, 0xb7, - 0xca, 0x52, 0x6f, 0x7f, 0x00, 0x2a, 0x5d, 0xf8, 0x2e, 0x82, 0x6c, 0x7c, 0x03, 0xd6, 0xb8, 0x13, - 0xc8, 0x80, 0xd2, 0x38, 0x24, 0x01, 0xcd, 0x25, 0x34, 0xd4, 0x42, 0x9b, 0x71, 0x2a, 0x16, 0x19, - 0xff, 0x92, 0xa0, 0x6e, 0xb5, 0x48, 0x10, 0xb5, 0x02, 0x42, 0x09, 0x48, 0x6e, 0xd1, 0x13, 0x90, - 0xa3, 0x90, 0x5b, 0xa1, 0x6f, 0xc7, 0xd9, 0x6b, 0x3b, 0xc9, 0x5e, 0xdb, 0x76, 0x92, 0xbd, 0xb0, - 0x1c, 0x85, 0xdc, 0x62, 0x79, 0x89, 0xc5, 0xef, 0xc4, 0x59, 0x24, 0x06, 0x60, 0x3d, 0x51, 0x61, - 0x19, 0x86, 0x25, 0x15, 0xf4, 0x1e, 0xa8, 0xa1, 0x3b, 0x8c, 0xb9, 0x95, 0x82, 0x48, 0x24, 0x13, - 0xcc, 0xc4, 0x14, 0x48, 0x32, 0x3a, 0xcb, 0x33, 0x6c, 0xaa, 0x45, 0xa5, 0xc5, 0xb8, 0xf5, 0x37, - 0x09, 0x1a, 0x19, 0x97, 0x43, 0x1f, 0x3d, 0x82, 0xd2, 0x19, 0x09, 0x84, 0xdb, 0xc2, 0x15, 0xaa, - 0x76, 0xe2, 0xb8, 0x01, 0x8e, 0xc5, 0xe8, 0x21, 0x94, 0xce, 0x2e, 0x1d, 0x77, 0xc4, 0x5d, 0xce, - 0xf9, 0x13, 0xcb, 0x50, 0x13, 0xd6, 0xfc, 0xab, 0x58, 0xad, 0xc4, 0xd2, 0x47, 0xd2, 0x7c, 0x35, - 0x18, 0xdf, 0x81, 0xea, 0x05, 0x89, 0xce, 0x2e, 0x31, 0x09, 0xc7, 0xd7, 0x11, 0xc7, 0xa4, 0x99, - 0x28, 0x1e, 0x51, 0x11, 0xdd, 0x17, 0x61, 0x2c, 0xc7, 0x69, 0x65, 0x63, 0x17, 0x6a, 0xcc, 0x2d, - 0xca, 0xe3, 0x42, 0x29, 0xc3, 0x98, 0xf0, 0xd8, 0x63, 0xf2, 0xd2, 0xbb, 0x22, 0x85, 0xd3, 0x0c, - 0x85, 0x82, 0x03, 0x50, 0x4b, 0x03, 0x85, 0x99, 0xa4, 0x18, 0xe5, 0x6d, 0xa8, 0xc6, 0x31, 0xc0, - 0x9d, 0x62, 0xeb, 0xf2, 0x59, 0xe5, 0xa5, 0xb3, 0xfe, 0x46, 0x82, 0xba, 0xfd, 0xdf, 0x64, 0xf3, - 0x43, 0x50, 0xfc, 0xf1, 0x69, 0xde, 0xb7, 0x14, 0x0b, 0xfd, 0xf1, 0x69, 0x62, 0xaa, 0xba, 0xd4, - 0xd4, 0x7d, 0x68, 0xd8, 0x39, 0x12, 0x26, 0xd0, 0x4a, 0x8b, 0xa0, 0x35, 0xfe, 0x2a, 0xc1, 0x46, - 0x6a, 0x14, 0xcf, 0x54, 0x77, 0xeb, 0xa2, 0x06, 0xca, 0x68, 0x7c, 0xc3, 0x5c, 0x5c, 0xc7, 0xf4, - 0x13, 0x1d, 0x64, 0xce, 0x0d, 0x95, 0x25, 0x93, 0xb7, 0x05, 0x79, 0xa9, 0x39, 0xf3, 0x0f, 0x0f, - 0x8e, 0x43, 0x69, 0x29, 0x0e, 0x07, 0x3c, 0x62, 0xd3, 0x74, 0xff, 0x2e, 0xac, 0x8b, 0x49, 0xba, - 0xd3, 0xbc, 0x9f, 0xed, 0x34, 0x3e, 0x00, 0x94, 0x47, 0x22, 0xf4, 0xd1, 0x7b, 0xd9, 0x7d, 0xdc, - 0x48, 0x63, 0x48, 0x75, 0x62, 0xa9, 0xf1, 0x77, 0x09, 0x34, 0x3b, 0xd9, 0x2b, 0x3d, 0x12, 0x85, - 0x14, 0xc6, 0x5d, 0x28, 0x9d, 0x92, 0xa1, 0x3b, 0x2a, 0x80, 0x64, 0xac, 0x88, 0xbe, 0x4e, 0x73, - 0x52, 0x82, 0xe6, 0x32, 0x7d, 0xaa, 0x96, 0x1c, 0x28, 0x4a, 0x91, 0x03, 0x45, 0x7d, 0xd5, 0x81, - 0xb2, 0x1c, 0xd4, 0x09, 0x07, 0xf5, 0x0b, 0xd8, 0xd8, 0x3f, 0x4d, 0x28, 0x1a, 0xaf, 0xcd, 0x29, - 0xfa, 0xea, 0xe5, 0x63, 0x12, 0xcb, 0x85, 0x48, 0x5c, 0x34, 0xc3, 0xd8, 0x77, 0x9f, 0x61, 0x7e, - 0x4b, 0x99, 0xd3, 0xe9, 0xfd, 0x7f, 0xe4, 0x98, 0x01, 0x6c, 0xe4, 0x6c, 0x2d, 0x92, 0x65, 0xd0, - 0x63, 0x28, 0x07, 0x9e, 0x17, 0xb5, 0x16, 0xb1, 0x41, 0x48, 0x8d, 0x3d, 0xa8, 0xf3, 0x05, 0x8a, - 0x1f, 0x3a, 0x1f, 0x0b, 0x00, 0xbf, 0x00, 0x76, 0xea, 0xa0, 0xd2, 0x21, 0xb4, 0xa4, 0x14, 0x20, - 0xd4, 0x78, 0x72, 0x7d, 0x1f, 0x4a, 0xf6, 0x22, 0x21, 0xad, 0x37, 0xfd, 0x80, 0x5c, 0xed, 0xf2, - 0xeb, 0x41, 0xdc, 0x30, 0x7e, 0x29, 0xc1, 0x1a, 0x4f, 0x2d, 0x77, 0x9f, 0x85, 0xe9, 0x8d, 0x46, - 0x11, 0x37, 0x1a, 0x56, 0x7a, 0xb0, 0xd4, 0x16, 0x27, 0xe0, 0xf5, 0x4c, 0x02, 0x4e, 0x12, 0xdb, - 0x0e, 0x94, 0xb9, 0x3d, 0x74, 0x97, 0xa8, 0x21, 0x89, 0x92, 0xea, 0x6f, 0x26, 0x15, 0x32, 0xa1, - 0xb1, 0x1b, 0x0f, 0xa0, 0x35, 0x0e, 0xf5, 0x9b, 0x55, 0x62, 0xdc, 0x6f, 0x56, 0x76, 0x69, 0x71, - 0xd9, 0xc5, 0x6f, 0x56, 0x64, 0x74, 0x66, 0xfc, 0x43, 0x02, 0x30, 0x5b, 0x26, 0xcd, 0xd7, 0x77, - 0xcf, 0x7d, 0x03, 0x4a, 0x84, 0xf1, 0x4e, 0x99, 0x13, 0xe7, 0x58, 0xf4, 0xc6, 0xc7, 0xd1, 0x0e, - 0x54, 0xc2, 0x84, 0x0d, 0x8b, 0xf3, 0xe7, 0x54, 0xc7, 0xf8, 0xb5, 0x02, 0x55, 0xe1, 0x69, 0xe8, - 0xa3, 0x83, 0xdc, 0xe5, 0xfc, 0x2b, 0xe2, 0xee, 0x34, 0x55, 0x9a, 0x73, 0x3f, 0x2f, 0xc0, 0xdd, - 0x8c, 0x69, 0x4a, 0x01, 0xd3, 0x7e, 0x2e, 0x67, 0xee, 0xfc, 0x9b, 0xd0, 0x38, 0xea, 0x77, 0x3a, - 0x83, 0x5e, 0xbf, 0xd5, 0xb2, 0x7a, 0xbd, 0xa3, 0x7e, 0x47, 0x5b, 0x41, 0x6f, 0x03, 0x3a, 0x31, - 0xb1, 0xdd, 0x36, 0x33, 0xfd, 0x12, 0xba, 0x0f, 0x9b, 0xdd, 0xe3, 0x81, 0x69, 0xdb, 0xb8, 0xfd, - 0xb4, 0x6f, 0x5b, 0xbd, 0xc1, 0xd1, 0x71, 0xbf, 0x7b, 0xa8, 0x95, 0x11, 0x82, 0xfa, 0x91, 0xd9, - 0xee, 0xf4, 0xb1, 0x35, 0x78, 0xde, 0xee, 0xbe, 0x30, 0x3b, 0xda, 0x39, 0xaa, 0xc2, 0x1a, 0xef, - 0xd3, 0x28, 0x29, 0xab, 0x4f, 0xcd, 0xc3, 0x01, 0xb6, 0x7e, 0xd8, 0xb7, 0x7a, 0xb6, 0xf6, 0x47, - 0x89, 0xf6, 0x50, 0xf1, 0xa0, 0xdb, 0xee, 0x0c, 0xec, 0x9e, 0xf6, 0xa7, 0x6c, 0x4f, 0xfb, 0x50, - 0xfb, 0xb3, 0x84, 0x36, 0xe3, 0x69, 0x59, 0x8f, 0xd5, 0xb2, 0xb0, 0xad, 0xfd, 0x85, 0x1a, 0x81, - 0x44, 0x67, 0xaf, 0xfd, 0xfd, 0xae, 0x69, 0xd3, 0x25, 0x3e, 0x91, 0x50, 0x13, 0x36, 0x85, 0x60, - 0x6a, 0xa3, 0xf6, 0xa9, 0x98, 0x87, 0x99, 0x67, 0xfe, 0x98, 0x9a, 0xf7, 0xa9, 0xa4, 0xcb, 0x9a, - 0x64, 0xfc, 0x4a, 0x82, 0x86, 0xd9, 0x32, 0x45, 0x75, 0xfc, 0xba, 0xb4, 0x14, 0xa4, 0x93, 0x17, - 0x93, 0xee, 0xb5, 0x23, 0xf4, 0x33, 0x09, 0xb4, 0xac, 0x51, 0xa1, 0x8f, 0x3e, 0xc8, 0x31, 0xe8, - 0x61, 0x8a, 0x41, 0x19, 0xcd, 0x79, 0x34, 0xd2, 0x40, 0x79, 0x1e, 0x0e, 0xf9, 0x85, 0x97, 0x7e, - 0x1a, 0x8f, 0x32, 0x24, 0xa8, 0xc2, 0x1a, 0x8f, 0xb3, 0xb6, 0x92, 0x89, 0x1b, 0xb3, 0x25, 0x7f, - 0x77, 0x58, 0x6c, 0x4b, 0x5e, 0xf3, 0x6e, 0x6d, 0xf9, 0x44, 0x82, 0x1a, 0xdf, 0x2f, 0xaf, 0x51, - 0xee, 0xa1, 0x47, 0x50, 0x17, 0x1d, 0x2f, 0xc4, 0xc5, 0xbf, 0x86, 0x73, 0xbd, 0xe8, 0xdb, 0x50, - 0x79, 0xe9, 0x5c, 0xbb, 0xe7, 0x47, 0x81, 0x77, 0xc3, 0xe3, 0xb4, 0x2c, 0xfc, 0x53, 0x65, 0xf4, - 0x4d, 0x58, 0x63, 0x0d, 0xdb, 0xe3, 0xa7, 0xea, 0xb2, 0x71, 0x89, 0xea, 0x93, 0xaf, 0x01, 0x4c, - 0x9f, 0x91, 0x50, 0x05, 0x4a, 0x56, 0xeb, 0xb0, 0x67, 0x6a, 0x2b, 0x68, 0x0d, 0x14, 0xdc, 0x33, - 0x35, 0x89, 0x7e, 0xd0, 0x1e, 0xf9, 0xc9, 0x73, 0x50, 0x69, 0x1d, 0x87, 0xca, 0xa0, 0x76, 0x8f, - 0xbb, 0x96, 0xb6, 0x82, 0x00, 0x56, 0x5b, 0x9d, 0xb6, 0xd5, 0xb5, 0x35, 0x89, 0xf6, 0x9e, 0x58, - 0x16, 0xd6, 0x64, 0xb4, 0x0e, 0x95, 0x17, 0x66, 0xa7, 0x7d, 0x68, 0xda, 0xc7, 0x58, 0x53, 0x29, - 0x7a, 0x66, 0xff, 0xb0, 0x4d, 0x1b, 0x65, 0x54, 0x01, 0xc5, 0xec, 0x74, 0xb4, 0xcf, 0x3e, 0x53, - 0xf6, 0x7e, 0x27, 0x83, 0x6a, 0xb5, 0xcc, 0x13, 0xb4, 0x0b, 0x1b, 0xf4, 0xf4, 0x6d, 0x99, 0x94, - 0xa8, 0xee, 0x85, 0x7b, 0xe6, 0x44, 0x04, 0x89, 0xe3, 0x81, 0x3d, 0xf8, 0xe9, 0x19, 0x4e, 0xa3, - 0x8f, 0xe0, 0xad, 0xb8, 0x20, 0x48, 0x8d, 0x60, 0x27, 0x80, 0x48, 0xa3, 0xd9, 0x27, 0x01, 0xfd, - 0xfe, 0xdc, 0xfe, 0xd0, 0x47, 0x1f, 0xc2, 0x26, 0x5b, 0x3b, 0x37, 0xcf, 0xbd, 0x8c, 0x3e, 0xaf, - 0x0d, 0xf4, 0x99, 0x5b, 0x35, 0xda, 0x87, 0xb7, 0x72, 0xc3, 0x9f, 0x4e, 0xd8, 0x0b, 0xa3, 0xb0, - 0x97, 0xb6, 0x72, 0xd6, 0x9b, 0x74, 0x10, 0xad, 0x1c, 0x96, 0x5b, 0x2f, 0xaa, 0x8b, 0xd4, 0xba, - 0xfc, 0x11, 0x75, 0xef, 0x9f, 0x12, 0xc3, 0xce, 0x44, 0x07, 0x50, 0x4b, 0xbf, 0xb4, 0xa1, 0xfb, - 0xd9, 0xa7, 0x2b, 0xf1, 0xfe, 0xa6, 0x67, 0x2f, 0xeb, 0xe8, 0x00, 0xaa, 0xa9, 0xe7, 0xa2, 0xe9, - 0xca, 0xd9, 0x37, 0x24, 0xbd, 0x91, 0x7e, 0x72, 0xa1, 0x8a, 0x1f, 0xd2, 0x58, 0xe5, 0x6c, 0x2f, - 0x6e, 0x37, 0xda, 0x07, 0x60, 0x75, 0x60, 0x78, 0xd9, 0xc2, 0x1d, 0xb4, 0x99, 0x8d, 0x0a, 0xab, - 0x73, 0xe7, 0x38, 0xfb, 0x0b, 0x19, 0x54, 0xfb, 0xcd, 0x88, 0xf2, 0x1c, 0xee, 0xcd, 0x10, 0x85, - 0xba, 0xf1, 0x20, 0x73, 0xdc, 0xa6, 0x2f, 0xa3, 0xba, 0xbe, 0x48, 0xc4, 0xd8, 0xb2, 0xcc, 0x7b, - 0xfb, 0x55, 0xde, 0xb7, 0xe0, 0xde, 0xcc, 0xf0, 0x59, 0x6b, 0xd2, 0xf7, 0x8e, 0x39, 0x68, 0xfc, - 0x41, 0x62, 0x68, 0x98, 0xff, 0x0b, 0xc6, 0x2c, 0x8a, 0xa7, 0xbd, 0x34, 0x9e, 0xff, 0x96, 0x60, - 0x95, 0x56, 0xd0, 0x6f, 0xb8, 0xf5, 0x37, 0x66, 0x22, 0x8a, 0xc4, 0x03, 0x53, 0xfe, 0x66, 0xa3, - 0x3f, 0x58, 0x20, 0x09, 0x7d, 0xf4, 0x2d, 0x68, 0xe4, 0xf6, 0x6e, 0x0a, 0xbd, 0xcc, 0xa5, 0x20, - 0x67, 0xc2, 0xf7, 0xe6, 0x01, 0xdf, 0x9c, 0x19, 0xba, 0x78, 0xf7, 0xb6, 0xb9, 0xff, 0xe6, 0xe7, - 0x9f, 0xea, 0xf7, 0x12, 0xa8, 0xe6, 0x9b, 0x21, 0xf9, 0x5d, 0x3a, 0xe2, 0x76, 0x4c, 0xc2, 0x69, - 0xb9, 0x19, 0x22, 0x34, 0x53, 0x12, 0xde, 0xea, 0x9b, 0x73, 0xca, 0x44, 0x74, 0x08, 0x0d, 0x71, - 0xce, 0xf2, 0xb1, 0xf7, 0xe7, 0x17, 0x03, 0xb7, 0x7a, 0x73, 0x51, 0x95, 0x70, 0x1a, 0xff, 0xc7, - 0xb4, 0xff, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xac, 0x0a, 0x0d, 0xf0, 0x76, 0x1a, 0x00, 0x00, -} diff --git a/membersrvc/protos/ca.proto b/membersrvc/protos/ca.proto deleted file mode 100644 index 7690e62f314..00000000000 --- a/membersrvc/protos/ca.proto +++ /dev/null @@ -1,409 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -syntax = "proto3"; - -package protos; - -import "google/protobuf/timestamp.proto"; - - -// Enrollment Certificate Authority (ECA). -// -service ECAP { // public service - rpc ReadCACertificate(Empty) returns (Cert); - rpc CreateCertificatePair(ECertCreateReq) returns (ECertCreateResp); - rpc ReadCertificatePair(ECertReadReq) returns (CertPair); - rpc ReadCertificateByHash(Hash) returns (Cert); - rpc RevokeCertificatePair(ECertRevokeReq) returns (CAStatus); // a user can revoke only his/her own cert -} - -service ECAA { // admin service - rpc RegisterUser(RegisterUserReq) returns (Token); - rpc ReadUserSet(ReadUserSetReq) returns (UserSet); - rpc RevokeCertificate(ECertRevokeReq) returns (CAStatus); // an admin can revoke any cert - rpc PublishCRL(ECertCRLReq) returns (CAStatus); // publishes CRL in the blockchain -} - -// Transaction Certificate Authority (TCA). -// -service TCAP { // public service - rpc ReadCACertificate(Empty) returns (Cert); - rpc CreateCertificateSet(TCertCreateSetReq) returns (TCertCreateSetResp); - rpc RevokeCertificate(TCertRevokeReq) returns (CAStatus); // a user can revoke only his/her cert - rpc RevokeCertificateSet(TCertRevokeSetReq) returns (CAStatus); // a user can revoke only his/her certs -} - -service TCAA { // admin service - rpc RevokeCertificate(TCertRevokeReq) returns (CAStatus); // an admin can revoke any cert - rpc RevokeCertificateSet(TCertRevokeSetReq) returns (CAStatus); // an admin can revoke any cert - rpc PublishCRL(TCertCRLReq) returns (CAStatus); // publishes CRL in the blockchain -} - -// TLS Certificate Authority (TLSCA) -// -service TLSCAP { // public service - rpc ReadCACertificate(Empty) returns (Cert); - rpc CreateCertificate(TLSCertCreateReq) returns (TLSCertCreateResp); - rpc ReadCertificate(TLSCertReadReq) returns (Cert); - rpc RevokeCertificate(TLSCertRevokeReq) returns (CAStatus); // a user can revoke only his/her cert -} - -service TLSCAA { // admin service - rpc RevokeCertificate(TLSCertRevokeReq) returns (CAStatus); // an admin can revoke any cert -} - -// Attribute Certificate Authority (ACA). -// -service ACAP { // public service - rpc ReadCACertificate(Empty) returns (Cert); - rpc RequestAttributes(ACAAttrReq) returns (ACAAttrResp); - rpc FetchAttributes(ACAFetchAttrReq) returns (ACAFetchAttrResp); -} - -// Status codes shared by both CAs. -// -message CAStatus { - enum StatusCode { - OK = 0; - UNKNOWN_ERROR = 1; - } - StatusCode status = 1; -} - - -// Empty message. -message Empty { -} - -// Uniquely identifies a user towards either CA. -message Identity { - string id = 1; -} - -message Token { - bytes tok = 1; -} - -message Hash { - bytes hash = 1; -} - -// Public/private keys. -enum CryptoType { - ECDSA = 0; - RSA = 1; - DSA = 2; -} - -message PublicKey { - CryptoType type = 1; - bytes key = 2; // DER / ASN.1 -} - -message PrivateKey { - CryptoType type = 1; - bytes key = 2; // DER / ASN.1 -} - -// Signature. -// -message Signature { - CryptoType type = 1; - bytes r = 2; - bytes s = 3; -} - -// User registration. -// -enum Role { - NONE = 0; - CLIENT = 1; // powers of 2 to | different roles - PEER = 2; - VALIDATOR = 4; - AUDITOR = 8; - ALL = 0xFFFF; -} - -message Registrar { - Identity id = 1; // The identity of the registrar - repeated string roles = 2; // Roles that the registrar can register - repeated string delegateRoles = 3; // Roles that the registrar can give to another to register -} - -message RegisterUserReq { - Identity id = 1; - Role role = 2; - repeated Attribute attributes = 3; - string affiliation = 4; - Registrar registrar = 5; - Signature sig = 6; -} - -message Attribute { - string name = 1; - string value = 2; - string notBefore = 3; - string notAfter = 4; -} - -message ReadUserSetReq { - Identity req = 1; - Role role = 2; // bitmask - Signature sig = 3; // sign(priv, req | id | role) -} - -message User { - Identity id = 1; - Role role = 2; -} - -message UserSet { - repeated User users = 1; -} - -// Certificate requests. -// -message ECertCreateReq { - google.protobuf.Timestamp ts = 1; - Identity id = 2; - Token tok = 3; - PublicKey sign = 4; - PublicKey enc = 5; - Signature sig = 6; // sign(priv, ts | id | tok | sign | enc) -} - -message ECertCreateResp { - CertPair certs = 1; - Token chain = 2; - bytes pkchain = 5; - Token tok = 3; - FetchAttrsResult fetchResult = 4; -} - -message ECertReadReq { - Identity id = 1; -} - -message ECertRevokeReq { - Identity id = 1; // user or admin whereby users can only revoke their own cert - Cert cert = 2; // cert to revoke - Signature sig = 3; // sign(priv, id | cert) -} - -message ECertCRLReq { - Identity id = 1; // admin - Signature sig = 2; // sign(priv, id) -} - -message TCertCreateReq { - google.protobuf.Timestamp ts = 1; - Identity id = 2; // corresponding ECert retrieved from ECA - PublicKey pub = 3; - Signature sig = 4; // sign(priv, ts | id | pub) -} - -message TCertCreateResp { - Cert cert = 1; -} - -message TCertCreateSetReq { - google.protobuf.Timestamp ts = 1; - Identity id = 2; // corresponding ECert retrieved from ECA - uint32 num = 3; // number of certs to create - repeated TCertAttribute attributes = 4; // array with the attributes to add to each TCert. - Signature sig = 5; // sign(priv, ts | id | attributes | num) -} - -message TCertAttribute { - string attributeName = 1; -} - -message TCertCreateSetResp { - CertSet certs = 1; -} - -message TCertReadSetsReq { - google.protobuf.Timestamp begin = 1; - google.protobuf.Timestamp end = 2; - Identity req = 3; // corresponding ECert retrieved from ECA - Role role = 4; // bitmask - Signature sig = 5; // sign(priv, begin | end | req | id | role) -} - -message TCertRevokeReq { - Identity id = 1; // user or admin whereby users can only revoke their own certs - Cert cert = 2; // cert to revoke - Signature sig = 3; // sign(priv, id | cert) -} - -message TCertRevokeSetReq { - Identity id = 1; // user or admin whereby users can only revoke their own certs - google.protobuf.Timestamp ts = 2; // timestamp of cert set to revoke (0 == latest set) - Signature sig = 3; // sign(priv, id | cert) -} - -message TCertCRLReq { - Identity id = 1; // admin - Signature sig = 2; // sign(priv, id) -} - -message TLSCertCreateReq { - google.protobuf.Timestamp ts = 1; - Identity id = 2; - PublicKey pub = 3; - Signature sig = 4; // sign(priv, ts | id | pub) -} - -message TLSCertCreateResp { - Cert cert = 1; - Cert rootCert = 2; -} - -message TLSCertReadReq { - Identity id = 1; -} - -message TLSCertRevokeReq { - Identity id = 1; // user or admin whereby users can only revoke their own cert - Cert cert = 2; // cert to revoke - Signature sig = 3; // sign(priv, id | cert) -} - -// Certificate issued by either the ECA or TCA. -// -message Cert { - bytes cert = 1; // DER / ASN.1 encoded -} - -// TCert -// -message TCert { - bytes cert = 1; // DER / ASN.1 encoded - bytes prek0 = 2; // PreK0 used to derive the keys to encrypt the TCert extensions (EnrollmentID, TCertIndex and attributes) -} - -message CertSet { - google.protobuf.Timestamp ts = 1; - Identity id = 2; - bytes key = 3; - repeated TCert certs = 4; -} - -message CertSets { - repeated CertSet sets = 1; -} - -message CertPair { - bytes sign = 1; // signature certificate, DER / ASN.1 encoded - bytes enc = 2; // encryption certificate, DER / ASN.1 encoded -} - -//ACAAttrReq is sent to request an ACert (attributes certificate) to the Attribute Certificate Authority (ACA). -message ACAAttrReq { - // Request time - google.protobuf.Timestamp ts = 1; - // User identity - Identity id = 2; - // Enrollment certificate - Cert eCert = 3; - // Collection of requested attributes including the attribute name and its respective value hash. - repeated TCertAttribute attributes = 4; // array with the pairs key/value-hash of each attribute. - // The request is signed by the TCA. - Signature signature = 5; -} - -//ACAAttrResp is the response of Attribute Certificate Authority (ACA) to the attribute request. Is composed by the following fields: -message ACAAttrResp { - enum StatusCode { - // Processed OK and all attributes included. - FULL_SUCCESSFUL = 000; - // Processed OK but some attributes included. - PARTIAL_SUCCESSFUL = 001; - // Processed OK but no attributes included. - NO_ATTRIBUTES_FOUND = 010; - - // Processed with errors. - option allow_alias = true; - FAILURE_MINVAL = 100; - FAILURE = 100; - BAD_REQUEST = 200; - // Missing parameters - FAIL_NIL_TS = 201; - FAIL_NIL_ID = 202; - FAIL_NIL_ECERT = 203; - FAIL_NIL_SIGNATURE = 204; - FAIL_NIL_ATTRIBUTES = 205; - - FAILURE_MAXVAL = 205; - } - // Indicates the request process status. - StatusCode status = 1; - // Attribute certificate. Include all the attributes certificated. - Cert cert = 2; - // The response is signed by the ACA. - Signature signature = 3; -} - -//ACAFetchAttrReq is a request to the Attribute Certificate Authority (ACA) to refresh attributes values from the sources. -message ACAFetchAttrReq { - // Request timestamp - google.protobuf.Timestamp ts = 1; - // Enrollment certificate. - Cert eCert = 2; - // The request is signed by the ECA. - Signature signature = 3; -} - -//ACAFetchAttrReq is the answer of the Attribute Certificate Authority (ACA) to the refresh request. -message ACAFetchAttrResp { - enum StatusCode { - // Processed OK - SUCCESS = 000; - // Processed with errors. - FAILURE = 100; - } - // Status of the fetch process. - StatusCode status = 1; - // Error message. - string Msg = 2; -} - -//FetchAttrsResult is returned within the ECertCreateResp indicating the results of the fetch attributes invoked during enroll. -message FetchAttrsResult { - enum StatusCode { - // Processed OK - SUCCESS = 000; - // Processed with errors - FAILURE = 100; - } - // Status of the fetch process. - StatusCode status = 1; - // Error message. - string Msg = 2; -} - -//ACAAttribute is an instance of an attribute with the time constraints. Is used to marshal attributes to be stored within the certificate extensions. -message ACAAttribute { - // Name of the attribute. - string attributeName = 1; - // Value of the attribute. - bytes attributeValue = 2; - // The timestamp which attribute is valid from. - google.protobuf.Timestamp validFrom = 3; - // The timestamp which attribute is valid to. - google.protobuf.Timestamp validTo = 4; -} diff --git a/membersrvc/server.go b/membersrvc/server.go deleted file mode 100644 index bdc7fc11736..00000000000 --- a/membersrvc/server.go +++ /dev/null @@ -1,117 +0,0 @@ -/* -Copyright IBM Corp. 2016 All Rights Reserved. - -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. -*/ - -package main - -import ( - "net" - "os" - "path/filepath" - "runtime" - - "strings" - - "github.com/hyperledger/fabric/core/crypto" - "github.com/hyperledger/fabric/flogging" - "github.com/hyperledger/fabric/membersrvc/ca" - "github.com/hyperledger/fabric/metadata" - "github.com/op/go-logging" - "github.com/spf13/viper" - "google.golang.org/grpc" - "google.golang.org/grpc/credentials" -) - -const envPrefix = "MEMBERSRVC_CA" - -var logger = logging.MustGetLogger("server") - -func main() { - - viper.SetEnvPrefix(envPrefix) - viper.AutomaticEnv() - replacer := strings.NewReplacer(".", "_") - viper.SetEnvKeyReplacer(replacer) - viper.SetConfigName("membersrvc") - viper.SetConfigType("yaml") - viper.AddConfigPath("./") - // Path to look for the config file based on GOPATH - gopath := os.Getenv("GOPATH") - for _, p := range filepath.SplitList(gopath) { - cfgpath := filepath.Join(p, "src/github.com/hyperledger/fabric/membersrvc") - viper.AddConfigPath(cfgpath) - } - err := viper.ReadInConfig() - if err != nil { - logger.Panicf("Fatal error when reading %s config file: %s", "membersrvc", err) - } - - flogging.LoggingInit("server") - - // Init the crypto layer - if err := crypto.Init(); err != nil { - logger.Panicf("Failed initializing the crypto layer [%s]", err) - } - - // cache configure - ca.CacheConfiguration() - - logger.Infof("CA Server (" + metadata.Version + ")") - - aca := ca.NewACA() - defer aca.Stop() - - eca := ca.NewECA(aca) - defer eca.Stop() - - tca := ca.NewTCA(eca) - defer tca.Stop() - - tlsca := ca.NewTLSCA(eca) - defer tlsca.Stop() - - runtime.GOMAXPROCS(viper.GetInt("server.gomaxprocs")) - - var opts []grpc.ServerOption - - if viper.GetBool("security.tls_enabled") { - logger.Debug("TLS was enabled [security.tls_enabled == true]") - creds, err := credentials.NewServerTLSFromFile(viper.GetString("server.tls.cert.file"), viper.GetString("server.tls.key.file")) - if err != nil { - logger.Panic(err) - } - opts = []grpc.ServerOption{grpc.Creds(creds)} - } else { - logger.Debug("TLS was not enabled [security.tls_enabled == false]") - } - - srv := grpc.NewServer(opts...) - - if viper.GetBool("aca.enabled") { - logger.Debug("ACA was enabled [aca.enabled == true]") - aca.Start(srv) - } - eca.Start(srv) - tca.Start(srv) - tlsca.Start(srv) - - if sock, err := net.Listen("tcp", viper.GetString("server.port")); err != nil { - logger.Errorf("Fail to start CA Server: %s", err) - os.Exit(1) - } else { - srv.Serve(sock) - sock.Close() - } -} diff --git a/peer/main.go b/peer/main.go index cecc0e7f4b3..1113618df99 100644 --- a/peer/main.go +++ b/peer/main.go @@ -30,7 +30,6 @@ import ( _ "net/http/pprof" "github.com/hyperledger/fabric/core" - "github.com/hyperledger/fabric/core/crypto" "github.com/hyperledger/fabric/flogging" "github.com/hyperledger/fabric/peer/chaincode" "github.com/hyperledger/fabric/peer/network" @@ -113,9 +112,7 @@ func main() { runtime.GOMAXPROCS(viper.GetInt("peer.gomaxprocs")) // Init the crypto layer - if err := crypto.Init(); err != nil { - panic(fmt.Errorf("Failed to initialize the crypto layer: %s", err)) - } + //TODO: integrate new crypto / idp code // On failure Cobra prints the usage message and error string, so we only // need to exit with a non-0 status diff --git a/peer/node/start.go b/peer/node/start.go index 13859552e61..ad125e479c0 100755 --- a/peer/node/start.go +++ b/peer/node/start.go @@ -356,34 +356,6 @@ var once sync.Once //NOTE- this crypto func might rightly belong in a crypto package //and universally accessed func getSecHelper() (crypto.Peer, error) { - var secHelper crypto.Peer - var err error - once.Do(func() { - if core.SecurityEnabled() { - enrollID := viper.GetString("security.enrollID") - enrollSecret := viper.GetString("security.enrollSecret") - if peer.ValidatorEnabled() { - logger.Debugf("Registering validator with enroll ID: %s", enrollID) - if err = crypto.RegisterValidator(enrollID, nil, enrollID, enrollSecret); nil != err { - return - } - logger.Debugf("Initializing validator with enroll ID: %s", enrollID) - secHelper, err = crypto.InitValidator(enrollID, nil) - if nil != err { - return - } - } else { - logger.Debugf("Registering non-validator with enroll ID: %s", enrollID) - if err = crypto.RegisterPeer(enrollID, nil, enrollID, enrollSecret); nil != err { - return - } - logger.Debugf("Initializing non-validator with enroll ID: %s", enrollID) - secHelper, err = crypto.InitPeer(enrollID, nil) - if nil != err { - return - } - } - } - }) - return secHelper, err + //TODO: integrated new crypto / idp code + return nil, nil } diff --git a/scripts/goUnitTests.sh b/scripts/goUnitTests.sh index 5b4a05b01c7..360cae041d0 100755 --- a/scripts/goUnitTests.sh +++ b/scripts/goUnitTests.sh @@ -15,9 +15,6 @@ fi echo "Running unit tests using $IMAGE" -echo "Cleaning membership services folder" -rm -rf membersrvc/ca/.ca/ - echo -n "Obtaining list of tests to run.." # Some examples don't play nice with `go test` PKGS=`go list github.com/hyperledger/fabric/... | grep -v /vendor/ | \ diff --git a/scripts/goimports.sh b/scripts/goimports.sh index f1966e3a5ba..7bc477412ce 100755 --- a/scripts/goimports.sh +++ b/scripts/goimports.sh @@ -2,7 +2,7 @@ set -e -declare -a arr=("./core" "./events" "./examples" "./membersrvc" "./peer" "./protos") +declare -a arr=("./core" "./events" "./examples" "./peer" "./protos") for i in "${arr[@]}" do