github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/bccsp/signer/signer.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 signer
    17  
    18  import (
    19  	"crypto"
    20  	"errors"
    21  	"fmt"
    22  	"io"
    23  
    24  	"github.com/hyperledger/fabric/bccsp"
    25  	"github.com/hyperledger/fabric/bccsp/utils"
    26  )
    27  
    28  // CryptoSigner is the BCCSP-based implementation of a crypto.Signer
    29  type CryptoSigner struct {
    30  	csp bccsp.BCCSP
    31  	key bccsp.Key
    32  	pk  interface{}
    33  }
    34  
    35  // Init initializes this CryptoSigner.
    36  func (s *CryptoSigner) Init(csp bccsp.BCCSP, key bccsp.Key) error {
    37  	// Validate arguments
    38  	if csp == nil {
    39  		return errors.New("Invalid BCCSP. Nil.")
    40  	}
    41  	if key == nil {
    42  		return errors.New("Invalid Key. Nil.")
    43  	}
    44  	if key.Symmetric() {
    45  		return errors.New("Invalid Key. Symmetric.")
    46  	}
    47  
    48  	// Marshall the bccsp public key as a crypto.PublicKey
    49  	pub, err := key.PublicKey()
    50  	if err != nil {
    51  		return fmt.Errorf("Failed getting public key [%s]", err)
    52  	}
    53  
    54  	raw, err := pub.Bytes()
    55  	if err != nil {
    56  		return fmt.Errorf("Failed marshalling public key [%s]", err)
    57  	}
    58  
    59  	pk, err := utils.DERToPublicKey(raw)
    60  	if err != nil {
    61  		return fmt.Errorf("Failed marshalling public key [%s]", err)
    62  	}
    63  
    64  	// Init fields
    65  	s.csp = csp
    66  	s.key = key
    67  	s.pk = pk
    68  
    69  	return nil
    70  
    71  }
    72  
    73  // Public returns the public key corresponding to the opaque,
    74  // private key.
    75  func (s *CryptoSigner) Public() crypto.PublicKey {
    76  	return s.pk
    77  }
    78  
    79  // Sign signs digest with the private key, possibly using entropy from
    80  // rand. For an RSA key, the resulting signature should be either a
    81  // PKCS#1 v1.5 or PSS signature (as indicated by opts). For an (EC)DSA
    82  // key, it should be a DER-serialised, ASN.1 signature structure.
    83  //
    84  // Hash implements the SignerOpts interface and, in most cases, one can
    85  // simply pass in the hash function used as opts. Sign may also attempt
    86  // to type assert opts to other types in order to obtain algorithm
    87  // specific values. See the documentation in each package for details.
    88  //
    89  // Note that when a signature of a hash of a larger message is needed,
    90  // the caller is responsible for hashing the larger message and passing
    91  // the hash (as digest) and the hash function (as opts) to Sign.
    92  func (s *CryptoSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
    93  	if opts == nil {
    94  		return s.csp.Sign(s.key, digest, nil)
    95  	}
    96  
    97  	so, ok := opts.(bccsp.SignerOpts)
    98  	if !ok {
    99  		return nil, errors.New("Invalid opts type. Expecting bccsp.SignerOpts")
   100  	}
   101  
   102  	return s.csp.Sign(s.key, digest, so)
   103  }