Skip to content

Commit

Permalink
Merge pull request #10 from D3vl0per/refactor
Browse files Browse the repository at this point in the history
Total refact
  • Loading branch information
D3vl0per authored Nov 22, 2023
2 parents 1465463 + afa691d commit ca4d532
Show file tree
Hide file tree
Showing 123 changed files with 14,639 additions and 927 deletions.
27 changes: 27 additions & 0 deletions .github/workflows/test_test.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Go Test

on: [push, pull_request]

jobs:
test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.21.3

- name: Install dependencies
run: go mod download

- name: Run tests
run: go test -race -coverprofile=coverage.txt -covermode=atomic ./...

- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

6 changes: 3 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
lint:
golangci-lint run
golangci-lint run --fix

test:
go test -cover ./...
go clean -testcache && go test -race -cover ./...

test-v:
go test ./... -v
go clean -testcache && go test ./... -v

golangci-lint-install:
go install github.com/golangci/golangci-lint/cmd/[email protected]
Expand Down
59 changes: 57 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,58 @@
# Go-Crypt
# Go-Crypt (!!! WIP !!!)

High-level API binding to low-level crypto APIs in golang
This project is a comprehensive toolkit for developers who need to implement various cryptographic operations in their Go applications


## Crypto suite:
- Generic
- (Secure) Overwrite
- (Secure) Delete
- CSPRNG
- CSPRNGHex
- /dev/hwrng
- Encoders
- Base64
- Base32
- Hex
- Key Wrappers
- ed25519
- PKIX
- PKCS
- Symmetric
- XChacha20-poly1305
- XChacha20-poly1305 Stream (modified age code)
- XOR
- AES-GCM
- Asymmetric
- ECDSA
- ed25519
- ed448
- ECDH
- Curve25519
- Hash
- Blake2b-256
- Blake2b-384
- Blake2b-512
- SHA3-256
- SHA3-384
- SHA3-512
- SHAKE-128 (planed)
- SHAKE-256 (planed)
- go_simhash (planed)
- Argon2id
- Scrypt (planed)
- HKDF (planed)
- Compression
- flate
- gzip
- zlib
- zstd
- Aged
- Age encryption suite
- Age header obfuscation v1

## Disclaimer

This project includes cryptographic operations that have not been independently audited. While every effort has been made to ensure the correctness and security of these operations, they are provided "as is". The author cannot guarantee their security and cannot be held responsible for any consequences arising from their use. If you use these package in your own projects, you do so at your own risk.

