Crypto and input management packages.
This commit is contained in:
parent
f0867a1063
commit
b8a4ad02d7
5 changed files with 163 additions and 0 deletions
10
go.mod
Normal file
10
go.mod
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
module github.com/AYM1607/ccclip
|
||||||
|
|
||||||
|
go 1.21
|
||||||
|
|
||||||
|
require (
|
||||||
|
golang.org/x/crypto v0.14.0
|
||||||
|
golang.org/x/term v0.13.0
|
||||||
|
)
|
||||||
|
|
||||||
|
require golang.org/x/sys v0.13.0 // indirect
|
||||||
6
go.sum
Normal file
6
go.sum
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
|
||||||
|
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
|
||||||
|
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
|
||||||
|
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
|
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
|
||||||
|
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
|
||||||
35
pkg/crypto/encryption.go
Normal file
35
pkg/crypto/encryption.go
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
package crypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/chacha20poly1305"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Encrypt(key, msg []byte) []byte {
|
||||||
|
aead, err := chacha20poly1305.NewX(key)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nonce := make([]byte, aead.NonceSize(), aead.NonceSize()+len(msg)+aead.Overhead())
|
||||||
|
if _, err := rand.Read(nonce); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return aead.Seal(nonce, nonce, msg, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Decrypt(key, encryptedMsg []byte) []byte {
|
||||||
|
aead, err := chacha20poly1305.NewX(key)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
nonce, ciphertext := encryptedMsg[:aead.NonceSize()], encryptedMsg[aead.NonceSize():]
|
||||||
|
msg, err := aead.Open(nil, nonce, ciphertext, nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return msg
|
||||||
|
}
|
||||||
95
pkg/crypto/keys.go
Normal file
95
pkg/crypto/keys.go
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
package crypto
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/ecdh"
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/base64"
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/crypto/blake2b"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Direction int
|
||||||
|
|
||||||
|
const (
|
||||||
|
KeySize uint = 32
|
||||||
|
|
||||||
|
SendDirection Direction = iota
|
||||||
|
ReceiveDirection
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewPrivateKey() *ecdh.PrivateKey {
|
||||||
|
c := ecdh.X25519()
|
||||||
|
k, err := c.GenerateKey(rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("could not generate private key: %s", err.Error()))
|
||||||
|
}
|
||||||
|
return k
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSharedKey(local *ecdh.PrivateKey, remote *ecdh.PublicKey, direction Direction) []byte {
|
||||||
|
// Calculating a shared secret.
|
||||||
|
secret, err := local.ECDH(remote)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Take into account public keys for key derivation.
|
||||||
|
// See raw_shared_secret @ https://monocypher.org/manual/x25519#DESCRIPTION
|
||||||
|
xof, err := blake2b.NewXOF(32, nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
xof.Write(secret)
|
||||||
|
if direction == SendDirection {
|
||||||
|
xof.Write(local.PublicKey().Bytes())
|
||||||
|
xof.Write(remote.Bytes())
|
||||||
|
} else {
|
||||||
|
xof.Write(remote.Bytes())
|
||||||
|
xof.Write(local.PublicKey().Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
key := make([]byte, 32)
|
||||||
|
_, err = xof.Read(key)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
func PrivateKeyFromBytes(keyBytes []byte) *ecdh.PrivateKey {
|
||||||
|
key, err := ecdh.X25519().NewPrivateKey(keyBytes)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
func PublicKeyFromBytes(keyBytes []byte) *ecdh.PublicKey {
|
||||||
|
key, err := ecdh.X25519().NewPublicKey(keyBytes)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return key
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadPrivateKey(fp string) *ecdh.PrivateKey {
|
||||||
|
return PrivateKeyFromBytes(loadKey(fp))
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadPublicKey(fp string) *ecdh.PublicKey {
|
||||||
|
return PublicKeyFromBytes(loadKey(fp))
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadKey(fn string) []byte {
|
||||||
|
b64Key, err := os.ReadFile(fn)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
keyBytes := make([]byte, KeySize)
|
||||||
|
base64.StdEncoding.Decode(keyBytes, b64Key)
|
||||||
|
return keyBytes
|
||||||
|
}
|
||||||
17
pkg/input/password.go
Normal file
17
pkg/input/password.go
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
package input
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"golang.org/x/term"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ReadPassword reads a single line of text from the terminal withouth echoing it out.
|
||||||
|
func ReadPassword() string {
|
||||||
|
raw, err := term.ReadPassword(int(os.Stdin.Fd()))
|
||||||
|
if err != nil {
|
||||||
|
panic(fmt.Sprintf("could not reat password from the terminal: %s", err.Error()))
|
||||||
|
}
|
||||||
|
return string(raw)
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue