traefik-certs-dumper/dumper.go
Fernandez Ludovic 4ca0745cbd feat: Birth.
2019-02-11 12:07:06 +01:00

108 lines
2.2 KiB
Go

package main
import (
"encoding/json"
"encoding/pem"
"io/ioutil"
"os"
"path/filepath"
"github.com/xenolf/lego/certcrypto"
"github.com/xenolf/lego/registration"
)
// StoredData represents the data managed by the Store
type StoredData struct {
Account *Account
Certificates []*Certificate
HTTPChallenges map[string]map[string][]byte
TLSChallenges map[string]*Certificate
}
// Certificate is a struct which contains all data needed from an ACME certificate
type Certificate struct {
Domain Domain
Certificate []byte
Key []byte
}
// Domain holds a domain name with SANs
type Domain struct {
Main string
SANs []string
}
// Account is used to store lets encrypt registration info
type Account struct {
Email string
Registration *registration.Resource
PrivateKey []byte
KeyType certcrypto.KeyType
}
func dump(acmeFile, dumpPath string) error {
f, err := os.Open(acmeFile)
if err != nil {
return err
}
data := StoredData{}
if err = json.NewDecoder(f).Decode(&data); err != nil {
return err
}
if err = os.RemoveAll(dumpPath); err != nil {
return err
}
err = os.MkdirAll(filepath.Join(dumpPath, "certs"), 0755)
if err != nil {
return err
}
err = os.MkdirAll(filepath.Join(dumpPath, "private"), 0755)
if err != nil {
return err
}
privateKeyPem := extractPEMPrivateKey(data.Account)
err = ioutil.WriteFile(filepath.Join(dumpPath, "private", "letsencrypt.key"), privateKeyPem, 0666)
if err != nil {
return err
}
for _, cert := range data.Certificates {
err = ioutil.WriteFile(filepath.Join(dumpPath, "private", cert.Domain.Main+".key"), cert.Key, 0666)
if err != nil {
return err
}
err = ioutil.WriteFile(filepath.Join(dumpPath, "certs", cert.Domain.Main+".crt"), cert.Certificate, 0666)
if err != nil {
return err
}
}
return nil
}
func extractPEMPrivateKey(account *Account) []byte {
var block *pem.Block
switch account.KeyType {
case certcrypto.RSA2048, certcrypto.RSA4096, certcrypto.RSA8192:
block = &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: account.PrivateKey,
}
case certcrypto.EC256, certcrypto.EC384:
block = &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: account.PrivateKey,
}
default:
panic("unsupported key type")
}
return pem.EncodeToMemory(block)
}