Skip to content

Instantly share code, notes, and snippets.

@yusufsyaifudin
Forked from shaneutt/LICENSE
Created February 25, 2020 08:54
Show Gist options
  • Save yusufsyaifudin/9c8868041414bc6c6878d5125ff4cc61 to your computer and use it in GitHub Desktop.
Save yusufsyaifudin/9c8868041414bc6c6878d5125ff4cc61 to your computer and use it in GitHub Desktop.

Revisions

  1. @shaneutt shaneutt created this gist Jan 19, 2019.
    163 changes: 163 additions & 0 deletions ca_and_cert_golang_demo.go
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,163 @@
    package main

    import (
    "bytes"
    "crypto/rand"
    "crypto/rsa"
    "crypto/tls"
    "crypto/x509"
    "crypto/x509/pkix"
    "encoding/pem"
    "fmt"
    "io/ioutil"
    "math/big"
    "net"
    "net/http"
    "net/http/httptest"
    "strings"
    "time"
    )

    func main() {
    // get our ca and server certificate
    serverTLSConf, clientTLSConf, err := certsetup()
    if err != nil {
    panic(err)
    }

    // set up the httptest.Server using our certificate signed by our CA
    server := httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintln(w, "success!")
    }))
    server.TLS = serverTLSConf
    server.StartTLS()
    defer server.Close()

    // communicate with the server using an http.Client configured to trust our CA
    transport := &http.Transport{
    TLSClientConfig: clientTLSConf,
    }
    http := http.Client{
    Transport: transport,
    }
    resp, err := http.Get(server.URL)
    if err != nil {
    panic(err)
    }

    // verify the response
    respBodyBytes, err := ioutil.ReadAll(resp.Body)
    if err != nil {
    panic(err)
    }
    body := strings.TrimSpace(string(respBodyBytes[:]))
    if body == "success!" {
    fmt.Println(body)
    } else {
    panic("not successful!")
    }
    }

    func certsetup() (serverTLSConf *tls.Config, clientTLSConf *tls.Config, err error) {
    // set up our CA certificate
    ca := &x509.Certificate{
    SerialNumber: big.NewInt(2019),
    Subject: pkix.Name{
    Organization: []string{"Company, INC."},
    Country: []string{"US"},
    Province: []string{""},
    Locality: []string{"San Francisco"},
    StreetAddress: []string{"Golden Gate Bridge"},
    PostalCode: []string{"94016"},
    },
    NotBefore: time.Now(),
    NotAfter: time.Now().AddDate(10, 0, 0),
    IsCA: true,
    ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
    KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
    BasicConstraintsValid: true,
    }

    // create our private and public key
    caPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
    if err != nil {
    return nil, nil, err
    }

    // create the CA
    caBytes, err := x509.CreateCertificate(rand.Reader, ca, ca, &caPrivKey.PublicKey, caPrivKey)
    if err != nil {
    return nil, nil, err
    }

    // pem encode
    caPEM := new(bytes.Buffer)
    pem.Encode(caPEM, &pem.Block{
    Type: "CERTIFICATE",
    Bytes: caBytes,
    })

    caPrivKeyPEM := new(bytes.Buffer)
    pem.Encode(caPrivKeyPEM, &pem.Block{
    Type: "RSA PRIVATE KEY",
    Bytes: x509.MarshalPKCS1PrivateKey(caPrivKey),
    })

    // set up our server certificate
    cert := &x509.Certificate{
    SerialNumber: big.NewInt(2019),
    Subject: pkix.Name{
    Organization: []string{"Company, INC."},
    Country: []string{"US"},
    Province: []string{""},
    Locality: []string{"San Francisco"},
    StreetAddress: []string{"Golden Gate Bridge"},
    PostalCode: []string{"94016"},
    },
    IPAddresses: []net.IP{net.IPv4(127, 0, 0, 1), net.IPv6loopback},
    NotBefore: time.Now(),
    NotAfter: time.Now().AddDate(10, 0, 0),
    SubjectKeyId: []byte{1, 2, 3, 4, 6},
    ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth},
    KeyUsage: x509.KeyUsageDigitalSignature,
    }

    certPrivKey, err := rsa.GenerateKey(rand.Reader, 4096)
    if err != nil {
    return nil, nil, err
    }

    certBytes, err := x509.CreateCertificate(rand.Reader, cert, ca, &certPrivKey.PublicKey, caPrivKey)
    if err != nil {
    return nil, nil, err
    }

    certPEM := new(bytes.Buffer)
    pem.Encode(certPEM, &pem.Block{
    Type: "CERTIFICATE",
    Bytes: certBytes,
    })

    certPrivKeyPEM := new(bytes.Buffer)
    pem.Encode(certPrivKeyPEM, &pem.Block{
    Type: "RSA PRIVATE KEY",
    Bytes: x509.MarshalPKCS1PrivateKey(certPrivKey),
    })

    serverCert, err := tls.X509KeyPair(certPEM.Bytes(), certPrivKeyPEM.Bytes())
    if err != nil {
    return nil, nil, err
    }

    serverTLSConf = &tls.Config{
    Certificates: []tls.Certificate{serverCert},
    }

    certpool := x509.NewCertPool()
    certpool.AppendCertsFromPEM(caPEM.Bytes())
    clientTLSConf = &tls.Config{
    RootCAs: certpool,
    }

    return
    }