github.com/true-sqn/fabric@v2.1.1+incompatible/bccsp/sw/impl.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 package sw 17 18 import ( 19 "hash" 20 "reflect" 21 22 "github.com/hyperledger/fabric/bccsp" 23 "github.com/hyperledger/fabric/common/flogging" 24 "github.com/pkg/errors" 25 ) 26 27 var ( 28 logger = flogging.MustGetLogger("bccsp_sw") 29 ) 30 31 // CSP provides a generic implementation of the BCCSP interface based 32 // on wrappers. It can be customized by providing implementations for the 33 // following algorithm-based wrappers: KeyGenerator, KeyDeriver, KeyImporter, 34 // Encryptor, Decryptor, Signer, Verifier, Hasher. Each wrapper is bound to a 35 // goland type representing either an option or a key. 36 type CSP struct { 37 ks bccsp.KeyStore 38 39 KeyGenerators map[reflect.Type]KeyGenerator 40 KeyDerivers map[reflect.Type]KeyDeriver 41 KeyImporters map[reflect.Type]KeyImporter 42 Encryptors map[reflect.Type]Encryptor 43 Decryptors map[reflect.Type]Decryptor 44 Signers map[reflect.Type]Signer 45 Verifiers map[reflect.Type]Verifier 46 Hashers map[reflect.Type]Hasher 47 } 48 49 func New(keyStore bccsp.KeyStore) (*CSP, error) { 50 if keyStore == nil { 51 return nil, errors.Errorf("Invalid bccsp.KeyStore instance. It must be different from nil.") 52 } 53 54 encryptors := make(map[reflect.Type]Encryptor) 55 decryptors := make(map[reflect.Type]Decryptor) 56 signers := make(map[reflect.Type]Signer) 57 verifiers := make(map[reflect.Type]Verifier) 58 hashers := make(map[reflect.Type]Hasher) 59 keyGenerators := make(map[reflect.Type]KeyGenerator) 60 keyDerivers := make(map[reflect.Type]KeyDeriver) 61 keyImporters := make(map[reflect.Type]KeyImporter) 62 63 csp := &CSP{keyStore, 64 keyGenerators, keyDerivers, keyImporters, encryptors, 65 decryptors, signers, verifiers, hashers} 66 67 return csp, nil 68 } 69 70 // KeyGen generates a key using opts. 71 func (csp *CSP) KeyGen(opts bccsp.KeyGenOpts) (k bccsp.Key, err error) { 72 // Validate arguments 73 if opts == nil { 74 return nil, errors.New("Invalid Opts parameter. It must not be nil.") 75 } 76 77 keyGenerator, found := csp.KeyGenerators[reflect.TypeOf(opts)] 78 if !found { 79 return nil, errors.Errorf("Unsupported 'KeyGenOpts' provided [%v]", opts) 80 } 81 82 k, err = keyGenerator.KeyGen(opts) 83 if err != nil { 84 return nil, errors.Wrapf(err, "Failed generating key with opts [%v]", opts) 85 } 86 87 // If the key is not Ephemeral, store it. 88 if !opts.Ephemeral() { 89 // Store the key 90 err = csp.ks.StoreKey(k) 91 if err != nil { 92 return nil, errors.Wrapf(err, "Failed storing key [%s]", opts.Algorithm()) 93 } 94 } 95 96 return k, nil 97 } 98 99 // KeyDeriv derives a key from k using opts. 100 // The opts argument should be appropriate for the primitive used. 101 func (csp *CSP) KeyDeriv(k bccsp.Key, opts bccsp.KeyDerivOpts) (dk bccsp.Key, err error) { 102 // Validate arguments 103 if k == nil { 104 return nil, errors.New("Invalid Key. It must not be nil.") 105 } 106 if opts == nil { 107 return nil, errors.New("Invalid opts. It must not be nil.") 108 } 109 110 keyDeriver, found := csp.KeyDerivers[reflect.TypeOf(k)] 111 if !found { 112 return nil, errors.Errorf("Unsupported 'Key' provided [%v]", k) 113 } 114 115 k, err = keyDeriver.KeyDeriv(k, opts) 116 if err != nil { 117 return nil, errors.Wrapf(err, "Failed deriving key with opts [%v]", opts) 118 } 119 120 // If the key is not Ephemeral, store it. 121 if !opts.Ephemeral() { 122 // Store the key 123 err = csp.ks.StoreKey(k) 124 if err != nil { 125 return nil, errors.Wrapf(err, "Failed storing key [%s]", opts.Algorithm()) 126 } 127 } 128 129 return k, nil 130 } 131 132 // KeyImport imports a key from its raw representation using opts. 133 // The opts argument should be appropriate for the primitive used. 134 func (csp *CSP) KeyImport(raw interface{}, opts bccsp.KeyImportOpts) (k bccsp.Key, err error) { 135 // Validate arguments 136 if raw == nil { 137 return nil, errors.New("Invalid raw. It must not be nil.") 138 } 139 if opts == nil { 140 return nil, errors.New("Invalid opts. It must not be nil.") 141 } 142 143 keyImporter, found := csp.KeyImporters[reflect.TypeOf(opts)] 144 if !found { 145 return nil, errors.Errorf("Unsupported 'KeyImportOpts' provided [%v]", opts) 146 } 147 148 k, err = keyImporter.KeyImport(raw, opts) 149 if err != nil { 150 return nil, errors.Wrapf(err, "Failed importing key with opts [%v]", opts) 151 } 152 153 // If the key is not Ephemeral, store it. 154 if !opts.Ephemeral() { 155 // Store the key 156 err = csp.ks.StoreKey(k) 157 if err != nil { 158 return nil, errors.Wrapf(err, "Failed storing imported key with opts [%v]", opts) 159 } 160 } 161 162 return 163 } 164 165 // GetKey returns the key this CSP associates to 166 // the Subject Key Identifier ski. 167 func (csp *CSP) GetKey(ski []byte) (k bccsp.Key, err error) { 168 k, err = csp.ks.GetKey(ski) 169 if err != nil { 170 return nil, errors.Wrapf(err, "Failed getting key for SKI [%v]", ski) 171 } 172 173 return 174 } 175 176 // Hash hashes messages msg using options opts. 177 func (csp *CSP) Hash(msg []byte, opts bccsp.HashOpts) (digest []byte, err error) { 178 // Validate arguments 179 if opts == nil { 180 return nil, errors.New("Invalid opts. It must not be nil.") 181 } 182 183 hasher, found := csp.Hashers[reflect.TypeOf(opts)] 184 if !found { 185 return nil, errors.Errorf("Unsupported 'HashOpt' provided [%v]", opts) 186 } 187 188 digest, err = hasher.Hash(msg, opts) 189 if err != nil { 190 return nil, errors.Wrapf(err, "Failed hashing with opts [%v]", opts) 191 } 192 193 return 194 } 195 196 // GetHash returns and instance of hash.Hash using options opts. 197 // If opts is nil then the default hash function is returned. 198 func (csp *CSP) GetHash(opts bccsp.HashOpts) (h hash.Hash, err error) { 199 // Validate arguments 200 if opts == nil { 201 return nil, errors.New("Invalid opts. It must not be nil.") 202 } 203 204 hasher, found := csp.Hashers[reflect.TypeOf(opts)] 205 if !found { 206 return nil, errors.Errorf("Unsupported 'HashOpt' provided [%v]", opts) 207 } 208 209 h, err = hasher.GetHash(opts) 210 if err != nil { 211 return nil, errors.Wrapf(err, "Failed getting hash function with opts [%v]", opts) 212 } 213 214 return 215 } 216 217 // Sign signs digest using key k. 218 // The opts argument should be appropriate for the primitive used. 219 // 220 // Note that when a signature of a hash of a larger message is needed, 221 // the caller is responsible for hashing the larger message and passing 222 // the hash (as digest). 223 func (csp *CSP) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) { 224 // Validate arguments 225 if k == nil { 226 return nil, errors.New("Invalid Key. It must not be nil.") 227 } 228 if len(digest) == 0 { 229 return nil, errors.New("Invalid digest. Cannot be empty.") 230 } 231 232 keyType := reflect.TypeOf(k) 233 signer, found := csp.Signers[keyType] 234 if !found { 235 return nil, errors.Errorf("Unsupported 'SignKey' provided [%s]", keyType) 236 } 237 238 signature, err = signer.Sign(k, digest, opts) 239 if err != nil { 240 return nil, errors.Wrapf(err, "Failed signing with opts [%v]", opts) 241 } 242 243 return 244 } 245 246 // Verify verifies signature against key k and digest 247 func (csp *CSP) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) { 248 // Validate arguments 249 if k == nil { 250 return false, errors.New("Invalid Key. It must not be nil.") 251 } 252 if len(signature) == 0 { 253 return false, errors.New("Invalid signature. Cannot be empty.") 254 } 255 if len(digest) == 0 { 256 return false, errors.New("Invalid digest. Cannot be empty.") 257 } 258 259 verifier, found := csp.Verifiers[reflect.TypeOf(k)] 260 if !found { 261 return false, errors.Errorf("Unsupported 'VerifyKey' provided [%v]", k) 262 } 263 264 valid, err = verifier.Verify(k, signature, digest, opts) 265 if err != nil { 266 return false, errors.Wrapf(err, "Failed verifing with opts [%v]", opts) 267 } 268 269 return 270 } 271 272 // Encrypt encrypts plaintext using key k. 273 // The opts argument should be appropriate for the primitive used. 274 func (csp *CSP) Encrypt(k bccsp.Key, plaintext []byte, opts bccsp.EncrypterOpts) ([]byte, error) { 275 // Validate arguments 276 if k == nil { 277 return nil, errors.New("Invalid Key. It must not be nil.") 278 } 279 280 encryptor, found := csp.Encryptors[reflect.TypeOf(k)] 281 if !found { 282 return nil, errors.Errorf("Unsupported 'EncryptKey' provided [%v]", k) 283 } 284 285 return encryptor.Encrypt(k, plaintext, opts) 286 } 287 288 // Decrypt decrypts ciphertext using key k. 289 // The opts argument should be appropriate for the primitive used. 290 func (csp *CSP) Decrypt(k bccsp.Key, ciphertext []byte, opts bccsp.DecrypterOpts) (plaintext []byte, err error) { 291 // Validate arguments 292 if k == nil { 293 return nil, errors.New("Invalid Key. It must not be nil.") 294 } 295 296 decryptor, found := csp.Decryptors[reflect.TypeOf(k)] 297 if !found { 298 return nil, errors.Errorf("Unsupported 'DecryptKey' provided [%v]", k) 299 } 300 301 plaintext, err = decryptor.Decrypt(k, ciphertext, opts) 302 if err != nil { 303 return nil, errors.Wrapf(err, "Failed decrypting with opts [%v]", opts) 304 } 305 306 return 307 } 308 309 // AddWrapper binds the passed type to the passed wrapper. 310 // Notice that that wrapper must be an instance of one of the following interfaces: 311 // KeyGenerator, KeyDeriver, KeyImporter, Encryptor, Decryptor, Signer, Verifier, Hasher. 312 func (csp *CSP) AddWrapper(t reflect.Type, w interface{}) error { 313 if t == nil { 314 return errors.Errorf("type cannot be nil") 315 } 316 if w == nil { 317 return errors.Errorf("wrapper cannot be nil") 318 } 319 switch dt := w.(type) { 320 case KeyGenerator: 321 csp.KeyGenerators[t] = dt 322 case KeyImporter: 323 csp.KeyImporters[t] = dt 324 case KeyDeriver: 325 csp.KeyDerivers[t] = dt 326 case Encryptor: 327 csp.Encryptors[t] = dt 328 case Decryptor: 329 csp.Decryptors[t] = dt 330 case Signer: 331 csp.Signers[t] = dt 332 case Verifier: 333 csp.Verifiers[t] = dt 334 case Hasher: 335 csp.Hashers[t] = dt 336 default: 337 return errors.Errorf("wrapper type not valid, must be on of: KeyGenerator, KeyDeriver, KeyImporter, Encryptor, Decryptor, Signer, Verifier, Hasher") 338 } 339 return nil 340 }