gofmt the .go files

#2
This commit is contained in:
Arjan H
2018-11-18 10:28:29 +01:00
parent 40693aa8d6
commit 472958ea03
4 changed files with 3078 additions and 3081 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,485 +1,485 @@
package main
import (
"errors"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"os"
"os/exec"
"path/filepath"
"runtime/debug"
"strings"
"errors"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"os"
"os/exec"
"path/filepath"
"runtime/debug"
"strings"
)
type CertificateInfo struct {
IsRoot bool
KeyTypes map[string]string
KeyType string
CreateType string
IsRoot bool
KeyTypes map[string]string
KeyType string
CreateType string
Country string
Organization string
OrgUnit string
CommonName string
Country string
Organization string
OrgUnit string
CommonName string
ImportFile multipart.File
ImportHandler *multipart.FileHeader
ImportPwd string
ImportFile multipart.File
ImportHandler *multipart.FileHeader
ImportPwd string
Key string
Passphrase string
Certificate string
Key string
Passphrase string
Certificate string
RequestBase string
Errors map[string]string
RequestBase string
Errors map[string]string
}
func (ci *CertificateInfo) Initialize() {
ci.Errors = make(map[string]string)
ci.Errors = make(map[string]string)
ci.KeyTypes = make(map[string]string)
ci.KeyTypes["rsa4096"] = "RSA-4096"
ci.KeyTypes["rsa3072"] = "RSA-3072"
ci.KeyTypes["rsa2048"] = "RSA-2048"
ci.KeyTypes["ecdsa384"] = "ECDSA-384"
ci.KeyTypes["ecdsa256"] = "ECDSA-256"
ci.KeyTypes = make(map[string]string)
ci.KeyTypes["rsa4096"] = "RSA-4096"
ci.KeyTypes["rsa3072"] = "RSA-3072"
ci.KeyTypes["rsa2048"] = "RSA-2048"
ci.KeyTypes["ecdsa384"] = "ECDSA-384"
ci.KeyTypes["ecdsa256"] = "ECDSA-256"
ci.KeyType = "rsa4096"
ci.KeyType = "rsa4096"
}
func (ci *CertificateInfo) Validate() bool {
ci.Errors = make(map[string]string)
ci.Errors = make(map[string]string)
if ci.CreateType == "generate" {
if strings.TrimSpace(ci.KeyType) == "" || strings.TrimSpace(ci.KeyTypes[ci.KeyType]) == "" {
ci.Errors["KeyType"] = "Please select a key type/size"
}
if strings.TrimSpace(ci.Country) == "" || len(ci.Country) < 2 {
ci.Errors["Country"] = "Please enter a valid 2-character country code"
}
if strings.TrimSpace(ci.Organization) == "" {
ci.Errors["Organization"] = "Please enter an organization name"
}
if strings.TrimSpace(ci.CommonName) == "" {
ci.Errors["CommonName"] = "Please enter a common name"
}
}
if ci.CreateType == "generate" {
if strings.TrimSpace(ci.KeyType) == "" || strings.TrimSpace(ci.KeyTypes[ci.KeyType]) == "" {
ci.Errors["KeyType"] = "Please select a key type/size"
}
if strings.TrimSpace(ci.Country) == "" || len(ci.Country) < 2 {
ci.Errors["Country"] = "Please enter a valid 2-character country code"
}
if strings.TrimSpace(ci.Organization) == "" {
ci.Errors["Organization"] = "Please enter an organization name"
}
if strings.TrimSpace(ci.CommonName) == "" {
ci.Errors["CommonName"] = "Please enter a common name"
}
}
if (ci.CreateType == "import") && (ci.ImportHandler != nil) {
ext := ci.ImportHandler.Filename[len(ci.ImportHandler.Filename)-4:]
if (ci.ImportHandler.Size == 0) || (ext != ".zip" && ext != ".pfx") {
ci.Errors["Import"] = "Please provide a bundle (.pfx or .zip) with a key and certificate"
}
}
if (ci.CreateType == "import") && (ci.ImportHandler != nil) {
ext := ci.ImportHandler.Filename[len(ci.ImportHandler.Filename)-4:]
if (ci.ImportHandler.Size == 0) || (ext != ".zip" && ext != ".pfx") {
ci.Errors["Import"] = "Please provide a bundle (.pfx or .zip) with a key and certificate"
}
}
if ci.CreateType == "upload" {
if strings.TrimSpace(ci.Key) == "" {
ci.Errors["Key"] = "Please provide a PEM-encoded key"
}
if strings.TrimSpace(ci.Certificate) == "" {
ci.Errors["Certificate"] = "Please provide a PEM-encoded certificate"
}
}
if ci.CreateType == "upload" {
if strings.TrimSpace(ci.Key) == "" {
ci.Errors["Key"] = "Please provide a PEM-encoded key"
}
if strings.TrimSpace(ci.Certificate) == "" {
ci.Errors["Certificate"] = "Please provide a PEM-encoded certificate"
}
}
return len(ci.Errors) == 0
return len(ci.Errors) == 0
}
func reportError(err error) error {
lines := strings.Split(string(debug.Stack()), "\n")
if len(lines) >= 5 {
lines = append(lines[:0], lines[5:]...)
}
lines := strings.Split(string(debug.Stack()), "\n")
if len(lines) >= 5 {
lines = append(lines[:0], lines[5:]...)
}
stop := len(lines)
for i := 0; i < len(lines); i++ {
if strings.Index(lines[i], ".ServeHTTP(") >= 0 {
stop = i
break
}
}
lines = lines[:stop]
lines = append(lines, "...")
stop := len(lines)
for i := 0; i < len(lines); i++ {
if strings.Index(lines[i], ".ServeHTTP(") >= 0 {
stop = i
break
}
}
lines = lines[:stop]
lines = append(lines, "...")
fmt.Println(strings.Join(lines, "\n"))
fmt.Println(strings.Join(lines, "\n"))
return errors.New("Error (" + err.Error() + ")! See LabCA logs for details")
return errors.New("Error (" + err.Error() + ")! See LabCA logs for details")
}
func preCreateTasks(path string) error {
if _, err := exe_cmd("touch " + path + "index.txt"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("touch " + path + "index.txt.attr"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("touch " + path + "index.txt"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("touch " + path + "index.txt.attr"); err != nil {
return reportError(err)
}
if _, err := os.Stat(path + "serial"); os.IsNotExist(err) {
if err := ioutil.WriteFile(path+"serial", []byte("1000\n"), 0644); err != nil {
return err
}
}
if _, err := os.Stat(path + "crlnumber"); os.IsNotExist(err) {
if err = ioutil.WriteFile(path+"crlnumber", []byte("1000\n"), 0644); err != nil {
return err
}
}
if _, err := os.Stat(path + "serial"); os.IsNotExist(err) {
if err := ioutil.WriteFile(path+"serial", []byte("1000\n"), 0644); err != nil {
return err
}
}
if _, err := os.Stat(path + "crlnumber"); os.IsNotExist(err) {
if err = ioutil.WriteFile(path+"crlnumber", []byte("1000\n"), 0644); err != nil {
return err
}
}
if _, err := exe_cmd("mkdir -p " + path + "certs"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("mkdir -p " + path + "certs"); err != nil {
return reportError(err)
}
return nil
return nil
}
func (ci *CertificateInfo) Create(path string, certBase string) error {
if err := preCreateTasks(path); err != nil {
return err
}
if err := preCreateTasks(path); err != nil {
return err
}
tmpDir, err := ioutil.TempDir("", "labca")
if err != nil {
return err
}
tmpDir, err := ioutil.TempDir("", "labca")
if err != nil {
return err
}
defer os.RemoveAll(tmpDir)
defer os.RemoveAll(tmpDir)
var tmpKey string
var tmpCert string
if ci.IsRoot {
tmpKey = filepath.Join(tmpDir, "root-ca.key")
tmpCert = filepath.Join(tmpDir, "root-ca.pem")
} else {
tmpKey = filepath.Join(tmpDir, "ca-int.key")
tmpCert = filepath.Join(tmpDir, "ca-int.pem")
}
var tmpKey string
var tmpCert string
if ci.IsRoot {
tmpKey = filepath.Join(tmpDir, "root-ca.key")
tmpCert = filepath.Join(tmpDir, "root-ca.pem")
} else {
tmpKey = filepath.Join(tmpDir, "ca-int.key")
tmpCert = filepath.Join(tmpDir, "ca-int.pem")
}
if ci.CreateType == "generate" {
// 1. Generate key
createCmd := "genrsa -aes256 -passout pass:foobar"
keySize := " 4096"
if strings.HasPrefix(ci.KeyType, "ecdsa") {
keySize = ""
createCmd = "ecparam -genkey -name "
if ci.KeyType == "ecdsa256" {
createCmd = createCmd + "prime256v1"
}
if ci.KeyType == "ecdsa384" {
createCmd = createCmd + "secp384r1"
}
} else {
if strings.HasSuffix(ci.KeyType, "3072") {
keySize = " 3072"
}
if strings.HasSuffix(ci.KeyType, "2048") {
keySize = " 2048"
}
}
if ci.CreateType == "generate" {
// 1. Generate key
createCmd := "genrsa -aes256 -passout pass:foobar"
keySize := " 4096"
if strings.HasPrefix(ci.KeyType, "ecdsa") {
keySize = ""
createCmd = "ecparam -genkey -name "
if ci.KeyType == "ecdsa256" {
createCmd = createCmd + "prime256v1"
}
if ci.KeyType == "ecdsa384" {
createCmd = createCmd + "secp384r1"
}
} else {
if strings.HasSuffix(ci.KeyType, "3072") {
keySize = " 3072"
}
if strings.HasSuffix(ci.KeyType, "2048") {
keySize = " 2048"
}
}
if _, err := exe_cmd("openssl " + createCmd + " -out " + path + certBase + ".key" + keySize); err != nil {
return reportError(err)
}
if _, err := exe_cmd("openssl pkey -in " + path + certBase + ".key -passin pass:foobar -out " + path + certBase + ".tmp"); err != nil {
return reportError(err)
}
if _, err = exe_cmd("mv " + path + certBase + ".tmp " + path + certBase + ".key"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("openssl " + createCmd + " -out " + path + certBase + ".key" + keySize); err != nil {
return reportError(err)
}
if _, err := exe_cmd("openssl pkey -in " + path + certBase + ".key -passin pass:foobar -out " + path + certBase + ".tmp"); err != nil {
return reportError(err)
}
if _, err = exe_cmd("mv " + path + certBase + ".tmp " + path + certBase + ".key"); err != nil {
return reportError(err)
}
_, _ = exe_cmd("sleep 1")
_, _ = exe_cmd("sleep 1")
// 2. Generate certificate
subject := "/C=" + ci.Country + "/O=" + ci.Organization
if ci.OrgUnit != "" {
subject = subject + "/OU=" + ci.OrgUnit
}
subject = subject + "/CN=" + ci.CommonName
subject = strings.Replace(subject, " ", "\\\\", -1)
// 2. Generate certificate
subject := "/C=" + ci.Country + "/O=" + ci.Organization
if ci.OrgUnit != "" {
subject = subject + "/OU=" + ci.OrgUnit
}
subject = subject + "/CN=" + ci.CommonName
subject = strings.Replace(subject, " ", "\\\\", -1)
if ci.IsRoot {
if _, err := exe_cmd("openssl req -config " + path + "openssl.cnf -days 3650 -new -x509 -extensions v3_ca -subj " + subject + " -key " + path + certBase + ".key -out " + path + certBase + ".pem"); err != nil {
return reportError(err)
}
} else {
if _, err := exe_cmd("openssl req -config " + path + "openssl.cnf -new -subj " + subject + " -key " + path + certBase + ".key -out " + path + certBase + ".csr"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("openssl ca -config " + path + "../openssl.cnf -extensions v3_intermediate_ca -days 3600 -md sha384 -notext -batch -in " + path + certBase + ".csr -out " + path + certBase + ".pem"); err != nil {
return reportError(err)
}
}
if ci.IsRoot {
if _, err := exe_cmd("openssl req -config " + path + "openssl.cnf -days 3650 -new -x509 -extensions v3_ca -subj " + subject + " -key " + path + certBase + ".key -out " + path + certBase + ".pem"); err != nil {
return reportError(err)
}
} else {
if _, err := exe_cmd("openssl req -config " + path + "openssl.cnf -new -subj " + subject + " -key " + path + certBase + ".key -out " + path + certBase + ".csr"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("openssl ca -config " + path + "../openssl.cnf -extensions v3_intermediate_ca -days 3600 -md sha384 -notext -batch -in " + path + certBase + ".csr -out " + path + certBase + ".pem"); err != nil {
return reportError(err)
}
}
} else if ci.CreateType == "import" {
tmpFile := filepath.Join(tmpDir, ci.ImportHandler.Filename)
} else if ci.CreateType == "import" {
tmpFile := filepath.Join(tmpDir, ci.ImportHandler.Filename)
f, err := os.OpenFile(tmpFile, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return err
}
f, err := os.OpenFile(tmpFile, os.O_WRONLY|os.O_CREATE, 0666)
if err != nil {
return err
}
defer f.Close()
defer f.Close()
io.Copy(f, ci.ImportFile)
io.Copy(f, ci.ImportFile)
contentType := ci.ImportHandler.Header.Get("Content-Type")
if contentType == "application/x-pkcs12" {
if ci.IsRoot {
if strings.Index(ci.ImportHandler.Filename, "labca_root") != 0 {
fmt.Printf("WARNING: importing root from .pfx file but name is %s\n", ci.ImportHandler.Filename)
}
} else {
if strings.Index(ci.ImportHandler.Filename, "labca_issuer") != 0 {
fmt.Printf("WARNING: importing issuer from .pfx file but name is %s\n", ci.ImportHandler.Filename)
}
}
contentType := ci.ImportHandler.Header.Get("Content-Type")
if contentType == "application/x-pkcs12" {
if ci.IsRoot {
if strings.Index(ci.ImportHandler.Filename, "labca_root") != 0 {
fmt.Printf("WARNING: importing root from .pfx file but name is %s\n", ci.ImportHandler.Filename)
}
} else {
if strings.Index(ci.ImportHandler.Filename, "labca_issuer") != 0 {
fmt.Printf("WARNING: importing issuer from .pfx file but name is %s\n", ci.ImportHandler.Filename)
}
}
pwd := "pass:dummy"
if ci.ImportPwd != "" {
pwd = "pass:" + strings.Replace(ci.ImportPwd, " ", "\\\\", -1)
}
pwd := "pass:dummy"
if ci.ImportPwd != "" {
pwd = "pass:" + strings.Replace(ci.ImportPwd, " ", "\\\\", -1)
}
if out, err := exe_cmd("openssl pkcs12 -in " + strings.Replace(tmpFile, " ", "\\\\", -1) + " -password " + pwd + " -nocerts -nodes -out " + tmpKey); err != nil {
if strings.Index(string(out), "invalid password") >= 0 {
return errors.New("Incorrect password!")
} else {
return reportError(err)
}
}
if out, err := exe_cmd("openssl pkcs12 -in " + strings.Replace(tmpFile, " ", "\\\\", -1) + " -password " + pwd + " -nokeys -out " + tmpCert); err != nil {
if strings.Index(string(out), "invalid password") >= 0 {
return errors.New("Incorrect password!")
} else {
return reportError(err)
}
}
} else if contentType == "application/zip" {
if ci.IsRoot {
if (strings.Index(ci.ImportHandler.Filename, "labca_root") != 0) && (strings.Index(ci.ImportHandler.Filename, "labca_certificates") != 0) {
fmt.Printf("WARNING: importing root from .zip file but name is %s\n", ci.ImportHandler.Filename)
}
} else {
if strings.Index(ci.ImportHandler.Filename, "labca_issuer") != 0 {
fmt.Printf("WARNING: importing issuer from .zip file but name is %s\n", ci.ImportHandler.Filename)
}
}
if out, err := exe_cmd("openssl pkcs12 -in " + strings.Replace(tmpFile, " ", "\\\\", -1) + " -password " + pwd + " -nocerts -nodes -out " + tmpKey); err != nil {
if strings.Index(string(out), "invalid password") >= 0 {
return errors.New("Incorrect password!")
} else {
return reportError(err)
}
}
if out, err := exe_cmd("openssl pkcs12 -in " + strings.Replace(tmpFile, " ", "\\\\", -1) + " -password " + pwd + " -nokeys -out " + tmpCert); err != nil {
if strings.Index(string(out), "invalid password") >= 0 {
return errors.New("Incorrect password!")
} else {
return reportError(err)
}
}
} else if contentType == "application/zip" {
if ci.IsRoot {
if (strings.Index(ci.ImportHandler.Filename, "labca_root") != 0) && (strings.Index(ci.ImportHandler.Filename, "labca_certificates") != 0) {
fmt.Printf("WARNING: importing root from .zip file but name is %s\n", ci.ImportHandler.Filename)
}
} else {
if strings.Index(ci.ImportHandler.Filename, "labca_issuer") != 0 {
fmt.Printf("WARNING: importing issuer from .zip file but name is %s\n", ci.ImportHandler.Filename)
}
}
cmd := "unzip -j"
if ci.ImportPwd != "" {
cmd = cmd + " -P " + strings.Replace(ci.ImportPwd, " ", "\\\\", -1)
} else {
cmd = cmd + " -P dummy"
}
cmd = cmd + " " + strings.Replace(tmpFile, " ", "\\\\", -1) + " -d " + tmpDir
cmd := "unzip -j"
if ci.ImportPwd != "" {
cmd = cmd + " -P " + strings.Replace(ci.ImportPwd, " ", "\\\\", -1)
} else {
cmd = cmd + " -P dummy"
}
cmd = cmd + " " + strings.Replace(tmpFile, " ", "\\\\", -1) + " -d " + tmpDir
if _, err := exe_cmd(cmd); err != nil {
if err.Error() == "exit status 82" {
return errors.New("Incorrect password!")
} else {
return reportError(err)
}
}
} else {
return errors.New("Content Type '" + contentType + "' not supported!")
}
if _, err := exe_cmd(cmd); err != nil {
if err.Error() == "exit status 82" {
return errors.New("Incorrect password!")
} else {
return reportError(err)
}
}
} else {
return errors.New("Content Type '" + contentType + "' not supported!")
}
} else if ci.CreateType == "upload" {
if err := ioutil.WriteFile(tmpKey, []byte(ci.Key), 0644); err != nil {
return err
}
} else if ci.CreateType == "upload" {
if err := ioutil.WriteFile(tmpKey, []byte(ci.Key), 0644); err != nil {
return err
}
pwd := "pass:dummy"
if ci.Passphrase != "" {
pwd = "pass:" + strings.Replace(ci.Passphrase, " ", "\\\\", -1)
}
pwd := "pass:dummy"
if ci.Passphrase != "" {
pwd = "pass:" + strings.Replace(ci.Passphrase, " ", "\\\\", -1)
}
if out, err := exe_cmd("openssl pkey -passin " + pwd + " -in " + tmpKey + " -out " + tmpKey + "-out"); err != nil {
if strings.Index(string(out), ":bad decrypt:") >= 0 {
return errors.New("Incorrect password!")
} else {
return reportError(err)
}
} else {
if _, err = exe_cmd("mv " + tmpKey + "-out " + tmpKey); err != nil {
return reportError(err)
}
}
if out, err := exe_cmd("openssl pkey -passin " + pwd + " -in " + tmpKey + " -out " + tmpKey + "-out"); err != nil {
if strings.Index(string(out), ":bad decrypt:") >= 0 {
return errors.New("Incorrect password!")
} else {
return reportError(err)
}
} else {
if _, err = exe_cmd("mv " + tmpKey + "-out " + tmpKey); err != nil {
return reportError(err)
}
}
if err := ioutil.WriteFile(tmpCert, []byte(ci.Certificate), 0644); err != nil {
return err
}
if err := ioutil.WriteFile(tmpCert, []byte(ci.Certificate), 0644); err != nil {
return err
}
} else {
return fmt.Errorf("Unknown CreateType!")
}
} else {
return fmt.Errorf("Unknown CreateType!")
}
// This is shared between pfx/zip upload and pem text upload
if ci.CreateType != "generate" {
var rootCert string
var rootKey string
var issuerCert string
var issuerKey string
// This is shared between pfx/zip upload and pem text upload
if ci.CreateType != "generate" {
var rootCert string
var rootKey string
var issuerCert string
var issuerKey string
if ci.IsRoot {
rootCert = filepath.Join(tmpDir, "root-ca.pem")
rootKey = filepath.Join(tmpDir, "root-ca.key")
if ci.IsRoot {
rootCert = filepath.Join(tmpDir, "root-ca.pem")
rootKey = filepath.Join(tmpDir, "root-ca.key")
if _, err := os.Stat(rootCert); os.IsNotExist(err) {
return errors.New("File does not contain root-ca.pem!")
}
if _, err := os.Stat(rootKey); os.IsNotExist(err) {
return errors.New("File does not contain root-ca.key!")
}
}
if _, err := os.Stat(rootCert); os.IsNotExist(err) {
return errors.New("File does not contain root-ca.pem!")
}
if _, err := os.Stat(rootKey); os.IsNotExist(err) {
return errors.New("File does not contain root-ca.key!")
}
}
issuerCert = filepath.Join(tmpDir, "ca-int.pem")
issuerKey = filepath.Join(tmpDir, "ca-int.key")
issuerCert = filepath.Join(tmpDir, "ca-int.pem")
issuerKey = filepath.Join(tmpDir, "ca-int.key")
if _, err := os.Stat(issuerCert); os.IsNotExist(err) {
if ci.IsRoot {
issuerCert = ""
} else {
return errors.New("File does not contain ca-int.pem!")
}
}
if _, err := os.Stat(issuerKey); os.IsNotExist(err) {
if ci.IsRoot {
issuerKey = ""
} else {
return errors.New("File does not contain ca-int.key!")
}
}
if _, err := os.Stat(issuerCert); os.IsNotExist(err) {
if ci.IsRoot {
issuerCert = ""
} else {
return errors.New("File does not contain ca-int.pem!")
}
}
if _, err := os.Stat(issuerKey); os.IsNotExist(err) {
if ci.IsRoot {
issuerKey = ""
} else {
return errors.New("File does not contain ca-int.key!")
}
}
var rootSubject string
if (rootCert != "") && (rootKey != "") {
r, err := exe_cmd("openssl x509 -noout -subject -in " + rootCert)
if err != nil {
return reportError(err)
} else {
rootSubject = string(r[0 : len(r)-1])
fmt.Printf("Import root with subject '%s'\n", rootSubject)
}
var rootSubject string
if (rootCert != "") && (rootKey != "") {
r, err := exe_cmd("openssl x509 -noout -subject -in " + rootCert)
if err != nil {
return reportError(err)
} else {
rootSubject = string(r[0 : len(r)-1])
fmt.Printf("Import root with subject '%s'\n", rootSubject)
}
r, err = exe_cmd("openssl pkey -noout -in " + rootKey)
if err != nil {
return reportError(err)
} else {
fmt.Println("Import root key")
}
}
r, err = exe_cmd("openssl pkey -noout -in " + rootKey)
if err != nil {
return reportError(err)
} else {
fmt.Println("Import root key")
}
}
if (issuerCert != "") && (issuerKey != "") {
if ci.IsRoot {
if err := preCreateTasks(path + "issuer/"); err != nil {
return err
}
}
if (issuerCert != "") && (issuerKey != "") {
if ci.IsRoot {
if err := preCreateTasks(path + "issuer/"); err != nil {
return err
}
}
r, err := exe_cmd("openssl x509 -noout -subject -in " + issuerCert)
if err != nil {
return reportError(err)
} else {
fmt.Printf("Import issuer with subject '%s'\n", string(r[0:len(r)-1]))
}
r, err := exe_cmd("openssl x509 -noout -subject -in " + issuerCert)
if err != nil {
return reportError(err)
} else {
fmt.Printf("Import issuer with subject '%s'\n", string(r[0:len(r)-1]))
}
r, err = exe_cmd("openssl x509 -noout -issuer -in " + issuerCert)
if err != nil {
return reportError(err)
} else {
issuerIssuer := string(r[0 : len(r)-1])
fmt.Printf("Issuer certificate issued by CA '%s'\n", issuerIssuer)
r, err = exe_cmd("openssl x509 -noout -issuer -in " + issuerCert)
if err != nil {
return reportError(err)
} else {
issuerIssuer := string(r[0 : len(r)-1])
fmt.Printf("Issuer certificate issued by CA '%s'\n", issuerIssuer)
if rootSubject == "" {
r, err := exe_cmd("openssl x509 -noout -subject -in data/root-ca.pem")
if err != nil {
return reportError(err)
} else {
rootSubject = string(r[0 : len(r)-1])
}
}
if rootSubject == "" {
r, err := exe_cmd("openssl x509 -noout -subject -in data/root-ca.pem")
if err != nil {
return reportError(err)
} else {
rootSubject = string(r[0 : len(r)-1])
}
}
issuerIssuer = strings.Replace(issuerIssuer, "issuer=", "", -1)
rootSubject = strings.Replace(rootSubject, "subject=", "", -1)
if issuerIssuer != rootSubject {
return errors.New("Issuer not issued by our Root CA!")
}
}
issuerIssuer = strings.Replace(issuerIssuer, "issuer=", "", -1)
rootSubject = strings.Replace(rootSubject, "subject=", "", -1)
if issuerIssuer != rootSubject {
return errors.New("Issuer not issued by our Root CA!")
}
}
r, err = exe_cmd("openssl pkey -noout -in " + issuerKey)
if err != nil {
return reportError(err)
} else {
fmt.Println("Import issuer key")
}
}
r, err = exe_cmd("openssl pkey -noout -in " + issuerKey)
if err != nil {
return reportError(err)
} else {
fmt.Println("Import issuer key")
}
}
// All is good now, move files to their permanent location...
if rootCert != "" {
if _, err = exe_cmd("mv " + rootCert + " " + path); err != nil {
return reportError(err)
}
}
if rootKey != "" {
if _, err = exe_cmd("mv " + rootKey + " " + path); err != nil {
return reportError(err)
}
}
if issuerCert != "" {
if _, err = exe_cmd("mv " + issuerCert + " data/issuer/"); err != nil {
return reportError(err)
}
}
if issuerKey != "" {
if _, err = exe_cmd("mv " + issuerKey + " data/issuer/"); err != nil {
return reportError(err)
}
}
// All is good now, move files to their permanent location...
if rootCert != "" {
if _, err = exe_cmd("mv " + rootCert + " " + path); err != nil {
return reportError(err)
}
}
if rootKey != "" {
if _, err = exe_cmd("mv " + rootKey + " " + path); err != nil {
return reportError(err)
}
}
if issuerCert != "" {
if _, err = exe_cmd("mv " + issuerCert + " data/issuer/"); err != nil {
return reportError(err)
}
}
if issuerKey != "" {
if _, err = exe_cmd("mv " + issuerKey + " data/issuer/"); err != nil {
return reportError(err)
}
}
if (issuerCert != "") && (issuerKey != "") && ci.IsRoot {
if err := postCreateTasks(path+"issuer/", "ca-int"); err != nil {
return err
}
}
}
if (issuerCert != "") && (issuerKey != "") && ci.IsRoot {
if err := postCreateTasks(path+"issuer/", "ca-int"); err != nil {
return err
}
}
}
if err := postCreateTasks(path, certBase); err != nil {
return err
}
if err := postCreateTasks(path, certBase); err != nil {
return err
}
if ci.IsRoot {
if _, err := exe_cmd("openssl ca -config " + path + "openssl.cnf -gencrl -keyfile " + path + certBase + ".key -cert " + path + certBase + ".pem -out " + path + certBase + ".crl"); err != nil {
return reportError(err)
}
}
if ci.IsRoot {
if _, err := exe_cmd("openssl ca -config " + path + "openssl.cnf -gencrl -keyfile " + path + certBase + ".key -cert " + path + certBase + ".pem -out " + path + certBase + ".crl"); err != nil {
return reportError(err)
}
}
return nil
return nil
}
func postCreateTasks(path string, certBase string) error {
if _, err := exe_cmd("openssl pkey -in " + path + certBase + ".key -out " + path + certBase + ".key.der -outform der"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("openssl pkey -in " + path + certBase + ".key -out " + path + certBase + ".key.der -outform der"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("openssl x509 -in " + path + certBase + ".pem -out " + path + certBase + ".der -outform DER"); err != nil {
return reportError(err)
}
if _, err := exe_cmd("openssl x509 -in " + path + certBase + ".pem -out " + path + certBase + ".der -outform DER"); err != nil {
return reportError(err)
}
return nil
return nil
}
func exe_cmd(cmd string) ([]byte, error) {
parts := strings.Fields(cmd)
for i := 0; i < len(parts); i++ {
parts[i] = strings.Replace(parts[i], "\\\\", " ", -1)
}
head := parts[0]
parts = parts[1:]
parts := strings.Fields(cmd)
for i := 0; i < len(parts); i++ {
parts[i] = strings.Replace(parts[i], "\\\\", " ", -1)
}
head := parts[0]
parts = parts[1:]
out, err := exec.Command(head, parts...).CombinedOutput()
if err != nil {
fmt.Print(fmt.Sprint(err) + ": " + string(out))
} else {
//fmt.Println(string(out))
}
return out, err
out, err := exec.Command(head, parts...).CombinedOutput()
if err != nil {
fmt.Print(fmt.Sprint(err) + ": " + string(out))
} else {
//fmt.Println(string(out))
}
return out, err
}

View File

@@ -1,359 +1,358 @@
package main
import (
"database/sql"
"fmt"
"github.com/dustin/go-humanize"
"log"
"net/http"
"regexp"
"strconv"
"strings"
"time"
"database/sql"
"fmt"
"github.com/dustin/go-humanize"
"log"
"net/http"
"regexp"
"strconv"
"strings"
"time"
)
type Activity struct {
Title string
Message string
Timestamp string
TimestampRel string
Class string
Title string
Message string
Timestamp string
TimestampRel string
Class string
}
func _parseLine(line string, loc *time.Location) Activity {
var activity Activity
var activity Activity
// Remove ansi colors
b := make([]byte, len(line))
var bl int
for i := 0; i < len(line); i++ {
c := line[i]
if c >= 32 && c != 127 {
b[bl] = c
bl++
}
}
line = string(b[:bl])
line = strings.Replace(line, "[31m", "", -1)
line = strings.Replace(line, "[1m", "", -1)
line = strings.Replace(line, "[0m", "", -1)
// Remove ansi colors
b := make([]byte, len(line))
var bl int
for i := 0; i < len(line); i++ {
c := line[i]
if c >= 32 && c != 127 {
b[bl] = c
bl++
}
}
line = string(b[:bl])
line = strings.Replace(line, "[31m", "", -1)
line = strings.Replace(line, "[1m", "", -1)
line = strings.Replace(line, "[0m", "", -1)
re := regexp.MustCompile("^.*\\|\\s*(\\S)(\\S+) (\\S+) (\\S+) (.*)$")
result := re.FindStringSubmatch(line)
re := regexp.MustCompile("^.*\\|\\s*(\\S)(\\S+) (\\S+) (\\S+) (.*)$")
result := re.FindStringSubmatch(line)
activity.Class = ""
if result[1] == "W" {
activity.Class = "warning"
}
if result[1] == "E" {
activity.Class = "error"
}
activity.Class = ""
if result[1] == "W" {
activity.Class = "warning"
}
if result[1] == "E" {
activity.Class = "error"
}
timestamp, err := time.ParseInLocation("060102150405", result[2], loc)
activity.Timestamp = ""
activity.TimestampRel = "??"
if err == nil {
activity.Timestamp = timestamp.Format("02-Jan-2006 15:04:05 MST")
activity.Timestamp = strings.Replace(activity.Timestamp, "+0000", "GMT", -1)
activity.TimestampRel = humanize.RelTime(timestamp, time.Now(), "", "")
}
timestamp, err := time.ParseInLocation("060102150405", result[2], loc)
activity.Timestamp = ""
activity.TimestampRel = "??"
if err == nil {
activity.Timestamp = timestamp.Format("02-Jan-2006 15:04:05 MST")
activity.Timestamp = strings.Replace(activity.Timestamp, "+0000", "GMT", -1)
activity.TimestampRel = humanize.RelTime(timestamp, time.Now(), "", "")
}
tail := result[3][len(result[3])-2:]
activity.Title = ""
switch tail {
case "ca":
activity.Title = "Certification Agent"
case "ra":
activity.Title = "Registration Agent"
case "sa":
activity.Title = "Storage Agent"
case "va":
activity.Title = "Validation Agent"
}
tail := result[3][len(result[3])-2:]
activity.Title = ""
switch tail {
case "ca":
activity.Title = "Certification Agent"
case "ra":
activity.Title = "Registration Agent"
case "sa":
activity.Title = "Storage Agent"
case "va":
activity.Title = "Validation Agent"
}
message := result[5]
idx := strings.Index(message, ".well-known/acme-challenge")
if idx > -1 {
message = message[0:idx]
}
if strings.Index(message, "Checked CAA records for") > -1 {
message = message[0:strings.Index(message, ",")]
}
if strings.Index(message, "Validation result") > -1 {
message = message[0:17]
}
idx = strings.Index(message, " csr=[")
if idx > -1 {
message = message[0:idx]
}
idx = strings.Index(message, " precertificate=[")
if idx > -1 {
message = message[0:idx]
}
if strings.Index(message, "Certificate request - ") > -1 {
idx = strings.Index(message, " JSON={")
if idx > -1 {
message = message[0:idx]
}
}
activity.Message = message
message := result[5]
idx := strings.Index(message, ".well-known/acme-challenge")
if idx > -1 {
message = message[0:idx]
}
if strings.Index(message, "Checked CAA records for") > -1 {
message = message[0:strings.Index(message, ",")]
}
if strings.Index(message, "Validation result") > -1 {
message = message[0:17]
}
idx = strings.Index(message, " csr=[")
if idx > -1 {
message = message[0:idx]
}
idx = strings.Index(message, " precertificate=[")
if idx > -1 {
message = message[0:idx]
}
if strings.Index(message, "Certificate request - ") > -1 {
idx = strings.Index(message, " JSON={")
if idx > -1 {
message = message[0:idx]
}
}
activity.Message = message
return activity
return activity
}
func _parseActivity(data string) []Activity {
var activity []Activity
var activity []Activity
lines := strings.Split(data, "\n")
lines := strings.Split(data, "\n")
loc, err := time.LoadLocation(lines[0])
if err != nil {
log.Printf("Could not determine location: %s\n", err)
loc = time.Local
}
loc, err := time.LoadLocation(lines[0])
if err != nil {
log.Printf("Could not determine location: %s\n", err)
loc = time.Local
}
for i := len(lines) - 2; i >= 1; i-- {
activity = append(activity, _parseLine(lines[i], loc))
}
for i := len(lines) - 2; i >= 1; i-- {
activity = append(activity, _parseLine(lines[i], loc))
}
return activity
return activity
}
type Component struct {
Name string
Timestamp string
TimestampRel string
Class string
LogUrl string
LogTitle string
Buttons []map[string]interface{}
Name string
Timestamp string
TimestampRel string
Class string
LogUrl string
LogTitle string
Buttons []map[string]interface{}
}
func _parseComponents(data string) []Component {
var components []Component
var components []Component
if data[len(data)-1:] == "\n" {
data = data[0 : len(data)-1]
}
if data[len(data)-1:] == "\n" {
data = data[0 : len(data)-1]
}
parts := strings.Split(data, "|")
parts := strings.Split(data, "|")
loc, err := time.LoadLocation(parts[0])
if err != nil {
log.Printf("Could not determine location: %s\n", err)
loc = time.Local
}
loc, err := time.LoadLocation(parts[0])
if err != nil {
log.Printf("Could not determine location: %s\n", err)
loc = time.Local
}
nginx, err := time.ParseInLocation("Jan _2 15:04:05 2006", parts[1], loc)
nginxReal := ""
nginxNice := "stopped"
nginxClass := "error"
if err == nil {
nginxReal = nginx.Format("02-Jan-2006 15:04:05 MST")
nginxNice = humanize.RelTime(nginx, time.Now(), "", "")
nginxClass = ""
}
nginx, err := time.ParseInLocation("Jan _2 15:04:05 2006", parts[1], loc)
nginxReal := ""
nginxNice := "stopped"
nginxClass := "error"
if err == nil {
nginxReal = nginx.Format("02-Jan-2006 15:04:05 MST")
nginxNice = humanize.RelTime(nginx, time.Now(), "", "")
nginxClass = ""
}
svc, err := time.ParseInLocation("Jan _2 15:04:05 2006", parts[2], loc)
svcReal := ""
svcNice := "stopped"
svcClass := "error"
if err == nil {
svcReal = svc.Format("02-Jan-2006 15:04:05 MST")
svcNice = humanize.RelTime(svc, time.Now(), "", "")
svcClass = ""
}
svc, err := time.ParseInLocation("Jan _2 15:04:05 2006", parts[2], loc)
svcReal := ""
svcNice := "stopped"
svcClass := "error"
if err == nil {
svcReal = svc.Format("02-Jan-2006 15:04:05 MST")
svcNice = humanize.RelTime(svc, time.Now(), "", "")
svcClass = ""
}
boulder, err := time.ParseInLocation("Jan _2 15:04:05 2006", parts[3], loc)
boulderReal := ""
boulderNice := "stopped"
boulderClass := "error"
if err == nil {
boulderReal = boulder.Format("02-Jan-2006 15:04:05 MST")
boulderNice = humanize.RelTime(boulder, time.Now(), "", "")
boulderClass = ""
}
boulder, err := time.ParseInLocation("Jan _2 15:04:05 2006", parts[3], loc)
boulderReal := ""
boulderNice := "stopped"
boulderClass := "error"
if err == nil {
boulderReal = boulder.Format("02-Jan-2006 15:04:05 MST")
boulderNice = humanize.RelTime(boulder, time.Now(), "", "")
boulderClass = ""
}
labca, err := time.ParseInLocation("Jan _2 15:04:05 2006", parts[4], loc)
labcaReal := ""
labcaNice := "stopped"
labcaClass := "error"
if err == nil {
labcaReal = labca.Format("02-Jan-2006 15:04:05 MST")
labcaNice = humanize.RelTime(labca, time.Now(), "", "")
labcaClass = ""
}
labca, err := time.ParseInLocation("Jan _2 15:04:05 2006", parts[4], loc)
labcaReal := ""
labcaNice := "stopped"
labcaClass := "error"
if err == nil {
labcaReal = labca.Format("02-Jan-2006 15:04:05 MST")
labcaNice = humanize.RelTime(labca, time.Now(), "", "")
labcaClass = ""
}
components = append(components, Component{Name: "NGINX Webserver", Timestamp: nginxReal, TimestampRel: nginxNice, Class: nginxClass})
components = append(components, Component{Name: "Host Service", Timestamp: svcReal, TimestampRel: svcNice, Class: svcClass})
components = append(components, Component{Name: "Boulder (ACME)", Timestamp: boulderReal, TimestampRel: boulderNice, Class: boulderClass})
components = append(components, Component{Name: "LabCA Application", Timestamp: labcaReal, TimestampRel: labcaNice, Class: labcaClass})
components = append(components, Component{Name: "NGINX Webserver", Timestamp: nginxReal, TimestampRel: nginxNice, Class: nginxClass})
components = append(components, Component{Name: "Host Service", Timestamp: svcReal, TimestampRel: svcNice, Class: svcClass})
components = append(components, Component{Name: "Boulder (ACME)", Timestamp: boulderReal, TimestampRel: boulderNice, Class: boulderClass})
components = append(components, Component{Name: "LabCA Application", Timestamp: labcaReal, TimestampRel: labcaNice, Class: labcaClass})
return components
return components
}
type Stat struct {
Name string
Hint string
Value string
Class string
Name string
Hint string
Value string
Class string
}
func _parseStats(data string) []Stat {
var stats []Stat
var stats []Stat
if data[len(data)-1:] == "\n" {
data = data[0 : len(data)-1]
}
if data[len(data)-1:] == "\n" {
data = data[0 : len(data)-1]
}
parts := strings.Split(data, "|")
parts := strings.Split(data, "|")
loc, err := time.LoadLocation(parts[0])
if err != nil {
log.Printf("Could not determine location: %s\n", err)
loc = time.Local
}
loc, err := time.LoadLocation(parts[0])
if err != nil {
log.Printf("Could not determine location: %s\n", err)
loc = time.Local
}
since, err := time.ParseInLocation("2006-01-02 15:04:05", parts[1], loc)
var sinceReal string
sinceNice := "??"
if err == nil {
sinceReal = since.Format("02-Jan-2006 15:04:05 MST")
sinceNice = humanize.RelTime(since, time.Now(), "", "")
}
stats = append(stats, Stat{Name: "System Uptime", Hint: sinceReal, Value: sinceNice})
since, err := time.ParseInLocation("2006-01-02 15:04:05", parts[1], loc)
var sinceReal string
sinceNice := "??"
if err == nil {
sinceReal = since.Format("02-Jan-2006 15:04:05 MST")
sinceNice = humanize.RelTime(since, time.Now(), "", "")
}
stats = append(stats, Stat{Name: "System Uptime", Hint: sinceReal, Value: sinceNice})
numProcs, err := strconv.Atoi(parts[2])
if err != nil {
numProcs = 0
}
stats = append(stats, Stat{Name: "Process Count", Value: strconv.Itoa(numProcs)})
numProcs, err := strconv.Atoi(parts[2])
if err != nil {
numProcs = 0
}
stats = append(stats, Stat{Name: "Process Count", Value: strconv.Itoa(numProcs)})
memUsed, err := strconv.ParseUint(parts[3], 10, 64)
if err != nil {
memUsed = 0
}
memAvail, err := strconv.ParseUint(parts[4], 10, 64)
if err != nil {
memAvail = 0
}
memUsed, err := strconv.ParseUint(parts[3], 10, 64)
if err != nil {
memUsed = 0
}
memAvail, err := strconv.ParseUint(parts[4], 10, 64)
if err != nil {
memAvail = 0
}
percMem := float64(0)
if (memUsed + memAvail) > 0 {
percMem = float64(100) * float64(memUsed) / float64(memUsed+memAvail)
}
percMem := float64(0)
if (memUsed + memAvail) > 0 {
percMem = float64(100) * float64(memUsed) / float64(memUsed+memAvail)
}
usedHuman := humanize.IBytes(memUsed)
availHuman := humanize.IBytes(memAvail)
percHuman := fmt.Sprintf("%s %%", humanize.FtoaWithDigits(percMem, 1))
usedHuman := humanize.IBytes(memUsed)
availHuman := humanize.IBytes(memAvail)
percHuman := fmt.Sprintf("%s %%", humanize.FtoaWithDigits(percMem, 1))
class := ""
if percMem > 75 {
class = "warning"
}
if percMem > 90 {
class = "error"
}
stats = append(stats, Stat{Name: "Memory Usage", Value: percHuman, Class: class})
stats = append(stats, Stat{Name: "Memory Used", Value: usedHuman})
class = ""
if memAvail < 250000000 {
class = "warning"
}
if memAvail < 100000000 {
class = "error"
}
stats = append(stats, Stat{Name: "Memory Available", Value: availHuman, Class: class})
class := ""
if percMem > 75 {
class = "warning"
}
if percMem > 90 {
class = "error"
}
stats = append(stats, Stat{Name: "Memory Usage", Value: percHuman, Class: class})
stats = append(stats, Stat{Name: "Memory Used", Value: usedHuman})
class = ""
if memAvail < 250000000 {
class = "warning"
}
if memAvail < 100000000 {
class = "error"
}
stats = append(stats, Stat{Name: "Memory Available", Value: availHuman, Class: class})
return stats
return stats
}
func CollectDashboardData(w http.ResponseWriter, r *http.Request) (map[string]interface {}, error) {
db, err := sql.Open(dbType, dbConn)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
func CollectDashboardData(w http.ResponseWriter, r *http.Request) (map[string]interface{}, error) {
db, err := sql.Open(dbType, dbConn)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
defer db.Close()
defer db.Close()
dashboardData := make(map[string]interface{})
dashboardData["RequestBase"] = r.Header.Get("X-Request-Base")
dashboardData := make(map[string]interface{})
dashboardData["RequestBase"] = r.Header.Get("X-Request-Base")
rows, err := db.Query("SELECT count(*) FROM registrations")
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
rows, err := db.Query("SELECT count(*) FROM registrations")
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
var dbres int
if rows.Next() {
err = rows.Scan(&dbres)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
var dbres int
if rows.Next() {
err = rows.Scan(&dbres)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
dashboardData["NumAccounts"] = dbres
}
dashboardData["NumAccounts"] = dbres
}
rows, err = db.Query("SELECT count(*) FROM certificateStatus WHERE revokedDate='0000-00-00 00:00:00' AND notAfter >= NOW()")
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
rows, err = db.Query("SELECT count(*) FROM certificateStatus WHERE revokedDate='0000-00-00 00:00:00' AND notAfter >= NOW()")
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
if rows.Next() {
err = rows.Scan(&dbres)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
if rows.Next() {
err = rows.Scan(&dbres)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
dashboardData["NumCerts"] = dbres
}
dashboardData["NumCerts"] = dbres
}
rows, err = db.Query("SELECT count(*) FROM certificateStatus WHERE revokedDate='0000-00-00 00:00:00' AND notAfter < NOW()")
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
rows, err = db.Query("SELECT count(*) FROM certificateStatus WHERE revokedDate='0000-00-00 00:00:00' AND notAfter < NOW()")
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
if rows.Next() {
err = rows.Scan(&dbres)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
if rows.Next() {
err = rows.Scan(&dbres)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
dashboardData["NumExpired"] = dbres
}
dashboardData["NumExpired"] = dbres
}
rows, err = db.Query("SELECT count(*) FROM certificateStatus WHERE revokedDate<>'0000-00-00 00:00:00'")
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
rows, err = db.Query("SELECT count(*) FROM certificateStatus WHERE revokedDate<>'0000-00-00 00:00:00'")
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
if rows.Next() {
err = rows.Scan(&dbres)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
if rows.Next() {
err = rows.Scan(&dbres)
if err != nil {
errorHandler(w, r, err, http.StatusInternalServerError)
return nil, err
}
dashboardData["NumRevoked"] = dbres
}
dashboardData["NumRevoked"] = dbres
}
activity := getLog(w, r, "activity")
dashboardData["Activity"] = _parseActivity(activity)
activity := getLog(w, r, "activity")
dashboardData["Activity"] = _parseActivity(activity)
components := getLog(w, r, "components")
dashboardData["Components"] = _parseComponents(components)
components := getLog(w, r, "components")
dashboardData["Components"] = _parseComponents(components)
stats := getLog(w, r, "stats")
dashboardData["Stats"] = _parseStats(stats)
stats := getLog(w, r, "stats")
dashboardData["Stats"] = _parseStats(stats)
return dashboardData, nil
return dashboardData, nil
}

File diff suppressed because it is too large Load Diff