From 3ef5a67efc3115983142ae53eb4c75dec54e9a4f Mon Sep 17 00:00:00 2001 From: Kali Kaneko Date: Thu, 13 Jun 2019 12:03:27 +0200 Subject: initial commit --- .gitignore | 1 + certs.go | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 30 +++++++++++++++++++++ test/files/ca.crt | 15 +++++++++++ test/files/ca.key | 16 ++++++++++++ 5 files changed, 140 insertions(+) create mode 100644 .gitignore create mode 100644 certs.go create mode 100644 main.go create mode 100644 test/files/ca.crt create mode 100644 test/files/ca.key diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..59c1baa --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +vpnweb diff --git a/certs.go b/certs.go new file mode 100644 index 0000000..f53b322 --- /dev/null +++ b/certs.go @@ -0,0 +1,78 @@ +package main + +import ( + "crypto/rand" + "crypto/rsa" + "crypto/tls" + "crypto/x509" + "crypto/x509/pkix" + "encoding/pem" + "io" + "math/big" + mrand "math/rand" + "time" +) + +const certPrefix = "UNLIMITED" + +var letterRunes = []rune("abcdefghijklmnopqrstuvwxyz") + +func RandStringRunes(n int) string { + b := make([]rune, n) + for i := range b { + b[i] = letterRunes[mrand.Intn(len(letterRunes))] + } + return string(b) +} + +type caInfo struct { + cacrt, cakey string +} + +func newCaInfo(cacrt string, cakey string) caInfo { + return caInfo{cacrt, cakey} +} + +// CertWriter main handler +func (ci *caInfo) CertWriter(out io.Writer) { + catls, err := tls.LoadX509KeyPair(ci.cacrt, ci.cakey) + + if err != nil { + panic(err) + } + ca, err := x509.ParseCertificate(catls.Certificate[0]) + if err != nil { + panic(err) + } + serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) + serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) + + subjectKeyID := make([]byte, 20) + rand.Read(subjectKeyID) + + // Prepare certificate + cert := &x509.Certificate{ + SerialNumber: serialNumber, + Subject: pkix.Name{ + CommonName: certPrefix + RandStringRunes(25), + }, + NotBefore: time.Now().AddDate(0, 0, -7), + NotAfter: time.Now().AddDate(0, 0, expiryDays), + + SubjectKeyId: subjectKeyID, + + ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth}, + KeyUsage: x509.KeyUsageDigitalSignature, + } + priv, _ := rsa.GenerateKey(rand.Reader, keySize) + pub := &priv.PublicKey + + // Sign the certificate + certB, err := x509.CreateCertificate(rand.Reader, cert, ca, pub, catls.PrivateKey) + + // Write the private Key + pem.Encode(out, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) + + // Write the public key + pem.Encode(out, &pem.Block{Type: "CERTIFICATE", Bytes: certB}) +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..233a26d --- /dev/null +++ b/main.go @@ -0,0 +1,30 @@ +package main + +import ( + "flag" + "net/http" +) + +const keySize = 2048 +const expiryDays = 28 + +type certHandler struct { + cainfo caInfo +} + +func (ch *certHandler) certResponder(w http.ResponseWriter, r *http.Request) { + ch.cainfo.CertWriter(w) +} + +func main() { + var caCrt = flag.String("caCrt", "", "path to the CA public key") + var caKey = flag.String("caKey", "", "path to the CA private key") + + flag.Parse() + + ci := newCaInfo(*caCrt, *caKey) + ch := certHandler{ci} + + http.HandleFunc("/cert", ch.certResponder) + http.ListenAndServe(":8000", nil) +} diff --git a/test/files/ca.crt b/test/files/ca.crt new file mode 100644 index 0000000..8393eee --- /dev/null +++ b/test/files/ca.crt @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICYDCCAcCgAwIBAgIBATANBgkqhkiG9w0BAQ0FADA7MREwDwYDVQQKDAh0ZXN0 +IG9yZzESMBAGA1UECwwJdGVzdCB1bml0MRIwEAYDVQQDDAl0ZXN0IG5hbWUwIBcN +MTMwMjA1MDAwMDAwWhgPMjExMzAyMDUwMDAwMDBaMDsxETAPBgNVBAoMCHRlc3Qg +b3JnMRIwEAYDVQQLDAl0ZXN0IHVuaXQxEjAQBgNVBAMMCXRlc3QgbmFtZTCBqDAN +BgkqhkiG9w0BAQEFAAOBlgAwgZICgYoAx076Dz8zswvCLuz0HP3Y3PWOgFDo9+8o +H4uXRcTpd+yw+5B79xjtQ7ojQy2465Jq00nkzHI6V1otM2uvVVIOcNk0t1HEjmK0 +T/r96dDHc59YvVQ+XPrzuQ4t3iREy8IAPNbc3r29PVZkMdGpeSYxyY1mUKza4DcY +My4SVko9pcP8zJBD4bHgEa0CAwEAAaNgMF4wHQYDVR0OBBYEFOQ+d2EUwBpi93TJ +9AX4Okew5/UIMA4GA1UdDwEB/wQEAwICBDAMBgNVHRMEBTADAQH/MB8GA1UdIwQY +MBaAFOQ+d2EUwBpi93TJ9AX4Okew5/UIMA0GCSqGSIb3DQEBDQUAA4GKAJW9/39P +VbVjH9C7F0XMOpd9nWBe9NUoiw36ZFZw95dqfUm6j5f3nejWG4lEtyMFu5i5rAw6 +GdDSXmq4sUqWTaJmQmZyY+WggQR4UGWJ0I18HRDiPxuA++OfkGzA20Gmvk+CIw/J +QLHlVjLyyUwaA+EO88rEcdc9VnGL/Xgjh8C/PYH2DpWw/kJa +-----END CERTIFICATE----- diff --git a/test/files/ca.key b/test/files/ca.key new file mode 100644 index 0000000..125997f --- /dev/null +++ b/test/files/ca.key @@ -0,0 +1,16 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIChAIBAAKBigDHTvoPPzOzC8Iu7PQc/djc9Y6AUOj37ygfi5dFxOl37LD7kHv3 +GO1DuiNDLbjrkmrTSeTMcjpXWi0za69VUg5w2TS3UcSOYrRP+v3p0Mdzn1i9VD5c ++vO5Di3eJETLwgA81tzevb09VmQx0al5JjHJjWZQrNrgNxgzLhJWSj2lw/zMkEPh +seARrQIDAQABAoGJIvn0HircOsaMfEmvCUtu/E/HgzMvvxrkMqz/jgnhYt9Rq8QO +TS29rY4D1C0473ZRcuTb1xkQrfWwSv7R1SpCSIGFo8obtGb0NjNaYGyQ0IrYDjk8 +H5kYFEY4X4oqFhgy3owewaZZLxLD336ARRj2HhsLzA+4nD/wF7Q+bggpuMdkM2Uj +tn12rIECRQ/XqIGF8jLw9IDMkr9kkfT+n03p8sOd4g7iSw0sknlzaZZpIDvibkyN +SDKM7VX4VQa7u58+sCF4ylwi0UQu7/VT7Smp4QJFDJSoEOKplBvaT9fTfdVKjE4P +QyCAWEsb6Up8KKswhtDqiWeFtktIvx1Mkxn25erLms3cUEBde//rwNB+6ItBR/N8 +4RlNAkUPLsc3Gn+7gmFQ7r3U3zViboON0B/wiWcUjJsQzR6zdoBCvg0+VwsOIniG +ubjbI1uZUGHHg/SYn4KQOm4DwlgF7aDkxQECRQjVZMEedlXxzLOdZvoHBuZHdT38 +F0Jn0rxXOaDQuy0eimBamS+r4vOWngr4Az3jRH15KMYMu9dyllX3z/R2uyrLVBc2 +TQJFBEHIjoMVgP2h+N6VUDgPOhnxnnLvowOtX23J1y2foKwfZrHH38LNcWmuaGUi +fz6EYeUO20D174GfhqB0j6yR50ejPjYD +-----END RSA PRIVATE KEY----- -- cgit v1.2.3