-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add tls authentication for transport
Signed-off-by: Alay Patel <[email protected]>
- Loading branch information
1 parent
402af80
commit a03075b
Showing
5 changed files
with
341 additions
and
80 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 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 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,163 @@ | ||
package certs | ||
|
||
import ( | ||
"bytes" | ||
"crypto/rand" | ||
"crypto/rsa" | ||
"crypto/x509" | ||
"crypto/x509/pkix" | ||
"encoding/pem" | ||
"math/big" | ||
"time" | ||
) | ||
|
||
var ( | ||
keySize = 2048 | ||
defaultCASubject = &pkix.Name{ | ||
Country: []string{"US"}, | ||
Province: []string{"NC"}, | ||
Locality: []string{"RDU"}, | ||
Organization: []string{"Backube"}, | ||
OrganizationalUnit: []string{"Engineering"}, | ||
// This does not have to be a domain name, but certain implementations/configuration | ||
// verify the requests from other side using this and SAN fields. | ||
CommonName: "ca.backube.dev", | ||
} | ||
defaultCrtSubject = &pkix.Name{ | ||
Country: []string{"US"}, | ||
Province: []string{"NC"}, | ||
Locality: []string{"RDU"}, | ||
Organization: []string{"Backube"}, | ||
OrganizationalUnit: []string{"Engineering"}, | ||
CommonName: "cert.backube.dev", | ||
} | ||
) | ||
|
||
// CertificateBundle stores the data used for create | ||
type CertificateBundle struct { | ||
caRSAKey *rsa.PrivateKey | ||
caCrtTemplate *x509.Certificate | ||
|
||
CACrt *bytes.Buffer | ||
CAKey *bytes.Buffer | ||
ServerCrt *bytes.Buffer | ||
ServerKey *bytes.Buffer | ||
ClientCrt *bytes.Buffer | ||
ClientKey *bytes.Buffer | ||
} | ||
|
||
func New() (*CertificateBundle, error) { | ||
c := &CertificateBundle{} | ||
var err error | ||
c.CACrt, c.caRSAKey, c.caCrtTemplate, err = GenerateCA(defaultCASubject) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
c.CAKey, err = rsaKeyBytes(c.caRSAKey) | ||
|
||
c.ServerCrt, c.ServerKey, err = Generate(defaultCrtSubject, *c.caCrtTemplate, *c.caRSAKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
c.ClientCrt, c.ClientKey, err = Generate(defaultCrtSubject, *c.caCrtTemplate, *c.caRSAKey) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return c, nil | ||
} | ||
|
||
// GenerateCA take a subject and returns caCrt, caKey and caCrtTemplate | ||
// The caKey and caCrtTemplate should be passed into Generate | ||
// along with a similar subject except the CN name should be different from | ||
// the CA. | ||
func GenerateCA(subject *pkix.Name) (caCrt *bytes.Buffer, caKey *rsa.PrivateKey, caCrtTemplate *x509.Certificate, err error) { | ||
if subject == nil { | ||
subject = defaultCASubject | ||
} | ||
caCrtTemplate = &x509.Certificate{ | ||
SerialNumber: big.NewInt(2021), | ||
Subject: *subject, | ||
NotBefore: time.Now(), | ||
NotAfter: time.Now().AddDate(10, 0, 0), | ||
IsCA: true, | ||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth, x509.ExtKeyUsageAny}, | ||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, | ||
BasicConstraintsValid: true, | ||
} | ||
caCrt, caKey, err = createCrtKeyPair(caCrtTemplate, nil, nil) | ||
if err != nil { | ||
return | ||
} | ||
return | ||
} | ||
|
||
// Generate takes a subject, caCrtTemplate and caKey and returns crt, key and error | ||
// if error is not nil, do not rely on crt or keys being not nil. | ||
func Generate(subject *pkix.Name, caCrtTemplate x509.Certificate, caKey rsa.PrivateKey) (crt *bytes.Buffer, key *bytes.Buffer, err error) { | ||
crtTemplate := &x509.Certificate{ | ||
SerialNumber: big.NewInt(2020), | ||
Subject: *subject, | ||
NotBefore: time.Now(), | ||
NotAfter: time.Now().AddDate(10, 0, 0), | ||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, | ||
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, | ||
} | ||
|
||
crt, rsaKey, err := createCrtKeyPair(crtTemplate, &caCrtTemplate, &caKey) | ||
if err != nil { | ||
return | ||
} | ||
key, err = rsaKeyBytes(rsaKey) | ||
if err != nil { | ||
return | ||
} | ||
return | ||
} | ||
|
||
func createCrtKeyPair(crtTemplate, parent *x509.Certificate, signer *rsa.PrivateKey) (crt *bytes.Buffer, key *rsa.PrivateKey, err error) { | ||
key, err = rsa.GenerateKey(rand.Reader, keySize) | ||
if err != nil { | ||
return | ||
} | ||
if parent == nil { | ||
parent = crtTemplate | ||
} | ||
if signer == nil { | ||
signer = key | ||
} | ||
|
||
crtBytes, err := x509.CreateCertificate( | ||
rand.Reader, | ||
crtTemplate, | ||
parent, | ||
&key.PublicKey, | ||
signer, | ||
) | ||
if err != nil { | ||
return | ||
} | ||
|
||
crt = new(bytes.Buffer) | ||
err = pem.Encode(crt, &pem.Block{ | ||
Type: "CERTIFICATE", | ||
Bytes: crtBytes, | ||
}) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
return | ||
} | ||
|
||
func rsaKeyBytes(key *rsa.PrivateKey) (keyBytes *bytes.Buffer, err error) { | ||
keyBytes = new(bytes.Buffer) | ||
err = pem.Encode(keyBytes, &pem.Block{ | ||
Type: "RSA PRIVATE KEY", | ||
Bytes: x509.MarshalPKCS1PrivateKey(key), | ||
}) | ||
if err != nil { | ||
return | ||
} | ||
return | ||
} |
Oops, something went wrong.