func (node *nodeImpl) retrieveTCACertsChain(userID string) error { // 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 (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 (node *nodeImpl) retrieveECACertsChain(userID string) error { // 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 }
//CreateAttributesMetadata create the AttributesMetadata from the original metadata func CreateAttributesMetadata(raw []byte, metadata []byte, preK0 []byte, attributeKeys []string) ([]byte, error) { cert, err := primitives.DERToX509Certificate(raw) if err != nil { return nil, err } return CreateAttributesMetadataFromCert(cert, metadata, preK0, attributeKeys) }
// 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 }
func (validator *validatorImpl) verifyValidityPeriod(tx *obc.Transaction) (*obc.Transaction, error) { if tx.Cert != nil && tx.Signature != nil { // Unmarshal cert cert, err := primitives.DERToX509Certificate(tx.Cert) if err != nil { validator.Errorf("verifyValidityPeriod: failed unmarshalling cert %s:", err) return tx, err } cid := viper.GetString("pki.validity-period.chaincodeHash") ledger, err := ledger.GetLedger() if err != nil { validator.Errorf("verifyValidityPeriod: failed getting access to the ledger %s:", err) return tx, err } vpBytes, err := ledger.GetState(cid, "system.validity.period", true) if err != nil { validator.Errorf("verifyValidityPeriod: failed reading validity period from the ledger %s:", err) return tx, err } i, err := strconv.ParseInt(string(vpBytes[:]), 10, 64) if err != nil { validator.Errorf("verifyValidityPeriod: failed to parse validity period %s:", err) return tx, err } vp := time.Unix(i, 0) var errMsg string // Verify the validity period of the TCert switch { case cert.NotAfter.Before(cert.NotBefore): errMsg = "verifyValidityPeriod: certificate validity period is invalid" case vp.Before(cert.NotBefore): errMsg = "verifyValidityPeriod: certificate validity period is in the future" case vp.After(cert.NotAfter): errMsg = "verifyValidityPeriod: certificate validity period is in the past" } if errMsg != "" { validator.Error(errMsg) return tx, errors.New(errMsg) } } return tx, nil }
// 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 } // TODO: verify cert // 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 }
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 (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 }
// 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 } // TODO: verify cert // 3. 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 // 2. 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 }
//NewAttributesHandlerImpl creates a new AttributesHandlerImpl from a pb.ChaincodeSecurityContext object. func NewAttributesHandlerImpl(holder chaincodeHolder) (*AttributesHandlerImpl, error) { // Getting certificate certRaw, err := holder.GetCallerCertificate() if err != nil { return nil, err } if certRaw == nil { return nil, errors.New("The certificate can't be nil.") } var tcert *x509.Certificate tcert, err = primitives.DERToX509Certificate(certRaw) if err != nil { return nil, err } keys := make(map[string][]byte) /* TODO: ##attributes-keys-pending This code have be redefined to avoid use of metadata field. //Getting Attributes Metadata from security context. var attrsMetadata *attributespb.AttributesMetadata var rawMetadata []byte rawMetadata, err = holder.GetCallerMetadata() if err != nil { return nil, err } if rawMetadata != nil { attrsMetadata, err = attributes.GetAttributesMetadata(rawMetadata) if err == nil { for _, entry := range attrsMetadata.Entries { keys[entry.AttributeName] = entry.AttributeKey } } }*/ cache := make(map[string][]byte) return &AttributesHandlerImpl{tcert, cache, keys, nil, false}, nil }
//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: &google_protobuf.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 }
// 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 }
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 (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.Debugf("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 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 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 (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.Debugf("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.Debugf("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) getTCertFromExternalDER(der []byte) (tCert, error) { // DER to x509 x509Cert, err := primitives.DERToX509Certificate(der) if err != nil { client.Debugf("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 }