func TestTLSConnection(t *testing.T) { reactor := NewReactor() client := reactor.CreateServer("local") initialiseServerConnection(client) // generate a test certificate to use priv, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) duration30Days, _ := time.ParseDuration("-30h") notBefore := time.Now().Add(duration30Days) // valid 30 hours ago duration1Year, _ := time.ParseDuration("90h") notAfter := notBefore.Add(duration1Year) // for 90 hours serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, _ := rand.Int(rand.Reader, serialNumberLimit) template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"gIRC-Go Co"}, }, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, IsCA: true, } template.IPAddresses = append(template.IPAddresses, net.ParseIP("127.0.0.1")) template.IPAddresses = append(template.IPAddresses, net.ParseIP("::")) template.DNSNames = append(template.DNSNames, "localhost") derBytes, _ := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) c := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) b, _ := x509.MarshalECPrivateKey(priv) k := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: b}) // we mock up a server connection to test the client listenerKeyPair, _ := tls.X509KeyPair(c, k) var listenerTLSConfig tls.Config listenerTLSConfig.Certificates = make([]tls.Certificate, 0) listenerTLSConfig.Certificates = append(listenerTLSConfig.Certificates, listenerKeyPair) listener, _ := tls.Listen("tcp", ":0", &listenerTLSConfig) // mock up the client side too clientTLSCertPool := x509.NewCertPool() clientTLSCertPool.AppendCertsFromPEM(c) var clientTLSConfig tls.Config clientTLSConfig.RootCAs = clientTLSCertPool clientTLSConfig.ServerName = "localhost" go client.Connect(listener.Addr().String(), true, &clientTLSConfig) go client.ReceiveLoop() testServerConnection(t, reactor, client, listener) }
// GenerateSelfSignedCert creates a self-signed certificate and key for the given host. // Host may be an IP or a DNS name // You may also specify additional subject alt names (either ip or dns names) for the certificate // The certificate will be created with file mode 0644. The key will be created with file mode 0600. // If the certificate or key files already exist, they will be overwritten. // Any parent directories of the certPath or keyPath will be created as needed with file mode 0755. func GenerateSelfSignedCert(host, certPath, keyPath string, alternateIPs []net.IP, alternateDNS []string) error { priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return err } template := x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{ CommonName: fmt.Sprintf("%s@%d", host, time.Now().Unix()), }, NotBefore: time.Now(), NotAfter: time.Now().Add(time.Hour * 24 * 365), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, IsCA: true, } if ip := net.ParseIP(host); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, host) } template.IPAddresses = append(template.IPAddresses, alternateIPs...) template.DNSNames = append(template.DNSNames, alternateDNS...) derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return err } // Generate cert certBuffer := bytes.Buffer{} if err := pem.Encode(&certBuffer, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { return err } // Generate key keyBuffer := bytes.Buffer{} if err := pem.Encode(&keyBuffer, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}); err != nil { return err } // Write cert if err := WriteCertToPath(certPath, certBuffer.Bytes()); err != nil { return err } // Write key if err := WriteKeyToPath(keyPath, keyBuffer.Bytes()); err != nil { return err } return nil }
// OverrideHosts fills template's IPAddresses and DNSNames with the // content of hosts, if it is not nil. func OverrideHosts(template *x509.Certificate, hosts []string) { if hosts != nil { template.IPAddresses = []net.IP{} template.DNSNames = []string{} } for i := range hosts { if ip := net.ParseIP(hosts[i]); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, hosts[i]) } } }
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}, } }
// Sign signs a new certificate based on the PEM-encoded client // certificate or certificate request with the signing profile, specified by profileName. // The certificate will be valid for the host named in the hostName parameter. func (s *Signer) Sign(hostName string, in []byte, profileName string) (cert []byte, err error) { profile := s.Policy.Profiles[profileName] block, _ := pem.Decode(in) if block == nil { return nil, cferr.New(cferr.CertificateError, cferr.DecodeFailed, err) } var template *x509.Certificate switch block.Type { case "CERTIFICATE": template, err = helpers.ParseSelfSignedCertificatePEM(in) case "CERTIFICATE REQUEST": template, err = s.parseCertificateRequest(block.Bytes) default: return nil, cferr.New(cferr.CertificateError, cferr.ParseFailed, errors.New("Not a certificate or csr.")) } if err != nil { return } if ip := net.ParseIP(hostName); ip != nil { template.IPAddresses = []net.IP{ip} } else { template.DNSNames = []string{hostName} } return s.sign(template, profile) }
// generateSelfSignedCert generates a self-signed cert/key pairs and writes to the certPath/keyPath. // This method is mostly identical to util.GenerateSelfSignedCert except for the 'IsCA' and 'KeyUsage' // in the certificate template. (Maybe we can merge these two methods). func generateSelfSignedCert(t *testing.T, host, certPath, keyPath string) { priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { t.Fatal(err) } template := x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{ CommonName: fmt.Sprintf("%s@%d", host, time.Now().Unix()), }, NotBefore: time.Now(), NotAfter: time.Now().Add(time.Hour * 24 * 365), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, IsCA: true, } if ip := net.ParseIP(host); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, host) } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { t.Fatal(err) } // Generate cert certBuffer := bytes.Buffer{} if err := pem.Encode(&certBuffer, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { t.Fatal(err) } // Generate key keyBuffer := bytes.Buffer{} if err := pem.Encode(&keyBuffer, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}); err != nil { t.Fatal(err) } // Write cert if err := os.MkdirAll(filepath.Dir(certPath), os.FileMode(0755)); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(certPath, certBuffer.Bytes(), os.FileMode(0644)); err != nil { t.Fatal(err) } // Write key if err := os.MkdirAll(filepath.Dir(keyPath), os.FileMode(0755)); err != nil { t.Fatal(err) } if err := ioutil.WriteFile(keyPath, keyBuffer.Bytes(), os.FileMode(0600)); err != nil { t.Fatal(err) } }
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()) }
// Sign signs a new certificate based on the PEM-encoded client // certificate or certificate request with the signing profile, // specified by profileName. func (s *Signer) Sign(req signer.SignRequest) (cert []byte, err error) { profile, err := signer.Profile(s, req.Profile) if err != nil { return } serialSeq := "" if profile.UseSerialSeq { serialSeq = req.SerialSeq } block, _ := pem.Decode([]byte(req.Request)) if block == nil { return nil, cferr.New(cferr.CSRError, cferr.DecodeFailed) } if block.Type != "CERTIFICATE REQUEST" { return nil, cferr.Wrap(cferr.CSRError, cferr.BadRequest, errors.New("not a certificate or csr")) } csrTemplate, err := signer.ParseCertificateRequest(s, block.Bytes) if err != nil { return nil, err } // Copy out only the fields from the CSR authorized by policy. safeTemplate := x509.Certificate{} // If the profile contains no explicit whitelist, assume that all fields // should be copied from the CSR. if profile.CSRWhitelist == nil { safeTemplate = *csrTemplate } else { if profile.CSRWhitelist.Subject { safeTemplate.Subject = csrTemplate.Subject } if profile.CSRWhitelist.PublicKeyAlgorithm { safeTemplate.PublicKeyAlgorithm = csrTemplate.PublicKeyAlgorithm } if profile.CSRWhitelist.PublicKey { safeTemplate.PublicKey = csrTemplate.PublicKey } if profile.CSRWhitelist.SignatureAlgorithm { safeTemplate.SignatureAlgorithm = csrTemplate.SignatureAlgorithm } if profile.CSRWhitelist.DNSNames { safeTemplate.DNSNames = csrTemplate.DNSNames } if profile.CSRWhitelist.IPAddresses { safeTemplate.IPAddresses = csrTemplate.IPAddresses } } OverrideHosts(&safeTemplate, req.Hosts) safeTemplate.Subject = PopulateSubjectFromCSR(req.Subject, safeTemplate.Subject) return s.sign(&safeTemplate, profile, serialSeq) }
// 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 }
// OverrideHosts fills template's IPAddresses, EmailAddresses, and DNSNames with the // content of hosts, if it is not nil. func OverrideHosts(template *x509.Certificate, hosts []string) { if hosts != nil { template.IPAddresses = []net.IP{} template.EmailAddresses = []string{} template.DNSNames = []string{} } for i := range hosts { if ip := net.ParseIP(hosts[i]); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else if email, err := mail.ParseAddress(hosts[i]); err == nil && email != nil { template.EmailAddresses = append(template.EmailAddresses, email.Address) } else { template.DNSNames = append(template.DNSNames, hosts[i]) } } }
func generateCertificate(c certificateConfig) ([]byte, *rsa.PrivateKey, error) { serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return nil, nil, err } key, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, nil, err } // Generate the subject key ID derEncodedPubKey, err := x509.MarshalPKIXPublicKey(&key.PublicKey) if err != nil { return nil, nil, err } pubKeyHash := sha1.New() pubKeyHash.Write(derEncodedPubKey) template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"Kubernetes"}, }, NotBefore: notBefore, NotAfter: notAfter, IsCA: c.isCA, KeyUsage: c.keyUsage, ExtKeyUsage: c.extKeyUsage, BasicConstraintsValid: true, SubjectKeyId: pubKeyHash.Sum(nil), } if c.hosts[0] != "" { template.Subject.CommonName = c.hosts[0] } if c.isCA { c.caCert = &template c.caKey = key } for _, h := range c.hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } derBytes, err := x509.CreateCertificate(rand.Reader, &template, c.caCert, &key.PublicKey, c.caKey) if err != nil { return nil, nil, err } return derBytes, key, nil }
// setHosts parses the comma separated host name / IP list and adds them to Subject Alternate Name list of a server/hosting certificate. func setHosts(host string, cert *x509.Certificate) { hosts := strings.Split(host, ",") for _, h := range hosts { if ip := net.ParseIP(h); ip != nil { cert.IPAddresses = append(cert.IPAddresses, ip) } else { cert.DNSNames = append(cert.DNSNames, h) } } }
// GenerateTestCerts generate certs for testing or hacking func GenerateTestCerts() (*Certs, error) { priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return nil, err } 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 { return nil, 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, } template.DNSNames = append(template.DNSNames, "example.com") derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return nil, err } var cbuf bytes.Buffer pem.Encode(&cbuf, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) var kbuf bytes.Buffer pem.Encode(&kbuf, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) privateKey, err := crypto.ParseRSAPrivateKeyFromPEM(kbuf.Bytes()) if err != nil { return nil, err } publicKey, err := crypto.ParseRSAPublicKeyFromPEM(cbuf.Bytes()) if err != nil { return nil, err } return &Certs{PrivateKey: privateKey, PublicKey: publicKey}, nil }
// You may also specify additional subject alt names (either ip or dns names) for the certificate // The certificate will be created with file mode 0644. The key will be created with file mode 0600. // If the certificate or key files already exist, they will be overwritten. // Any parent directories of the certPath or keyPath will be created as needed with file mode 0755. func GenerateSelfSignedCert(certPath, keyPath string, ips []net.IP, alternateDNS []string) error { priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return err } template := x509.Certificate{ SerialNumber: big.NewInt(1), Subject: pkix.Name{ CommonName: "minishift", }, NotBefore: time.Now(), NotAfter: time.Now().Add(time.Hour * 24 * 365), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, BasicConstraintsValid: true, IsCA: true, } template.IPAddresses = append(template.IPAddresses, ips...) template.DNSNames = append(template.DNSNames, alternateDNS...) derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return err } certBuffer := bytes.Buffer{} if err := pem.Encode(&certBuffer, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}); err != nil { return err } keyBuffer := bytes.Buffer{} if err := pem.Encode(&keyBuffer, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}); err != nil { return err } if err := os.MkdirAll(filepath.Dir(certPath), os.FileMode(0755)); err != nil { return err } if err := ioutil.WriteFile(certPath, certBuffer.Bytes(), os.FileMode(0644)); err != nil { return err } if err := os.MkdirAll(filepath.Dir(keyPath), os.FileMode(0755)); err != nil { return err } if err := ioutil.WriteFile(keyPath, keyBuffer.Bytes(), os.FileMode(0600)); err != nil { return err } 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 }
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 }
func signHost(ca tls.Certificate, hosts []string) (cert tls.Certificate, err error) { var x509ca *x509.Certificate // Use the provided ca and not the global GoproxyCa for certificate generation. if x509ca, err = x509.ParseCertificate(ca.Certificate[0]); err != nil { return } start := time.Unix(0, 0) end, err := time.Parse("2006-01-02", "2049-12-31") if err != nil { panic(err) } hash := hashSorted(append(hosts, goproxySignerVersion, ":"+runtime.Version())) serial := new(big.Int) serial.SetBytes(hash) template := x509.Certificate{ // TODO(elazar): instead of this ugly hack, just encode the certificate and hash the binary form. SerialNumber: serial, Issuer: x509ca.Subject, Subject: pkix.Name{ Organization: []string{CertOrganisation}, }, NotBefore: start, NotAfter: end, 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) } } var csprng CounterEncryptorRand if csprng, err = NewCounterEncryptorRandFromKey(ca.PrivateKey, hash); err != nil { return } var certpriv *rsa.PrivateKey if certpriv, err = rsa.GenerateKey(&csprng, 1024); err != nil { return } var derBytes []byte if derBytes, err = x509.CreateCertificate(&csprng, &template, x509ca, &certpriv.PublicKey, ca.PrivateKey); err != nil { return } return tls.Certificate{ Certificate: [][]byte{derBytes, ca.Certificate[0]}, PrivateKey: certpriv, }, nil }
func (s *Signer) sign(template *x509.Certificate, profile *config.SigningProfile) (cert []byte, err error) { var distPoints = template.CRLDistributionPoints err = signer.FillTemplate(template, s.policy.Default, profile) if distPoints != nil && len(distPoints) > 0 { template.CRLDistributionPoints = distPoints } if err != nil { return } var initRoot bool if s.ca == nil { if !template.IsCA { err = cferr.New(cferr.PolicyError, cferr.InvalidRequest) return } template.DNSNames = nil template.EmailAddresses = nil s.ca = template initRoot = true } else if template.IsCA { template.DNSNames = nil template.EmailAddresses = nil } derBytes, err := x509.CreateCertificate(rand.Reader, template, s.ca, template.PublicKey, s.priv) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err) } if initRoot { s.ca, err = x509.ParseCertificate(derBytes) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } } cert = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) log.Infof("signed certificate with serial number %d", template.SerialNumber) return }
//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() }
// GenerateCert generates a certificate for the given hostnames in the given location func GenerateCert(location string, hostnames ...string) error { privKey, err := LoadKeypair(location) if err != nil { return err } // Build Certificate 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 err } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"The Things Network"}, }, IsCA: true, NotBefore: notBefore, NotAfter: notAfter, KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, BasicConstraintsValid: true, } for _, h := range hostnames { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, h) } } // Generate certificate certBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, privKey.Public(), privKey) if err != nil { return err } certPEM := pem.EncodeToMemory(&pem.Block{ Type: "CERTIFICATE", Bytes: certBytes, }) err = ioutil.WriteFile(filepath.Clean(location+"/server.cert"), certPEM, 0644) if err != nil { return err } return nil }
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 (s *Signer) sign(template *x509.Certificate, profile *config.SigningProfile, serialSeq string) (cert []byte, err error) { err = signer.FillTemplate(template, s.policy.Default, profile, serialSeq) if err != nil { return } serialNumber := template.SerialNumber var initRoot bool if s.ca == nil { if !template.IsCA { err = cferr.New(cferr.PolicyError, cferr.InvalidRequest) return } template.DNSNames = nil s.ca = template initRoot = true template.MaxPathLen = signer.MaxPathLen } else if template.IsCA { template.MaxPathLen = 1 template.DNSNames = nil } derBytes, err := x509.CreateCertificate(rand.Reader, template, s.ca, template.PublicKey, s.priv) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.Unknown, err) } if initRoot { s.ca, err = x509.ParseCertificate(derBytes) if err != nil { return nil, cferr.Wrap(cferr.CertificateError, cferr.ParseFailed, err) } } cert = pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) log.Infof("signed certificate with serial number %s", serialNumber) return }
// You may also specify additional subject alt names (either ip or dns names) for the certificate // The certificate will be created with file mode 0644. The key will be created with file mode 0600. // If the certificate or key files already exist, they will be overwritten. // Any parent directories of the certPath or keyPath will be created as needed with file mode 0755. func GenerateSignedCert(certPath, keyPath string, ips []net.IP, alternateDNS []string, signerCertPath, signerKeyPath string) error { signerCertBytes, err := ioutil.ReadFile(signerCertPath) if err != nil { return errors.Wrap(err, "Error reading file: signerCertPath") } decodedSignerCert, _ := pem.Decode(signerCertBytes) if decodedSignerCert == nil { return errors.New("Unable to decode certificate.") } signerCert, err := x509.ParseCertificate(decodedSignerCert.Bytes) if err != nil { return errors.Wrap(err, "Error parsing certificate: decodedSignerCert.Bytes") } signerKeyBytes, err := ioutil.ReadFile(signerKeyPath) if err != nil { return errors.Wrap(err, "Error reading file: signerKeyPath") } decodedSignerKey, _ := pem.Decode(signerKeyBytes) if decodedSignerKey == nil { return errors.New("Unable to decode key.") } signerKey, err := x509.ParsePKCS1PrivateKey(decodedSignerKey.Bytes) if err != nil { return errors.Wrap(err, "Error parsing prive key: decodedSignerKey.Bytes") } template := x509.Certificate{ SerialNumber: big.NewInt(2), Subject: pkix.Name{ CommonName: "minikube", }, NotBefore: time.Now(), NotAfter: time.Now().Add(time.Hour * 24 * 365), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageClientAuth}, BasicConstraintsValid: true, } template.IPAddresses = append(template.IPAddresses, ips...) template.DNSNames = append(template.DNSNames, alternateDNS...) priv, err := loadOrGeneratePrivateKey(keyPath) if err != nil { return errors.Wrap(err, "Error loading or generating private key: keyPath") } return writeCertsAndKeys(&template, certPath, priv, keyPath, signerCert, signerKey) }
// templateWithServer adds the capabilities of the certificate to be only used for server auth func templateWithServer(template *x509.Certificate, domain string) *x509.Certificate { template.ExtKeyUsage = append(template.ExtKeyUsage, x509.ExtKeyUsageServerAuth) // abide by the spec - if CN is an IP, put it in the subjectAltName as well ip := net.ParseIP(domain) if ip != nil { template.IPAddresses = []net.IP{ip} // try best guess at DNSNames entries names, err := net.LookupAddr(domain) if err == nil && len(names) > 0 { template.DNSNames = names } return template } if domain != "" { template.Subject.CommonName = domain template.DNSNames = []string{domain} } return template }
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 NewTLSCertificate(host string, priv *rsa.PrivateKey) ([]byte, error) { func NewTLSCertificate(host string, priv *ecdsa.PrivateKey) ([]byte, error) { notBefore := time.Now() notAfter := notBefore.Add(5 * 365 * 24 * time.Hour) serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) if err != nil { return nil, err } template := x509.Certificate{ SerialNumber: serialNumber, Subject: pkix.Name{ Organization: []string{"I2P Anonymous Network"}, OrganizationalUnit: []string{"I2P"}, Locality: []string{"XX"}, StreetAddress: []string{"XX"}, Country: []string{"XX"}, CommonName: host, }, NotBefore: notBefore, NotAfter: notAfter, // SignatureAlgorithm: x509.SHA256WithRSA, SignatureAlgorithm: x509.ECDSAWithSHA512, KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, IsCA: 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) } } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return nil, err } return derBytes, nil }
// tlsChallengeCert creates a temporary certificate for TLS-SNI challenges // with the given SANs and auto-generated public/private key pair. // To create a cert with a custom key pair, specify WithKey option. func tlsChallengeCert(san []string, opt []CertOption) (tls.Certificate, error) { var ( key crypto.Signer tmpl *x509.Certificate ) for _, o := range opt { switch o := o.(type) { case *certOptKey: if key != nil { return tls.Certificate{}, errors.New("acme: duplicate key option") } key = o.key case *certOptTemplate: var t = *(*x509.Certificate)(o) // shallow copy is ok tmpl = &t default: // package's fault, if we let this happen: panic(fmt.Sprintf("unsupported option type %T", o)) } } if key == nil { var err error if key, err = ecdsa.GenerateKey(elliptic.P256(), rand.Reader); err != nil { return tls.Certificate{}, err } } if tmpl == nil { tmpl = &x509.Certificate{ SerialNumber: big.NewInt(1), NotBefore: time.Now(), NotAfter: time.Now().Add(24 * time.Hour), BasicConstraintsValid: true, KeyUsage: x509.KeyUsageKeyEncipherment, } } tmpl.DNSNames = san der, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, key.Public(), key) if err != nil { return tls.Certificate{}, err } return tls.Certificate{ Certificate: [][]byte{der}, PrivateKey: 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 (a *GenTLSCertAction) generateCert(s *State) (cert, privKey, pin string, err error) { priv, err := rsa.GenerateKey(rand.Reader, 2048) if err != nil { return } template := x509.Certificate{ SerialNumber: new(big.Int).SetInt64(0), Subject: pkix.Name{ Organization: []string{"Flynn"}, }, NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 * time.Hour), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, BasicConstraintsValid: true, } for _, h := range a.Hosts { host := interpolate(s, h) if ip := net.ParseIP(host); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, host) } } derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) if err != nil { return } h := sha256.New() h.Write(derBytes) pin = base64.StdEncoding.EncodeToString(h.Sum(nil)) var buf bytes.Buffer pem.Encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) cert = buf.String() buf.Reset() pem.Encode(&buf, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) privKey = buf.String() return }
// create plain old https server certificates // doesn't have to be too strong. func GenerateCert(serverName string, altnames []string, caCert *x509.Certificate, caKey *rsa.PrivateKey, bits int) (*x509.Certificate, *rsa.PrivateKey, error) { priv, err := rsa.GenerateKey(rand.Reader, bits) if err != nil { return nil, nil, err } serial := randBigInt() keyId := randBytes() template := x509.Certificate{ Subject: pkix.Name{ CommonName: serverName, }, SerialNumber: serial, SubjectKeyId: keyId, AuthorityKeyId: caCert.AuthorityKeyId, NotBefore: time.Now().Add(-5 * time.Minute).UTC(), NotAfter: time.Now().AddDate(2, 0, 0).UTC(), } // set IP-addesses and Server Alternate Names for _, name := range altnames { if ip := net.ParseIP(name); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { template.DNSNames = append(template.DNSNames, name) } } derBytes, err := x509.CreateCertificate(rand.Reader, &template, caCert, &priv.PublicKey, caKey) if err != nil { return nil, nil, err } certs, err := x509.ParseCertificates(derBytes) if err != nil { return nil, nil, err } if len(certs) != 1 { return nil, nil, errors.New("Failed to generate a parsable certificate") } return certs[0], priv, nil }