github.com/tenywen/fabric@v1.0.0-beta.0.20170620030522-a5b1ed380643/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 template.SubjectKeyId = []byte{1, 2, 3, 4} 235 236 x509Cert, err := genCertificateECDSA(name, &template, signCert, &key.PublicKey, signKey) 237 238 if err != nil { 239 return nil, nil, err 240 } 241 return key, x509Cert, nil 242 } 243 244 func main() { 245 246 //parse the command line flags 247 flag.Parse() 248 249 fmt.Printf("Generating %d organizations each with %d server(s) and %d client(s)\n", 250 *numOrgs, *numServerCerts, *numClientCerts) 251 252 baseOrgName := "Org" 253 //generate orgs / CAs 254 for i := 1; i <= *numOrgs; i++ { 255 signKey, signCert, err := genCertificateAuthorityECDSA(fmt.Sprintf(baseOrgName+"%d", i)) 256 if err != nil { 257 fmt.Printf("error generating CA %s%d : %s\n", baseOrgName, i, err.Error()) 258 } 259 //generate server certificates for the org 260 for j := 1; j <= *numServerCerts; j++ { 261 err := genServerCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-server%d", i, j), signKey, signCert) 262 if err != nil { 263 fmt.Printf("error generating server certificate for %s%d-server%d : %s\n", 264 baseOrgName, i, j, err.Error()) 265 } 266 } 267 //generate client certificates for the org 268 for k := 1; k <= *numClientCerts; k++ { 269 err := genClientCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-client%d", i, k), signKey, signCert) 270 if err != nil { 271 fmt.Printf("error generating client certificate for %s%d-client%d : %s\n", 272 baseOrgName, i, k, err.Error()) 273 } 274 } 275 //generate child orgs (intermediary authorities) 276 for m := 1; m <= *numChildOrgs; m++ { 277 childSignKey, childSignCert, err := genIntermediateCertificateAuthorityECDSA( 278 fmt.Sprintf(baseOrgName+"%d-child%d", i, m), signKey, signCert) 279 if err != nil { 280 fmt.Printf("error generating CA %s%d-child%d : %s\n", 281 baseOrgName, i, m, err.Error()) 282 } 283 //generate server certificates for the child org 284 for n := 1; n <= *numServerCerts; n++ { 285 err := genServerCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-child%d-server%d", i, m, n), 286 childSignKey, childSignCert) 287 if err != nil { 288 fmt.Printf("error generating server certificate for %s%d-child%d-server%d : %s\n", 289 baseOrgName, i, m, n, err.Error()) 290 } 291 } 292 //generate client certificates for the child org 293 for p := 1; p <= *numClientCerts; p++ { 294 err := genClientCertificateECDSA(fmt.Sprintf(baseOrgName+"%d-child%d-client%d", i, m, p), 295 childSignKey, childSignCert) 296 if err != nil { 297 fmt.Printf("error generating server certificate for %s%d-child%d-client%d : %s\n", 298 baseOrgName, i, m, p, err.Error()) 299 } 300 } 301 } 302 } 303 304 }