Skip to content

Commit

Permalink
Merge branch 'atomic-key-file' into 'huawei-1.11.2'
Browse files Browse the repository at this point in the history
Atomically save libtrust key file

The libtrust keyfile which is used to set the "ID" property of a daemon must be generated or loaded on every startup.
If the process crashes during startup this could cause the file to be incomplete causing future startup errors.
Ensure that the file is written atomically to ensure the file is never in an incomplete state.

Fixes moby#23985

cherry-pick from moby#24013

Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)
Signed-off-by: Lei Jitang <leijitang@huawei.com>
(cherry picked from commit 9836162)



See merge request docker/docker!623
  • Loading branch information
coolljt0725 committed Jul 3, 2017
2 parents b85fdc9 + 344bbc4 commit dcc1d2e
Showing 1 changed file with 25 additions and 1 deletion.
26 changes: 25 additions & 1 deletion api/common.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package api

import (
"encoding/json"
"encoding/pem"
"fmt"
"mime"
"os"
"path/filepath"
"sort"
"strconv"
"strings"

"github.com/Sirupsen/logrus"
"github.com/docker/docker/pkg/ioutils"
"github.com/docker/docker/pkg/system"
"github.com/docker/docker/pkg/version"
"github.com/docker/engine-api/types"
Expand Down Expand Up @@ -136,11 +140,31 @@ func LoadOrCreateTrustKey(trustKeyPath string) (libtrust.PrivateKey, error) {
if err != nil {
return nil, fmt.Errorf("Error generating key: %s", err)
}
if err := libtrust.SaveKey(trustKeyPath, trustKey); err != nil {
encodedKey, err := serializePrivateKey(trustKey, filepath.Ext(trustKeyPath))
if err != nil {
return nil, fmt.Errorf("Error serializing key: %s", err)
}
if err := ioutils.AtomicWriteFile(trustKeyPath, encodedKey, os.FileMode(0600)); err != nil {
return nil, fmt.Errorf("Error saving key file: %s", err)
}
} else if err != nil {
return nil, fmt.Errorf("Error loading key file %s: %s", trustKeyPath, err)
}
return trustKey, nil
}

func serializePrivateKey(key libtrust.PrivateKey, ext string) (encoded []byte, err error) {
if ext == ".json" || ext == ".jwk" {
encoded, err = json.Marshal(key)
if err != nil {
return nil, fmt.Errorf("unable to encode private key JWK: %s", err)
}
} else {
pemBlock, err := key.PEMBlock()
if err != nil {
return nil, fmt.Errorf("unable to encode private key PEM: %s", err)
}
encoded = pem.EncodeToMemory(pemBlock)
}
return
}

0 comments on commit dcc1d2e

Please sign in to comment.