// Current implements storage.Vault. func (v *vault) Current() (*sf.KeyPair, error) { var keyPair sf.KeyPair err := v.db.View(func(tx *bolt.Tx) error { logBucket := tx.Bucket([]byte("log")) if logBucket == nil { return errgo.New("empty vault") } seqBytes, encBytes := logBucket.Cursor().Last() if seqBytes == nil { return errgo.New("empty vault") } seq := new(sf.Nonce) copy(seq[:], seqBytes) keyPairBytes, ok := secretbox.Open(nil, encBytes, (*[24]byte)(seq), (*[32]byte)(v.secretKey)) if !ok { seq := new(big.Int) seq.SetBytes(seqBytes) return errgo.Newf("error opening key pair #%s", seq.String()) } keyPair.PublicKey = new(sf.PublicKey) copy(keyPair.PublicKey[:], keyPairBytes[:32]) keyPair.PrivateKey = new(sf.PrivateKey) copy(keyPair.PrivateKey[:], keyPairBytes[32:]) // TODO: mprotect private key // TODO: zeroize keyPairBytes return nil }) if err != nil { return nil, errgo.Mask(err) } return &keyPair, nil }
// Get implements storage.Vault. func (v *vault) Get(key *sf.PublicKey) (*sf.KeyPair, error) { var keyPair sf.KeyPair err := v.db.View(func(tx *bolt.Tx) error { keysBucket := tx.Bucket([]byte("keys")) if keysBucket == nil { return errgo.New("empty vault") } logBucket := tx.Bucket([]byte("log")) if logBucket == nil { return errgo.New("empty vault") } seqBytes := keysBucket.Get(key[:]) if seqBytes == nil { return errgo.Newf("key pair not found for %q", key.Encode()) } seqInt := new(big.Int) seqInt.SetBytes(seqBytes) encBytes := logBucket.Get(seqBytes) if encBytes == nil { return errgo.Newf("missing expected key #%s", seqInt.String()) } seq := new(sf.Nonce) copy(seq[:], seqBytes) keyPairBytes, ok := secretbox.Open(nil, encBytes, (*[24]byte)(seq), (*[32]byte)(v.secretKey)) if !ok { return errgo.Newf("error opening key pair #%s", seqInt.String()) } keyPair.PublicKey = new(sf.PublicKey) copy(keyPair.PublicKey[:], keyPairBytes[:32]) keyPair.PrivateKey = new(sf.PrivateKey) copy(keyPair.PrivateKey[:], keyPairBytes[32:]) // TODO: mprotect private key // TODO: zeroize keyPairBytes return nil }) if err != nil { return nil, errgo.Mask(err) } return &keyPair, nil }
// Each implements storage.Each. func (v *vault) Each(kpf func(keyPair *sf.KeyPair) error) error { err := v.db.View(func(tx *bolt.Tx) error { logBucket := tx.Bucket([]byte("log")) if logBucket == nil { return errgo.New("empty vault") } c := logBucket.Cursor() for seqBytes, encBytes := c.First(); seqBytes != nil; seqBytes, encBytes = c.Next() { if v == nil { // TODO: warning, empty value for key not expected continue } // TODO: mprotect private key? var keyPair sf.KeyPair seq := new(sf.Nonce) copy(seq[:], seqBytes) keyPairBytes, ok := secretbox.Open(nil, encBytes, (*[24]byte)(seq), (*[32]byte)(v.secretKey)) if !ok { seq := new(big.Int) seq.SetBytes(seqBytes) return errgo.Newf("error opening key pair #%s", seq.String()) } keyPair.PublicKey = new(sf.PublicKey) copy(keyPair.PublicKey[:], keyPairBytes[:32]) keyPair.PrivateKey = new(sf.PrivateKey) copy(keyPair.PrivateKey[:], keyPairBytes[32:]) err := kpf(&keyPair) if err != nil { return errgo.Mask(err) } // TODO: zeroize keyPairBytes } return nil }) return errgo.Mask(err) }
func loadKeyPair() (*sf.KeyPair, error) { f, err := os.Open(*keypairFlag) if os.IsNotExist(err) { return newKeyPair() } else if err != nil { return nil, errgo.Mask(err) } defer f.Close() var keyPair sf.KeyPair keyPair.PublicKey = new(sf.PublicKey) keyPair.PrivateKey = new(sf.PrivateKey) _, err = io.ReadFull(f, keyPair.PublicKey[:]) if err != nil { return nil, errgo.Mask(err) } _, err = io.ReadFull(f, keyPair.PrivateKey[:]) if err != nil { return nil, errgo.Mask(err) } return &keyPair, nil }