diff --git a/pixiecore/booters.go b/pixiecore/booters.go index a83daa83..5c4ebaee 100644 --- a/pixiecore/booters.go +++ b/pixiecore/booters.go @@ -15,6 +15,7 @@ package pixiecore import ( + "bytes" "crypto/rand" "encoding/json" "fmt" @@ -126,16 +127,20 @@ func (s *staticBooter) WriteBootFile(ID, io.Reader) error { // APIBooter gets a BootSpec from a remote server over HTTP. // // The API is described in README.api.md -func APIBooter(url string, timeout time.Duration) (Booter, error) { +func APIBooter(url string, timeout time.Duration, signingKey [32]byte) (Booter, error) { if !strings.HasSuffix(url, "/") { url += "/" } ret := &apibooter{ client: &http.Client{Timeout: timeout}, urlPrefix: url + "v1", + key: signingKey, } - if _, err := io.ReadFull(rand.Reader, ret.key[:]); err != nil { - return nil, fmt.Errorf("failed to get randomness for signing key: %s", err) + emptyByteVar := make([]byte, 32) + if bytes.Equal(signingKey[:], emptyByteVar) { + if _, err := io.ReadFull(rand.Reader, ret.key[:]); err != nil { + return nil, fmt.Errorf("failed to get randomness for signing key: %s", err) + } } return ret, nil diff --git a/pixiecore/cli/apicmd.go b/pixiecore/cli/apicmd.go index 597cc2f9..989e63ef 100644 --- a/pixiecore/cli/apicmd.go +++ b/pixiecore/cli/apicmd.go @@ -15,6 +15,7 @@ package cli import ( + "encoding/base64" "fmt" "time" @@ -42,10 +43,31 @@ the Pixiecore boot API. The specification can be found at .`, fatalf("Error reading flag: %s", err) } - booter, err := pixiecore.APIBooter(server, timeout) + var key [32]byte + + signingKey, err := cmd.Flags().GetString("signing-key") + if err != nil { + fatalf("Error reading flag: %s", err) + } else { + if signingKey != "" { + keydata, err := base64.StdEncoding.DecodeString(signingKey) + if err != nil { + fmt.Println("Error decoding signing key (it should be base64 encoded):", err) + } else { + if len(keydata) > 32 { + fatalf("Too long signin key") + } else { + copy(key[:], keydata) + } + } + } + } + + booter, err := pixiecore.APIBooter(server, timeout, key) if err != nil { fatalf("Failed to create API booter: %s", err) } + s := serverFromFlags(cmd) s.Booter = booter @@ -56,5 +78,6 @@ func init() { rootCmd.AddCommand(apiCmd) serverConfigFlags(apiCmd) apiCmd.Flags().Duration("api-request-timeout", 5*time.Second, "Timeout for request to the API server") + apiCmd.Flags().String("signing-key", "", "Signing key") // TODO: SSL cert flags for both client and server auth. } diff --git a/pixiecore/cli/v1compat.go b/pixiecore/cli/v1compat.go index 5dbfe92a..1009230f 100644 --- a/pixiecore/cli/v1compat.go +++ b/pixiecore/cli/v1compat.go @@ -73,8 +73,10 @@ func v1compatCLI() bool { fatalf("cannot provide -cmdline with -api") } + var key [32]byte + log.Printf("Starting Pixiecore in API mode, with server %s", *apiServer) - booter, err := pixiecore.APIBooter(*apiServer, *apiTimeout) + booter, err := pixiecore.APIBooter(*apiServer, *apiTimeout, key) if err != nil { fatalf("Failed to create API booter: %s", err) }