Skip to content

Commit

Permalink
Merge pull request #5 from graynk/bump
Browse files Browse the repository at this point in the history
Cleanup
  • Loading branch information
graynk authored Feb 15, 2025
2 parents 20fbbf5 + 4fefbb6 commit d1eafde
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 58 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,19 @@ jobs:
releases-matrix:
name: Release Go Binary
runs-on: ubuntu-latest
permissions:
contents: write
strategy:
matrix:
# build and publish in parallel: linux/386, linux/amd64, linux/arm64, windows/386, windows/amd64, darwin/amd64, darwin/arm64
# build and publish in parallel: linux/amd64, linux/arm64, windows/amd64, darwin/amd64, darwin/arm64
goos: [ linux, windows, darwin ]
goarch: [ "386", amd64, arm64 ]
goarch: [ amd64, arm64 ]
exclude:
- goarch: "386"
goos: darwin
- goarch: arm64
goos: windows
steps:
- uses: actions/checkout@v2
- uses: wangyoucao577/go-release-action@v1.30
- uses: actions/checkout@v4
- uses: wangyoucao577/go-release-action@v1.53
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
goos: ${{ matrix.goos }}
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
atk
*.kdbx
*.exe
aegis-export-*.json
6 changes: 3 additions & 3 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@
A simple tool to convert exported (and encrypted) JSON from [Aegis](https://getaegis.app/) to [KeePass](https://keepass.info/download.html) database. Notes, custom icons and Steam entries get exported as well.

## Installation
`go install github.com/graynk/atk@latest` or grab a binary from [Releases](https://github.com/graynk/atk/releases) page
`go install github.com/graynk/atk@latest` or grab a binary from the [Releases](https://github.com/graynk/atk/releases) page

## Usage
`atk /path/to/aegis-export.json /path/to/output.kdbx`

You will be asked to enter the password that was used to encrypt the Aegis vault. The same password will be used for resulting KDBX database.
You will be asked to enter the password that was used to encrypt the Aegis vault. The same password will be used for the resulting KDBX database.

## Limitations
* This tool does not support _changing_ existing databases, `atk` creates a separate clean database for your TOTP codes. You should not store TOTP secrets in the same database as your passwords anyway, since this removes all the benifits of having a second factor in the first place.
* This tool does not support _changing_ existing databases, `atk` creates a separate clean database for your TOTP codes. You should not store TOTP secrets in the same database as your passwords anyway, since this removes all the benefits of having a second factor in the first place.
* This tool also does not accept unencrypted Aegis JSON files (yet, at least) as input
12 changes: 6 additions & 6 deletions aegis.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ type params struct {
Tag hexedBytes
}

func (a aegis) Decrypt(password []byte) db {
func (a aegis) Decrypt(password []byte) (db, error) {
aegisDb := db{}
var masterKey []byte
for _, slot := range a.Header.Slots {
if slot.Type != 1 {
Expand All @@ -57,20 +58,19 @@ func (a aegis) Decrypt(password []byte) db {
}

if masterKey == nil {
errAndExit("Provided password did not match any of the slots", nil)
return aegisDb, fmt.Errorf("unable to decrypt the master key with the given password")
}

output, err := decryptData(masterKey, a.Db, a.Header.Params)
if err != nil {
errAndExit("Failed to decrypt database field: %v", err)
return aegisDb, fmt.Errorf("failed to decrypt database field: %v", err)
}

aegisDb := db{}
err = json.Unmarshal(output, &aegisDb)
if err != nil {
errAndExit("Failed to unmarshal decrypted database: %v", err)
return aegisDb, fmt.Errorf("failed to unmarshal decrypted database: %v", err)
}
return aegisDb
return aegisDb, nil
}

func (b *hexedBytes) UnmarshalJSON(data []byte) error {
Expand Down
15 changes: 8 additions & 7 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"
"github.com/tobischo/gokeepasslib/v3"
"github.com/tobischo/gokeepasslib/v3/wrappers"
"log"
"os"
)

Expand Down Expand Up @@ -42,7 +41,7 @@ func (e entry) ToKeePassEntry() (gokeepasslib.Entry, error) {
case "steam":
totpFormat = fmt.Sprintf("%d;S", e.Info.Period)
default:
return convertedEntry, fmt.Errorf("unknown type: %s", e.Type)
return convertedEntry, fmt.Errorf("unknown type for entry \"%s\": %s", e.Name, e.Type)
}

values := []gokeepasslib.ValueData{
Expand Down Expand Up @@ -84,10 +83,10 @@ func (e entry) ToKeePassEntry() (gokeepasslib.Entry, error) {
return convertedEntry, nil
}

func (d db) ToKeePass(path string, password []byte) {
func (d db) ToKeePass(path string, password []byte) error {
file, err := os.Create(path)
if err != nil {
errAndExit("Failed to create file for KeePass database: %v", err)
return fmt.Errorf("failed to create file for KeePass database: %v", err)
}
defer file.Close()

Expand All @@ -98,7 +97,7 @@ func (d db) ToKeePass(path string, password []byte) {
for _, entry := range d.Entries {
converted, err := entry.ToKeePassEntry()
if err != nil {
log.Println(err)
fmt.Println(err)
continue
}
if entry.Icon != "" {
Expand All @@ -115,12 +114,14 @@ func (d db) ToKeePass(path string, password []byte) {

err = db.LockProtectedEntries()
if err != nil {
errAndExit("Failed to lock entries when saving KeePass database: %v", err)
return fmt.Errorf("failed to lock entries when saving KeePass database: %v", err)
}

keepassEncoder := gokeepasslib.NewEncoder(file)
err = keepassEncoder.Encode(db)
if err != nil {
errAndExit("Failed to save KeePass database: %v", err)
return fmt.Errorf("failed to save KeePass database: %v", err)
}

return nil
}
13 changes: 6 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
module github.com/graynk/atk

go 1.15
go 1.24

require (
github.com/tobischo/gokeepasslib/v3 v3.2.4
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
github.com/tobischo/gokeepasslib/v3 v3.6.1
golang.org/x/crypto v0.33.0
golang.org/x/term v0.29.0
)

require (
github.com/aead/argon2 v0.0.0-20180111183520-a87724528b07 // indirect
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1
github.com/tobischo/argon2 v0.1.0 // indirect
golang.org/x/sys v0.30.0 // indirect
)
47 changes: 22 additions & 25 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
github.com/aead/argon2 v0.0.0-20180111183520-a87724528b07 h1:i9/M2RadeVsPBMNwXFiaYkXQi9lY9VuZeI4Onavd3pA=
github.com/aead/argon2 v0.0.0-20180111183520-a87724528b07/go.mod h1:Tnm/osX+XXr9R+S71o5/F0E60sRkPVALdhWw25qPImQ=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY=
github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA=
github.com/tobischo/gokeepasslib/v3 v3.2.4 h1:Dn4o3aFtaJ7aUKAysHJFu2iWcKcOXUfCMi9HyEKWNCk=
github.com/tobischo/gokeepasslib/v3 v3.2.4/go.mod h1:iwxOzUuk/ccA0mitrFC4MovT1p0IRY8EA35L4u1x/ug=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3 h1:0es+/5331RGQPcXlMfP+WrnIIS6dNnNRe0WB02W0F4M=
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200513112337-417ce2331b5c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/tobischo/argon2 v0.1.0 h1:mwAx/9DK/4rP0xzNifb/XMAf43dU3eG1B3aeF88qu4Y=
github.com/tobischo/argon2 v0.1.0/go.mod h1:4NLmLFwhWPbT66nRZNgcktV/mibJ6fESoeEp43h9GRw=
github.com/tobischo/gokeepasslib/v3 v3.6.1 h1:AShQlTypdM19glj0UUePQcUi56qQyeFI5NcrWnVFudA=
github.com/tobischo/gokeepasslib/v3 v3.6.1/go.mod h1:B31dx/dj0egameQrNtuoOx9RnwxnYaZR4kXaahRuZN8=
golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus=
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3 h1:fJwx88sMf5RXwDwziL0/Mn9Wqs+efMSo/RYcL+37W9c=
golang.org/x/exp v0.0.0-20230105202349-8879d0199aa3/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc=
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU=
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
22 changes: 18 additions & 4 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import (
"bytes"
"encoding/json"
"fmt"
"os"

"golang.org/x/term"
"os"
"strings"
)

func errAndExit(message string, err error) {
Expand All @@ -20,6 +20,13 @@ func errAndExit(message string, err error) {
}

func main() {
for _, arg := range os.Args {
if arg == "-h" || strings.Contains(arg, "help") {
fmt.Printf("A simple tool to convert exported (and encrypted) JSON from Aegis to KeePass database.\n\nUsage:\natk /path/to/aegis-export.json /path/to/output.kdbx\n")
os.Exit(0)
}
}

if len(os.Args) < 2 {
errAndExit("Please pass the path to the encrypted Aegis JSON file as parameter", nil)
}
Expand Down Expand Up @@ -49,7 +56,10 @@ func main() {
if len(password) < 1 {
errAndExit("Empty password", nil)
}
aegisDb := exported.Decrypt(password)
aegisDb, err := exported.Decrypt(password)
if err != nil {
errAndExit("Failed to decrypt Aegis database: %v", err)
}
if len(aegisDb.Entries) == 0 {
errAndExit("No entries in the database, nothing to save", nil)
}
Expand All @@ -66,5 +76,9 @@ func main() {
os.Exit(0)
}
}
aegisDb.ToKeePass(kdbxPath, password)
err = aegisDb.ToKeePass(kdbxPath, password)
if err != nil {
errAndExit("Conversion process failed: %v", err)
}
fmt.Println("Done")
}

0 comments on commit d1eafde

Please sign in to comment.