mirror of https://github.com/mautrix/go.git
verification: remove (go)olm SAS code
Signed-off-by: Sumner Evans <sumner@beeper.com>pull/186/head
parent
bb6c88faf3
commit
a10c114203
|
@ -1,76 +0,0 @@
|
|||
// Package sas provides the means to do SAS between keys
|
||||
package sas
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/goolm"
|
||||
"maunium.net/go/mautrix/crypto/goolm/crypto"
|
||||
)
|
||||
|
||||
// SAS contains the key pair and secret for SAS.
|
||||
type SAS struct {
|
||||
KeyPair crypto.Curve25519KeyPair
|
||||
Secret []byte
|
||||
}
|
||||
|
||||
// New creates a new SAS with a new key pair.
|
||||
func New() (*SAS, error) {
|
||||
kp, err := crypto.Curve25519GenerateKey(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
s := &SAS{
|
||||
KeyPair: kp,
|
||||
}
|
||||
return s, nil
|
||||
}
|
||||
|
||||
// GetPubkey returns the public key of the key pair base64 encoded
|
||||
func (s SAS) GetPubkey() []byte {
|
||||
return goolm.Base64Encode(s.KeyPair.PublicKey)
|
||||
}
|
||||
|
||||
// SetTheirKey sets the key of the other party and computes the shared secret.
|
||||
func (s *SAS) SetTheirKey(key []byte) error {
|
||||
keyDecoded, err := goolm.Base64Decode(key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sharedSecret, err := s.KeyPair.SharedSecret(keyDecoded)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Secret = sharedSecret
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateBytes creates length bytes from the shared secret and info.
|
||||
func (s SAS) GenerateBytes(info []byte, length uint) ([]byte, error) {
|
||||
byteReader := crypto.HKDFSHA256(s.Secret, nil, info)
|
||||
output := make([]byte, length)
|
||||
if _, err := io.ReadFull(byteReader, output); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// calculateMAC returns a base64 encoded MAC of input.
|
||||
func (s *SAS) calculateMAC(input, info []byte, length uint) ([]byte, error) {
|
||||
key, err := s.GenerateBytes(info, length)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
mac := crypto.HMACSHA256(key, input)
|
||||
return goolm.Base64Encode(mac), nil
|
||||
}
|
||||
|
||||
// CalculateMACFixes returns a base64 encoded, 32 byte long MAC of input.
|
||||
func (s SAS) CalculateMAC(input, info []byte) ([]byte, error) {
|
||||
return s.calculateMAC(input, info, 32)
|
||||
}
|
||||
|
||||
// CalculateMACLongKDF returns a base64 encoded, 256 byte long MAC of input.
|
||||
func (s SAS) CalculateMACLongKDF(input, info []byte) ([]byte, error) {
|
||||
return s.calculateMAC(input, info, 256)
|
||||
}
|
|
@ -1,112 +0,0 @@
|
|||
package sas_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"testing"
|
||||
|
||||
"maunium.net/go/mautrix/crypto/goolm/crypto"
|
||||
"maunium.net/go/mautrix/crypto/goolm/sas"
|
||||
)
|
||||
|
||||
func initSAS() (*sas.SAS, *sas.SAS, error) {
|
||||
alicePrivate := crypto.Curve25519PrivateKey([]byte{
|
||||
0x77, 0x07, 0x6D, 0x0A, 0x73, 0x18, 0xA5, 0x7D,
|
||||
0x3C, 0x16, 0xC1, 0x72, 0x51, 0xB2, 0x66, 0x45,
|
||||
0xDF, 0x4C, 0x2F, 0x87, 0xEB, 0xC0, 0x99, 0x2A,
|
||||
0xB1, 0x77, 0xFB, 0xA5, 0x1D, 0xB9, 0x2C, 0x2A,
|
||||
})
|
||||
bobPrivate := crypto.Curve25519PrivateKey([]byte{
|
||||
0x5D, 0xAB, 0x08, 0x7E, 0x62, 0x4A, 0x8A, 0x4B,
|
||||
0x79, 0xE1, 0x7F, 0x8B, 0x83, 0x80, 0x0E, 0xE6,
|
||||
0x6F, 0x3B, 0xB1, 0x29, 0x26, 0x18, 0xB6, 0xFD,
|
||||
0x1C, 0x2F, 0x8B, 0x27, 0xFF, 0x88, 0xE0, 0xEB,
|
||||
})
|
||||
|
||||
aliceSAS, err := sas.New()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
aliceSAS.KeyPair.PrivateKey = alicePrivate
|
||||
aliceSAS.KeyPair.PublicKey, err = alicePrivate.PubKey()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
bobSAS, err := sas.New()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
bobSAS.KeyPair.PrivateKey = bobPrivate
|
||||
bobSAS.KeyPair.PublicKey, err = bobPrivate.PubKey()
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
return aliceSAS, bobSAS, nil
|
||||
}
|
||||
|
||||
func TestGenerateBytes(t *testing.T) {
|
||||
aliceSAS, bobSAS, err := initSAS()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
alicePublicEncoded := []byte("hSDwCYkwp1R0i33ctD73Wg2/Og0mOBr066SpjqqbTmo")
|
||||
bobPublicEncoded := []byte("3p7bfXt9wbTTW2HC7OQ1Nz+DQ8hbeGdNrfx+FG+IK08")
|
||||
|
||||
if !bytes.Equal(aliceSAS.GetPubkey(), alicePublicEncoded) {
|
||||
t.Fatal("public keys not equal")
|
||||
}
|
||||
if !bytes.Equal(bobSAS.GetPubkey(), bobPublicEncoded) {
|
||||
t.Fatal("public keys not equal")
|
||||
}
|
||||
|
||||
err = aliceSAS.SetTheirKey(bobSAS.GetPubkey())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = bobSAS.SetTheirKey(aliceSAS.GetPubkey())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
aliceBytes, err := aliceSAS.GenerateBytes([]byte("SAS"), 6)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bobBytes, err := bobSAS.GenerateBytes([]byte("SAS"), 6)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(aliceBytes, bobBytes) {
|
||||
t.Fatal("results are not equal")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSASMac(t *testing.T) {
|
||||
aliceSAS, bobSAS, err := initSAS()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = aliceSAS.SetTheirKey(bobSAS.GetPubkey())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = bobSAS.SetTheirKey(aliceSAS.GetPubkey())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
plainText := []byte("Hello world!")
|
||||
info := []byte("MAC")
|
||||
|
||||
aliceMac, err := aliceSAS.CalculateMAC(plainText, info)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
bobMac, err := bobSAS.CalculateMAC(plainText, info)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(aliceMac, bobMac) {
|
||||
t.Fatal("results are not equal")
|
||||
}
|
||||
}
|
|
@ -1,142 +0,0 @@
|
|||
//go:build !nosas && !goolm
|
||||
|
||||
package olm
|
||||
|
||||
// #cgo LDFLAGS: -lolm -lstdc++
|
||||
// #include <olm/olm.h>
|
||||
// #include <olm/sas.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// SAS stores an Olm Short Authentication String (SAS) object.
|
||||
type SAS struct {
|
||||
int *C.OlmSAS
|
||||
mem []byte
|
||||
}
|
||||
|
||||
// NewBlankSAS initializes an empty SAS object.
|
||||
func NewBlankSAS() *SAS {
|
||||
memory := make([]byte, sasSize())
|
||||
return &SAS{
|
||||
int: C.olm_sas(unsafe.Pointer(&memory[0])),
|
||||
mem: memory,
|
||||
}
|
||||
}
|
||||
|
||||
// sasSize is the size of a SAS object in bytes.
|
||||
func sasSize() uint {
|
||||
return uint(C.olm_sas_size())
|
||||
}
|
||||
|
||||
// sasRandomLength is the number of random bytes needed to create an SAS object.
|
||||
func (sas *SAS) sasRandomLength() uint {
|
||||
return uint(C.olm_create_sas_random_length(sas.int))
|
||||
}
|
||||
|
||||
// NewSAS creates a new SAS object.
|
||||
func NewSAS() *SAS {
|
||||
sas := NewBlankSAS()
|
||||
random := make([]byte, sas.sasRandomLength()+1)
|
||||
_, err := rand.Read(random)
|
||||
if err != nil {
|
||||
panic(NotEnoughGoRandom)
|
||||
}
|
||||
r := C.olm_create_sas(
|
||||
(*C.OlmSAS)(sas.int),
|
||||
unsafe.Pointer(&random[0]),
|
||||
C.size_t(len(random)))
|
||||
if r == errorVal() {
|
||||
panic(sas.lastError())
|
||||
} else {
|
||||
return sas
|
||||
}
|
||||
}
|
||||
|
||||
// clear clears the memory used to back an SAS object.
|
||||
func (sas *SAS) clear() uint {
|
||||
return uint(C.olm_clear_sas(sas.int))
|
||||
}
|
||||
|
||||
// lastError returns the most recent error to happen to an SAS object.
|
||||
func (sas *SAS) lastError() error {
|
||||
return convertError(C.GoString(C.olm_sas_last_error(sas.int)))
|
||||
}
|
||||
|
||||
// pubkeyLength is the size of a public key in bytes.
|
||||
func (sas *SAS) pubkeyLength() uint {
|
||||
return uint(C.olm_sas_pubkey_length((*C.OlmSAS)(sas.int)))
|
||||
}
|
||||
|
||||
// GetPubkey gets the public key for the SAS object.
|
||||
func (sas *SAS) GetPubkey() []byte {
|
||||
pubkey := make([]byte, sas.pubkeyLength())
|
||||
r := C.olm_sas_get_pubkey(
|
||||
(*C.OlmSAS)(sas.int),
|
||||
unsafe.Pointer(&pubkey[0]),
|
||||
C.size_t(len(pubkey)))
|
||||
if r == errorVal() {
|
||||
panic(sas.lastError())
|
||||
}
|
||||
return pubkey
|
||||
}
|
||||
|
||||
// SetTheirKey sets the public key of the other user.
|
||||
func (sas *SAS) SetTheirKey(theirKey []byte) error {
|
||||
theirKeyCopy := make([]byte, len(theirKey))
|
||||
copy(theirKeyCopy, theirKey)
|
||||
r := C.olm_sas_set_their_key(
|
||||
(*C.OlmSAS)(sas.int),
|
||||
unsafe.Pointer(&theirKeyCopy[0]),
|
||||
C.size_t(len(theirKeyCopy)))
|
||||
if r == errorVal() {
|
||||
return sas.lastError()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GenerateBytes generates bytes to use for the short authentication string.
|
||||
func (sas *SAS) GenerateBytes(info []byte, count uint) ([]byte, error) {
|
||||
infoCopy := make([]byte, len(info))
|
||||
copy(infoCopy, info)
|
||||
output := make([]byte, count)
|
||||
r := C.olm_sas_generate_bytes(
|
||||
(*C.OlmSAS)(sas.int),
|
||||
unsafe.Pointer(&infoCopy[0]),
|
||||
C.size_t(len(infoCopy)),
|
||||
unsafe.Pointer(&output[0]),
|
||||
C.size_t(len(output)))
|
||||
if r == errorVal() {
|
||||
return nil, sas.lastError()
|
||||
}
|
||||
return output, nil
|
||||
}
|
||||
|
||||
// macLength is the size of a message authentication code generated by olm_sas_calculate_mac.
|
||||
func (sas *SAS) macLength() uint {
|
||||
return uint(C.olm_sas_mac_length((*C.OlmSAS)(sas.int)))
|
||||
}
|
||||
|
||||
// CalculateMAC generates a message authentication code (MAC) based on the shared secret.
|
||||
func (sas *SAS) CalculateMAC(input []byte, info []byte) ([]byte, error) {
|
||||
inputCopy := make([]byte, len(input))
|
||||
copy(inputCopy, input)
|
||||
infoCopy := make([]byte, len(info))
|
||||
copy(infoCopy, info)
|
||||
mac := make([]byte, sas.macLength())
|
||||
r := C.olm_sas_calculate_mac(
|
||||
(*C.OlmSAS)(sas.int),
|
||||
unsafe.Pointer(&inputCopy[0]),
|
||||
C.size_t(len(inputCopy)),
|
||||
unsafe.Pointer(&infoCopy[0]),
|
||||
C.size_t(len(infoCopy)),
|
||||
unsafe.Pointer(&mac[0]),
|
||||
C.size_t(len(mac)))
|
||||
if r == errorVal() {
|
||||
return nil, sas.lastError()
|
||||
}
|
||||
return mac, nil
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
//go:build !nosas && goolm
|
||||
|
||||
package olm
|
||||
|
||||
import (
|
||||
"maunium.net/go/mautrix/crypto/goolm/sas"
|
||||
)
|
||||
|
||||
// SAS stores an Olm Short Authentication String (SAS) object.
|
||||
type SAS struct {
|
||||
sas.SAS
|
||||
}
|
||||
|
||||
// NewSAS creates a new SAS object.
|
||||
func NewSAS() *SAS {
|
||||
newSAS, err := sas.New()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &SAS{
|
||||
SAS: *newSAS,
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue