github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/core/comm/testdata/certs/generate.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  // +build ignore
    18  
    19  //go:generate -command gencerts go run $GOPATH/src/github.com/hyperledger/fabric/core/comm/testdata/certs/generate.go
    20  //go:generate gencerts -orgs 2 -child-orgs 2 -servers 2 -clients 2
    21  
    22  package main
    23  
    24  import (
    25  	"crypto/ecdsa"
    26  	"crypto/elliptic"
    27  	"crypto/rand"
    28  	"crypto/x509"
    29  	"crypto/x509/pkix"
    30  	"encoding/pem"
    31  	"flag"
    32  	"fmt"
    33  	"math/big"
    34  	"os"
    35  	"time"
    36  )
    37  
    38  //command line flags
    39  var (
    40  	numOrgs        = flag.Int("orgs", 2, "number of unique organizations")
    41  	numChildOrgs   = flag.Int("child-orgs", 2, "number of intermediaries per organization")
    42  	numClientCerts = flag.Int("clients", 1, "number of client certificates per organization")
    43  	numServerCerts = flag.Int("servers", 1, "number of server certificates per organization")
    44  )
    45  
    46  //default template for X509 subject
    47  func subjectTemplate() pkix.Name {
    48  	return pkix.Name{
    49  		Country:  []string{"US"},
    50  		Locality: []string{"San Francisco"},
    51  		Province: []string{"California"},
    52  	}
    53  }
    54  
    55  //default template for X509 certificates
    56  func x509Template() (x509.Certificate, error) {
    57  
    58  	//generate a serial number
    59  	serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
    60  	serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
    61  	if err != nil {
    62  		return x509.Certificate{}, err
    63  	}
    64  
    65  	now := time.Now()
    66  	//basic template to use
    67  	x509 := x509.Certificate{
    68  		SerialNumber:          serialNumber,
    69  		NotBefore:             now,
    70  		NotAfter:              now.Add(3650 * 24 * time.Hour), //~ten years
    71  		KeyUsage:              x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
    72  		BasicConstraintsValid: true,
    73  	}
    74  	return x509, nil
    75  
    76  }
    77  
    78  //generate an EC private key (P256 curve)
    79  func genKeyECDSA(name string) (*ecdsa.PrivateKey, error) {
    80  	priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  	//write key out to file
    85  	keyBytes, err := x509.MarshalECPrivateKey(priv)
    86  	keyFile, err := os.OpenFile(name+"-key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
    87  	if err != nil {
    88  		return nil, err
    89  	}
    90  	pem.Encode(keyFile, &pem.Block{Type: "EC PRIVATE KEY", Bytes: keyBytes})
    91  	keyFile.Close()
    92  	return priv, nil
    93  }
    94  
    95  //generate a signed X509 certficate using ECDSA
    96  func genCertificateECDSA(name string, template, parent *x509.Certificate, pub *ecdsa.PublicKey,
    97  	priv *ecdsa.PrivateKey) (*x509.Certificate, error) {
    98  
    99  	//create the x509 public cert
   100  	certBytes, err := x509.CreateCertificate(rand.Reader, template, parent, pub, priv)
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  
   105  	//write cert out to file
   106  	certFile, err := os.Create(name + "-cert.pem")
   107  	if err != nil {
   108  		return nil, err
   109  	}
   110  	//pem encode the cert
   111  	pem.Encode(certFile, &pem.Block{Type: "CERTIFICATE", Bytes: certBytes})
   112  	certFile.Close()
   113  
   114  	x509Cert, err := x509.ParseCertificate(certBytes)
   115  	if err != nil {
   116  		return nil, err
   117  	}
   118  	return x509Cert, nil
   119  }
   120  
   121  //generate an EC certificate appropriate for use by a TLS server
   122  func genServerCertificateECDSA(name string, signKey *ecdsa.PrivateKey, signCert *x509.Certificate) error {
   123  	fmt.Println(name)
   124  	key, err := genKeyECDSA(name)
   125  	template, err := x509Template()
   126  
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth,
   132  		x509.ExtKeyUsageClientAuth}
   133  
   134  	//set the organization for the subject
   135  	subject := subjectTemplate()
   136  	subject.Organization = []string{name}
   137  	//hardcode to localhost for hostname verification
   138  	subject.CommonName = "localhost"
   139  
   140  	template.Subject = subject
   141  
   142  	_, err = genCertificateECDSA(name, &template, signCert, &key.PublicKey, signKey)
   143  
   144  	if err != nil {
   145  		return err
   146  	}
   147  
   148  	return nil
   149  }
   150  
   151  //generate an EC certificate appropriate for use by a TLS server
   152  func genClientCertificateECDSA(name string, signKey *ecdsa.PrivateKey, signCert *x509.Certificate) error {
   153  	fmt.Println(name)
   154  	key, err := genKeyECDSA(name)
   155  	template, err := x509Template()
   156  
   157  	if err != nil {
   158  		return err
   159  	}
   160  
   161  	template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
   162  
   163  	//set the organization for the subject
   164  	subject := subjectTemplate()
   165  	subject.Organization = []string{name}
   166  	subject.CommonName = name
   167  
   168  	template.Subject = subject
   169  
   170  	_, err = genCertificateECDSA(name, &template, signCert, &key.PublicKey, signKey)
   171  
   172  	if err != nil {
   173  		return err
   174  	}
   175  
   176  	return nil
   177  }
   178  
   179  //generate an EC certificate signing(CA) key pair and output as
   180  //PEM-encoded files
   181  func genCertificateAuthorityECDSA(name string) (*ecdsa.PrivateKey, *x509.Certificate, error) {
   182  
   183  	key, err := genKeyECDSA(name)
   184  	template, err := x509Template()
   185  
   186  	if err != nil {
   187  		return nil, nil, err
   188  	}
   189  
   190  	//this is a CA
   191  	template.IsCA = true
   192  	template.KeyUsage |= x509.KeyUsageCertSign | x509.KeyUsageCRLSign
   193  	template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
   194  
   195  	//set the organization for the subject
   196  	subject := subjectTemplate()
   197  	subject.Organization = []string{name}
   198  	subject.CommonName = name
   199  
   200  	template.Subject = subject
   201  	template.SubjectKeyId = []byte{1, 2, 3, 4}
   202  
   203  	x509Cert, err := genCertificateECDSA(name, &template, &template, &key.PublicKey, key)
   204  
   205  	if err != nil {
   206  		return nil, nil, err
   207  	}
   208  	return key, x509Cert, nil
   209  }
   210  
   211  //generate an EC certificate appropriate for use by a TLS server
   212  func genIntermediateCertificateAuthorityECDSA(name string, signKey *ecdsa.PrivateKey,
   213  	signCert *x509.Certificate) (*ecdsa.PrivateKey, *x509.Certificate, error) {
   214  
   215  	fmt.Println(name)
   216  	key, err := genKeyECDSA(name)
   217  	template, err := x509Template()
   218  
   219  	if err != nil {
   220  		return nil, nil, err
   221  	}
   222  
   223  	//this is a CA
   224  	template.IsCA = true
   225  	template.KeyUsage |= x509.KeyUsageCertSign | x509.KeyUsageCRLSign
   226  	template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
   227  
   228  	//set the organization for the subject
   229  	subject := subjectTemplate()
   230  	subject.Organization = []string{name}
   231  	subject.CommonName = name
   232  
   233  	template.Subject = subject
   234  
   235  	x509Cert, err := genCertificateECDSA(name, &template, signCert, &key.PublicKey, signKey)
   236  
   237  	if err != nil {
   238  		return nil, nil, err
   239  	}
   240  	return key, x509Cert, nil
   241  }
   242  
   243  func main() {
   244  
   245  	//parse the command line flags
   246  	flag.Parse()
   247  
   248  	fmt.Printf("Generating %d organizations each with %d server(s) and %d client(s)\n",
   249  		*numOrgs, *numServerCerts, *numClientCerts)
   250  
   251  	baseOrgName := "Org"
   252  	//generate orgs / CAs
   253  	for i := 1; i <= *numOrgs; i++ {
   254  		signKey, signCert, err := genCertificateAuthorityECDSA(fmt.Sprintf(baseOrgName+"%d", i))
   255  		if err != nil {
   256  			fmt.Printf("error generating CA %s%d : %s\n", baseOrgName, i, err.Error())
   257  		}
   258  		//generate server certificates for the org
   259  		for j := 1; j <= *numServerCerts; j++ {
   260  			err := genServerCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-server%d", i, j), signKey, signCert)
   261  			if err != nil {
   262  				fmt.Printf("error generating server certificate for %s%d-server%d : %s\n",
   263  					baseOrgName, i, j, err.Error())
   264  			}
   265  		}
   266  		//generate client certificates for the org
   267  		for k := 1; k <= *numClientCerts; k++ {
   268  			err := genClientCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-client%d", i, k), signKey, signCert)
   269  			if err != nil {
   270  				fmt.Printf("error generating client certificate for %s%d-client%d : %s\n",
   271  					baseOrgName, i, k, err.Error())
   272  			}
   273  		}
   274  		//generate child orgs (intermediary authorities)
   275  		for m := 1; m <= *numChildOrgs; m++ {
   276  			childSignKey, childSignCert, err := genIntermediateCertificateAuthorityECDSA(
   277  				fmt.Sprintf(baseOrgName+"%d-child%d", i, m), signKey, signCert)
   278  			if err != nil {
   279  				fmt.Printf("error generating CA %s%d-child%d : %s\n",
   280  					baseOrgName, i, m, err.Error())
   281  			}
   282  			//generate server certificates for the child org
   283  			for n := 1; n <= *numServerCerts; n++ {
   284  				err := genServerCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-child%d-server%d", i, m, n),
   285  					childSignKey, childSignCert)
   286  				if err != nil {
   287  					fmt.Printf("error generating server certificate for %s%d-child%d-server%d : %s\n",
   288  						baseOrgName, i, m, n, err.Error())
   289  				}
   290  			}
   291  			//generate client certificates for the child org
   292  			for p := 1; p <= *numClientCerts; p++ {
   293  				err := genClientCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-child%d-client%d", i, m, p),
   294  					childSignKey, childSignCert)
   295  				if err != nil {
   296  					fmt.Printf("error generating server certificate for %s%d-child%d-client%d : %s\n",
   297  						baseOrgName, i, m, p, err.Error())
   298  				}
   299  			}
   300  		}
   301  	}
   302  
   303  }