// Save set options to a configuration file. If categories are given, only those // options in one of the categories is saved. func Save(path, comment string, category ...string) error { file, err := util.CreatePath(path, 0777, 0777) if err != nil { return err } defer file.Close() set := make(map[string]bool) flag.Visit(func(f *flag.Flag) { set[f.Name] = true }) for _, s := range strings.Split(comment, "\n") { fmt.Fprintf(file, "# %s\n", s) } fmt.Fprintf(file, "# Generated on %s\n", time.Now()) for _, opt := range Options { f := flag.Lookup(opt.Name) if !opt.Relevant(category...) || f == nil { continue } fmt.Fprintf(file, "\n# %s\n", opt.Help) if set[opt.Name] { fmt.Fprintf(file, "%s = %v\n", opt.Name, f.Value) } else { fmt.Fprintf(file, "# %s = %v\n", opt.Name, f.Value) } } return nil }
// Save writes all domain configuration and policy data. func (d *Domain) Save() error { file, err := util.CreatePath(d.ConfigPath, 0777, 0666) if err != nil { return err } ds := proto.MarshalTextString(&d.Config) fmt.Fprint(file, ds) file.Close() return d.Guard.Save(d.Keys.SigningKey) }
func initHost(domain *tao.Domain) { var cfg tao.LinuxHostConfig configureFromOptions(&cfg) _, err := loadHost(domain, &cfg) options.FailIf(err, "Can't create host") // If we get here, keys were created and flags must be ok. file, err := util.CreatePath(hostConfigPath(), 0777, 0666) options.FailIf(err, "Can't create host configuration") cs := proto.MarshalTextString(&cfg) fmt.Fprint(file, cs) file.Close() }
// NewOnDiskPBEKeys creates a new Keys structure with the specified key types // store under PBE on disk. If keys are generated and name is not nil, then a // self-signed x509 certificate will be generated and saved as well. func NewOnDiskPBEKeys(keyTypes KeyType, password []byte, path string, name *pkix.Name) (*Keys, error) { if keyTypes == 0 || (keyTypes & ^Signing & ^Crypting & ^Deriving != 0) { return nil, newError("bad key type") } if path == "" { return nil, newError("bad init call: no path for keys") } k := &Keys{ keyTypes: keyTypes, dir: path, } if len(password) == 0 { // This means there's no secret information: just load a public // verifying key. if k.keyTypes & ^Signing != 0 { return nil, newError("without a password, only a verifying key can be loaded") } err := k.loadCert() if err != nil { return nil, err } if k.Cert == nil { return nil, newError("no password and can't load cert: %s", k.X509Path()) } if k.VerifyingKey, err = FromX509(k.Cert); err != nil { return nil, err } } else { // There are two different types of keysets: in one there's // just a Signer, so we use an encrypted PEM format. In the // other, there are multiple keys, so we use a custom protobuf // format. if k.keyTypes & ^Signing != 0 { // Check to see if there are already keys. f, err := os.Open(k.PBEKeysetPath()) if err == nil { defer f.Close() ks, err := ioutil.ReadAll(f) if err != nil { return nil, err } data, err := PBEDecrypt(ks, password) if err != nil { return nil, err } defer ZeroBytes(data) var cks CryptoKeyset if err = proto.Unmarshal(data, &cks); err != nil { return nil, err } // TODO(tmroeder): defer zeroKeyset(&cks) ktemp, err := UnmarshalKeyset(&cks) if err != nil { return nil, err } // Note that this loads the certificate if it's // present, and it returns nil otherwise. err = k.loadCert() if err != nil { return nil, err } k.SigningKey = ktemp.SigningKey k.VerifyingKey = ktemp.VerifyingKey k.CryptingKey = ktemp.CryptingKey k.DerivingKey = ktemp.DerivingKey } else { // Create and store a new set of keys. k, err = NewTemporaryKeys(keyTypes) if err != nil { return nil, err } k.dir = path cks, err := MarshalKeyset(k) if err != nil { return nil, err } // TODO(tmroeder): defer zeroKeyset(cks) m, err := proto.Marshal(cks) if err != nil { return nil, err } defer ZeroBytes(m) enc, err := PBEEncrypt(m, password) if err != nil { return nil, err } if err = util.WritePath(k.PBEKeysetPath(), enc, 0777, 0600); err != nil { return nil, err } if k.SigningKey != nil && name != nil { err = k.newCert(name) if err != nil { return nil, err } } } } else { // There's just a signer, so do PEM encryption of the encoded key. f, err := os.Open(k.PBESignerPath()) if err == nil { defer f.Close() // Read the signer. ss, err := ioutil.ReadAll(f) if err != nil { return nil, err } pb, rest := pem.Decode(ss) if pb == nil || len(rest) > 0 { return nil, newError("decoding failure") } p, err := x509.DecryptPEMBlock(pb, password) if err != nil { return nil, err } defer ZeroBytes(p) err = k.loadCert() if err != nil { return nil, err } if k.SigningKey, err = UnmarshalSignerDER(p); err != nil { return nil, err } k.VerifyingKey = k.SigningKey.GetVerifier() } else { // Create a fresh key and store it to the PBESignerPath. if k.SigningKey, err = GenerateSigner(); err != nil { return nil, err } k.VerifyingKey = k.SigningKey.GetVerifier() p, err := MarshalSignerDER(k.SigningKey) if err != nil { return nil, err } defer ZeroBytes(p) pb, err := x509.EncryptPEMBlock(rand.Reader, "EC PRIVATE KEY", p, password, x509.PEMCipherAES128) if err != nil { return nil, err } pbes, err := util.CreatePath(k.PBESignerPath(), 0777, 0600) if err != nil { return nil, err } defer pbes.Close() if err = pem.Encode(pbes, pb); err != nil { return nil, err } if k.SigningKey != nil && name != nil { err = k.newCert(name) if err != nil { return nil, err } } } } } return k, nil }
// InitOnDiskPBEKeys creates a new Keys structure with the specified key types // stored under PBE on disk. If name is not nil, then a self-signed x509 // certificate will be generated and saved as well. func InitOnDiskPBEKeys(keyTypes KeyType, password []byte, path string, name *pkix.Name) (*Keys, error) { if keyTypes == 0 || (keyTypes & ^Signing & ^Crypting & ^Deriving != 0) { return nil, newError("bad key type") } if path == "" { return nil, newError("bad init call: no path for keys") } if len(password) == 0 { return nil, newError("password may not be empty") } var k *Keys var err error if keyTypes & ^Signing != 0 { // There are are multiple keys, so use a custom protobuf format. k, err = NewTemporaryNamedKeys(keyTypes, name) if err != nil { return nil, err } k.dir = path cks, err := MarshalKeyset(k) if err != nil { return nil, err } // TODO(tmroeder): defer zeroKeyset(cks) m, err := proto.Marshal(cks) if err != nil { return nil, err } defer ZeroBytes(m) enc, err := PBEEncrypt(m, password) if err != nil { return nil, err } if err = util.WritePath(k.PBEKeysetPath(), enc, 0777, 0600); err != nil { return nil, err } } else { k = &Keys{ keyTypes: keyTypes, dir: path, CertificatePool: NewCertificatePool(), } // Just a signer, so create fresh key and store it to PBESignerPath. if k.SigningKey, err = GenerateSigner(); err != nil { return nil, err } k.VerifyingKey = k.SigningKey.GetVerifier() p, err := MarshalSignerDER(k.SigningKey) if err != nil { return nil, err } defer ZeroBytes(p) pb, err := x509.EncryptPEMBlock(rand.Reader, "EC PRIVATE KEY", p, password, x509.PEMCipherAES128) if err != nil { return nil, err } pbes, err := util.CreatePath(k.PBESignerPath(), 0777, 0600) if err != nil { return nil, err } defer pbes.Close() if err = pem.Encode(pbes, pb); err != nil { return nil, err } if name == nil { name = DefaultEphemeralX509Name } template := k.SigningKey.X509Template(name) template.IsCA = true cert, err := k.SigningKey.CreateSelfSignedX509(template) if err != nil { return nil, err } k.Cert["self"] = cert k.Cert["default"] = cert } if err = k.SaveCerts(); err != nil { return nil, err } return k, nil }