From 8bab8ad53ae6c5190e57956594b7dcadaa97667d Mon Sep 17 00:00:00 2001 From: Massimiliano Adamo <maxadamo@gmail.com> Date: Tue, 1 Dec 2020 19:20:10 +0100 Subject: [PATCH] addedd private key check --- build.sh | 5 +++-- main.go | 61 +++++++++++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 57 insertions(+), 9 deletions(-) diff --git a/build.sh b/build.sh index dedb0e2..74c6d61 100755 --- a/build.sh +++ b/build.sh @@ -22,13 +22,14 @@ run_upx() { } rm -rf ${GOPATH}/src/github.com/maxadamo/${BIN_NAME} ${GOPATH}/src/gitlab.geant.net/devops/${BIN_NAME} -go get -ldflags "-s -w -X main.appVersion=${PROG_VERSION} -X main.buildTime=${BUILDTIME}" gitlab.geant.net/devops/${BIN_NAME} -#go get -ldflags "-s -w -X main.appVersion=${PROG_VERSION} -X main.buildTime=${BUILDTIME}" . +#go get -ldflags "-s -w -X main.appVersion=${PROG_VERSION} -X main.buildTime=${BUILDTIME}" gitlab.geant.net/devops/${BIN_NAME} +go get -ldflags "-s -w -X main.appVersion=${PROG_VERSION} -X main.buildTime=${BUILDTIME}" . if [ $? -gt 0 ]; then echo -e "\nthere was an error while compiling the code\n" exit fi echo "" + while true; do read -p "Do you wish to run upx against ${BIN_NAME}? (y/n) " yn case $yn in diff --git a/main.go b/main.go index ddb2b8c..7d639a4 100644 --- a/main.go +++ b/main.go @@ -7,6 +7,7 @@ import ( "io/ioutil" "net/http" "os" + "os/exec" "os/user" "path/filepath" "runtime" @@ -38,6 +39,7 @@ var ( tmpCaDestination string tmpKeyDestination string certTmpDir string + opensslBinary string ) // app clean and exit @@ -54,7 +56,7 @@ func appExit(status int) { } // check certificates -func checkCerificates(dnsname string, certificate string, fullchain string, ca string, key string, days int, fail bool) bool { +func checkCertificates(dnsname string, certificate string, fullchain string, ca string, key string, days int, fail bool) bool { Seconds := days * 86400 daysNumber := time.Now().Local().Add(time.Second * time.Duration(Seconds)) @@ -164,6 +166,42 @@ func checkCerificates(dnsname string, certificate string, fullchain string, ca s } +// check if priv key matches the publick key +func checkPrivkey(privkey string, pubcert string, opensslbinary string, fail bool, silent bool) bool { + _, errOpenssl := exec.Command(opensslbinary, "help").Output() + if errOpenssl != nil { + fmt.Printf("[WARN] skipping private key matching check: please install OpenSSL: %v\n", errOpenssl) + } else { + certPubKey, errCertPubKey := exec.Command(opensslbinary, "x509", "-noout", "-pubkey", "-in", pubcert).Output() + if errCertPubKey != nil { + if fail == true { + fmt.Printf("[ERR] running openssl against %s: %s\n", pubcert, errCertPubKey) + appExit(255) + } else { + return false + } + } + certPrivKey, errCertPrivKey := exec.Command(opensslbinary, "pkey", "-pubout", "-in", privkey).Output() + if errCertPrivKey != nil { + if fail == true { + fmt.Printf("[ERR] running openssl against %s: %s\n", privkey, errCertPrivKey) + appExit(255) + } else { + return false + } + } + pubkeyOutput := string(certPubKey[:]) + privkeyOutput := string(certPrivKey[:]) + if pubkeyOutput != privkeyOutput { + if fail == true { + fmt.Printf("[ERR] the private key %v does not match the the public certificate %v\n", privkey, pubcert) + appExit(255) + } + } + } + return true +} + // get redis key func GetRedisKey(redisurl string, redistoken string) string { client := &http.Client{} @@ -293,7 +331,7 @@ func main() { - fetches and stores a given Certificate, Full Chain, CA and Private Key Usage: - acme-downloader --redis-token=REDISTOKEN --vault-token=VAULTTOKEN --cert-name=CERTNAME --team-name=TEAMNAME [--days=DAYS] [--type=TYPE] [--cert-destination=CERTDESTINATION] [--fullchain-destination=FULLCHAINDESTINATION] [--key-destination=KEYDESTINATION] [--ca-destination=CADESTINATION] + acme-downloader --redis-token=REDISTOKEN --vault-token=VAULTTOKEN --cert-name=CERTNAME --team-name=TEAMNAME [--silent] [--days=DAYS] [--type=TYPE] [--cert-destination=CERTDESTINATION] [--fullchain-destination=FULLCHAINDESTINATION] [--key-destination=KEYDESTINATION] [--ca-destination=CADESTINATION] acme-downloader -v | --version acme-downloader -b | --build acme-downloader -h | --help @@ -302,6 +340,7 @@ Options: -h --help Show this screen -v --version Print version exit -b --build Print version and build information and exit + -s --silent Suppress warnings --redis-token=REDISTOKEN Redis access token --vault-token=VAULTTOKEN Vault access token --cert-name=CERTNAME Certificate name @@ -320,21 +359,27 @@ Options: fmt.Printf("acme-downloader version: %v, built on: %v\n", appVersion, buildTime) appExit(0) } + silent := false + if arguments["--silent"] == true { + silent = true + } if runtime.GOOS == "windows" { + opensslBinary = "openssl.exe" tmpCertificateDestination = "C:\\tmp\\acme-downloader\\cert\\amce_cert.pem" tmpFullchainDestination = "C:\\tmp\\acme-downloader\\cert\\amce_fullchain.pem" tmpCaDestination = "C:\\tmp\\acme-downloader\\cert\\amce_ca.pem" tmpKeyDestination = "C:\\tmp\\acme-downloader\\key\\amce_key.pem" GroupID = 0 // just a fake one } else { + opensslBinary = "openssl" tmpCertificateDestination = "/tmp/acme-downloader/cert/amce_cert.pem" tmpFullchainDestination = "/tmp/acme-downloader/cert/amce_fullchain.pem" tmpCaDestination = "/tmp/acme-downloader/cert/amce_ca.pem" tmpKeyDestination = "/tmp/acme-downloader/key/amce_key.pem" group, groupErr := user.LookupGroup(GroupName) if groupErr != nil { - fmt.Printf("[ERR] Fail looking up %v user user info", GroupName) + fmt.Printf("[ERR] Fail looking up %v user user info\n", GroupName) appExit(255) } GroupID, _ = strconv.Atoi(group.Gid) @@ -381,9 +426,10 @@ Options: } // check if there is a certificate installed and it is valid - existingCert := checkCerificates(CertName, certificateDestination, fullchainDestination, caDestination, keyDestination, Days, false) - if existingCert == true { - fmt.Printf("[INFO] the certificates are still valid\n") + existingCert := checkCertificates(CertName, certificateDestination, fullchainDestination, caDestination, keyDestination, Days, false) + existingKey := checkPrivkey(keyDestination, certificateDestination, opensslBinary, false, silent) + if existingCert == true && existingKey == true { + fmt.Printf("[INFO] the certificate is still valid\n") appExit(0) } certificate := GetRedisKey(RedisCertURL, RedisToken) @@ -397,7 +443,8 @@ Options: WriteToFile(ca, tmpCaDestination, 0644) WriteToFile(privKey, tmpKeyDestination, 0640) - checkCerificates(CertName, tmpCertificateDestination, tmpFullchainDestination, tmpCaDestination, tmpKeyDestination, Days, true) + checkCertificates(CertName, tmpCertificateDestination, tmpFullchainDestination, tmpCaDestination, tmpKeyDestination, Days, true) + checkPrivkey(keyDestination, tmpCertificateDestination, opensslBinary, false, silent) // move certificates in place moveFile(tmpCertificateDestination, certificateDestination, GroupID, 0644, 0755) -- GitLab