github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/common/tools/cryptogen/msp/generator.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 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 msp
    17  
    18  import (
    19  	"crypto/x509"
    20  	"encoding/pem"
    21  	"os"
    22  	"path/filepath"
    23  
    24  	"encoding/hex"
    25  	"io"
    26  
    27  	"github.com/hyperledger/fabric/bccsp"
    28  	"github.com/hyperledger/fabric/common/tools/cryptogen/ca"
    29  	"github.com/hyperledger/fabric/common/tools/cryptogen/csp"
    30  )
    31  
    32  func GenerateLocalMSP(baseDir, name string, sans []string, rootCA *ca.CA) error {
    33  
    34  	// create folder structure
    35  	mspDir := filepath.Join(baseDir, "msp")
    36  	tlsDir := filepath.Join(baseDir, "tls")
    37  
    38  	err := createFolderStructure(mspDir)
    39  	if err != nil {
    40  		return err
    41  	}
    42  
    43  	err = os.MkdirAll(tlsDir, 0755)
    44  	if err != nil {
    45  		return err
    46  	}
    47  
    48  	// get keystore path
    49  	keystore := filepath.Join(mspDir, "keystore")
    50  
    51  	// generate private key
    52  	priv, _, err := csp.GeneratePrivateKey(keystore)
    53  	if err != nil {
    54  		return err
    55  	}
    56  
    57  	// get public signing certificate
    58  	ecPubKey, err := csp.GetECPublicKey(priv)
    59  	if err != nil {
    60  		return err
    61  	}
    62  
    63  	cert, err := rootCA.SignCertificate(filepath.Join(mspDir, "signcerts"), name, sans, ecPubKey)
    64  	if err != nil {
    65  		return err
    66  	}
    67  
    68  	// write artifacts to MSP folders
    69  	folders := []string{"admincerts", "cacerts"}
    70  	for _, folder := range folders {
    71  		err = x509Export(filepath.Join(mspDir, folder, x509Filename(rootCA.Name)), rootCA.SignCert)
    72  		if err != nil {
    73  			return err
    74  		}
    75  	}
    76  
    77  	// write artifacts to TLS folder
    78  	err = x509Export(filepath.Join(tlsDir, "ca.crt"), rootCA.SignCert)
    79  	if err != nil {
    80  		return err
    81  	}
    82  
    83  	err = x509Export(filepath.Join(tlsDir, "server.crt"), cert)
    84  	if err != nil {
    85  		return err
    86  	}
    87  
    88  	err = keyExport(keystore, filepath.Join(tlsDir, "server.key"), priv)
    89  	if err != nil {
    90  		return err
    91  	}
    92  
    93  	return nil
    94  }
    95  
    96  func GenerateVerifyingMSP(baseDir string, rootCA *ca.CA) error {
    97  
    98  	// create folder structure
    99  	err := createFolderStructure(baseDir)
   100  	if err == nil {
   101  		// write MSP cert to appropriate folders
   102  		folders := []string{"admincerts", "cacerts", "signcerts"}
   103  		for _, folder := range folders {
   104  			err = x509Export(filepath.Join(baseDir, folder, x509Filename(rootCA.Name)), rootCA.SignCert)
   105  			if err != nil {
   106  				return err
   107  			}
   108  		}
   109  	}
   110  
   111  	return nil
   112  }
   113  
   114  func createFolderStructure(rootDir string) error {
   115  
   116  	// create admincerts, cacerts, keystore and signcerts folders
   117  	folders := []string{
   118  		filepath.Join(rootDir, "admincerts"),
   119  		filepath.Join(rootDir, "cacerts"),
   120  		filepath.Join(rootDir, "keystore"),
   121  		filepath.Join(rootDir, "signcerts"),
   122  	}
   123  
   124  	for _, folder := range folders {
   125  		err := os.MkdirAll(folder, 0755)
   126  		if err != nil {
   127  			return err
   128  		}
   129  	}
   130  
   131  	return nil
   132  }
   133  
   134  func x509Filename(name string) string {
   135  	return name + "-cert.pem"
   136  }
   137  
   138  func x509Export(path string, cert *x509.Certificate) error {
   139  	return pemExport(path, "CERTIFICATE", cert.Raw)
   140  }
   141  
   142  func copyFile(src, dst string) error {
   143  	in, err := os.Open(src)
   144  	if err != nil {
   145  		return err
   146  	}
   147  	defer in.Close()
   148  	out, err := os.Create(dst)
   149  	if err != nil {
   150  		return err
   151  	}
   152  	defer out.Close()
   153  	_, err = io.Copy(out, in)
   154  	cerr := out.Close()
   155  	if err != nil {
   156  		return err
   157  	}
   158  	return cerr
   159  }
   160  
   161  func keyExport(keystore, output string, key bccsp.Key) error {
   162  	id := hex.EncodeToString(key.SKI())
   163  
   164  	return copyFile(filepath.Join(keystore, id+"_sk"), output)
   165  }
   166  
   167  func pemExport(path, pemType string, bytes []byte) error {
   168  	//write pem out to file
   169  	file, err := os.Create(path)
   170  	if err != nil {
   171  		return err
   172  	}
   173  	defer file.Close()
   174  
   175  	return pem.Encode(file, &pem.Block{Type: pemType, Bytes: bytes})
   176  }