summaryrefslogtreecommitdiffstats
path: root/vendor/go.mau.fi/whatsmeow/util
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/go.mau.fi/whatsmeow/util')
-rw-r--r--vendor/go.mau.fi/whatsmeow/util/cbcutil/cbc.go101
-rw-r--r--vendor/go.mau.fi/whatsmeow/util/hkdfutil/hkdf.go28
-rw-r--r--vendor/go.mau.fi/whatsmeow/util/keys/keypair.go75
-rw-r--r--vendor/go.mau.fi/whatsmeow/util/log/log.go83
4 files changed, 287 insertions, 0 deletions
diff --git a/vendor/go.mau.fi/whatsmeow/util/cbcutil/cbc.go b/vendor/go.mau.fi/whatsmeow/util/cbcutil/cbc.go
new file mode 100644
index 00000000..05fa8577
--- /dev/null
+++ b/vendor/go.mau.fi/whatsmeow/util/cbcutil/cbc.go
@@ -0,0 +1,101 @@
+/*
+CBC describes a block cipher mode. In cryptography, a block cipher mode of operation is an algorithm that uses a
+block cipher to provide an information service such as confidentiality or authenticity. A block cipher by itself
+is only suitable for the secure cryptographic transformation (encryption or decryption) of one fixed-length group of
+bits called a block. A mode of operation describes how to repeatedly apply a cipher's single-block operation to
+securely transform amounts of data larger than a block.
+
+This package simplifies the usage of AES-256-CBC.
+*/
+package cbcutil
+
+/*
+Some code is provided by the GitHub user locked (github.com/locked):
+https://gist.github.com/locked/b066aa1ddeb2b28e855e
+Thanks!
+*/
+import (
+ "bytes"
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "fmt"
+ "io"
+)
+
+/*
+Decrypt is a function that decrypts a given cipher text with a provided key and initialization vector(iv).
+*/
+func Decrypt(key, iv, ciphertext []byte) ([]byte, error) {
+ block, err := aes.NewCipher(key)
+
+ if err != nil {
+ return nil, err
+ }
+
+ if len(ciphertext) < aes.BlockSize {
+ return nil, fmt.Errorf("ciphertext is shorter then block size: %d / %d", len(ciphertext), aes.BlockSize)
+ }
+
+ if iv == nil {
+ iv = ciphertext[:aes.BlockSize]
+ ciphertext = ciphertext[aes.BlockSize:]
+ }
+
+ cbc := cipher.NewCBCDecrypter(block, iv)
+ cbc.CryptBlocks(ciphertext, ciphertext)
+
+ return unpad(ciphertext)
+}
+
+/*
+Encrypt is a function that encrypts plaintext with a given key and an optional initialization vector(iv).
+*/
+func Encrypt(key, iv, plaintext []byte) ([]byte, error) {
+ plaintext = pad(plaintext, aes.BlockSize)
+
+ if len(plaintext)%aes.BlockSize != 0 {
+ return nil, fmt.Errorf("plaintext is not a multiple of the block size: %d / %d", len(plaintext), aes.BlockSize)
+ }
+
+ block, err := aes.NewCipher(key)
+ if err != nil {
+ return nil, err
+ }
+
+ var ciphertext []byte
+ if iv == nil {
+ ciphertext = make([]byte, aes.BlockSize+len(plaintext))
+ iv := ciphertext[:aes.BlockSize]
+ if _, err := io.ReadFull(rand.Reader, iv); err != nil {
+ return nil, err
+ }
+
+ cbc := cipher.NewCBCEncrypter(block, iv)
+ cbc.CryptBlocks(ciphertext[aes.BlockSize:], plaintext)
+ } else {
+ ciphertext = make([]byte, len(plaintext))
+
+ cbc := cipher.NewCBCEncrypter(block, iv)
+ cbc.CryptBlocks(ciphertext, plaintext)
+ }
+
+ return ciphertext, nil
+}
+
+func pad(ciphertext []byte, blockSize int) []byte {
+ padding := blockSize - len(ciphertext)%blockSize
+ padtext := bytes.Repeat([]byte{byte(padding)}, padding)
+ return append(ciphertext, padtext...)
+}
+
+func unpad(src []byte) ([]byte, error) {
+ length := len(src)
+ padLen := int(src[length-1])
+
+ if padLen > length {
+ return nil, fmt.Errorf("padding is greater then the length: %d / %d", padLen, length)
+ }
+
+ return src[:(length - padLen)], nil
+}
diff --git a/vendor/go.mau.fi/whatsmeow/util/hkdfutil/hkdf.go b/vendor/go.mau.fi/whatsmeow/util/hkdfutil/hkdf.go
new file mode 100644
index 00000000..fbc97124
--- /dev/null
+++ b/vendor/go.mau.fi/whatsmeow/util/hkdfutil/hkdf.go
@@ -0,0 +1,28 @@
+// Copyright (c) 2021 Tulir Asokan
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// Package hkdfutil contains a simple wrapper for golang.org/x/crypto/hkdf that reads a specified number of bytes.
+package hkdfutil
+
+import (
+ "crypto/sha256"
+ "fmt"
+
+ "golang.org/x/crypto/hkdf"
+)
+
+func SHA256(key, salt, info []byte, length uint8) []byte {
+ data := make([]byte, length)
+ h := hkdf.New(sha256.New, key, salt, info)
+ n, err := h.Read(data)
+ if err != nil {
+ // Length is limited to 255 by being uint8, so these errors can't actually happen
+ panic(fmt.Errorf("failed to expand key: %w", err))
+ } else if uint8(n) != length {
+ panic(fmt.Errorf("didn't read enough bytes (got %d, wanted %d)", n, length))
+ }
+ return data
+}
diff --git a/vendor/go.mau.fi/whatsmeow/util/keys/keypair.go b/vendor/go.mau.fi/whatsmeow/util/keys/keypair.go
new file mode 100644
index 00000000..55679ff2
--- /dev/null
+++ b/vendor/go.mau.fi/whatsmeow/util/keys/keypair.go
@@ -0,0 +1,75 @@
+// Copyright (c) 2021 Tulir Asokan
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// Package keys contains a utility struct for elliptic curve keypairs.
+package keys
+
+import (
+ "crypto/rand"
+ "fmt"
+
+ "go.mau.fi/libsignal/ecc"
+ "golang.org/x/crypto/curve25519"
+)
+
+type KeyPair struct {
+ Pub *[32]byte
+ Priv *[32]byte
+}
+
+var _ ecc.ECPublicKeyable
+
+func NewKeyPairFromPrivateKey(priv [32]byte) *KeyPair {
+ var kp KeyPair
+ kp.Priv = &priv
+ var pub [32]byte
+ curve25519.ScalarBaseMult(&pub, kp.Priv)
+ kp.Pub = &pub
+ return &kp
+}
+
+func NewKeyPair() *KeyPair {
+ var priv [32]byte
+
+ _, err := rand.Read(priv[:])
+ if err != nil {
+ panic(fmt.Errorf("failed to generate curve25519 private key: %w", err))
+ }
+
+ priv[0] &= 248
+ priv[31] &= 127
+ priv[31] |= 64
+
+ return NewKeyPairFromPrivateKey(priv)
+}
+
+func (kp *KeyPair) CreateSignedPreKey(keyID uint32) *PreKey {
+ newKey := NewPreKey(keyID)
+ newKey.Signature = kp.Sign(&newKey.KeyPair)
+ return newKey
+}
+
+func (kp *KeyPair) Sign(keyToSign *KeyPair) *[64]byte {
+ pubKeyForSignature := make([]byte, 33)
+ pubKeyForSignature[0] = ecc.DjbType
+ copy(pubKeyForSignature[1:], keyToSign.Pub[:])
+
+ signature := ecc.CalculateSignature(ecc.NewDjbECPrivateKey(*kp.Priv), pubKeyForSignature)
+ return &signature
+}
+
+type PreKey struct {
+ KeyPair
+ KeyID uint32
+ Signature *[64]byte
+}
+
+func NewPreKey(keyID uint32) *PreKey {
+ return &PreKey{
+ KeyPair: *NewKeyPair(),
+ KeyID: keyID,
+ }
+}
diff --git a/vendor/go.mau.fi/whatsmeow/util/log/log.go b/vendor/go.mau.fi/whatsmeow/util/log/log.go
new file mode 100644
index 00000000..2662cdea
--- /dev/null
+++ b/vendor/go.mau.fi/whatsmeow/util/log/log.go
@@ -0,0 +1,83 @@
+// Copyright (c) 2021 Tulir Asokan
+//
+// This Source Code Form is subject to the terms of the Mozilla Public
+// License, v. 2.0. If a copy of the MPL was not distributed with this
+// file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+// Package waLog contains a simple logger interface used by the other whatsmeow packages.
+package waLog
+
+import (
+ "fmt"
+ "strings"
+ "time"
+)
+
+// Logger is a simple logger interface that can have subloggers for specific areas.
+type Logger interface {
+ Warnf(msg string, args ...interface{})
+ Errorf(msg string, args ...interface{})
+ Infof(msg string, args ...interface{})
+ Debugf(msg string, args ...interface{})
+ Sub(module string) Logger
+}
+
+type noopLogger struct{}
+
+func (n *noopLogger) Errorf(_ string, _ ...interface{}) {}
+func (n *noopLogger) Warnf(_ string, _ ...interface{}) {}
+func (n *noopLogger) Infof(_ string, _ ...interface{}) {}
+func (n *noopLogger) Debugf(_ string, _ ...interface{}) {}
+func (n *noopLogger) Sub(_ string) Logger { return n }
+
+// Noop is a no-op Logger implementation that silently drops everything.
+var Noop Logger = &noopLogger{}
+
+type stdoutLogger struct {
+ mod string
+ color bool
+ min int
+}
+
+var colors = map[string]string{
+ "INFO": "\033[36m",
+ "WARN": "\033[33m",
+ "ERROR": "\033[31m",
+}
+
+var levelToInt = map[string]int{
+ "": -1,
+ "DEBUG": 0,
+ "INFO": 1,
+ "WARN": 2,
+ "ERROR": 3,
+}
+
+func (s *stdoutLogger) outputf(level, msg string, args ...interface{}) {
+ if levelToInt[level] < s.min {
+ return
+ }
+ var colorStart, colorReset string
+ if s.color {
+ colorStart = colors[level]
+ colorReset = "\033[0m"
+ }
+ fmt.Printf("%s%s [%s %s] %s%s\n", time.Now().Format("15:04:05.000"), colorStart, s.mod, level, fmt.Sprintf(msg, args...), colorReset)
+}
+
+func (s *stdoutLogger) Errorf(msg string, args ...interface{}) { s.outputf("ERROR", msg, args...) }
+func (s *stdoutLogger) Warnf(msg string, args ...interface{}) { s.outputf("WARN", msg, args...) }
+func (s *stdoutLogger) Infof(msg string, args ...interface{}) { s.outputf("INFO", msg, args...) }
+func (s *stdoutLogger) Debugf(msg string, args ...interface{}) { s.outputf("DEBUG", msg, args...) }
+func (s *stdoutLogger) Sub(mod string) Logger {
+ return &stdoutLogger{mod: fmt.Sprintf("%s/%s", s.mod, mod), color: s.color, min: s.min}
+}
+
+// Stdout is a simple Logger implementation that outputs to stdout. The module name given is included in log lines.
+//
+// minLevel specifies the minimum log level to output. An empty string will output all logs.
+//
+// If color is true, then info, warn and error logs will be colored cyan, yellow and red respectively using ANSI color escape codes.
+func Stdout(module string, minLevel string, color bool) Logger {
+ return &stdoutLogger{mod: module, color: color, min: levelToInt[strings.ToUpper(minLevel)]}
+}