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 }