3 Star 6 Fork 7

Gitee 极速下载/Hyperledger fabric

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
此仓库是为了提升国内下载速度的镜像仓库,每日同步一次。 原始仓库: https://github.com/hyperledger/fabric
克隆/下载
client_tca.go 18.64 KB
一键复制 编辑 原始数据 按行查看 历史
YACOVM 提交于 2016-08-22 13:57 . Upgrade go protobuf from 3-beta to 3
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615
/*
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: &timestamp,
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
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/mirrors/fabric.git
git@gitee.com:mirrors/fabric.git
mirrors
fabric
Hyperledger fabric
v0.6.1-preview

搜索帮助

0d507c66 1850385 C8b1a773 1850385