func unarm_stealth(p string) { if len(wallet.ArmedStealthSecrets) == 0 { fmt.Println("You have no armed seed keys") listarmkeys("") return } if p == "*" || p == "all" { for i := range wallet.ArmedStealthSecrets { sys.ClearBuffer(wallet.ArmedStealthSecrets[i]) } wallet.ArmedStealthSecrets = nil fmt.Println("Removed all armed stealth keys") return } v, e := strconv.ParseUint(p, 10, 32) if e != nil { println(e.Error()) fmt.Println("Specify a valid armed seed key index. Type 'armed seed' to list them.") return } if v >= uint64(len(wallet.ArmedStealthSecrets)) { fmt.Println("Specify a valid armed seed key index. Type 'armed seed' to list them.") return } sys.ClearBuffer(wallet.ArmedStealthSecrets[v]) wallet.ArmedStealthSecrets = append(wallet.ArmedStealthSecrets[:v], wallet.ArmedStealthSecrets[v+1:len(wallet.ArmedStealthSecrets)]...) fmt.Println("Removed armed stealth key number", v) }
// exit after cleaning up private data from memory func cleanExit(code int) { if *verbose { fmt.Println("Cleaning up private keys") } for k := range keys { sys.ClearBuffer(keys[k].Key) } if type2_secret != nil { sys.ClearBuffer(type2_secret) } os.Exit(code) }
func arm_stealth(p string) { var buf, b2 [256]byte create := p != "" fmt.Print("Enter seed password of the stealth key (empty line to abort) : ") le := sys.ReadPassword(buf[:]) if le <= 0 { fmt.Println("Aborted") return } if create { fmt.Print("Re-enter the seed password : "******"The passwords you entered do not match") return } } nw := make([]byte, 32) btc.ShaHash(buf[:le], nw) // seed sys.ClearBuffer(buf[:le]) btc.ShaHash(nw, nw) // 1st key wallet.ArmedStealthSecrets = append(wallet.ArmedStealthSecrets, nw) if create { fmt.Println("You have created a new stealth scan-key. Make sure to not forget this password!") pk := btc.PublicFromPrivate(nw, true) fmt.Println("Public hexdump:", hex.EncodeToString(pk)) fmt.Println(" Go to your wallet machine and execute:") fmt.Println(" wallet -scankey", hex.EncodeToString(pk), "-prefix 0") fmt.Println(" (change the prefix to a different value if you want)") } fmt.Println("Stealth key number", len(wallet.ArmedStealthSecrets)-1, "has been stored in memory") fmt.Println("Reloading the current wallet...") usif.ExecUiReq(&usif.OneUiReq{Handler: func(p string) { wallet.LoadWallet(wallet.MyWallet.FileName) }}) show_prompt = false }
func listarmkeys(p string) { if p != "seed" { if len(wallet.StealthSecrets) > 0 { fmt.Println("Persistent secret scan keys:") for i := range wallet.StealthSecrets { pk := btc.PublicFromPrivate(wallet.StealthSecrets[i], true) fmt.Print(" #", i, " ", hex.EncodeToString(pk)) if p == "addr" { fmt.Print(" ", btc.NewAddrFromPubkey(pk, btc.AddrVerPubkey(common.Testnet)).String()) } fmt.Println() } } else { fmt.Println("You have no persistent secret scan keys") } } if p != "file" { if len(wallet.ArmedStealthSecrets) > 0 { fmt.Println("Volatile secret scan keys:") for i := range wallet.ArmedStealthSecrets { pk := btc.PublicFromPrivate(wallet.ArmedStealthSecrets[i], true) fmt.Print(" #", i, " ", hex.EncodeToString(pk)) if p == "addr" { fmt.Print(" ", btc.NewAddrFromPubkey(pk, btc.AddrVerPubkey(common.Testnet)).String()) } if p == "save" { fn := common.GocoinHomeDir + "wallet/stealth/" + hex.EncodeToString(pk) if fi, er := os.Stat(fn); er == nil && fi.Size() >= 32 { fmt.Print(" already on disk") } else { ioutil.WriteFile(fn, wallet.ArmedStealthSecrets[i], 0600) fmt.Print(" saved") } sys.ClearBuffer(wallet.ArmedStealthSecrets[i]) } fmt.Println() } } else { fmt.Println("You have no volatile secret scan keys") } } if p == "save" { wallet.ArmedStealthSecrets = nil wallet.FetchStealthKeys() } }
func FreeStealthSecrets() { for i := range StealthSecrets { sys.ClearBuffer(StealthSecrets[i]) } StealthSecrets = nil }
func getpass() []byte { var pass [1024]byte var n int var e error var f *os.File if !*ask4pass { f, e = os.Open(PassSeedFilename) if e == nil { n, e = f.Read(pass[:]) f.Close() if n <= 0 { return nil } goto check_pass } fmt.Println("Seed file", PassSeedFilename, "not found") } fmt.Print("Enter your wallet's seed password: "******"" { if !*singleask { fmt.Print("Re-enter the seed password (to be sure): ") var pass2 [1024]byte p2len := sys.ReadPassword(pass2[:]) if p2len != n || !bytes.Equal(pass[:n], pass2[:p2len]) { sys.ClearBuffer(pass[:n]) sys.ClearBuffer(pass2[:p2len]) println("The two passwords you entered do not match") return nil } sys.ClearBuffer(pass2[:p2len]) } if *list { // Maybe he wants to save the password? if ask_yes_no("Save the password on disk, so you won't be asked for it later?") { e = ioutil.WriteFile(PassSeedFilename, pass[:n], 0600) if e != nil { fmt.Println("WARNING: Could not save the password", e.Error()) } else { fmt.Println("The seed password has been stored in", PassSeedFilename) } } } } check_pass: for i := 0; i < n; i++ { if pass[i] < ' ' || pass[i] > 126 { fmt.Println("WARNING: Your secret contains non-printable characters") break } } outpass := make([]byte, n+len(secret_seed)) if len(secret_seed) > 0 { copy(outpass, secret_seed) } copy(outpass[len(secret_seed):], pass[:n]) sys.ClearBuffer(pass[:n]) return outpass }
// Get the secret seed and generate "keycnt" key pairs (both private and public) func make_wallet() { var lab string load_others() var seed_key []byte var hdwal *btc.HDWallet defer func() { sys.ClearBuffer(seed_key) if hdwal != nil { sys.ClearBuffer(hdwal.Key) sys.ClearBuffer(hdwal.ChCode) } }() pass := getpass() if pass == nil { cleanExit(0) } if waltype >= 1 && waltype <= 3 { seed_key = make([]byte, 32) btc.ShaHash(pass, seed_key) sys.ClearBuffer(pass) lab = fmt.Sprintf("Typ%c", 'A'+waltype-1) if waltype == 1 { println("WARNING: Wallet Type 1 is obsolete") } else if waltype == 2 { if type2sec != "" { d, e := hex.DecodeString(type2sec) if e != nil { println("t2sec error:", e.Error()) cleanExit(1) } type2_secret = d } else { type2_secret = make([]byte, 20) btc.RimpHash(seed_key, type2_secret) } } } else if waltype == 4 { lab = "TypHD" hdwal = btc.MasterKey(pass, testnet) sys.ClearBuffer(pass) } else { sys.ClearBuffer(pass) println("ERROR: Unsupported wallet type", waltype) cleanExit(1) } if *verbose { fmt.Println("Generating", keycnt, "keys, version", ver_pubkey(), "...") } first_determ_idx = len(keys) for i := uint(0); i < keycnt; { prv_key := make([]byte, 32) if waltype == 3 { btc.ShaHash(seed_key, prv_key) seed_key = append(seed_key, byte(i)) } else if waltype == 2 { seed_key = btc.DeriveNextPrivate(seed_key, type2_secret) copy(prv_key, seed_key) } else if waltype == 1 { btc.ShaHash(seed_key, prv_key) copy(seed_key, prv_key) } else /*if waltype==4*/ { // HD wallet _hd := hdwal.Child(uint32(0x80000000 | i)) copy(prv_key, _hd.Key[1:]) sys.ClearBuffer(_hd.Key) sys.ClearBuffer(_hd.ChCode) } if *scankey != "" { new_stealth_address(prv_key) return } rec := btc.NewPrivateAddr(prv_key, ver_secret(), !uncompressed) if *pubkey != "" && *pubkey == rec.BtcAddr.String() { fmt.Println("Public address:", rec.BtcAddr.String()) fmt.Println("Public hexdump:", hex.EncodeToString(rec.BtcAddr.Pubkey)) return } rec.BtcAddr.Extra.Label = fmt.Sprint(lab, " ", i+1) keys = append(keys, rec) i++ } if *verbose { fmt.Println("Private keys re-generated") } }