package main import ( "crypto/rsa" "errors" "flag" "log" "os" "path" "dim13.org/acme" ) var confName = flag.String("conf", "acme.toml", "configuration file") func chkKey(k PrivKey) (*rsa.PrivateKey, error) { key := k.KeyPath() if k.KeyExists() { fd, err := os.Open(key) if err != nil { return nil, err } defer fd.Close() return acme.LoadKey(fd) } else { if err := os.MkdirAll(path.Dir(key), 0700); err != nil { return nil, err } flags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC fd, err := os.OpenFile(key, flags, 0600) if err != nil { return nil, err } defer fd.Close() return acme.NewKey(fd, k.KeySize()) } } func chkCert(k Cert) error { if !k.CertExists() { return errors.New("cert missing") } return nil } func saveCert(k Cert, crt []byte) error { cert := k.CertPath() if err := os.MkdirAll(path.Dir(cert), 0755); err != nil { return err } fd, err := os.Create(cert) if err != nil { return err } defer fd.Close() return acme.SaveCert(fd, crt) } func chkKeys(c *Config) error { var err error for k, acc := range c.Account { acc.key, err = chkKey(acc) if err != nil { return err } c.Account[k] = acc } for k, des := range c.Desire { des.key, err = chkKey(des) if err != nil { return err } c.Desire[k] = des } return nil } func main() { flag.Parse() conf, err := LoadConfig(*confName) if err != nil { log.Fatal(err) } err = chkKeys(conf) if err != nil { log.Fatal(err) } for k, des := range conf.Desire { a, _ := acme.NewAccount(des.account.key) a.AddMail(des.account.Mail) a.AddPhone(des.account.Phone) log.Println(k, a) c, err := acme.NewClient(des.provider.Directory) if err != nil { log.Fatal(err) } log.Println(k, c) err = c.Register(a) if err != nil { log.Fatal("register", err) } err = c.Authorize(a, des.Altnames) if err != nil { log.Fatal("authz", err) } crt, err := c.Cert(a, des.Altnames, des.key) if err != nil { log.Fatal("cert", err) } err = saveCert(des, crt) if err != nil { log.Fatal("save cert", err) } } }