aboutsummaryrefslogtreecommitdiff
path: root/cmd
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2015-12-15 14:58:19 +0100
committerDimitri Sokolyuk <demon@dim13.org>2015-12-15 14:58:19 +0100
commit7ca19d9f729b96229ddec049b23adfc28a582aa8 (patch)
tree1f19ba20ce587bc39b6b2c759b73b31cff8b3897 /cmd
parentc636683a650a2e2604bbbb6510d044f95285ba69 (diff)
Create keys
Diffstat (limited to 'cmd')
-rw-r--r--cmd/acmed/config.go27
-rw-r--r--cmd/acmed/main.go83
2 files changed, 106 insertions, 4 deletions
diff --git a/cmd/acmed/config.go b/cmd/acmed/config.go
index 2e19849..4130aab 100644
--- a/cmd/acmed/config.go
+++ b/cmd/acmed/config.go
@@ -1,6 +1,10 @@
package main
-import "github.com/BurntSushi/toml"
+import (
+ "crypto/rsa"
+
+ "github.com/BurntSushi/toml"
+)
type Config struct {
Defaults defaults
@@ -16,6 +20,7 @@ type defaults struct {
Provider string
Account string
Basedir string
+ KeySize int
}
type provider struct {
@@ -23,9 +28,11 @@ type provider struct {
}
type account struct {
- Mail string
- Phone string
- Key string
+ Mail string
+ Phone string
+ Key string
+ KeySize int
+ key *rsa.PrivateKey `toml:"-"`
}
type hook struct {
@@ -37,9 +44,11 @@ type desire struct {
Account string
Altnames []string
Key string
+ KeySize int
Cert string
Webroot string
Hooks []string
+ key *rsa.PrivateKey `toml:"-"`
}
func LoadConfig(fname string) (*Config, error) {
@@ -47,3 +56,13 @@ func LoadConfig(fname string) (*Config, error) {
_, err := toml.DecodeFile(fname, c)
return c, err
}
+
+type Keychain interface {
+ Path() string
+ Size() int
+}
+
+func (d desire) Path() string { return d.Key }
+func (d desire) Size() int { return d.KeySize }
+func (a account) Path() string { return a.Key }
+func (a account) Size() int { return a.KeySize }
diff --git a/cmd/acmed/main.go b/cmd/acmed/main.go
index 06ab7d0..01691e5 100644
--- a/cmd/acmed/main.go
+++ b/cmd/acmed/main.go
@@ -1 +1,84 @@
package main
+
+import (
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "encoding/pem"
+ "flag"
+ "io"
+ "io/ioutil"
+ "log"
+ "os"
+ "path"
+)
+
+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(baseDir string, k Keychain) (*rsa.PrivateKey, error) {
+ key := path.Join(baseDir, 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 {
+ if acc.KeySize == 0 {
+ acc.KeySize = conf.Defaults.KeySize
+ }
+ acc.key, err = chkKey(conf.Defaults.Basedir, acc)
+ if err != nil {
+ log.Fatal(err)
+ }
+ conf.Account[k] = acc
+ }
+
+ for k, des := range conf.Desire {
+ if des.KeySize == 0 {
+ des.KeySize = conf.Defaults.KeySize
+ }
+ des.key, err = chkKey(conf.Defaults.Basedir, des)
+ if err != nil {
+ log.Fatal(err)
+ }
+ conf.Desire[k] = des
+ }
+
+ log.Println(conf)
+}