package main import ( "crypto/rand" "crypto/rsa" "crypto/x509" "encoding/pem" "flag" "io" "io/ioutil" "log" "os" "path" "dim13.org/acme" ) var confName = flag.String("conf", "acme.toml", "configuration file") func newKey(w io.Writer, size int) (*rsa.PrivateKey, error) { key, err := rsa.GenerateKey(rand.Reader, size) if err != nil { return nil, err } block := &pem.Block{ Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key), } return key, pem.Encode(w, block) } func chkKey(k Keychain) (*rsa.PrivateKey, error) { key := k.Path() flags := os.O_WRONLY | os.O_CREATE | os.O_TRUNC if _, err := os.Stat(key); os.IsNotExist(err) { log.Println("allocating", key, k.Size()) if err := os.MkdirAll(path.Dir(key), 0700); err != nil { return nil, err } fd, err := os.OpenFile(key, flags, 0600) if err != nil { return nil, err } defer fd.Close() return newKey(fd, k.Size()) } else { der, err := ioutil.ReadFile(key) if err != nil { return nil, err } block, _ := pem.Decode(der) return x509.ParsePKCS1PrivateKey(block.Bytes) } } func main() { flag.Parse() conf, err := LoadConfig(*confName) if err != nil { log.Fatal(err) } for k, acc := range conf.Account { acc.key, err = chkKey(acc) if err != nil { log.Fatal(err) } conf.Account[k] = acc } for k, des := range conf.Desire { des.key, err = chkKey(des) if err != nil { log.Fatal(err) } conf.Desire[k] = des } for k, des := range conf.Desire { a, _ := acme.NewAccount(des.account.Mail, des.account.Phone, des.account.key) log.Println(k, a) } }