func CreateTLS() *tls.Config { priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { log.Fatal("failed to generate private key:", err) } var notBefore time.Time notBefore = time.Now() notAfter := notBefore.Add(365 * 24 * time.Hour) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { log.Fatal("failed to generate serial number:", err) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Wago"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := []string{"127.0.0.1", "::1", "localhost"} for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { log.Fatal("Failed to create certificate:", err) } certPEMBlock := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) keyPEMBlock := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) cert, err := tls.X509KeyPair(certPEMBlock, keyPEMBlock) if err != nil { log.Fatal(err) } return &tls.Config{ Certificates: []tls.Certificate{cert}, } }
// upgradeCACertificate upgrades a certificate to a self-signing CA certificate if the CN matches. // Issue #108: Allow generated AWS API Gateway certs to be used for client cert authentication func upgradeCACertificate(cert *x509.Certificate, caUpgradeCN string) { if caUpgradeCN != "" && caUpgradeCN == cert.Issuer.CommonName { cert.BasicConstraintsValid = true cert.IsCA = true cert.KeyUsage = x509.KeyUsageCertSign log.Printf("[INFO] cert: Upgrading cert %s to CA cert", cert.Issuer.CommonName) } }
func Certificate(host ...string) (tls.Certificate, error) { priv, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader) if err != nil { return tls.Certificate{}, err } notBefore := time.Now() notAfter := notBefore.Add(time.Hour * 24 * 365) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return tls.Certificate{}, err } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Acme Co"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } for _, h := range host { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return tls.Certificate{}, err } // create public key certOut := bytes.NewBuffer(nil) pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) // create private key keyOut := bytes.NewBuffer(nil) b, err := x509.MarshalECPrivateKey(priv) if err != nil { return tls.Certificate{}, err } pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b}) return tls.X509KeyPair(certOut.Bytes(), keyOut.Bytes()) }
// generateRSACerts generates a basic self signed certificate using a key length // of rsaBits, valid for validFor time. func generateRSACerts(host string, isCA bool, keyOut, certOut io.Writer) error { if len(host) == 0 { return fmt.Errorf("Require a non-empty host for client hello") } priv, err := rsa.GenerateKey(rand.Reader, rsaBits) if err != nil { return fmt.Errorf("Failed to generate key: %v", err) } notBefore := time.Now() notAfter := notBefore.Add(validFor) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return fmt.Errorf("failed to generate serial number: %s", err) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ CommonName: "default", Organization: []string{"Acme Co"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return fmt.Errorf("Failed to create certificate: %s", err) } if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { return fmt.Errorf("Failed creating cert: %v", err) } if err := pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}); err != nil { return fmt.Errorf("Failed creating keay: %v", err) } return nil }
func templateWithCA(template *x509.Certificate) *x509.Certificate { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign template.KeyUsage |= x509.KeyUsageKeyEncipherment template.KeyUsage |= x509.KeyUsageKeyAgreement template.ExtKeyUsage = nil return template }
func createCertificate(d *schema.ResourceData, template, parent *x509.Certificate, pub crypto.PublicKey, priv interface{}) error { var err error template.NotBefore = time.Now() template.NotAfter = template.NotBefore.Add(time.Duration(d.Get("validity_period_hours").(int)) * time.Hour) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) template.SerialNumber, err = rand.Int(rand.Reader, serialNumberLimit) if err != nil { return fmt.Errorf("failed to generate serial number: %s", err) } keyUsesI := d.Get("allowed_uses").([]interface{}) for _, keyUseI := range keyUsesI { keyUse := keyUseI.(string) if usage, ok := keyUsages[keyUse]; ok { template.KeyUsage |= usage } if usage, ok := extKeyUsages[keyUse]; ok { template.ExtKeyUsage = append(template.ExtKeyUsage, usage) } } if d.Get("is_ca_certificate").(bool) { template.IsCA = true template.SubjectKeyId, err = generateSubjectKeyID(pub) if err != nil { return fmt.Errorf("failed to set subject key identifier: %s", err) } } certBytes, err := x509.CreateCertificate(rand.Reader, template, parent, pub, priv) if err != nil { return fmt.Errorf("error creating certificate: %s", err) } certPem := string(pem.EncodeToMemory(&pem.Block{Type: pemCertType, Bytes: certBytes})) validFromBytes, err := template.NotBefore.MarshalText() if err != nil { return fmt.Errorf("error serializing validity_start_time: %s", err) } validToBytes, err := template.NotAfter.MarshalText() if err != nil { return fmt.Errorf("error serializing validity_end_time: %s", err) } d.SetId(template.SerialNumber.String()) d.Set("cert_pem", certPem) d.Set("validity_start_time", string(validFromBytes)) d.Set("validity_end_time", string(validToBytes)) return nil }
/* Function to create (missing) cert files */ func CreateCert(host string, cPath *config.CertPaths) error { //Data to work with: const validFor = 365 * 24 * time.Hour const isCA = false const rsaBits = 4096 notBefore := time.Now() notAfter := notBefore.Add(validFor) //Generating a key: priv, err := rsa.GenerateKey(rand.Reader, rsaBits) if err != nil { return errors.New(fmt.Sprintf("Failed to generate private key: %s\n", err)) } template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(0), Subject: pkix.Name{ Country: []string{"DE"}, Province: []string{"Saxony"}, CommonName: string(host), }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } template.DNSNames = append(template.DNSNames, host) template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return errors.New(fmt.Sprintf("Failed to create certificate: %s", err)) } certOut, err := os.Create(cPath.Certfile) if err != nil { return errors.New(fmt.Sprintf("Failed to open %s for writing: %s", cPath.Certfile, err)) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() fmt.Printf("Wrote %s\n", cPath.Certfile) keyOut, err := os.OpenFile(cPath.Keyfile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return errors.New(fmt.Sprintf("Failed to open %s for writing: %s", cPath.Keyfile, err)) } pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) keyOut.Close() fmt.Printf("Wrote %s\n", cPath.Keyfile) //Finish: return nil }
// generateTestCert creates a cert and a key used for testing only func generateTestCert(host string) error { certPath := mustGetCertFile() keyPath := mustGetKeyFile() priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return err } serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return err } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Minio Test Cert"}, }, NotBefore: time.Now(), NotAfter: time.Now().Add(time.Minute * 1), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } if ip := net.ParseIP(host); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return err } certOut, err := os.Create(certPath) if err != nil { return err } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() keyOut, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return err } pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) keyOut.Close() return nil }
func generateSingleCertificate(isCa bool) (*x509.Certificate, error) { var notBefore time.Time var err error if len(validFrom) == 0 { notBefore = time.Now() } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom) if err != nil { return nil, fmt.Errorf("Failed to parse creation date: %s\n", err.Error()) } } notAfter := notBefore.Add(validFor) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return nil, fmt.Errorf("failed to generate serial number: %s\n", err.Error()) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Arduino LLC US"}, Country: []string{"US"}, CommonName: "localhost", OrganizationalUnit: []string{"IT"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if isCa { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign template.Subject.CommonName = "Arduino" } return &template, nil }
//http://golang.org/src/pkg/crypto/tls/generate_cert.go func generateCertificate(hosts []string) (cert, key []byte) { private, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { log.Fatal(err) } before := time.Now() after := before.Add(10 * 365 * 24 * time.Hour) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { log.Fatalf("failed to generate serial number: %s", err) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Acme Co"}, }, NotBefore: before, NotAfter: after, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &private.PublicKey, private) if err != nil { log.Fatalf("Failed to create certificate: %s", err) } certOut := bytes.Buffer{} pem.Encode(&certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) keyOut := bytes.Buffer{} pem.Encode(&keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(private)}) return certOut.Bytes(), keyOut.Bytes() }
func generateCert(hosts []string, notAfter time.Time, isAuthorizedToSign bool) tls.Certificate { priv, err := rsa.GenerateKey(rand.Reader, 1024) if err != nil { panic(err) } template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(0), Subject: pkix.Name{ Organization: []string{"Acme Co"}, }, NotBefore: time.Date(1980, time.January, 1, 0, 0, 0, 0, time.UTC), NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } for _, host := range hosts { if ip := net.ParseIP(host); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, host) } } if isAuthorizedToSign { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { panic(err) } certOut := new(bytes.Buffer) pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) keyOut := new(bytes.Buffer) pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) cert, err := tls.X509KeyPair(certOut.Bytes(), keyOut.Bytes()) if err != nil { panic(err) } return cert }
func GenCert(hosts []string, validFor time.Duration, isCA bool) (cert []byte, key []byte, err error) { priv, err := ecdsa.GenerateKey(ellyptic.P521(), rand.Reader) if err != nil { return "", "", err } notBefore := time.Now() notAfter := notBefore.Add(*validFor) if notAfter.After(endOfTime) { notAfter = endOfTime } template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(notBefore.UnixNano()), Subject: pkix.Name{ Organization: []string{"Localhost Inc."}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return "", "", err } cert := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) key := pem.EncodeToMemory(&pem.Block{Type: "ECDSA PRIVATE KEY", Bytes: x509.MarshalECPrivateKey(priv)}) return cert, key, nil }
func MakeCert(organization string, size int, hosts []string, lifespan time.Duration, isCA bool) (*Cert, error) { var err error var cert Cert if cert.privateKey, err = rsa.GenerateKey(rand.Reader, size); err != nil { return nil, errors.New(fmt.Sprintf("Unable to generate key [%s]\n", err)) } // Setup certificate expiration notBefore := time.Now() notAfter := notBefore.Add(lifespan) // Setup certificate configuration template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(0), Subject: pkix.Name{ Organization: []string{organization}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } // Separate valid IP addresses from the named hosts provided for _, host := range hosts { if ip := net.ParseIP(host); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, host) } } // Append usage for Cert Signing if CA is specified if isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } // Make certificate blob if cert.data, err = x509.CreateCertificate(rand.Reader, &template, &template, &cert.privateKey.PublicKey, cert.privateKey); err != nil { return nil, errors.New(fmt.Sprintf("Unable to create certificate [%s]\n", err)) } return &cert, nil }
func finalizeTLSConfig(tlsConfig *tls.Config, tlsRemoteCert *x509.Certificate) { // Trusted certificates if tlsRemoteCert != nil { caCertPool := x509.NewCertPool() // Make it a valid RootCA tlsRemoteCert.IsCA = true tlsRemoteCert.KeyUsage = x509.KeyUsageCertSign // Setup the pool caCertPool.AddCert(tlsRemoteCert) tlsConfig.RootCAs = caCertPool // Set the ServerName if tlsRemoteCert.DNSNames != nil { tlsConfig.ServerName = tlsRemoteCert.DNSNames[0] } } tlsConfig.BuildNameToCertificate() }
// GenClientCert generates a client certificate. // The generated certificate will have its extended key usage set to 'client authentication' and will be ready for use in TLS client authentication. // The returned slices are the PEM encoded X.509 certificate and private key pair. func GenClientCert(subject pkix.Name, validFor time.Duration, keyLength int, signingCert, signingKey []byte) (cert, key []byte, err error) { var ( sc, c *x509.Certificate sk, k *rsa.PrivateKey ) if sc, sk, err = parseCertAndKey(signingCert, signingKey); err != nil { return } if c, k, err = createBaseCert(subject, validFor, keyLength); err != nil { return } c.KeyUsage = x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature c.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth} c.IsCA = false cert, key, err = signAndEncodeCert(sc, sk, c, k) return }
// GenCACert generates a CA certificate. // If signingCert and signingKey are not provided, the certificate is created as a self-signed root CA. // If signingCert and signingKey are provided, the certificate is created as an intermediate CA, signed with provided certificate. // The generated certificate can only be used for signing other certificates and CRLs. // The returned slices are the PEM encoded X.509 certificate and private key pair. func GenCACert(subject pkix.Name, validFor time.Duration, keyLength int, signingCert, signingKey []byte) (cert, key []byte, err error) { var ( sc, c *x509.Certificate sk, k *rsa.PrivateKey ) if c, k, err = createBaseCert(subject, validFor, keyLength); err != nil { return } if signingCert == nil || signingKey == nil { sc = c sk = k } else if sc, sk, err = parseCertAndKey(signingCert, signingKey); err != nil { return } c.KeyUsage = x509.KeyUsageCertSign | x509.KeyUsageCRLSign c.IsCA = true cert, key, err = signAndEncodeCert(sc, sk, c, k) return }
func runCert(ctx *cli.Context) error { if len(ctx.String("host")) == 0 { log.Fatal("Missing required --host parameter") } var priv interface{} var err error switch ctx.String("ecdsa-curve") { case "": priv, err = rsa.GenerateKey(rand.Reader, ctx.Int("rsa-bits")) case "P224": priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) case "P256": priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) case "P384": priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) case "P521": priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) default: log.Fatalf("Unrecognized elliptic curve: %q", ctx.String("ecdsa-curve")) } if err != nil { log.Fatalf("Failed to generate private key: %s", err) } var notBefore time.Time if len(ctx.String("start-date")) == 0 { notBefore = time.Now() } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", ctx.String("start-date")) if err != nil { log.Fatalf("Failed to parse creation date: %s", err) } } notAfter := notBefore.Add(ctx.Duration("duration")) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { log.Fatalf("Failed to generate serial number: %s", err) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Acme Co"}, CommonName: "Gogs", }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(ctx.String("host"), ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if ctx.Bool("ca") { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) if err != nil { log.Fatalf("Failed to create certificate: %s", err) } certOut, err := os.Create("cert.pem") if err != nil { log.Fatalf("Failed to open cert.pem for writing: %s", err) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() log.Println("Written cert.pem") keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Fatal("failed to open key.pem for writing: %v", err) } pem.Encode(keyOut, pemBlockForKey(priv)) keyOut.Close() log.Println("Written key.pem") return nil }
func generateCert(logger *gosteno.Logger) { // see: http://golang.org/src/pkg/crypto/tls/generate_cert.go host := "localhost" validFrom := "Jan 1 15:04:05 2011" validFor := 10 * 365 * 24 * time.Hour isCA := true rsaBits := 1024 if len(host) == 0 { logger.Fatalf("Missing required --host parameter") } priv, err := rsa.GenerateKey(rand.Reader, rsaBits) if err != nil { logger.Fatalf("failed to generate private key: %s", err) panic(err) } var notBefore time.Time if len(validFrom) == 0 { notBefore = time.Now() } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom) if err != nil { logger.Fatalf("Failed to parse creation date: %s\n", err) panic(err) } } notAfter := notBefore.Add(validFor) // end of ASN.1 time endOfTime := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) if notAfter.After(endOfTime) { notAfter = endOfTime } template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(0), Subject: pkix.Name{ Organization: []string{"Loggregator TrafficController TEST"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { logger.Fatalf("Failed to create certificate: %s", err) panic(err) } certOut, err := os.Create("cert.pem") if err != nil { logger.Fatalf("failed to open cert.pem for writing: %s", err) panic(err) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() logger.Info("written cert.pem\n") keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { logger.Fatalf("failed to open key.pem for writing: %s", err) panic(err) } pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) keyOut.Close() logger.Info("written key.pem\n") }
func createCertAndKey(certPath, keyPath, host string, ca bool) error { validFrom := "" validFor := 365 * 24 * time.Hour rsaBits := 1024 priv, err := rsa.GenerateKey(rand.Reader, rsaBits) if err != nil { return err } var notBefore time.Time if len(validFrom) == 0 { notBefore = time.Now() } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom) if err != nil { return err } } notAfter := notBefore.Add(validFor) // end of ASN.1 time endOfTime := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) if notAfter.After(endOfTime) { notAfter = endOfTime } template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(0), Subject: pkix.Name{ Organization: []string{"Acme Co"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if ca { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return err } certOut, err := os.Create("cert.pem") if err != nil { return err } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return err } pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) keyOut.Close() return nil }
func GenerateFakeX509Certificate(certType string) (string, string) { priv, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) if err != nil { logging.GetLogger().Fatal("ECDSA GenerateKey failed : " + err.Error()) } serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { logging.GetLogger().Fatal("Serial number generation error : " + err.Error()) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Skydive Co"}, }, NotBefore: time.Now(), NotAfter: time.Now().Add(1 * time.Hour), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, BasicConstraintsValid: true, } if certType == "server" { template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth} } else { template.ExtKeyUsage = []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth} } hosts := strings.Split("127.0.0.1,::1", ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } template.DNSNames = append(template.DNSNames, "localhost") template.EmailAddresses = append(template.EmailAddresses, "*****@*****.**") /* Generate CA */ template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign /* Certificate */ derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) if err != nil { logging.GetLogger().Fatalf("Failed to create certificate: %s", err) } basedir, err := ioutil.TempDir("", "skydive-keys") if err != nil { logging.GetLogger().Fatal("can't create tempdir skydive-keys") } certFilename := filepath.Join(basedir, "cert.pem") certOut, err := os.Create(certFilename) if err != nil { logging.GetLogger().Fatalf("failed to open %s for writing: %s", certFilename, err) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() /* Private Key */ privKeyFilename := filepath.Join(basedir, "key.pem") keyOut, err := os.OpenFile(privKeyFilename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { logging.GetLogger().Fatalf("failed to open %s for writing: %s", privKeyFilename, err) } pem.Encode(keyOut, pemBlockForKey(priv)) keyOut.Close() return certFilename, privKeyFilename }
// Generate a self-signed X.509 certificate for a TLS server. Outputs to // certFile and keyFile and will overwrite existing files. func GenerateCert(certFile, keyFile, host, organization string, rsaBits int, isCA bool, validFrom time.Time, validFor time.Duration) error { priv, err := rsa.GenerateKey(rand.Reader, rsaBits) if err != nil { return fmt.Errorf("Failed to generate private key: %v", err) } notBefore := validFrom notAfter := notBefore.Add(validFor) // end of ASN.1 time endOfTime := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) if notAfter.After(endOfTime) { notAfter = endOfTime } template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(0), Subject: pkix.Name{ Organization: []string{organization}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return fmt.Errorf("Failed to create certificate: %v", err) } certOut, err := os.Create(certFile) if err != nil { return fmt.Errorf("Failed to open %s for writing: %v", certFile, err) } defer certOut.Close() pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) keyOut, err := os.OpenFile(keyFile, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { return fmt.Errorf("Failed to open %s for writing:", keyFile, err) } defer keyOut.Close() pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) return nil }
func (s *Signer) sign(template *x509.Certificate, profile *config.SigningProfile) (cert []byte, err error) { pub := template.PublicKey encodedpub, err := x509.MarshalPKIXPublicKey(pub) if err != nil { return } pubhash := sha1.New() pubhash.Write(encodedpub) if profile == nil { profile = s.Policy.Default } var ( eku []x509.ExtKeyUsage ku x509.KeyUsage expiry time.Duration crlURL, ocspURL string ) // The third value returned from Usages is a list of unknown key usages. // This should be used when validating the profile at load, and isn't used // here. ku, eku, _ = profile.Usages() expiry = profile.Expiry if profile.IssuerURL == nil { profile.IssuerURL = s.Policy.Default.IssuerURL } if ku == 0 && len(eku) == 0 { err = cferr.New(cferr.PolicyError, cferr.NoKeyUsages, errors.New("no key usage available")) return } if expiry == 0 { expiry = s.Policy.Default.Expiry } if crlURL = profile.CRL; crlURL == "" { crlURL = s.Policy.Default.CRL } if ocspURL = profile.OCSP; ocspURL == "" { ocspURL = s.Policy.Default.OCSP } now := time.Now() serialNumber, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64)) if err != nil { err = cferr.New(cferr.CertificateError, cferr.Unknown, err) } template.SerialNumber = serialNumber template.NotBefore = now.Add(-5 * time.Minute).UTC() template.NotAfter = now.Add(expiry).UTC() template.KeyUsage = ku template.ExtKeyUsage = eku template.BasicConstraintsValid = true template.IsCA = profile.CA template.SubjectKeyId = pubhash.Sum(nil) if ocspURL != "" { template.OCSPServer = []string{ocspURL} } if crlURL != "" { template.CRLDistributionPoints = []string{crlURL} } if len(profile.IssuerURL) != 0 { template.IssuingCertificateURL = profile.IssuerURL } var initRoot bool if s.CA == nil { if !template.IsCA { err = cferr.New(cferr.PolicyError, cferr.InvalidRequest, nil) return } template.DNSNames = nil s.CA = template initRoot = true template.MaxPathLen = 2 } else if template.IsCA { template.MaxPathLen = 1 template.DNSNames = nil } derBytes, err := x509.CreateCertificate(rand.Reader, template, s.CA, pub, s.Priv) if err != nil { return } if initRoot { s.CA, err = x509.ParseCertificate(derBytes) if err != nil { err = cferr.New(cferr.CertificateError, cferr.ParseFailed, err) return } } cert = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) return }
func generateCertificates(host string) { var priv interface{} var err error priv, err = rsa.GenerateKey(rand.Reader, rsaBits) if err != nil { log.Fatalf("failed to generate private key: %s", err) } var notBefore = validFrom notAfter := notBefore.Add(validFor) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { log.Fatalf("failed to generate serial number: %s", err) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Acme Co"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) if err != nil { log.Fatalf("Failed to create certificate: %s", err) } certOut, err := os.Create("cert.pem") if err != nil { log.Fatalf("failed to open cert.pem for writing: %s", err) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() log.Print("written cert.pem\n") keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Print("failed to open key.pem for writing:", err) return } pem.Encode(keyOut, pemBlockForKey(priv)) keyOut.Close() log.Print("written key.pem\n") }
func main() { flag.Parse() hostname, err := os.Hostname() if err != nil { panic(fmt.Sprintf("fatal error, could not get default hostname: %s", err)) } if len(*host) != 0 { hostname = *host //log.Fatalf("Missing required --host parameter") } else { fmt.Printf("defaulting to hostname: '%s'. Use --host if more specificity is required.\n", hostname) } priv, err := rsa.GenerateKey(rand.Reader, *rsaBits) if err != nil { log.Fatalf("failed to generate private key: %s", err) } var notBefore time.Time if len(*validFrom) == 0 { notBefore = time.Now() } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) if err != nil { fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) os.Exit(1) } } notAfter := notBefore.Add(*validFor) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { log.Fatalf("failed to generate serial number: %s", err) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Acme Co"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(*host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if *isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { log.Fatalf("Failed to create certificate: %s", err) } certOut, err := os.Create("cert.pem") if err != nil { log.Fatalf("failed to open cert.pem for writing: %s", err) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() log.Print("written cert.pem\n") keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Print("failed to open key.pem for writing:", err) return } pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) keyOut.Close() log.Print("written key.pem\n") }
func Generate(certPath string, keyPath string, host string) error { var priv interface{} var err error switch ecdsaCurve { case "": priv, err = rsa.GenerateKey(rand.Reader, rsaBits) case "P224": priv, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) case "P256": priv, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) case "P384": priv, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) case "P521": priv, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) default: fmt.Fprintf(os.Stderr, "Unrecognized elliptic curve: %q", ecdsaCurve) os.Exit(1) } if err != nil { log.Printf("failed to generate private key: %s", err) return err } var notBefore time.Time if len(validFrom) == 0 { notBefore = time.Now() } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", validFrom) if err != nil { fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) return err } } notAfter := notBefore.Add(validFor) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { log.Printf("failed to generate serial number: %s", err) return err } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Acme Co"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, publicKey(priv), priv) if err != nil { log.Printf("Failed to create certificate: %s", err) return err } certOut, err := os.Create(certPath) if err != nil { log.Printf("failed to open "+certPath+" for writing: %s", err) return err } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() log.Print("written cert.pem\n") keyOut, err := os.OpenFile(keyPath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Print("failed to open "+keyPath+" for writing:", err) return err } pem.Encode(keyOut, pemBlockForKey(priv)) keyOut.Close() log.Print("written key.pem\n") return nil }
func main() { flag.Parse() if *printVersion { fmt.Println("Quickcert v" + version) fmt.Println("https://github.com/andmarios/quickcert") os.Exit(0) } if len(*host) == 0 && !*isCA { fmt.Println("If you are not creating a CA pair, you need to set the -hosts parameter. Use -h for help.") os.Exit(1) } var cacert *x509.Certificate var cacertpem *pem.Block var cakey interface{} var err error // If not CA, read the CA key and cert if !*isCA { // Read CAcert log.Println("Reading CA certificate") data, err := readDecodePemFile(*CAcertFile) checkError("Could not read ca key file: ", err) cacert, err = x509.ParseCertificate(data.Bytes) checkError("Could not parse CA certificate: ", err) cacertpem = data // Read CAkey log.Println("Reading CA private key") data, err = readDecodePemFile(*CAkeyFile) checkError("Could not read ca key file: ", err) // If encrypted, decrypt it if x509.IsEncryptedPEMBlock(data) { password, err := readPassword("CA key is encrypted\nEnter password: "******"Error reading CA private key password: "******"Could not decrypt CA private key: ", err) } // Detect type and parse key if data.Type == "RSA PRIVATE KEY" { cakey, err = x509.ParsePKCS1PrivateKey(data.Bytes) checkError("Could not parse CA RSA private key: ", err) } else if data.Type == "EC PRIVATE KEY" { cakey, err = x509.ParseECPrivateKey(data.Bytes) checkError("Could not parse CA ECDSA key: ", err) } else { log.Fatalf("Could not find a compatible private key type (%s), only RSA and ECDSA are accepted", data.Type) } } // Create new key log.Println("Generating private key. This may take some time, depending on type and length.") var privkey interface{} switch *ecdsaCurve { case "": if *rsaBits < 2048 && !*isCA { log.Println("Consider upgrading your key to 2048 bits or better.") } else if *rsaBits < 4096 && *isCA { log.Println("Consider upgrading your CA key 4096 bits.") } privkey, err = rsa.GenerateKey(rand.Reader, *rsaBits) // I disabled P224 curve because Redhat patched their golang to // not support this curve due to patent law reasons. // I could leave it, but then quickcert won't compile on centos, rhel and fedora // case "P224": // privkey, err = ecdsa.GenerateKey(elliptic.P224(), rand.Reader) case "P256": privkey, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader) case "P384": privkey, err = ecdsa.GenerateKey(elliptic.P384(), rand.Reader) case "P521": privkey, err = ecdsa.GenerateKey(elliptic.P521(), rand.Reader) default: log.Fatalf("Unrecognized elliptic curve: %q", *ecdsaCurve) } checkError("Failed to generate private key: ", err) // Create certificate log.Println("Generating certificate.") var notBefore time.Time if len(*validFrom) == 0 { notBefore = time.Now() } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) checkError("Failed to parse creation date: ", err) } // time.Duration takes nanoseconds |--these are nsecs of a day--| duration := time.Duration(*validFor * 24 * 3600 * 1000 * 1000 * 1000) notAfter := notBefore.Add(duration) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) checkError("Failed to generate serial number: ", err) template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Country: []string{}, Organization: []string{}, OrganizationalUnit: []string{}, CommonName: "", }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, BasicConstraintsValid: true, } if len(*cnAttr) > 0 { template.Subject.CommonName = *cnAttr } if len(*cAttr) > 0 { template.Subject.Country = append(template.Subject.Country, *cAttr) } if len(*oAttr) > 0 { template.Subject.Organization = append(template.Subject.Organization, *oAttr) } if len(*ouAttr) > 0 { template.Subject.OrganizationalUnit = append(template.Subject.OrganizationalUnit, *ouAttr) } hosts := strings.Split(*host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if len(*email) > 0 { emails := strings.Split(*email, ",") for _, e := range emails { template.EmailAddresses = append(template.EmailAddresses, e) } } if *isCA { cakey = privkey cacert = &template template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } // Sign certificate log.Println("Signing certificate") derBytes, err := x509.CreateCertificate(rand.Reader, &template, cacert, publicKey(privkey), cakey) checkError("Failed to create certificate: ", err) // Check if files to be written exist outCrt := *outFile + "crt.pem" outKey := *outFile + "key.pem" if _, err := os.Stat(outCrt); err == nil { checkError("Certificate file exists: ", userConfirmation("Certificate file ("+outCrt+") exists. Overwrite? [Yn]: ")) } if _, err := os.Stat(outKey); err == nil { checkError("Key file exists: ", userConfirmation("Key file ("+outKey+") exists. Overwrite? [Yn]: ")) } // Save certificate to file log.Println("Writing certificate file: ", outCrt) certOut, err := os.Create(outCrt) checkError("Failed to open "+outCrt+" for writing: ", err) pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) if *chain { pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: cacertpem.Bytes}) } certOut.Close() // Save private key to file log.Println("Writing key file: ", outKey) keyOut, err := os.OpenFile(outKey, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) checkError("Failed to open key.pem for writing:", err) keyPemBlock := pemBlockForKey(privkey) if *encryptKey { ASK_KEY: pass1, err := readPassword("Enter password for private key: ") checkError("Error reading private key password, attempt 1: ", err) pass2, err := readPassword("Please re-enter password for private key: ") checkError("Error reading private key password, attempt 2: ", err) if string(pass1) == string(pass2) { keyPemBlock, err = x509.EncryptPEMBlock(rand.Reader, keyPemBlock.Type, keyPemBlock.Bytes, pass1, x509.PEMCipher3DES) } else { fmt.Println("Passwords mismatch. Try again.") goto ASK_KEY } } pem.Encode(keyOut, keyPemBlock) keyOut.Close() log.Println("Files written succesfully. Exiting.") }
// FillTemplate is a utility function that tries to load as much of // the certificate template as possible from the profiles and current // template. It fills in the key uses, expiration, revocation URLs // and SKI. func FillTemplate(template *x509.Certificate, defaultProfile, profile *config.SigningProfile) error { ski, err := ComputeSKI(template) var ( eku []x509.ExtKeyUsage ku x509.KeyUsage backdate time.Duration expiry time.Duration notBefore time.Time notAfter time.Time crlURL, ocspURL string ) // The third value returned from Usages is a list of unknown key usages. // This should be used when validating the profile at load, and isn't used // here. ku, eku, _ = profile.Usages() if profile.IssuerURL == nil { profile.IssuerURL = defaultProfile.IssuerURL } if ku == 0 && len(eku) == 0 { return cferr.New(cferr.PolicyError, cferr.NoKeyUsages) } if expiry = profile.Expiry; expiry == 0 { expiry = defaultProfile.Expiry } if crlURL = profile.CRL; crlURL == "" { crlURL = defaultProfile.CRL } if ocspURL = profile.OCSP; ocspURL == "" { ocspURL = defaultProfile.OCSP } if backdate = profile.Backdate; backdate == 0 { backdate = -5 * time.Minute } else { backdate = -1 * profile.Backdate } if !profile.NotBefore.IsZero() { notBefore = profile.NotBefore.UTC() } else { notBefore = time.Now().Round(time.Minute).Add(backdate).UTC() } if !profile.NotAfter.IsZero() { notAfter = profile.NotAfter.UTC() } else { notAfter = notBefore.Add(expiry).UTC() } template.NotBefore = notBefore template.NotAfter = notAfter template.KeyUsage = ku template.ExtKeyUsage = eku template.BasicConstraintsValid = true template.IsCA = profile.CA template.SubjectKeyId = ski if ocspURL != "" { template.OCSPServer = []string{ocspURL} } if crlURL != "" { template.CRLDistributionPoints = []string{crlURL} } if len(profile.IssuerURL) != 0 { template.IssuingCertificateURL = profile.IssuerURL } if len(profile.Policies) != 0 { err = addPolicies(template, profile.Policies) if err != nil { return cferr.Wrap(cferr.PolicyError, cferr.InvalidPolicy, err) } } if profile.OCSPNoCheck { ocspNoCheckExtension := pkix.Extension{ Id: asn1.ObjectIdentifier{1, 3, 6, 1, 5, 5, 7, 48, 1, 5}, Critical: false, Value: []byte{0x05, 0x00}, } template.ExtraExtensions = append(template.ExtraExtensions, ocspNoCheckExtension) } return nil }
func genCetificate(keyFilePath, certFilePath, host string) { validFor := 10 * 365 * 24 * time.Hour isCA := true rsaBits := 2048 priv, err := rsa.GenerateKey(rand.Reader, rsaBits) if err != nil { SendError(err, "Fatal: Failed to generate private key", nil) os.RemoveAll(TutumPidFile) Logger.Fatalf("Failed to generate private key: %s", err) } notBefore := time.Now() notAfter := notBefore.Add(validFor) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { SendError(err, "Fatal: Failed to generate serial number", nil) os.RemoveAll(TutumPidFile) Logger.Fatalf("Failed to generate serial number: %s", err) } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Tutum Self-Signed Host"}, CommonName: host, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { SendError(err, "Fatal: Failed to create certificate", nil) os.RemoveAll(TutumPidFile) Logger.Fatalf("Failed to create certificate: %s", err) } certOut, err := os.Create(certFilePath) if err != nil { SendError(err, "Fatal: Failed to open cert.pem for writing", nil) os.RemoveAll(TutumPidFile) Logger.Fatalf("Failed to open cert.pem for writing: %s", err) } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() keyOut, err := os.OpenFile(keyFilePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { SendError(err, "Fatal: Failed to open key.pem for writing", nil) os.RemoveAll(TutumPidFile) Logger.Fatalf("Failed to open key.pem for writing:", err) } pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) keyOut.Close() }
// GenerateCA func GenerateCert(validFrom time.Time, validFor time.Duration, isCA bool, rsaBits int, subject pkix.Name, certName string) error { /* if host == "" { log.Fatalf("Missing required host parameter.") } */ if rsaBits == 0 { rsaBits = 2048 } priv, err := rsa.GenerateKey(rand.Reader, rsaBits) if err != nil { log.Printf("faild to generate private key: %s", err) return err } var notBefore time.Time if validFrom.IsZero() { notBefore = time.Now() } else { notBefore = validFrom } notAfter := notBefore.Add(validFor) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { log.Printf("failed to generate serial number: %s", err) return err } template := x509.Certificate{ SerialNumber: serialNumber, Subject: subject, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{ x509.ExtKeyUsageServerAuth, }, BasicConstraintsValid: true, } /* hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } */ var parent *x509.Certificate if isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign parent = &template } derBytes, err := x509.CreateCertificate(rand.Reader, &template, parent, &priv.PublicKey, priv) if err != nil { log.Printf("Failed to create certificate: %s", err) return err } certOut, err := os.Create(fmt.Sprintf("%s.crt", certName)) if err != nil { log.Printf("failed to open %s.crt for writing: %s", certName, err) return err } defer certOut.Close() pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) log.Printf("written %s.crt\n", certName) keyOut, err := os.OpenFile(fmt.Sprintf("%s.key", certName), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Printf("failed to open %s.key for writing:", err) return err } defer keyOut.Close() pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) log.Printf("written %s.key\n", certName) return nil }
func main() { flag.Parse() if len(*host) == 0 { log.Fatalf("Missing required --host parameter") } priv, err := rsa.GenerateKey(rand.Reader, *rsaBits) if err != nil { log.Fatalf("failed to generate private key: %s", err) return } var notBefore time.Time if len(*validFrom) == 0 { notBefore = time.Now() } else { notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) if err != nil { fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) os.Exit(1) } } notAfter := notBefore.Add(*validFor) // end of ASN.1 time endOfTime := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) if notAfter.After(endOfTime) { notAfter = endOfTime } template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(0), Subject: pkix.Name{ Organization: []string{"Acme Co"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } hosts := strings.Split(*host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } if *isCA { template.IsCA = true template.KeyUsage |= x509.KeyUsageCertSign } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { log.Fatalf("Failed to create certificate: %s", err) return } certOut, err := os.Create("cert.pem") if err != nil { log.Fatalf("failed to open cert.pem for writing: %s", err) return } pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) certOut.Close() log.Print("written cert.pem\n") keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) if err != nil { log.Print("failed to open key.pem for writing:", err) return } pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) keyOut.Close() log.Print("written key.pem\n") }