mirror of https://github.com/status-im/go-waku.git
fix: noise padding, docs and http status for rpc errors (#300)
This commit is contained in:
parent
1be745ebe8
commit
b226f34f9f
|
@ -446,7 +446,7 @@ For example:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### `extern char* waku_connect_peer(char* address, int timeoutMs)`
|
### `extern char* waku_connect(char* address, int timeoutMs)`
|
||||||
|
|
||||||
Dial peer using a multiaddress.
|
Dial peer using a multiaddress.
|
||||||
|
|
||||||
|
@ -499,7 +499,7 @@ For example:
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
### `extern char* waku_disconnect_peer(char* peerId)`
|
### `extern char* waku_disconnect(char* peerId)`
|
||||||
|
|
||||||
Disconnect a peer using its peerID
|
Disconnect a peer using its peerID
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ func main() {}
|
||||||
// - keepAliveInterval: interval in seconds to ping all peers
|
// - keepAliveInterval: interval in seconds to ping all peers
|
||||||
// - relay: Enable WakuRelay. Default `true`
|
// - relay: Enable WakuRelay. Default `true`
|
||||||
// - minPeersToPublish: The minimum number of peers required on a topic to allow broadcasting a message. Default `0`
|
// - minPeersToPublish: The minimum number of peers required on a topic to allow broadcasting a message. Default `0`
|
||||||
|
// - filter: Enable Filter. Default `false`
|
||||||
func waku_new(configJSON *C.char) *C.char {
|
func waku_new(configJSON *C.char) *C.char {
|
||||||
response := mobile.NewNode(C.GoString(configJSON))
|
response := mobile.NewNode(C.GoString(configJSON))
|
||||||
return C.CString(response)
|
return C.CString(response)
|
||||||
|
|
|
@ -19,6 +19,8 @@ var (
|
||||||
ChaChaPoly = WakuNoiseProtocolID(30)
|
ChaChaPoly = WakuNoiseProtocolID(30)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const NoisePaddingBlockSize = 248
|
||||||
|
|
||||||
var ErrorHandshakeComplete = errors.New("handshake complete")
|
var ErrorHandshakeComplete = errors.New("handshake complete")
|
||||||
|
|
||||||
// All protocols share same cipher suite
|
// All protocols share same cipher suite
|
||||||
|
@ -121,8 +123,13 @@ func (hs *Handshake) Step(readPayloadV2 *PayloadV2, transportMessage []byte) (*H
|
||||||
// We initialize a payload v2 and we set proper protocol ID (if supported)
|
// We initialize a payload v2 and we set proper protocol ID (if supported)
|
||||||
result.Payload2.ProtocolId = hs.protocolID
|
result.Payload2.ProtocolId = hs.protocolID
|
||||||
|
|
||||||
|
payload, err := PKCS7_Pad(transportMessage, NoisePaddingBlockSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
var noisePubKeys [][]byte
|
var noisePubKeys [][]byte
|
||||||
msg, cs1, cs2, err = hs.state.WriteMessageAndGetPK(hs.hsBuff, &noisePubKeys, transportMessage)
|
msg, cs1, cs2, err = hs.state.WriteMessageAndGetPK(hs.hsBuff, &noisePubKeys, payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -149,8 +156,14 @@ func (hs *Handshake) Step(readPayloadV2 *PayloadV2, transportMessage []byte) (*H
|
||||||
|
|
||||||
hs.shouldWrite = true
|
hs.shouldWrite = true
|
||||||
|
|
||||||
// We retrieve and store the (decrypted) received transport message
|
// We retrieve, and store the (unpadded decrypted) received transport message
|
||||||
result.TransportMessage = msg
|
|
||||||
|
payload, err := PKCS7_Unpad(msg, NoisePaddingBlockSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
result.TransportMessage = payload
|
||||||
}
|
}
|
||||||
|
|
||||||
if cs1 != nil && cs2 != nil {
|
if cs1 != nil && cs2 != nil {
|
||||||
|
@ -186,9 +199,12 @@ func (hs *Handshake) Encrypt(plaintext []byte) (*PayloadV2, error) {
|
||||||
return nil, errors.New("tried to encrypt empty plaintext")
|
return nil, errors.New("tried to encrypt empty plaintext")
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: add padding (?)
|
paddedTransportMessage, err := PKCS7_Pad(plaintext, NoisePaddingBlockSize)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
cyphertext, err := hs.enc.Encrypt(nil, nil, plaintext)
|
cyphertext, err := hs.enc.Encrypt(nil, nil, paddedTransportMessage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -215,7 +231,12 @@ func (hs *Handshake) Decrypt(payload *PayloadV2) ([]byte, error) {
|
||||||
return nil, errors.New("tried to decrypt empty ciphertext")
|
return nil, errors.New("tried to decrypt empty ciphertext")
|
||||||
}
|
}
|
||||||
|
|
||||||
return hs.dec.Decrypt(nil, nil, payload.TransportMessage)
|
paddedMessage, err := hs.dec.Decrypt(nil, nil, payload.TransportMessage)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return PKCS7_Unpad(paddedMessage, NoisePaddingBlockSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewHandshake_XX_25519_ChaChaPoly_SHA256 creates a handshake where the initiator and receiver are not aware of each other static keys
|
// NewHandshake_XX_25519_ChaChaPoly_SHA256 creates a handshake where the initiator and receiver are not aware of each other static keys
|
||||||
|
|
|
@ -186,3 +186,18 @@ func TestNoiseXK1HandshakeRoundtrip(t *testing.T) {
|
||||||
|
|
||||||
handshakeTest(t, hsAlice, hsBob)
|
handshakeTest(t, hsAlice, hsBob)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestPKCSPaddingUnpadding(t *testing.T) {
|
||||||
|
maxMessageLength := 3 * NoisePaddingBlockSize
|
||||||
|
for messageLen := 0; messageLen <= maxMessageLength; messageLen++ {
|
||||||
|
message := generateRandomBytes(t, messageLen)
|
||||||
|
padded, err := PKCS7_Pad(message, NoisePaddingBlockSize)
|
||||||
|
require.NoError(t, err)
|
||||||
|
unpadded, err := PKCS7_Unpad(padded, NoisePaddingBlockSize)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
require.Greater(t, len(padded), 0)
|
||||||
|
require.Equal(t, len(padded)%NoisePaddingBlockSize, 0)
|
||||||
|
require.Equal(t, message, unpadded)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package noise
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PKCS7_Pad pads a payload according to PKCS#7 as per
|
||||||
|
// RFC 5652 https://datatracker.ietf.org/doc/html/rfc5652#section-6.3
|
||||||
|
func PKCS7_Pad(payload []byte, paddingSize int) ([]byte, error) {
|
||||||
|
if paddingSize >= 256 {
|
||||||
|
return nil, errors.New("invalid padding size")
|
||||||
|
}
|
||||||
|
|
||||||
|
k := paddingSize - (len(payload) % paddingSize)
|
||||||
|
|
||||||
|
var padVal int
|
||||||
|
if k != 0 {
|
||||||
|
padVal = k
|
||||||
|
} else {
|
||||||
|
padVal = paddingSize
|
||||||
|
}
|
||||||
|
|
||||||
|
padding := make([]byte, padVal)
|
||||||
|
for i := range padding {
|
||||||
|
padding[i] = byte(padVal)
|
||||||
|
}
|
||||||
|
|
||||||
|
return append(payload, padding...), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// PKCS7_Unpad unpads a payload according to PKCS#7 as per
|
||||||
|
// RFC 5652 https://datatracker.ietf.org/doc/html/rfc5652#section-6.3
|
||||||
|
func PKCS7_Unpad(payload []byte, paddingSize int) ([]byte, error) {
|
||||||
|
if paddingSize >= 256 {
|
||||||
|
return nil, errors.New("invalid padding size")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(payload) == 0 {
|
||||||
|
return nil, nil // empty payload
|
||||||
|
}
|
||||||
|
|
||||||
|
high := len(payload) - 1
|
||||||
|
k := payload[high]
|
||||||
|
|
||||||
|
unpadded := payload[0:(high + 1 - int(k))]
|
||||||
|
|
||||||
|
return unpadded, nil
|
||||||
|
}
|
|
@ -190,6 +190,6 @@ func (c *CodecRequest) writeServerResponse(w http.ResponseWriter, status int, re
|
||||||
_, _ = w.Write(b)
|
_, _ = w.Write(b)
|
||||||
} else {
|
} else {
|
||||||
// Not sure in which case will this happen. But seems harmless.
|
// Not sure in which case will this happen. But seems harmless.
|
||||||
rpc.WriteError(w, 400, err.Error())
|
rpc.WriteError(w, status, err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue