Example #1
0
func cryptSignFile(ks *store.KeyStore, cfg *config) error {
	message, err := util.ReadFile(cfg.Args[0])
	if err != nil {
		util.Errorf("%v", err)
		return err
	}

	out, ok := ks.EncryptAndSignTo(cfg.Label, message)
	if !ok {
		util.Errorf("Failed to encrypt message.")
		return errors.New("signcryption failed")
	}

	if cfg.Armour {
		block := pem.Block{
			Type:  public.SignedAndEncryptedType,
			Bytes: out,
		}
		out = pem.EncodeToMemory(&block)
	}

	err = util.WriteFile(out, cfg.Args[1])
	if err != nil {
		util.Errorf("%v", err)
		return nil
	}
	return nil
}
Example #2
0
func loadStore(path string, m secret.ScryptMode) *store.SecretStore {
	passphrase, err := util.PassPrompt("Secrets passphrase> ")
	if err != nil {
		util.Errorf("Failed to read passphrase: %v", err)
		return nil
	}

	var passwords *store.SecretStore
	if ok, _ := util.Exists(path); ok {
		defer util.Zero(passphrase)
		fileData, err := util.ReadFile(path)
		if err != nil {
			util.Errorf("%v", err)
			return nil
		}
		var ok bool
		passwords, ok = store.UnmarshalSecretStore(fileData, passphrase, m)
		if !ok {
			return nil
		}
		return passwords
	}
	util.Errorf("could not find %s", path)
	return nil
}
Example #3
0
// LoadKeyStore attempts to load a keystore from the given path. If
// the keystore doesn't exist, a new one is created with a
// freshly-generated keys if the orNew argument is true.
func LoadKeyStore(path string, orNew bool) (*KeyStore, bool) {
	data, err := ioutil.ReadFile(path)
	if err != nil && os.IsNotExist(err) && orNew {
		var priv *public.PrivateKey
		priv, err = public.GenerateKey()
		if err != nil {
			util.Errorf("Failed to generate key.")
			return nil, false
		}
		return NewPrivateKeyStore(priv)
	} else if err != nil {
		util.Errorf("%v", err)
		return nil, false
	}

	store := new(KeyStore)
	err = json.Unmarshal(data, store)
	if err != nil {
		util.Errorf("%v", err)
		return nil, false
	}
	if store.Keys == nil {
		store.Keys = map[string]*PublicKeyRecord{}
	}
	if store.PrivateKey != nil {
		store.locked = true
	}

	if !store.Valid(true) {
		util.Errorf("invalid keystore %v", store)
		return nil, false
	}
	return store, true
}
Example #4
0
// UnmarshalSecretStore decrypts and parses the secret store contained
// in the input byte slice.
func UnmarshalSecretStore(in, passphrase []byte, m secret.ScryptMode) (*SecretStore, bool) {
	if len(in) < saltSize {
		return nil, false
	}

	salt := in[:saltSize]
	enc := in[saltSize:]
	key := secret.DeriveKeyStrength(passphrase, salt, m)
	if key == nil {
		return nil, false
	}
	defer util.Zero(key[:])

	data, ok := secret.Decrypt(key, enc)
	if !ok {
		util.Errorf("decrypt fails")
		return nil, false
	}
	defer util.Zero(data)

	var store SecretStore
	err := json.Unmarshal(data, &store)
	if err != nil {
		util.Errorf("encrypt fails")
		return nil, false
	}

	store.passphrase = make([]byte, len(passphrase))
	copy(store.passphrase, passphrase)
	return &store, true
}
Example #5
0
func loadStore(path string) *store.KeyStore {
	// If keystore is newly created, we'll want to write it to
	// disk before leaving this function.
	var flush bool
	if exists, _ := util.Exists(path); !exists {
		flush = true
	}

	passphrase, err := util.PassPrompt("keystore passphrase> ")
	if err != nil {
		util.Errorf("%v", err)
		return nil
	}
	defer util.Zero(passphrase)

	keystore, ok := store.LoadKeyStore(path, true)
	if !ok {
		fmt.Printf("error in LoadKeyStore")
		return nil
	}
	if !keystore.Valid(false) {
		fmt.Println("keystore not valid")
		return nil
	}

	if !flush {
		if !keystore.Unlock(passphrase) {
			return nil
		}
		return keystore
	}

	if !keystore.LockWith(passphrase) {
		util.Errorf("Failed to set initial passphrase.")
		return nil
	} else if !keystore.Unlock(passphrase) {
		util.Errorf("Flushing keystore failed.")
		return nil
	}

	out, err := keystore.Dump()
	if err != nil {
		log.Printf("WARNING: failed to dump keystore: %v", err)
		return nil
	}
	err = ioutil.WriteFile(path, out, 0644)
	if err != nil {
		log.Printf("WARNING: failed to write keystore: %v", err)
	}

	return keystore
}
Example #6
0
func writeStore(ks *store.KeyStore, path string) bool {
	storeData := store.DumpKeyStore(ks)
	if storeData == nil {
		util.Errorf("Failed to dump keystore.")
		return false
	}

	err := ioutil.WriteFile(path, storeData, 0644)
	if err != nil {
		util.Errorf("%v", err)
		return false
	}
	return true
}
Example #7
0
func addSecret(ps *store.SecretStore, cfg *config, m secret.ScryptMode) error {
	if cfg.WithMeta {
		return addMeta(ps, cfg, m)
	}
	label := cfg.Args[0]

	var rec *store.SecretRecord
	if ps.Has(label) {
		if !cfg.Overwrite {
			return errors.New("entry exists, not forcing overwrite")
		}
		util.Errorf("*** WARNING: overwriting password")
		rec = ps.Store[label]
	} else {
		rec = &store.SecretRecord{Label: label}
	}

	password, err := readpass.PasswordPromptBytes("New password: "******"no password entered")
	}
	rec.Secret = password
	rec.Timestamp = time.Now().Unix()
	ps.Store[label] = rec
	return nil
}
Example #8
0
func removeMeta(ps *store.SecretStore, cfg *config) error {
	label := cfg.Args[0]
	if !ps.Has(label) {
		return errors.New("entry not found")
	}

	rec := ps.Store[label]

	for {
		var keys = make([]string, 0, len(rec.Metadata))
		for k := range rec.Metadata {
			keys = append(keys, k)
		}
		sort.Strings(keys)
		fmt.Println("Keys:")
		for i := range keys {
			fmt.Printf("\t%s\n", keys[i])
		}

		key, err := util.ReadLine("Remove key: ")
		if err != nil {
			util.Errorf("Failed to read key: %v", err)
			continue
		} else if key == "" {
			break
		}
		delete(rec.Metadata, key)
		fmt.Println("Deleted key", key)
	}
	rec.Timestamp = time.Now().Unix()
	ps.Store[label] = rec
	return nil
}
Example #9
0
func initStore(path string, m secret.ScryptMode) error {
	passphrase, err := util.PassPrompt("Secrets passphrase> ")
	if err != nil {
		util.Errorf("Failed to read passphrase: %v", err)
		return err
	}

	if len(passphrase) == 0 {
		return fmt.Errorf("No passphrase provided.")
	}

	defer util.Zero(passphrase)
	passwords := store.NewSecretStore(passphrase)
	if passwords == nil {
		return fmt.Errorf("failed to create store")
	}

	fmt.Println("creating store...")
	fileData, ok := store.MarshalSecretStore(passwords, m)
	if !ok {
		return fmt.Errorf("failed to marshal store")
	}

	err = util.WriteFile(fileData, path)
	if err != nil {
		return err
	}

	passwords, ok = store.UnmarshalSecretStore(fileData, passphrase, m)
	if !ok {
		err = fmt.Errorf("failed to unmarshal store")
	}
	return err
}
Example #10
0
// migrateStore decrypts a file using the legacy settings for scrypt,
// and re-encrypts with the current settings.
func migrateStore(path string) {
	prompt := fmt.Sprintf("Password for %s: ", path)
	pass, err := readpass.PasswordPromptBytes(prompt)
	if err != nil {
		util.Errorf("%v", err)
		os.Exit(1)
	}

	blob, err := legacy.DecryptFile(path, pass)
	if err != nil {
		util.Errorf("%v", err)
		os.Exit(1)
	}
	fmt.Printf("[+] Decrypted %s.\n", path)

	err = secret.EncryptFile(path, pass, blob)
	if err != nil {
		util.Errorf("%v", err)
		os.Exit(1)
	}
	fmt.Printf("[+] Migrated %s.\n", path)
}
Example #11
0
// KeyAudit verifies the signature chain on all keys in the
// keystore. This operation may be slow, and it is recommended that it
// be run at most once per hour. For large keystores, once per day
// might be more suitable.
func (s *KeyStore) KeyAudit() bool {
	if !s.Valid(true) {
		return false
	}

	for lbl := range s.Keys {
		if !s.VerifyChain(lbl) {
			util.Errorf("Key %s is not trusted.", lbl)
			return false
		}
	}
	return true
}
Example #12
0
func writeStore(ps *store.SecretStore, path string, m secret.ScryptMode) bool {
	fileData, ok := store.MarshalSecretStore(ps, m)
	if !ok {
		return false
	}

	err := util.WriteFile(fileData, path)
	if err != nil {
		util.Errorf("Write failed: %v", err)
		return false
	}
	return true
}
Example #13
0
func multi(ps *store.SecretStore, cfg *config, m secret.ScryptMode) error {
	fmt.Println("Use an empty name to indicate that you are done.")
	for {
		name, err := util.ReadLine("Name: ")
		if err != nil {
			return err
		} else if name == "" {
			break
		}

		var rec *store.SecretRecord
		if ps.Has(name) {
			if !cfg.Overwrite {
				util.Errorf("Entry exists, not forcing overwrite.")
				continue
			} else {
				util.Errorf("*** WARNING: overwriting password")
			}
			rec = ps.Store[name]
		} else {
			rec = &store.SecretRecord{
				Label: name,
			}
		}

		password, err := util.PassPrompt("Password: "******"No password entered.")
			continue
		}
		rec.Secret = password
		rec.Timestamp = time.Now().Unix()
		ps.Store[name] = rec
	}
	return nil
}
Example #14
0
func unlockStore(ks *store.KeyStore) bool {
	if !ks.Locked() {
		return true
	}
	passphrase, err := util.PassPrompt("keystore passphrase> ")
	if err != nil {
		util.Errorf("%v", err)
		return false
	}
	defer util.Zero(passphrase)

	if !ks.Locked() && ks.PrivateKey == nil {
		if !ks.LockWith(passphrase) {
			util.Errorf("Failed to set initial passphrase.")
			return false
		}
	}

	if !ks.Unlock(passphrase) {
		util.Errorf("Unlock failed (bad passphrase?)")
		return false
	}
	return true
}
Example #15
0
func writeMeta(args []string) error {
	if len(args) == 0 {
		return errors.New("no label specified")
	} else if len(args) > 1 {
		return errors.New("only one label may be specified")
	}

	label := args[0]
	r, ok := session.Store.Store[label]
	if !ok {
		return errors.New("no such record")
	}

	if r.Metadata == nil {
		r.Metadata = map[string][]byte{}
	}

	fmt.Println("Enter metadata; use an empty line to indicate that you are done.")
	for {
		line, err := util.ReadLine("key = value: ")
		if err != nil {
			return err
		} else if line == "" {
			break
		}

		meta := strings.SplitN(line, "=", 2)
		if len(meta) < 2 {
			util.Errorf("Metadata should be in the form 'key=value'")
			continue
		}

		key := strings.TrimSpace(meta[0])
		val := strings.TrimSpace(meta[1])

		if prev, ok := r.Metadata[key]; ok {
			fmt.Printf("Note: replacing previous value of '%s'\n", string(prev))
		}

		r.Metadata[key] = []byte(val)
	}
	r.Timestamp = time.Now().Unix()
	session.Store.Timestamp = r.Timestamp
	session.Store.Store[label] = r
	session.Dirty = true
	return nil
}
Example #16
0
func addMeta(ps *store.SecretStore, cfg *config, m secret.ScryptMode) error {
	label := cfg.Args[0]
	if !ps.Has(label) {
		tempConfig := *cfg
		tempConfig.WithMeta = false
		err := addSecret(ps, &tempConfig, m)
		if err != nil {
			return err
		}
	}

	rec := ps.Store[label]
	if rec.Metadata == nil {
		rec.Metadata = map[string][]byte{}
	}
	fmt.Println("Enter metadata; use an empty line to indicate that you are done.")
	for {
		line, err := util.ReadLine("key = value: ")
		if err != nil {
			return err
		} else if line == "" {
			break
		}

		meta := strings.SplitN(line, "=", 2)
		if len(meta) < 2 {
			util.Errorf("Metadata should be in the form 'key=value'")
			continue
		}

		key := strings.TrimSpace(meta[0])
		val := strings.TrimSpace(meta[1])
		rec.Metadata[key] = []byte(val)
	}
	rec.Timestamp = time.Now().Unix()
	ps.Store[label] = rec
	return nil
}
Example #17
0
func main() {
	baseFile := filepath.Join(os.Getenv("HOME"), ".secrets.db")
	doInit := flag.Bool("init", false, "initialize a new store")
	doMerge := flag.Bool("merge", false, "merge another store into this store")
	doExport := flag.Bool("export", false, "export store to PEM")
	doImport := flag.Bool("import", false, "import store from PEM")
	doMulti := flag.Bool("multi", false, "enter multiple passwords")
	doChPass := flag.Bool("c", false, "change the store's password")
	storePath := flag.String("f", baseFile, "path to password store")
	doList := flag.Bool("l", false, "list accounts")
	withMeta := flag.Bool("m", false, "include metadata")
	doRemove := flag.Bool("r", false, "remove entries")
	doStore := flag.Bool("s", false, "store password")
	clipExport := flag.Bool("x", false, "dump secrets for clipboard")
	overWrite := flag.Bool("w", false, "overwrite existing secrets")
	doVersion := flag.Bool("V", false, "display version and exit")
	scryptInteractive := flag.Bool("i", false, "use scrypt interactive")
	flag.Parse()

	if *doVersion {
		fmt.Println("secrets version", util.VersionString())
		os.Exit(0)
	}

	scryptMode := secret.ScryptStandard
	if *scryptInteractive {
		scryptMode = secret.ScryptInteractive
	}

	var cfg = &config{
		Args:      flag.Args(),
		Clip:      *clipExport,
		WithMeta:  *withMeta,
		Overwrite: *overWrite,
	}

	var cmd command
	switch {
	case *doInit:
		cmd = commandSet["init"]
		err := initStore(*storePath, scryptMode)
		if err != nil {
			util.Errorf("Failed: %v", err)
			os.Exit(1)
		}
		return
	case *doChPass:
		cmd = commandSet["passwd"]
	case *doStore:
		cmd = commandSet["store"]
	case *doRemove:
		cmd = commandSet["remove"]
	case *doList:
		cmd = commandSet["list"]
	case *doMulti:
		cmd = commandSet["multi"]
	case *doMerge:
		cmd = commandSet["merge"]
	case *doExport:
		if flag.NArg() != 1 {
			util.Errorf("No output file specified.")
		}
		err := exportStore(*storePath, flag.Arg(0))
		if err != nil {
			util.Errorf("Failed: %v", err)
			os.Exit(1)
		}
		return
	case *doImport:
		if flag.NArg() != 1 {
			util.Errorf("No input file specified.")
		}
		err := importStore(*storePath, flag.Arg(0))
		if err != nil {
			util.Errorf("Failed: %v", err)
			os.Exit(1)
		}
		return
	default:
		cmd = commandSet["show"]
	}

	if flag.NArg() < cmd.RequiredArgc {
		util.Errorf("Not enough arguments: want %d, have %d.",
			cmd.RequiredArgc, flag.NArg())
		util.Errorf("Want: %v", strings.Join(cmd.Args, ", "))
		os.Exit(1)
	}

	passwords := loadStore(*storePath, scryptMode)
	if passwords == nil {
		util.Errorf("Failed to open password store")
		os.Exit(1)
	}
	defer passwords.Zero()

	err := cmd.Run(passwords, cfg, scryptMode)
	if err != nil {
		util.Errorf("Failed: %v", err)
		os.Exit(1)
	}

	if cmd.ShouldWrite {
		passwords.Timestamp = time.Now().Unix()
		if !writeStore(passwords, *storePath, scryptMode) {
			util.Errorf("Failed to write store!")
			os.Exit(1)
		}
	}
}
Example #18
0
func addSecret(ps *store.SecretStore, cfg *config) error {
	label := cfg.Args[0]
	if ps.Has(label) {
		if cfg.Overwrite {
			util.Errorf("WARNING: a token already exists under this label!")
		} else {
			return errors.New("token already exists under label")
		}
	}

	// Default prompt is echoing, which we want here.
	secret, err := util.PassPrompt("Secret: ")
	if err != nil {
		return err
	}

	var rec *store.SecretRecord
	secret = sanitiseSecret(secret)
	switch cfg.OTPType {
	case HOTP:
		in, err := util.ReadLine("Initial counter (0): ")
		if err != nil {
			return err
		}
		if in == "" {
			in = "0"
		}
		d, err := strconv.Atoi(in)
		if err != nil {
			return err
		}

		in, err = util.ReadLine("Digits (6 or 8): ")
		if err != nil {
			return err
		} else if in == "" {
			in = "6"
		}

		digits, err := strconv.Atoi(in)
		if err != nil {
			return err
		}

		key, err := base32.StdEncoding.DecodeString(string(secret))
		if err != nil {
			fmt.Printf("%s", secret)
			return err
		}

		var hotp *twofactor.HOTP
		hotp = twofactor.NewHOTP(key, uint64(d), digits)
		confirmation := hotp.OTP()
		fmt.Printf("Confirmation: %s\n", confirmation)
		rec = &store.SecretRecord{
			Label:     label,
			Secret:    []byte(hotp.URL(label)),
			Timestamp: time.Now().Unix(),
			Metadata: map[string][]byte{
				"key":          secret,
				"type":         []byte("HOTP"),
				"confirmation": []byte(confirmation),
			},
		}
	case TOTP:
		in, err := util.ReadLine("Time step (30s): ")
		if err != nil {
			return err
		}
		if in == "" {
			in = "30s"
		}
		d, err := time.ParseDuration(in)
		if err != nil {
			return err
		}

		in, err = util.ReadLine("Digits (6 or 8): ")
		if err != nil {
			return err
		} else if in == "" {
			in = "6"
		}

		digits, err := strconv.Atoi(in)
		if err != nil {
			return err
		}

		key, err := base32.StdEncoding.DecodeString(string(secret))
		if err != nil {
			return err
		}

		var totp *twofactor.TOTP
		totp = twofactor.NewTOTPSHA1(key, 0, uint64(d.Seconds()), digits)
		confirmation := totp.OTP()
		fmt.Printf("Confirmation: %s\n", confirmation)
		rec = &store.SecretRecord{
			Label:     label,
			Secret:    []byte(totp.URL(label)),
			Timestamp: time.Now().Unix(),
			Metadata: map[string][]byte{
				"key":          secret,
				"type":         []byte("TOTP-SHA1"),
				"step":         []byte(d.String()),
				"confirmation": []byte(confirmation),
			},
		}
	case GoogleTOTP:
		var totp *twofactor.TOTP
		totp, err = twofactor.NewGoogleTOTP(string(secret))
		if err != nil {
			return err
		}
		confirmation := totp.OTP()
		fmt.Printf("Confirmation: %s\n", confirmation)
		rec = &store.SecretRecord{
			Label:     label,
			Secret:    []byte(totp.URL(label)),
			Timestamp: time.Now().Unix(),
			Metadata: map[string][]byte{
				"key":          secret,
				"type":         []byte("TOTP-GOOGLE"),
				"step":         []byte("30s"),
				"confirmation": []byte(confirmation),
			},
		}
	default:
		return errors.New("unrecognised OTP type")
	}
	ps.Store[label] = rec
	return nil
}
Example #19
0
func main() {
	baseFile := filepath.Join(os.Getenv("HOME"), ".otpc.db")
	doInit := flag.Bool("init", false, "initialize a new store")
	doStore := flag.Bool("s", false, "store a new two-factor token")
	storePath := flag.String("f", baseFile, "path to password store")
	otpKind := flag.String("t", "", "OTP type (TOTP, HOTP, GOOGLE)")
	doQR := flag.Bool("qr", false, "dump QR code for secret")
	doVersion := flag.Bool("V", false, "display version and exit")
	scryptInteractive := flag.Bool("i", false, "use scrypt interactive")
	flag.Parse()

	if *doVersion {
		fmt.Println("otpc version", util.VersionString())
		os.Exit(0)
	}

	scryptMode := secret.ScryptStandard
	if *scryptInteractive {
		scryptMode = secret.ScryptInteractive
	}

	var cfg = &config{
		Args:    flag.Args(),
		OTPType: parseOTPKind(*otpKind),
	}

	var cmd command
	switch {
	case *doInit:
		cmd = commandSet["init"]
		err := initStore(*storePath, scryptMode)
		if err != nil {
			util.Errorf("Failed: %v", err)
			os.Exit(1)
		}
		return
	case *doStore:
		cmd = commandSet["store"]
	case *doQR:
		cmd = commandSet["qr"]
	default:
		cmd = commandSet["show"]
	}

	if flag.NArg() < cmd.RequiredArgc {
		util.Errorf("Not enough arguments: want %d, have %d.",
			cmd.RequiredArgc, flag.NArg())
		util.Errorf("Want: %v", strings.Join(cmd.Args, ", "))
		os.Exit(1)
	}

	ps := loadStore(*storePath, scryptMode)
	if ps == nil {
		util.Errorf("Failed to open two-factor store.")
		os.Exit(1)
	}
	defer ps.Zero()

	err := cmd.Run(ps, cfg)
	if err != nil {
		util.Errorf("Failed: %v", err)
		os.Exit(1)
	}

	if cmd.ShouldWrite || cfg.Updated {
		ps.Timestamp = time.Now().Unix()
		if !writeStore(ps, *storePath, scryptMode) {
			util.Errorf("Failed to write store!")
			os.Exit(1)
		}
	}
}
Example #20
0
func main() {
	baseFile := filepath.Join(os.Getenv("HOME"), ".secrets.db")
	count := flag.Int("n", 5, "how many delegations are going out?")
	caFile := flag.String("ca", "", "CA file for Red October")
	storePath := flag.String("f", baseFile, "path to password store")
	scryptInteractive := flag.Bool("i", false, "use scrypt interactive")
	forTime := flag.String("for", "1h", "how long should the delegation be active for?")
	labels := flag.String("labels", "", "red october labels to use for decryption")
	server := flag.String("server", "127.0.0.1:8080", "host:port of red october server")
	owners := flag.String("to", "", "users to whitelist for decryption")
	userName := flag.String("u", "", "username for red october")
	flag.Parse()

	if flag.NArg() != 2 {
		usage()
		os.Exit(1)
	}

	scryptMode := secret.ScryptStandard
	if *scryptInteractive {
		scryptMode = secret.ScryptInteractive
	}

	passwords := loadStore(*storePath, scryptMode)
	if passwords == nil {
		util.Errorf("Failed to open password store")
		os.Exit(1)
	}
	defer passwords.Zero()

	rec, ok := passwords.Store[flag.Arg(0)]
	if !ok {
		util.Errorf("%s is not a valid label.", flag.Arg(0))
		os.Exit(1)
	}

	var ro roData
	ro.User, ok = getMetadata(rec, "ro-user", *userName)
	if !ok {
		util.Errorf("Unable to get a valid user.")
		os.Exit(1)
	}

	ro.Password = string(rec.Secret)
	ro.Server, ok = getMetadata(rec, "ro-server", *server)
	if !ok {
		util.Errorf("Unable to get a valid user.")
		os.Exit(1)
	}

	ro.CAFile, ok = getMetadata(rec, "ro-ca", *caFile)
	if !ok {
		util.Errorf("Unable to get a valid user.")
		os.Exit(1)
	}

	ro.Labels = split(*labels)
	ro.Owners = split(*owners)
	ro.Count = *count
	ro.Dur = *forTime

	var err error
	cmd := flag.Arg(1)
	switch cmd {
	case "delegate":
		err = delegate(&ro)
	case "summary":
		err = summary(&ro)
	default:
		err = errors.New("rocli: invalid command " + cmd)
	}
	if err != nil {
		util.Errorf("%v", err)
		os.Exit(1)
	}
}
Example #21
0
func main() {
	flArmour := flag.Bool("a", false, "armour output")
	flOutDir := flag.String("o", ".", "output directory")
	flOutfile := flag.String("f", "passcrypt.enc", "pack file")
	flShowManifest := flag.Bool("l", false, "list the files in the archive")
	flUnpack := flag.Bool("u", false, "unpack the archive")
	flag.BoolVar(&verbose, "v", false, "verbose mode")
	flVersion := flag.Bool("V", false, "display version and exit")
	flag.Parse()

	if *flVersion {
		fmt.Println("passcrypt version", util.VersionString())
		os.Exit(0)
	}

	if *flUnpack || *flShowManifest {
		if flag.NArg() != 1 {
			util.Errorf("Only one file may be unpacked at a time.\n")
			os.Exit(1)
		}

		in, err := ioutil.ReadFile(flag.Arg(0))
		if err != nil {
			util.Errorf("%v\n", err)
			os.Exit(1)
		}

		if p, _ := pem.Decode(in); p != nil {
			if p.Type != header {
				util.Errorf("Wrong header for archive.\n")
				os.Exit(1)
			}
			in = p.Bytes
		}

		if len(in) <= saltLength {
			util.Errorf("Invalid archive.\n")
			os.Exit(1)
		}
		salt := in[:saltLength]
		in = in[saltLength:]

		passphrase, err := readpass.PasswordPromptBytes("Password: "******"%v\n", err)
			os.Exit(1)
		}

		key := secret.DeriveKey(passphrase, salt)
		if key == nil {
			util.Errorf("Failed to derive key.n\n")
			os.Exit(1)
		}

		in, ok := secret.Decrypt(key, in)
		if !ok {
			util.Errorf("Decryption failed.\n")
			os.Exit(1)
		}
		defer util.Zero(in)

		if *flUnpack {
			err = unpackFiles(in, *flOutDir)
			if err != nil {
				util.Errorf("%v\n", err)
				os.Exit(1)
			}
		} else if *flShowManifest {
			var files []File
			_, err := asn1.Unmarshal(in, &files)
			if err != nil {
				util.Errorf("%v\n", err)
				os.Exit(1)
			}

			fmt.Println("Manifest for", flag.Arg(0))
			fmt.Printf("\n")
			for _, file := range files {
				fmt.Printf("\t%s", file.Path)
				if os.FileMode(file.Mode).IsDir() {
					fmt.Printf("/")
				}
				fmt.Printf("\n")
			}
		}
		return
	}

	if flag.NArg() == 0 {
		return
	}

	passphrase, err := readpass.PasswordPromptBytes("Password: "******"%v\n", err)
		os.Exit(1)
	}

	salt := util.RandBytes(saltLength)
	if salt == nil {
		util.Errorf("Failed to generate a random salt.\n")
		os.Exit(1)
	}

	key := secret.DeriveKey(passphrase, salt)
	if key == nil {
		util.Errorf("Failed to derive key.n\n")
		os.Exit(1)
	}

	out, err := packFiles(flag.Args())
	if err != nil {
		util.Errorf("%v\n", err)
		os.Exit(1)
	}

	var ok bool
	out, ok = secret.Encrypt(key, out)
	if !ok {
		util.Errorf("Encryption failed.\n")
		os.Exit(1)
	}

	out = append(salt, out...)

	if *flArmour {
		p := &pem.Block{
			Type:  header,
			Bytes: out,
		}
		out = pem.EncodeToMemory(p)
	}

	err = ioutil.WriteFile(*flOutfile, out, 0644)
	if err != nil {
		util.Errorf("%v\n", err)
		os.Exit(1)
	}
}
Example #22
0
func main() {
	baseFile := filepath.Join(os.Getenv("HOME"), ".cukeystore.db")
	doCheck := flag.Bool("check", false, "check keystore's integrity'")
	doExport := flag.Bool("export", false, "export a verified key")
	doImport := flag.Bool("import", false, "import a key")
	doArmour := flag.Bool("a", false, "armour output")
	doDecrypt := flag.Bool("d", false, "decrypt file")
	doEncrypt := flag.Bool("e", false, "encrypt file")
	keystorePath := flag.String("f", baseFile, "path to keystore")
	doList := flag.Bool("k", false, "list keys")
	label := flag.String("l", "self", "label selecting a key")
	doRemove := flag.Bool("r", false, "remove named key")
	doSign := flag.Bool("s", false, "sign file")
	untrustedOK := flag.Bool("u", false, "accept untrusted keys when importing")
	doVerify := flag.Bool("v", false, "verify signature")
	flag.Parse()

	cfg := &config{
		Args:   flag.Args(),
		Label:  *label,
		Armour: *doArmour,
	}

	var cmd command
	switch {
	case *doCheck:
		cmd = commandSet["check"]
	case *doSign && *doEncrypt:
		cfg.Armour = true
		cmd = commandSet["cryptsign"]
	case *doSign:
		cmd = commandSet["sign"]
	case *doVerify:
		cmd = commandSet["verify"]
	case *doEncrypt:
		cmd = commandSet["encrypt"]
	case *doDecrypt:
		cmd = commandSet["decrypt"]
	case *doRemove:
		cmd = commandSet["remove"]
	case *doList:
		cmd = commandSet["list"]
	case *doExport && *label == "self":
		cmd = commandSet["exportself"]
	case *doExport:
		cmd = commandSet["export"]
	case *doImport:
		if *untrustedOK {
			cmd = commandSet["uimport"]
		} else {
			cmd = commandSet["import"]
		}
	default:
		util.Errorf("Nothing to do.")
		return
	}

	if flag.NArg() < cmd.RequiredArgc {
		util.Errorf("Not enough arguments: want %d, have %d.",
			cmd.RequiredArgc, flag.NArg())
		util.Errorf("Want: %v", strings.Join(cmd.Args, ", "))
		os.Exit(1)
	}

	ks := loadStore(*keystorePath)
	if ks == nil {
		util.Errorf("Failed to load keystore.")
		os.Exit(1)
	}
	if *doCheck && ks.ExportKey == nil {
		cmd.ShouldWrite = true
	}

	if cmd.NeedsUnlock {
		if !unlockStore(ks) {
			os.Exit(1)
		}
		defer ks.Lock()
	}

	err := cmd.Run(ks, cfg)
	if err != nil {
		util.Errorf("Failed: %v", err)
		os.Exit(1)
	}

	shouldWrite := cmd.ShouldWrite
	exists, ok := util.Exists(*keystorePath)
	if !ok {
		util.Errorf("Error checking %s", *keystorePath)
		os.Exit(1)
	}
	shouldWrite = shouldWrite || !exists
	if shouldWrite {
		ks.Timestamp = time.Now().Unix()
		fmt.Println("Writing keystore.")
		if !writeStore(ks, *keystorePath) {
			os.Exit(1)
		}
	}
}
Example #23
0
func main() {
	baseFile := filepath.Join(os.Getenv("HOME"), ".cu_journal")
	doInit := flag.Bool("init", false, "initialize a new store")
	currentEditor := os.Getenv("EDITOR")
	editor := flag.String("editor", currentEditor, "editor for writing entries")
	doEdit := flag.Bool("e", false, "edit entry")
	storePath := flag.String("f", baseFile, "path to journal")
	doList := flag.Bool("l", false, "list entries")
	doWrite := flag.Bool("w", false, "write new entry")
	doVersion := flag.Bool("V", false, "display version and exit")
	scryptInteractive := flag.Bool("i", false, "use scrypt interactive")
	flag.Parse()

	if *doVersion {
		fmt.Println("journal version", util.VersionString())
		os.Exit(0)
	}

	scryptMode := secret.ScryptStandard
	if *scryptInteractive {
		scryptMode = secret.ScryptInteractive
	}

	var cfg = &config{
		Args:   flag.Args(),
		Editor: *editor,
	}

	var cmd command
	switch {
	case *doInit:
		cmd = commandSet["init"]
		err := initStore(*storePath, scryptMode)
		if err != nil {
			util.Errorf("Failed: %v", err)
			os.Exit(1)
		}
		return
	case *doEdit:
		cmd = commandSet["edit"]
	case *doList:
		cmd = commandSet["list"]
	case *doWrite:
		cmd = commandSet["write"]
	default:
		cmd = commandSet["show"]
	}

	if flag.NArg() < cmd.RequiredArgc {
		util.Errorf("Not enough arguments: want %d, have %d.",
			cmd.RequiredArgc, flag.NArg())
		util.Errorf("Want: %v", strings.Join(cmd.Args, ", "))
		os.Exit(1)
	}

	passwords := loadStore(*storePath, scryptMode)
	if passwords == nil {
		util.Errorf("Failed to open password store")
		os.Exit(1)
	}
	defer passwords.Zero()

	err := cmd.Run(passwords, cfg)
	if err != nil {
		util.Errorf("Failed: %v", err)
		os.Exit(1)
	}

	if cmd.ShouldWrite {
		passwords.Timestamp = time.Now().Unix()
		if !writeStore(passwords, *storePath, scryptMode) {
			util.Errorf("Failed to write store!")
			os.Exit(1)
		}
	}
}