Skip to content

Instantly share code, notes, and snippets.

@dvas0004
Created June 17, 2015 13:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dvas0004/82250551f34c77e0b35a to your computer and use it in GitHub Desktop.
Save dvas0004/82250551f34c77e0b35a to your computer and use it in GitHub Desktop.
Example of Golang embedding, see http://blog.davidvassallo.me/?p=1650
package main
import (
"io"
"net/http"
"log"
"crypto/tls"
"net"
"sixpmplc.com/golang/license_server/tls_common"
)
type embeddedServer struct {
/*
custom struct that embeds golang's standard http.Server type
another way of looking at this is that embeddedServer "inherits" from http.Server,
though this is not strictly accurate. Have a look at note below for additional information
*/
http.Server
webserverCertificate string
webserverKey string
}
func (srv *embeddedServer) ListenAndServeTLS(addr string) error {
/*
This is where we "hide" or "override" the default "ListenAndServeTLS" method so we modify it to accept
hardcoded certificates and keys rather than the default filenames
The default implementation of ListenAndServeTLS was obtained from:
https://github.com/zenazn/goji/blob/master/graceful/server.go#L33
and tls.X509KeyPair (http://golang.org/pkg/crypto/tls/#X509KeyPair) is used,
rather than the default tls.LoadX509KeyPair
*/
config := &tls.Config{
MinVersion: tls.VersionTLS10,
}
if srv.TLSConfig != nil {
*config = *srv.TLSConfig
}
if config.NextProtos == nil {
config.NextProtos = []string{"http/1.1"}
}
var err error
config.Certificates = make([]tls.Certificate, 1)
config.Certificates[0], err = tls.X509KeyPair([]byte(srv.webserverCertificate), []byte(srv.webserverKey))
if err != nil {
return err
}
conn, err := net.Listen("tcp", addr)
if err != nil {
return err
}
tlsListener := tls.NewListener(conn, config)
return srv.Serve(tlsListener)
}
func hello(w http.ResponseWriter, r *http.Request) {
io.WriteString(w, "Hello world!")
}
func main() {
// instantiating an embeddedServer type, and assigning hardcoded TLS certificate and key
embeddedTLSserver := &embeddedServer{
webserverCertificate: tls_common.WebserverCertificate,
webserverKey: tls_common.WebserverPrivateKey,
}
// reference: https://golang.org/doc/articles/wiki/
http.HandleFunc("/", hello)
http.HandleFunc("/decrypt", decryptMessage)
http.HandleFunc("/verify", verifyMessage)
/*
reference: http://golang.org/pkg/net/http/#ListenAndServeTLS
Normally we would call an TLS server using the ListenAndServeTLS as described above, resulting in a call similar to:
http.ListenAndServeTLS(":10443", "server.crt", "server.key", nil)
However, we have a problem with that because it references external files, which we dont want. Since this executable
is going to be installed in a "hostile" environment, we want to make sure that all sensitive information like
certificates and private keys are hardcoded into the executable.
Unfortunately, we can't simply set the TLSConfig attribute of http.Server (why golang gods, why?!)
So we need to write our own implementation of ListenAndServeTLS.
This is where "embeddedServer" type comes in. Note that we define "type embeddedServer struct" towards the beginning
of this program. We then proceed to use a feature of golang called "embedding". Please refer to the following link
for more information:
http://www.hydrogen18.com/blog/golang-embedding.html
*/
log.Fatal(embeddedTLSserver.ListenAndServeTLS(":10443"))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment