github.com/true-sqn/fabric@v2.1.1+incompatible/internal/pkg/comm/testdata/certs/generate.go (about)

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