-
-
Save miy4mori/038fd7a1174c569718a8cb6abd67a8f8 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
package main | |
import ( | |
"crypto/rand" | |
"crypto/rsa" | |
"crypto/tls" | |
"crypto/x509" | |
"crypto/x509/pkix" | |
"fmt" | |
"log" | |
"math/big" | |
"net" | |
"net/http" | |
"time" | |
) | |
type KeyPair struct { | |
Certificate []byte | |
PrivateKey interface{} | |
} | |
type CertificateOptions struct { | |
Subject pkix.Name | |
ValidFor time.Duration | |
IsCA bool | |
DNSNames []string | |
IPAddresses []net.IP | |
} | |
func GenerateRSAKeyPair(rsaBits int, parent *KeyPair, opts CertificateOptions) (*KeyPair, error) { | |
fail := func(format string, args ...interface{}) (*KeyPair, error) { | |
return nil, fmt.Errorf(format, args) | |
} | |
priv, err := rsa.GenerateKey(rand.Reader, rsaBits) | |
if err != nil { | |
return fail("failed to generate private key: %s", err) | |
} | |
notBefore := time.Now() | |
notAfter := notBefore.Add(opts.ValidFor) | |
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) | |
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) | |
if err != nil { | |
return fail("failed to generate serial number: %s", err) | |
} | |
keyUsage := x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | |
if opts.IsCA { | |
keyUsage |= x509.KeyUsageCertSign | |
} | |
template := x509.Certificate{ | |
SerialNumber: serialNumber, | |
Subject: opts.Subject, | |
NotBefore: notBefore, | |
NotAfter: notAfter, | |
KeyUsage: keyUsage, | |
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, | |
BasicConstraintsValid: true, | |
IsCA: opts.IsCA, | |
DNSNames: opts.DNSNames, | |
IPAddresses: opts.IPAddresses, | |
} | |
var parentCert *x509.Certificate | |
var parentPriv interface{} | |
if parent != nil { | |
parentCert, err = x509.ParseCertificate(parent.Certificate) | |
if err != nil { | |
return fail("failed to parse parent certificate: %s", err) | |
} | |
parentPriv = parent.PrivateKey | |
} else { | |
parentCert = &template | |
parentPriv = priv | |
} | |
derBytes, err := x509.CreateCertificate(rand.Reader, &template, parentCert, &priv.PublicKey, parentPriv) | |
if err != nil { | |
return fail("failed to create certificate: %s", err) | |
} | |
return &KeyPair{ | |
Certificate: derBytes, | |
PrivateKey: priv, | |
}, nil | |
} | |
func main() { | |
rootKeyPair, err := GenerateRSAKeyPair(1024, nil, CertificateOptions{ | |
Subject: pkix.Name{ | |
Organization: []string{"OpenShift Test Suite"}, | |
}, | |
ValidFor: 24 * time.Hour, | |
IsCA: true, | |
}) | |
if err != nil { | |
log.Fatal(err) | |
} | |
keyPair, err := GenerateRSAKeyPair(1024, rootKeyPair, CertificateOptions{ | |
Subject: pkix.Name{ | |
Organization: []string{"Server Certificate"}, | |
CommonName: "localhost", | |
}, | |
ValidFor: 12 * time.Hour, | |
}) | |
if err != nil { | |
log.Fatal(err) | |
} | |
config := &tls.Config{ | |
Certificates: []tls.Certificate{{ | |
Certificate: [][]byte{keyPair.Certificate}, | |
PrivateKey: keyPair.PrivateKey, | |
}}, | |
} | |
server := &http.Server{ | |
Addr: ":8443", | |
TLSConfig: config, | |
} | |
log.Fatal(server.ListenAndServeTLS("", "")) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment