github.com/dddengyunjie/fabric-ca@v0.0.0-20190606043049-92df60ae2f0f/lib/tcert/keytree.go (about) 1 /* 2 Copyright IBM Corp. 2016 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package tcert 18 19 import ( 20 "fmt" 21 "strings" 22 23 "github.com/hyperledger/fabric/bccsp" 24 ) 25 26 /* 27 * A key tree is a hierarchy of derived keys with a single root key. 28 * Each node in the tree has a key and a name, where the key is secret 29 * and the name may be public. If the secret associated with a node 30 * is known, then the secret of each node in it's sub-tree can be derived 31 * if the name of the nodes are known; however, it is not possible to 32 * derive the keys associated with other nodes in the tree which are not 33 * part of this sub-tree. 34 * 35 * This data structure is useful to support releasing a secret associated 36 * with any node to an auditor without giving the auditor access to all 37 * nodes in the tree. 38 */ 39 40 const ( 41 keyPathSep = "/" 42 ) 43 44 // NewKeyTree is the constructor for a key tree 45 func NewKeyTree(bccspMgr bccsp.BCCSP, rootKey bccsp.Key) *KeyTree { 46 tree := new(KeyTree) 47 tree.bccspMgr = bccspMgr 48 tree.rootKey = rootKey 49 tree.keys = make(map[string]bccsp.Key) 50 return tree 51 } 52 53 // KeyTree is a tree of derived keys 54 type KeyTree struct { 55 bccspMgr bccsp.BCCSP 56 rootKey bccsp.Key 57 keys map[string]bccsp.Key 58 } 59 60 // GetKey returns a key associated with a specific path in the tree. 61 func (m *KeyTree) GetKey(path []string) (bccsp.Key, error) { 62 if path == nil || len(path) == 0 { 63 return m.rootKey, nil 64 } 65 pathStr := strings.Join(path, keyPathSep) 66 key := m.keys[pathStr] 67 if key != nil { 68 return key, nil 69 } 70 parentKey, err := m.GetKey(path[0 : len(path)-1]) 71 if err != nil { 72 return nil, err 73 } 74 childName := path[len(path)-1] 75 key, err = m.deriveChildKey(parentKey, childName, pathStr) 76 if err != nil { 77 return nil, err 78 } 79 m.keys[pathStr] = key 80 return key, nil 81 } 82 83 // Given a parentKey and a childName, derive the child's key 84 func (m *KeyTree) deriveChildKey(parentKey bccsp.Key, childName, path string) (bccsp.Key, error) { 85 opts := &bccsp.HMACDeriveKeyOpts{ 86 Temporary: true, 87 Arg: []byte(childName), 88 } 89 key, err := m.bccspMgr.KeyDeriv(parentKey, opts) 90 if err != nil { 91 return nil, fmt.Errorf("Failed to derive key %s: %s", path, err) 92 } 93 return key, nil 94 }