github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/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  
   133  	//set the organization for the subject
   134  	subject := subjectTemplate()
   135  	subject.Organization = []string{name}
   136  	//hardcode to localhost for hostname verification
   137  	subject.CommonName = "localhost"
   138  
   139  	template.Subject = subject
   140  
   141  	_, err = genCertificateECDSA(name, &template, signCert, &key.PublicKey, signKey)
   142  
   143  	if err != nil {
   144  		return err
   145  	}
   146  
   147  	return nil
   148  }
   149  
   150  //generate an EC certificate appropriate for use by a TLS server
   151  func genClientCertificateECDSA(name string, signKey *ecdsa.PrivateKey, signCert *x509.Certificate) error {
   152  	fmt.Println(name)
   153  	key, err := genKeyECDSA(name)
   154  	template, err := x509Template()
   155  
   156  	if err != nil {
   157  		return err
   158  	}
   159  
   160  	template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}
   161  
   162  	//set the organization for the subject
   163  	subject := subjectTemplate()
   164  	subject.Organization = []string{name}
   165  	subject.CommonName = name
   166  
   167  	template.Subject = subject
   168  
   169  	_, err = genCertificateECDSA(name, &template, signCert, &key.PublicKey, signKey)
   170  
   171  	if err != nil {
   172  		return err
   173  	}
   174  
   175  	return nil
   176  }
   177  
   178  //generate an EC certificate signing(CA) key pair and output as
   179  //PEM-encoded files
   180  func genCertificateAuthorityECDSA(name string) (*ecdsa.PrivateKey, *x509.Certificate, error) {
   181  
   182  	key, err := genKeyECDSA(name)
   183  	template, err := x509Template()
   184  
   185  	if err != nil {
   186  		return nil, nil, err
   187  	}
   188  
   189  	//this is a CA
   190  	template.IsCA = true
   191  	template.KeyUsage |= x509.KeyUsageCertSign | x509.KeyUsageCRLSign
   192  	template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
   193  
   194  	//set the organization for the subject
   195  	subject := subjectTemplate()
   196  	subject.Organization = []string{name}
   197  	subject.CommonName = name
   198  
   199  	template.Subject = subject
   200  
   201  	x509Cert, err := genCertificateECDSA(name, &template, &template, &key.PublicKey, key)
   202  
   203  	if err != nil {
   204  		return nil, nil, err
   205  	}
   206  	return key, x509Cert, nil
   207  }
   208  
   209  //generate an EC certificate appropriate for use by a TLS server
   210  func genIntermediateCertificateAuthorityECDSA(name string, signKey *ecdsa.PrivateKey,
   211  	signCert *x509.Certificate) (*ecdsa.PrivateKey, *x509.Certificate, error) {
   212  
   213  	fmt.Println(name)
   214  	key, err := genKeyECDSA(name)
   215  	template, err := x509Template()
   216  
   217  	if err != nil {
   218  		return nil, nil, err
   219  	}
   220  
   221  	//this is a CA
   222  	template.IsCA = true
   223  	template.KeyUsage |= x509.KeyUsageCertSign | x509.KeyUsageCRLSign
   224  	template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageAny}
   225  
   226  	//set the organization for the subject
   227  	subject := subjectTemplate()
   228  	subject.Organization = []string{name}
   229  	subject.CommonName = name
   230  
   231  	template.Subject = subject
   232  
   233  	x509Cert, err := genCertificateECDSA(name, &template, signCert, &key.PublicKey, signKey)
   234  
   235  	if err != nil {
   236  		return nil, nil, err
   237  	}
   238  	return key, x509Cert, nil
   239  }
   240  
   241  func main() {
   242  
   243  	//parse the command line flags
   244  	flag.Parse()
   245  
   246  	fmt.Printf("Generating %d organizations each with %d server(s) and %d client(s)\n",
   247  		*numOrgs, *numServerCerts, *numClientCerts)
   248  
   249  	baseOrgName := "Org"
   250  	//generate orgs / CAs
   251  	for i := 1; i <= *numOrgs; i++ {
   252  		signKey, signCert, err := genCertificateAuthorityECDSA(fmt.Sprintf(baseOrgName+"%d", i))
   253  		if err != nil {
   254  			fmt.Printf("error generating CA %s%d : %s\n", baseOrgName, i, err.Error())
   255  		}
   256  		//generate server certificates for the org
   257  		for j := 1; j <= *numServerCerts; j++ {
   258  			err := genServerCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-server%d", i, j), signKey, signCert)
   259  			if err != nil {
   260  				fmt.Printf("error generating server certificate for %s%d-server%d : %s\n",
   261  					baseOrgName, i, j, err.Error())
   262  			}
   263  		}
   264  		//generate client certificates for the org
   265  		for k := 1; k <= *numServerCerts; k++ {
   266  			err := genClientCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-client%d", i, k), signKey, signCert)
   267  			if err != nil {
   268  				fmt.Printf("error generating client certificate for %s%d-client%d : %s\n",
   269  					baseOrgName, i, k, err.Error())
   270  			}
   271  		}
   272  		//generate child orgs (intermediary authorities)
   273  		for m := 1; m <= *numChildOrgs; m++ {
   274  			childSignKey, childSignCert, err := genIntermediateCertificateAuthorityECDSA(
   275  				fmt.Sprintf(baseOrgName+"%d-child%d", i, m), signKey, signCert)
   276  			if err != nil {
   277  				fmt.Printf("error generating CA %s%d-child%d : %s\n",
   278  					baseOrgName, i, m, err.Error())
   279  			}
   280  			//generate server certificates for the child org
   281  			for n := 1; n <= *numServerCerts; n++ {
   282  				err := genServerCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-child%d-server%d", i, m, n),
   283  					childSignKey, childSignCert)
   284  				if err != nil {
   285  					fmt.Printf("error generating server certificate for %s%d-child%d-server%d : %s\n",
   286  						baseOrgName, i, m, n, err.Error())
   287  				}
   288  			}
   289  			//generate client certificates for the child org
   290  			for p := 1; p <= *numClientCerts; p++ {
   291  				err := genClientCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-child%d-client%d", i, m, p),
   292  					childSignKey, childSignCert)
   293  				if err != nil {
   294  					fmt.Printf("error generating server certificate for %s%d-child%d-client%d : %s\n",
   295  						baseOrgName, i, m, p, err.Error())
   296  				}
   297  			}
   298  		}
   299  	}
   300  
   301  }