It is strongly recommended that you seek an independent security review if you plan to use them in a production environment.
196 changes: 118 additions & 78 deletions aged/age_bind.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package aged
import (
"bytes"
"errors"
"fmt"
"io"

"filippo.io/age"
Expand All @@ -14,22 +15,37 @@ type Keychain struct {
recipients []age.Recipient
}

func SetupKeychain(secretKey string, publicKeys []string) (Keychain, error) {
type SetupKeychainParameters struct {
SecretKey string
PublicKeys []string
SelfRecipient bool
}

func SetupKeychain(keychainSetup SetupKeychainParameters) (Keychain, error) {
var keychain Keychain

identity, err := age.ParseX25519Identity(secretKey)
identity, err := age.ParseX25519Identity(keychainSetup.SecretKey)
if err != nil {
return Keychain{}, err
}

keychain.secretKey = identity
keychain.recipients = append(keychain.recipients, identity.Recipient())

for _, e := range publicKeys {
publicKey, err := age.ParseX25519Recipient(e)
if err != nil {
return Keychain{}, err
for _, e := range keychainSetup.PublicKeys {
if e == "" {
continue
}
if identity.Recipient().String() != e {
publicKey, err := age.ParseX25519Recipient(e)
if err != nil {
return Keychain{}, err
}
keychain.recipients = append(keychain.recipients, publicKey)
}
keychain.recipients = append(keychain.recipients, publicKey)
}

if keychainSetup.SelfRecipient {
keychain.recipients = append(keychain.recipients, identity.Recipient())
}

return keychain, nil
Expand All @@ -43,55 +59,43 @@ func GenKeypair() (*age.X25519Identity, error) {
return identity, nil
}

func (k Keychain) Encrypt(data []byte, compress bool, header bool) ([]byte, error) {
var reader *bytes.Reader
if compress {
raw, err := compression.GzipCompress(data, 6)
if err != nil {
return []byte{}, err
}
reader = bytes.NewReader(raw)
} else {
reader = bytes.NewReader(data)
}
type Parameters struct {
Data []byte
Compressor compression.Compressor
Compress bool
Obfuscation bool
Obfuscator Obfuscation
}

out := &bytes.Buffer{}
w, err := age.Encrypt(out, k.recipients...)
func (k Keychain) Encrypt(p Parameters) ([]byte, error) {

in, err := compressor(p)
if err != nil {
return []byte{}, err
}

out := &bytes.Buffer{}
w, err := age.Encrypt(out, k.recipients...)
if err != nil {
return []byte{}, err
}

if _, err := io.Copy(w, reader); err != nil {
if _, err := io.Copy(w, in); err != nil {
return []byte{}, err
}
if err := w.Close(); err != nil {
return []byte{}, err
}

if header {
obf, err := ObfHeader(out.Bytes())
if err != nil {
return []byte{}, errors.New("failed to obfuscate header")
}
return obf, nil
}
return out.Bytes(), nil
return obfuscator(p, out.Bytes())
}

func (k Keychain) Decrypt(cipherdata []byte, compress bool, header bool) ([]byte, error) {
if header {
var err error
cipherdata, err = DeobfHeader(cipherdata)
if err != nil {
return []byte{}, errors.New("failed to deobfuscate header, maybe not encrypted")
}
func (k Keychain) Decrypt(p Parameters) ([]byte, error) {
cipherData, err := deobfuscator(p)
if err != nil {
return []byte{}, err
}

r, err := age.Decrypt(bytes.NewReader(cipherdata), k.secretKey)
r, err := age.Decrypt(bytes.NewReader(cipherData), k.secretKey)
if err != nil {
return []byte{}, err
}
Expand All @@ -100,27 +104,13 @@ func (k Keychain) Decrypt(cipherdata []byte, compress bool, header bool) ([]byte
return []byte{}, err
}

if compress {
raw, err := compression.GzipDecompress(out.Bytes())
if err != nil {
return []byte{}, err
}
return raw, nil
}

return out.Bytes(), nil
return decompressor(p, out.Bytes())
}

func EncryptWithPwd(pwd string, data []byte, compress bool, header bool) ([]byte, error) {
var reader *bytes.Reader
if compress {
raw, err := compression.GzipCompress(data, 6)
if err != nil {
return []byte{}, err
}
reader = bytes.NewReader(raw)
} else {
reader = bytes.NewReader(data)
func EncryptWithPwd(p Parameters, pwd string) ([]byte, error) {
in, err := compressor(p)
if err != nil {
return []byte{}, err
}

pwdRecepient, err := age.NewScryptRecipient(pwd)
Expand All @@ -138,38 +128,28 @@ func EncryptWithPwd(pwd string, data []byte, compress bool, header bool) ([]byte
return []byte{}, err
}

if _, err := io.Copy(w, reader); err != nil {
if _, err := io.Copy(w, in); err != nil {
return []byte{}, err
}
if err := w.Close(); err != nil {
return []byte{}, err
}

if header {
obf, err := ObfHeader(out.Bytes())
if err != nil {
return []byte{}, errors.New("failed to obfuscate header")
}
return obf, nil
}
return out.Bytes(), nil
return obfuscator(p, out.Bytes())
}

func DecryptWithPwd(pwd string, cipherdata []byte, compress bool, header bool) ([]byte, error) {
if header {
var err error
cipherdata, err = DeobfHeader(cipherdata)
if err != nil {
return []byte{}, errors.New("failed to deobfuscate header, maybe not encrypted")
}
func DecryptWithPwd(p Parameters, pwd string) ([]byte, error) {
cipherData, err := deobfuscator(p)
if err != nil {
return []byte{}, err
}

pwdIdentity, err := age.NewScryptIdentity(pwd)
if err != nil {
return []byte{}, err
}

r, err := age.Decrypt(bytes.NewReader(cipherdata), pwdIdentity)
r, err := age.Decrypt(bytes.NewReader(cipherData), pwdIdentity)
if err != nil {
return []byte{}, err
}
Expand All @@ -179,13 +159,73 @@ func DecryptWithPwd(pwd string, cipherdata []byte, compress bool, header bool) (
return []byte{}, err
}

if compress {
raw, err := compression.GzipDecompress(out.Bytes())
return decompressor(p, out.Bytes())
}

func compressor(p Parameters) (*bytes.Reader, error) {
var in *bytes.Reader

if p.Compress {
var writer bytes.Buffer
compressorIn := bytes.NewReader(p.Data)

err := p.Compressor.CompressStream(compressorIn, &writer)
if err != nil {
return nil, err
}

in = bytes.NewReader(writer.Bytes())

} else {
in = bytes.NewReader(p.Data)
}
return in, nil
}

func decompressor(p Parameters, data []byte) ([]byte, error) {
if p.Compress {
raw, err := p.Compressor.Decompress(data)
if err != nil {
return []byte{}, err
}
return raw, nil
}
return data, nil
}

func obfuscator(p Parameters, in []byte) ([]byte, error) {
if p.Obfuscation {
obf, err := p.Obfuscator.Obfuscate(in)
if err != nil {
return []byte{}, errors.New("failed to obfuscate header")
}
return obf, nil
}
return in, nil
}

func deobfuscator(p Parameters) ([]byte, error) {
var cipherData []byte
if p.Obfuscation {
var err error
cipherData, err = p.Obfuscator.Deobfuscate(p.Data)
if err != nil {
return []byte{}, errors.New("failed to deobfuscate header, maybe not obfuscated?")
}
} else {
cipherData = p.Data
}
return cipherData, nil
}

func (k Keychain) KeychainExport() []string {
keys := make([]string, len(k.recipients))
for _, key := range k.recipients {
keys = append(keys, fmt.Sprint(key))
}
return keys
}

return out.Bytes(), nil
func (k Keychain) KeychainExportSecretKey() string {
return k.secretKey.String()
}
Loading

0 comments on commit ca4d532

Please sign in to comment.