Automatic Creation of SSL Certificates (#443)

Thanks @ss23!
pull/446/head
Jordan Wright 2016-11-19 12:04:10 -06:00 committed by GitHub
parent f12af50d46
commit 0f5bf29972
3 changed files with 89 additions and 3 deletions

View File

@ -1,9 +1,9 @@
{ {
"admin_server" : { "admin_server" : {
"listen_url" : "127.0.0.1:3333", "listen_url" : "127.0.0.1:3333",
"use_tls" : false, "use_tls" : true,
"cert_path" : "example.crt", "cert_path" : "gophish_admin.crt",
"key_path" : "example.key" "key_path" : "gophish_admin.key"
}, },
"phish_server" : { "phish_server" : {
"listen_url" : "0.0.0.0:80", "listen_url" : "0.0.0.0:80",

View File

@ -37,6 +37,7 @@ import (
"github.com/gophish/gophish/config" "github.com/gophish/gophish/config"
"github.com/gophish/gophish/controllers" "github.com/gophish/gophish/controllers"
"github.com/gophish/gophish/models" "github.com/gophish/gophish/models"
"github.com/gophish/gophish/util"
"github.com/gorilla/handlers" "github.com/gorilla/handlers"
) )
@ -56,6 +57,10 @@ func main() {
adminHandler := gziphandler.GzipHandler(controllers.CreateAdminRouter()) adminHandler := gziphandler.GzipHandler(controllers.CreateAdminRouter())
auth.Store.Options.Secure = config.Conf.AdminConf.UseTLS auth.Store.Options.Secure = config.Conf.AdminConf.UseTLS
if config.Conf.AdminConf.UseTLS { // use TLS for Admin web server if available if config.Conf.AdminConf.UseTLS { // use TLS for Admin web server if available
err := util.CheckAndCreateSSL(config.Conf.AdminConf.CertPath, config.Conf.AdminConf.KeyPath)
if err != nil {
Logger.Fatal(err)
}
Logger.Printf("Starting admin server at https://%s\n", config.Conf.AdminConf.ListenURL) Logger.Printf("Starting admin server at https://%s\n", config.Conf.AdminConf.ListenURL)
Logger.Fatal(http.ListenAndServeTLS(config.Conf.AdminConf.ListenURL, config.Conf.AdminConf.CertPath, config.Conf.AdminConf.KeyPath, Logger.Fatal(http.ListenAndServeTLS(config.Conf.AdminConf.ListenURL, config.Conf.AdminConf.CertPath, config.Conf.AdminConf.KeyPath,
handlers.CombinedLoggingHandler(os.Stdout, adminHandler))) handlers.CombinedLoggingHandler(os.Stdout, adminHandler)))

View File

@ -1,17 +1,31 @@
package util package util
import ( import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/csv" "encoding/csv"
"encoding/pem"
"errors"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"log"
"math/big"
"net/http" "net/http"
"net/mail" "net/mail"
"os"
"time"
"github.com/gophish/gophish/models" "github.com/gophish/gophish/models"
"github.com/jordan-wright/email" "github.com/jordan-wright/email"
) )
// Logger is used to send logging messages to stdout.
var Logger = log.New(os.Stdout, " ", log.Ldate|log.Ltime|log.Lshortfile)
// ParseMail takes in an HTTP Request and returns an Email object // ParseMail takes in an HTTP Request and returns an Email object
// TODO: This function will likely be changed to take in a []byte // TODO: This function will likely be changed to take in a []byte
func ParseMail(r *http.Request) (email.Email, error) { func ParseMail(r *http.Request) (email.Email, error) {
@ -96,3 +110,70 @@ func ParseCSV(r *http.Request) ([]models.Target, error) {
} }
return ts, nil return ts, nil
} }
// CheckAndCreateSSL is a helper to setup self-signed certificates for the administrative interface.
func CheckAndCreateSSL(cp string, kp string) error {
// Check whether there is an existing SSL certificate and/or key, and if so, abort execution of this function
if _, err := os.Stat(cp); !os.IsNotExist(err) {
return nil
}
if _, err := os.Stat(kp); !os.IsNotExist(err) {
return nil
}
Logger.Printf("Creating new self-signed certificates for administration interface...\n")
priv, err := ecdsa.GenerateKey(elliptic.P384(), rand.Reader)
notBefore := time.Now()
// Generate a certificate that lasts for 10 years
notAfter := notBefore.Add(10 * 365 * 24 * time.Hour)
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128)
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit)
if err != nil {
return errors.New(fmt.Sprintf("TLS Certificate Generation: Failed to generate a random serial number: %s", err))
}
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Organization: []string{"Gophish"},
},
NotBefore: notBefore,
NotAfter: notAfter,
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
}
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, priv.Public(), priv)
if err != nil {
return errors.New(fmt.Sprintf("TLS Certificate Generation: Failed to create certificate: %s", err))
}
certOut, err := os.Create(cp)
if err != nil {
return errors.New(fmt.Sprintf("TLS Certificate Generation: Failed to open %s for writing: %s", cp, err))
}
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
certOut.Close()
keyOut, err := os.OpenFile(kp, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return errors.New(fmt.Sprintf("TLS Certificate Generation: Failed to open %s for writing", kp))
}
b, err := x509.MarshalECPrivateKey(priv)
if err != nil {
return errors.New(fmt.Sprintf("TLS Certificate Generation: Unable to marshal ECDSA private key: %v", err))
}
pem.Encode(keyOut, &pem.Block{Type: "EC PRIVATE KEY", Bytes: b})
keyOut.Close()
Logger.Println("TLS Certificate Generation complete")
return nil
}