github.com/yimialmonte/fabric@v2.1.1+incompatible/common/tools/idemixgen/idemixca/idemixca.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package idemixca
     8  
     9  import (
    10  	"crypto/ecdsa"
    11  
    12  	"github.com/golang/protobuf/proto"
    13  	"github.com/hyperledger/fabric-amcl/amcl/FP256BN"
    14  	m "github.com/hyperledger/fabric-protos-go/msp"
    15  	"github.com/hyperledger/fabric/idemix"
    16  	"github.com/hyperledger/fabric/msp"
    17  	"github.com/pkg/errors"
    18  )
    19  
    20  // GenerateIssuerKey invokes Idemix library to generate an issuer (CA) signing key pair.
    21  // Currently four attributes are supported by the issuer:
    22  // AttributeNameOU is the organization unit name
    23  // AttributeNameRole is the role (member or admin) name
    24  // AttributeNameEnrollmentId is the enrollment id
    25  // AttributeNameRevocationHandle contains the revocation handle, which can be used to revoke this user
    26  // Generated keys are serialized to bytes.
    27  func GenerateIssuerKey() ([]byte, []byte, error) {
    28  	rng, err := idemix.GetRand()
    29  	if err != nil {
    30  		return nil, nil, err
    31  	}
    32  	AttributeNames := []string{msp.AttributeNameOU, msp.AttributeNameRole, msp.AttributeNameEnrollmentId, msp.AttributeNameRevocationHandle}
    33  	key, err := idemix.NewIssuerKey(AttributeNames, rng)
    34  	if err != nil {
    35  		return nil, nil, errors.WithMessage(err, "cannot generate CA key")
    36  	}
    37  	ipkSerialized, err := proto.Marshal(key.Ipk)
    38  
    39  	return key.Isk, ipkSerialized, err
    40  }
    41  
    42  // GenerateSignerConfig creates a new signer config.
    43  // It generates a fresh user secret and issues a credential
    44  // with four attributes (described above) using the CA's key pair.
    45  func GenerateSignerConfig(roleMask int, ouString string, enrollmentId string, revocationHandle int, key *idemix.IssuerKey, revKey *ecdsa.PrivateKey) ([]byte, error) {
    46  	attrs := make([]*FP256BN.BIG, 4)
    47  
    48  	if ouString == "" {
    49  		return nil, errors.Errorf("the OU attribute value is empty")
    50  	}
    51  
    52  	if enrollmentId == "" {
    53  		return nil, errors.Errorf("the enrollment id value is empty")
    54  	}
    55  
    56  	attrs[msp.AttributeIndexOU] = idemix.HashModOrder([]byte(ouString))
    57  	attrs[msp.AttributeIndexRole] = FP256BN.NewBIGint(roleMask)
    58  	attrs[msp.AttributeIndexEnrollmentId] = idemix.HashModOrder([]byte(enrollmentId))
    59  	attrs[msp.AttributeIndexRevocationHandle] = FP256BN.NewBIGint(revocationHandle)
    60  
    61  	rng, err := idemix.GetRand()
    62  	if err != nil {
    63  		return nil, errors.WithMessage(err, "Error getting PRNG")
    64  	}
    65  	sk := idemix.RandModOrder(rng)
    66  	ni := idemix.BigToBytes(idemix.RandModOrder(rng))
    67  	msg := idemix.NewCredRequest(sk, ni, key.Ipk, rng)
    68  	cred, err := idemix.NewCredential(key, msg, attrs, rng)
    69  	if err != nil {
    70  		return nil, errors.WithMessage(err, "failed to generate a credential")
    71  	}
    72  
    73  	credBytes, err := proto.Marshal(cred)
    74  	if err != nil {
    75  		return nil, errors.WithMessage(err, "failed to marshal credential")
    76  	}
    77  
    78  	// NOTE currently, idemixca creates CRI's with "ALG_NO_REVOCATION"
    79  	cri, err := idemix.CreateCRI(revKey, []*FP256BN.BIG{FP256BN.NewBIGint(revocationHandle)}, 0, idemix.ALG_NO_REVOCATION, rng)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	criBytes, err := proto.Marshal(cri)
    84  	if err != nil {
    85  		return nil, errors.WithMessage(err, "failed to marshal CRI")
    86  	}
    87  
    88  	signer := &m.IdemixMSPSignerConfig{
    89  		Cred:                            credBytes,
    90  		Sk:                              idemix.BigToBytes(sk),
    91  		OrganizationalUnitIdentifier:    ouString,
    92  		Role:                            int32(roleMask),
    93  		EnrollmentId:                    enrollmentId,
    94  		CredentialRevocationInformation: criBytes,
    95  	}
    96  
    97  	return proto.Marshal(signer)
    98  }