Update Picocrypt.go

This commit is contained in:
Evan Su 2021-05-25 23:26:24 -04:00 committed by GitHub
parent b52514f5bd
commit 599c7bddd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 117 additions and 51 deletions

View File

@ -17,6 +17,7 @@ import (
"fmt" "fmt"
"math" "math"
"time" "time"
"sync"
"os/exec" "os/exec"
"strings" "strings"
"strconv" "strconv"
@ -30,6 +31,7 @@ import (
"encoding/hex" "encoding/hex"
"path/filepath" "path/filepath"
"crypto/sha256" "crypto/sha256"
"runtime/debug"
"github.com/pkg/browser" "github.com/pkg/browser"
"github.com/zeebo/blake3" "github.com/zeebo/blake3"
"golang.org/x/crypto/sha3" "golang.org/x/crypto/sha3"
@ -162,7 +164,7 @@ func startUI(){
), ),
// Label listing the input files and a button to clear input files // Label listing the input files and a button to clear input files
g.Dummy(10,0), //g.Dummy(10,0),
g.Row( g.Row(
g.Label(inputLabel), g.Label(inputLabel),
g.Dummy(-55,0), g.Dummy(-55,0),
@ -170,7 +172,7 @@ func startUI(){
), ),
// Allow user to choose a custom output path and name // Allow user to choose a custom output path and name
g.Dummy(10,0), //g.Dummy(10,0),
g.Label("Save output as:"), g.Label("Save output as:"),
g.Row( g.Row(
g.InputText("##output",&outputEntry).Size(outputWidth/dpi), g.InputText("##output",&outputEntry).Size(outputWidth/dpi),
@ -192,7 +194,7 @@ func startUI(){
), ),
// Prompt for password // Prompt for password
g.Dummy(10,0), //g.Dummy(10,0),
g.Row( g.Row(
g.Label("Password:"), g.Label("Password:"),
g.Dummy(-200,0), g.Dummy(-200,0),
@ -213,17 +215,17 @@ func startUI(){
), ),
// Prompt to confirm password // Prompt to confirm password
g.Dummy(10,0), //g.Dummy(10,0),
g.Label("Confirm password:"), g.Label("Confirm password:"),
g.InputText("##cPassword",&cPassword).Size(200/dpi).Flags(passwordState), g.InputText("##cPassword",&cPassword).Size(200/dpi).Flags(passwordState),
// Optional metadata // Optional metadata
g.Dummy(10,0), //g.Dummy(10,0),
g.Label("Metadata (optional):"), g.Label("Metadata (optional):"),
g.InputTextMultiline("##metadata",&metadata).Size(226,126), g.InputTextMultiline("##metadata",&metadata).Size(226,126),
// Advanced options can be enabled with checkboxes // Advanced options can be enabled with checkboxes
g.Dummy(10,0), //g.Dummy(10,0),
g.Checkbox("Keep decrypted output even if it's corrupted or modified",&keep), g.Checkbox("Keep decrypted output even if it's corrupted or modified",&keep),
g.Row( g.Row(
g.Checkbox("Encode with Reed-Solomon to prevent corruption",&reedsolo), g.Checkbox("Encode with Reed-Solomon to prevent corruption",&reedsolo),
@ -239,7 +241,7 @@ func startUI(){
g.Checkbox("Fast mode (less secure, not as durable)",&fast), g.Checkbox("Fast mode (less secure, not as durable)",&fast),
// Start and cancel buttons // Start and cancel buttons
g.Dummy(10,0), //g.Dummy(10,0),
g.Button("Start").Size(-1,20).OnClick(func(){ g.Button("Start").Size(-1,20).OnClick(func(){
if mode=="encrypt"{ if mode=="encrypt"{
outputFile = outputEntry+".pcv" outputFile = outputEntry+".pcv"
@ -254,7 +256,7 @@ func startUI(){
} }
}), }),
g.Dummy(10,0), //g.Dummy(10,0),
g.Style().SetColor(ig.StyleColorText,_status_color).To( g.Style().SetColor(ig.StyleColorText,_status_color).To(
g.Label(_status), g.Label(_status),
), ),
@ -269,12 +271,11 @@ func startUI(){
} }
}), }),
g.Dummy(30,0),
g.Label("Select a mode below and drop a file here."), g.Label("Select a mode below and drop a file here."),
g.Label("Warning: Anything dropped here will be shredded immediately!"), g.Label("Warning: Anything dropped here will be shredded immediately!"),
g.Dummy(10,0), //g.Dummy(10,0),
g.Combo("##shredder_mode",items[itemSelected],items,&itemSelected).Size(464), g.Combo("##shredder_mode",items[itemSelected],items,&itemSelected).Size(464),
g.Dummy(10,0), //g.Dummy(10,0),
g.ProgressBar(shredProgress).Overlay(shredOverlay).Size(-1,0), g.ProgressBar(shredProgress).Overlay(shredOverlay).Size(-1,0),
g.Label(shredding).Wrapped(true), g.Label(shredding).Wrapped(true),
), ),
@ -288,11 +289,10 @@ func startUI(){
} }
}), }),
g.Dummy(30,0),
g.Label("Toggle the hashes you would like to generate and drop a file here."), g.Label("Toggle the hashes you would like to generate and drop a file here."),
// MD5 // MD5
g.Dummy(10,0), //g.Dummy(10,0),
g.Row( g.Row(
g.Checkbox("MD5:",&md5_selected), g.Checkbox("MD5:",&md5_selected),
g.Dummy(-45,0), g.Dummy(-45,0),
@ -304,7 +304,7 @@ func startUI(){
), ),
// SHA1 // SHA1
g.Dummy(10,0), //g.Dummy(10,0),
g.Row( g.Row(
g.Checkbox("SHA1:",&sha1_selected), g.Checkbox("SHA1:",&sha1_selected),
g.Dummy(-45,0), g.Dummy(-45,0),
@ -317,7 +317,7 @@ func startUI(){
), ),
// SHA256 // SHA256
g.Dummy(10,0), //g.Dummy(10,0),
g.Row( g.Row(
g.Checkbox("SHA256:",&sha256_selected), g.Checkbox("SHA256:",&sha256_selected),
g.Dummy(-45,0), g.Dummy(-45,0),
@ -330,7 +330,7 @@ func startUI(){
), ),
// SHA3-256 // SHA3-256
g.Dummy(10,0), //g.Dummy(10,0),
g.Row( g.Row(
g.Checkbox("SHA3-256:",&sha3_256_selected), g.Checkbox("SHA3-256:",&sha3_256_selected),
g.Dummy(-45,0), g.Dummy(-45,0),
@ -343,7 +343,7 @@ func startUI(){
), ),
// BLAKE2b // BLAKE2b
g.Dummy(10,0), //g.Dummy(10,0),
g.Row( g.Row(
g.Checkbox("BLAKE2b:",&blake2b_selected), g.Checkbox("BLAKE2b:",&blake2b_selected),
g.Dummy(-45,0), g.Dummy(-45,0),
@ -356,7 +356,7 @@ func startUI(){
), ),
// BLAKE2s // BLAKE2s
g.Dummy(10,0), //g.Dummy(10,0),
g.Row( g.Row(
g.Checkbox("BLAKE2s:",&blake2s_selected), g.Checkbox("BLAKE2s:",&blake2s_selected),
g.Dummy(-45,0), g.Dummy(-45,0),
@ -369,7 +369,7 @@ func startUI(){
), ),
// BLAKE3 // BLAKE3
g.Dummy(10,0), //g.Dummy(10,0),
g.Row( g.Row(
g.Checkbox("BLAKE3:",&blake3_selected), g.Checkbox("BLAKE3:",&blake3_selected),
g.Dummy(-45,0), g.Dummy(-45,0),
@ -382,7 +382,7 @@ func startUI(){
), ),
// Input box for validating checksum // Input box for validating checksum
g.Dummy(10,0), //g.Dummy(10,0),
g.Label("Validate a checksum:"), g.Label("Validate a checksum:"),
g.InputText("##cs_validate",&cs_validate).Size(-1).OnChange(func(){ g.InputText("##cs_validate",&cs_validate).Size(-1).OnChange(func(){
md5_color = color.RGBA{0x10,0x10,0x10,255} md5_color = color.RGBA{0x10,0x10,0x10,255}
@ -414,7 +414,7 @@ func startUI(){
}), }),
// Progress bar // Progress bar
g.Dummy(10,0), //g.Dummy(10,0),
g.Label("Progress:"), g.Label("Progress:"),
g.ProgressBar(cs_progress).Size(-1,0), g.ProgressBar(cs_progress).Size(-1,0),
), ),
@ -425,7 +425,7 @@ func startUI(){
tab = 3 tab = 3
} }
}), }),
g.Dummy(30,0), //g.Dummy(30,0),
g.Label("Picocrypt "+version+", created by Evan Su (https://evansu.cc)"), g.Label("Picocrypt "+version+", created by Evan Su (https://evansu.cc)"),
), ),
), ),
@ -433,7 +433,7 @@ func startUI(){
) )
if working{ if working{
g.SingleWindow("Working..").IsOpen(&working).Layout( g.SingleWindow("Working..").IsOpen(&working).Layout(
g.Dummy(30,0), //g.Dummy(30,0),
g.Label("Tips:"), g.Label("Tips:"),
g.Label(" - Choose a strong password with more than 16 characters."), g.Label(" - Choose a strong password with more than 16 characters."),
g.Label(" - Use a unique password that isn't used anywhere else."), g.Label(" - Use a unique password that isn't used anywhere else."),
@ -452,7 +452,7 @@ func startUI(){
working = false working = false
}), }),
), ),
g.Dummy(10,0), //g.Dummy(10,0),
g.Label(status), g.Label(status),
) )
} }
@ -491,6 +491,9 @@ func onDrop(names []string){
outputEntry = filepath.Join(filepath.Dir(names[0]),"Encrypted.zip") outputEntry = filepath.Join(filepath.Dir(names[0]),"Encrypted.zip")
mode = "encrypt" mode = "encrypt"
// Show the ".pcv" file extension
orLabel = ".pcv or"
outputWidth = 341
}else{ }else{
files++ files++
name := filepath.Base(names[0]) name := filepath.Base(names[0])
@ -564,6 +567,8 @@ func onDrop(names []string){
inputLabel = fmt.Sprintf("1 file and %d folders selected.",folders) inputLabel = fmt.Sprintf("1 file and %d folders selected.",folders)
}else if folders==1&&files>1{ }else if folders==1&&files>1{
inputLabel = fmt.Sprintf("%d files and 1 folder selected.",files) inputLabel = fmt.Sprintf("%d files and 1 folder selected.",files)
}else if folders==1&&files==1{
inputLabel = "1 file and 1 folder selected."
}else{ }else{
inputLabel = fmt.Sprintf("%d files and %d folders selected.",files,folders) inputLabel = fmt.Sprintf("%d files and %d folders selected.",files,folders)
} }
@ -611,19 +616,15 @@ func work(){
// Set the output file based on mode // Set the output file based on mode
if mode=="encrypt"{ if mode=="encrypt"{
outputFile = outputEntry+".pcv"
// Compress files into a zip archive // Compress files into a zip archive
if len(allFiles)>1{ if len(allFiles)>1||len(onlyFolders)>0{
rootDir := filepath.Dir(outputEntry) rootDir := filepath.Dir(outputEntry)
inputFile = outputEntry inputFile = outputEntry
fmt.Println(inputFile) fmt.Println(inputFile)
file,_ := os.Create(inputFile) file,_ := os.Create(inputFile)
defer file.Close()
w := zip.NewWriter(file) w := zip.NewWriter(file)
for _,path := range(allFiles){ for _,path := range(allFiles){
fmt.Printf("Crawling: %#v\n",path)
if path==inputFile{ if path==inputFile{
continue continue
} }
@ -632,17 +633,14 @@ func work(){
header.Name = strings.Replace(path,rootDir,"",1) header.Name = strings.Replace(path,rootDir,"",1)
header.Method = zip.Deflate header.Method = zip.Deflate
writer,_ := w.CreateHeader(header) writer,_ := w.CreateHeader(header)
file,_ := os.Open(path) file,_ := os.Open(path)
defer file.Close()
io.Copy(writer,file) io.Copy(writer,file)
file.Close()
} }
w.Flush() w.Flush()
w.Close() w.Close()
file.Close()
} }
}else{
outputFile = outputEntry
} }
fmt.Println(inputFile) fmt.Println(inputFile)
@ -652,9 +650,10 @@ func work(){
// Open input file in read-only mode // Open input file in read-only mode
fin,_ := os.Open(inputFile) fin,_ := os.Open(inputFile)
defer fin.Close()
var fout *os.File var fout *os.File
fmt.Println(mode)
// If encrypting, generate values; If decrypting, read values from file // If encrypting, generate values; If decrypting, read values from file
if mode=="encrypt"{ if mode=="encrypt"{
@ -665,7 +664,6 @@ func work(){
os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.O_RDWR|os.O_CREATE|os.O_TRUNC,
0755, 0755,
) )
defer fout.Close()
// Argon2 salt and XChaCha20 nonce // Argon2 salt and XChaCha20 nonce
salt = make([]byte,16) salt = make([]byte,16)
@ -788,7 +786,7 @@ func work(){
//fmt.Println("key",key) //fmt.Println("key",key)
//key = make([]byte,32) //key = make([]byte,32)
fmt.Println("output",outputFile)
sha3_512 := sha3.New512() sha3_512 := sha3.New512()
sha3_512.Write(key) sha3_512.Write(key)
keyHash = sha3_512.Sum(nil) keyHash = sha3_512.Sum(nil)
@ -807,7 +805,7 @@ func work(){
if keep{ if keep{
kept = true kept = true
}else{ }else{
fout.Close() fin.Close()
broken() broken()
return return
} }
@ -817,7 +815,6 @@ func work(){
os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.O_RDWR|os.O_CREATE|os.O_TRUNC,
0755, 0755,
) )
defer fout.Close()
} }
//crc := blake3.New() //crc := blake3.New()
@ -859,6 +856,8 @@ func work(){
if keep{ if keep{
kept = true kept = true
}else{ }else{
fin.Close()
fout.Close()
working = false working = false
_status = "The file is either corrupted or intentionally modified." _status = "The file is either corrupted or intentionally modified."
_status_color = color.RGBA{0xff,0x00,0x00,255} _status_color = color.RGBA{0xff,0x00,0x00,255}
@ -869,6 +868,7 @@ func work(){
} }
for{ for{
if !working{ if !working{
fin.Close()
fout.Close() fout.Close()
os.Remove(outputFile) os.Remove(outputFile)
return return
@ -920,7 +920,20 @@ func work(){
//fmt.Println("DECODE LOOP") //fmt.Println("DECODE LOOP")
//crc.Write(data) //crc.Write(data)
if fast{ if fast{
data,_ = cipher.Open(nil,_nonce,data,nil) data,err = cipher.Open(nil,_nonce,data,nil)
if err!=nil{
if keep{
kept = true
mac := data[len(data)-16:]
data = data[:len(data)-16]
data,_ = monocypher.Unlock(data,_nonce,key,mac)
}else{
fin.Close()
fout.Close()
broken()
return
}
}
}else{ }else{
//crc.Write(data) //crc.Write(data)
mac := data[len(data)-16:] mac := data[len(data)-16:]
@ -931,6 +944,7 @@ func work(){
if keep{ if keep{
kept = true kept = true
}else{ }else{
fin.Close()
fout.Close() fout.Close()
broken() broken()
return return
@ -1004,6 +1018,12 @@ func work(){
} }
working = false working = false
kept = false kept = false
key = nil
fin.Close()
fout.Close()
status = "Ready."
debug.FreeOSMemory()
fmt.Println("Exit goroutine")
} }
// Generate file checksums // Generate file checksums
@ -1129,15 +1149,61 @@ func shred(names []string){
for _,name := range(names){ for _,name := range(names){
shredding = name shredding = name
if runtime.GOOS=="linux"{ if runtime.GOOS=="linux"{
if itemSelected==0{ stat,_ := os.Stat(name)
cmd := exec.Command("shred","-uvfz -n 4 \""+name+"\"") if stat.IsDir(){
stdout,err := cmd.Output() var coming []string
if err!=nil{ filepath.Walk(name,func(path string,_ os.FileInfo,err error) error{
fmt.Println(err) if err!=nil{
return nil
}
fmt.Println(path)
stat,_ := os.Stat(path)
if !stat.IsDir(){
if len(coming)==128{
var wg sync.WaitGroup
for i,j := range(coming){
wg.Add(1)
go func(wg *sync.WaitGroup,id int,j string){
defer wg.Done()
cmd := exec.Command("shred","-ufvz","-n","4",j)
output,err := cmd.Output()
fmt.Println(err)
fmt.Println(output)
shredding = j
shredDone++
shredUpdate()
g.Update()
}(&wg,i,j)
}
wg.Wait()
coming = nil
}else{
coming = append(coming,path)
}
}
return nil
})
fmt.Println(coming)
for _,i := range(coming){
go func(){
cmd := exec.Command("shred","-ufvz","-n","4",i)
output,err := cmd.Output()
fmt.Println(err)
fmt.Println(output)
shredding = i
shredDone++
shredUpdate()
g.Update()
}()
} }
fmt.Println(string(stdout)) os.RemoveAll(name)
}else{ }else{
cmd := exec.Command("shred","-ufvz","-n","4",name)
cmd.Run()
shredding = name+"/*"
shredDone++
shredUpdate()
} }
}else if runtime.GOOS=="windows"{ }else if runtime.GOOS=="windows"{
stat,_ := os.Stat(name) stat,_ := os.Stat(name)
@ -1166,7 +1232,7 @@ func shred(names []string){
} }
return nil return nil
}) })
os.Remove(name) os.RemoveAll(name)
}else{ }else{
exec.Command(filepath.Join(rootDir,"sdelete64.exe"),name,"-p","4").Run() exec.Command(filepath.Join(rootDir,"sdelete64.exe"),name,"-p","4").Run()
shredDone++ shredDone++
@ -1180,14 +1246,14 @@ func shred(names []string){
fmt.Println(name) fmt.Println(name)
g.Update() g.Update()
} }
if itemSelected==1&&runtime.GOOS=="windows"{ /*if itemSelected==1&&runtime.GOOS=="windows"{
cmd := exec.Command("cipher","/w:\""+name+"\"") cmd := exec.Command("cipher","/w:\""+name+"\"")
stdout,err := cmd.Output() stdout,err := cmd.Output()
if err!=nil{ if err!=nil{
fmt.Println(err) fmt.Println(err)
} }
fmt.Println(string(stdout)) fmt.Println(string(stdout))
} }*/
shredding = "Ready." shredding = "Ready."
shredProgress = 0 shredProgress = 0
shredOverlay = "" shredOverlay = ""
@ -1258,7 +1324,7 @@ func main(){
if runtime.GOOS=="windows"{ if runtime.GOOS=="windows"{
exec.Command(filepath.Join(rootDir,"sdelete64.exe"),"/accepteula") exec.Command(filepath.Join(rootDir,"sdelete64.exe"),"/accepteula")
} }
window := g.NewMasterWindow("Picocrypt",480,496,g.MasterWindowFlagsNotResizable,nil) window := g.NewMasterWindow("Picocrypt",480,480,g.MasterWindowFlagsNotResizable,nil)
window.SetDropCallback(onDrop) window.SetDropCallback(onDrop)
dpi = g.Context.GetPlatform().GetContentScale() dpi = g.Context.GetPlatform().GetContentScale()
window.Run(startUI) window.Run(startUI)