-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reworked autocert to it's own repo and made later customization easier
- Loading branch information
Zach Brown
committed
Dec 1, 2018
1 parent
f952c95
commit a0ea4ed
Showing
5 changed files
with
202 additions
and
130 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
package autocert | ||
|
||
import ( | ||
"crypto/ecdsa" | ||
"crypto/elliptic" | ||
"crypto/tls" | ||
"crypto/x509" | ||
"crypto/x509/pkix" | ||
"encoding/pem" | ||
"fmt" | ||
"io" | ||
"math/big" | ||
"net" | ||
"net/url" | ||
"time" | ||
) | ||
|
||
type AutoCertOption func(*x509.Certificate) | ||
|
||
// AutoCert generates a self-signed cert using the specified keyReader for a source for private key generation | ||
func New(keyReader io.Reader, opts ...AutoCertOption) (tls.Certificate, error) { | ||
|
||
// Generate the key | ||
privKey, err := ecdsa.GenerateKey(elliptic.P256(), keyReader) | ||
if err != nil { | ||
return tls.Certificate{}, fmt.Errorf("Could not generate private key: %v\n", err) | ||
} | ||
|
||
// Build Cert | ||
cert := x509.Certificate{ | ||
SerialNumber: big.NewInt(0), | ||
Subject: pkix.Name{ | ||
CommonName: "localhost", | ||
}, | ||
|
||
// Starting jan 1, 2010 for 100 years | ||
NotBefore: time.Date(2010, 1, 1, 0, 0, 0, 0, time.UTC), | ||
NotAfter: time.Date(2010, 1, 1, 0, 0, 0, 0, time.UTC).Add(100 * 365 * 24 * time.Hour), | ||
|
||
IsCA: true, | ||
|
||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, | ||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, | ||
|
||
BasicConstraintsValid: true, | ||
} | ||
|
||
// Apply the options | ||
for _, f := range opts { | ||
f(&cert) | ||
} | ||
|
||
// Create Cert | ||
derBytes, err := x509.CreateCertificate(keyReader, &cert, &cert, &privKey.PublicKey, privKey) | ||
if err != nil { | ||
return tls.Certificate{}, fmt.Errorf("Failed to create certificate: %s", err) | ||
} | ||
|
||
pKeyBytes, err := x509.MarshalECPrivateKey(privKey) | ||
if err != nil { | ||
return tls.Certificate{}, fmt.Errorf("Failed to marshal private key: %s", err) | ||
} | ||
|
||
certBytes := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) | ||
privBytes := pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: pKeyBytes}) | ||
|
||
tlsCert, err := tls.X509KeyPair(certBytes, privBytes) | ||
if err != nil { | ||
return tls.Certificate{}, fmt.Errorf("Failed to load key-pair: %s", err) | ||
} | ||
|
||
return tlsCert, nil | ||
} | ||
|
||
// SerialNummber sets the serial number for the cert | ||
func SerialNumber(sn int64) AutoCertOption { | ||
return func(c *x509.Certificate) { | ||
c.SerialNumber = big.NewInt(sn) | ||
} | ||
} | ||
|
||
// CommonName sets the commont name of the certificate | ||
func CommonName(cn string) AutoCertOption { | ||
return func(c *x509.Certificate) { | ||
c.Subject = pkix.Name{ | ||
CommonName: cn, | ||
} | ||
} | ||
} | ||
|
||
// Organization sets the Organization(s) of the cert subject | ||
func Organization(o []string) AutoCertOption { | ||
return func(c *x509.Certificate) { | ||
c.Subject.Organization = o | ||
} | ||
} | ||
|
||
// OrganizationalUnit sets the OrganizationalUnit(s) of the cert subject | ||
func OrganizationalUnit(ou []string) AutoCertOption { | ||
return func(c *x509.Certificate) { | ||
c.Subject.OrganizationalUnit = ou | ||
} | ||
} | ||
|
||
// DNSNames sets the DNS names of the cert | ||
func DNSNames(dnsNames []string) AutoCertOption { | ||
return func(c *x509.Certificate) { | ||
c.DNSNames = dnsNames | ||
} | ||
} | ||
|
||
// URIs sets the URIs of the cert | ||
func URIs(uris []*url.URL) AutoCertOption { | ||
return func(c *x509.Certificate) { | ||
c.URIs = uris | ||
} | ||
} | ||
|
||
// IPAddresses sets the IPAddresses of the cert | ||
func IPAddresses(ips []net.IP) AutoCertOption { | ||
return func(c *x509.Certificate) { | ||
c.IPAddresses = ips | ||
} | ||
} | ||
|
||
// ValidTimes sets the times in which this cert is valid | ||
func ValidTimes(notBefore time.Time, notAfter time.Time) AutoCertOption { | ||
return func(c *x509.Certificate) { | ||
c.NotBefore = notBefore | ||
c.NotAfter = notAfter | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package autocert | ||
|
||
// InsecureGlobalStatic is a non-random byte reader that can be used to generaate an insecure private key | ||
// This will generate the same bytes on every box (all zeros). It is horribly insecure. | ||
type InsecureGlobalStatic struct{} | ||
|
||
func InsecureGlobalStaticReader() InsecureGlobalStatic { | ||
return InsecureGlobalStatic{} | ||
} | ||
|
||
func (r InsecureGlobalStatic) Read(s []byte) (int, error) { | ||
// Set it to all zeros | ||
l := len(s) | ||
for x := 0; x < l; x++ { | ||
s[x] = 0 | ||
} | ||
return l, nil | ||
} | ||
|
||
// InsecureString is a non-random bytes reader that can be used to generate an insecure private key based on a provided string | ||
// The upside of this is that the same string input should yield the same bytes so you can send in something like the hostname | ||
// and it will generate the same output everytime you run your program. | ||
// The downside is that it is very insecure and should only be used for testing | ||
type InsecureString struct { | ||
seed []byte | ||
pos int | ||
length int | ||
} | ||
|
||
func InsecureStringReader(seed string) *InsecureString { | ||
// Ensure there is at least one character in seed | ||
if len(seed) == 0 { | ||
seed = " " | ||
} | ||
return &InsecureString{ | ||
seed: []byte(seed), | ||
pos: 0, | ||
length: len(seed), | ||
} | ||
} | ||
func (r *InsecureString) Read(s []byte) (int, error) { | ||
// Just repead the string over and over | ||
l := len(s) | ||
for x := 0; x < l; x++ { | ||
s[x] = r.seed[r.pos%r.length] | ||
r.pos++ | ||
} | ||
return l, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters