simplecert/cert.go
2019-07-23 09:27:09 +02:00

103 lines
2.4 KiB
Go

//
// simplecert
//
// Created by Philipp Mieden
// Contact: dreadl0ck@protonmail.ch
// Copyright © 2018 bestbytes. All rights reserved.
//
package simplecert
import (
"crypto/x509"
"encoding/json"
"encoding/pem"
"errors"
"io/ioutil"
"os"
"path/filepath"
"github.com/go-acme/lego/certificate"
)
// parsePEMBundle parses a certificate bundle from top to bottom and returns
// a slice of x509 certificates. This function will error if no certificates are found.
func parsePEMBundle(bundle []byte) ([]*x509.Certificate, error) {
var (
certificates []*x509.Certificate
certDERBlock *pem.Block
)
for {
certDERBlock, bundle = pem.Decode(bundle)
if certDERBlock == nil {
break
}
if certDERBlock.Type == "CERTIFICATE" {
cert, err := x509.ParseCertificate(certDERBlock.Bytes)
if err != nil {
return nil, err
}
certificates = append(certificates, cert)
}
}
if len(certificates) == 0 {
return nil, errors.New("No certificates were found while parsing the bundle")
}
return certificates, nil
}
// cert exists in cacheDir?
func certCached(cacheDir string) bool {
_, errCert := os.Stat(filepath.Join(cacheDir, certFileName))
_, errKey := os.Stat(filepath.Join(cacheDir, keyFileName))
if errCert == nil && errKey == nil {
return true
}
return false
}
// Persist the certificate on disk
// this assumes that cacheDir exists
func saveCertToDisk(cert *certificate.Resource, cacheDir string) error {
// JSON encode certificate resource
// needs to be a CR otherwise the fields with the keys will be lost
b, err := json.MarshalIndent(CR{
Domain: cert.Domain,
CertURL: cert.CertURL,
CertStableURL: cert.CertStableURL,
PrivateKey: cert.PrivateKey,
Certificate: cert.Certificate,
IssuerCertificate: cert.IssuerCertificate,
CSR: cert.CSR,
}, "", " ")
if err != nil {
return err
}
// write certificate resource to disk
err = ioutil.WriteFile(filepath.Join(cacheDir, certResourceFileName), b, c.CacheDirPerm)
if err != nil {
return err
}
// write certificate PEM to disk
err = ioutil.WriteFile(filepath.Join(cacheDir, certFileName), cert.Certificate, c.CacheDirPerm)
if err != nil {
return err
}
// write private key PEM to disk
err = ioutil.WriteFile(filepath.Join(cacheDir, keyFileName), cert.PrivateKey, c.CacheDirPerm)
if err != nil {
return err
}
return nil
}