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 }