github.com/lzy4123/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 }