Update dependencies and build to go1.22 (#2113)
* Update dependencies and build to go1.22 * Fix api changes wrt to dependencies * Update golangci config
This commit is contained in:
69
vendor/go.mau.fi/whatsmeow/handshake.go
vendored
69
vendor/go.mau.fi/whatsmeow/handshake.go
vendored
@@ -11,6 +11,7 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"go.mau.fi/libsignal/ecc"
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
waProto "go.mau.fi/whatsmeow/binary/proto"
|
||||
@@ -19,6 +20,9 @@ import (
|
||||
)
|
||||
|
||||
const NoiseHandshakeResponseTimeout = 20 * time.Second
|
||||
const WACertIssuerSerial = 0
|
||||
|
||||
var WACertPubKey = [...]byte{0x14, 0x23, 0x75, 0x57, 0x4d, 0xa, 0x58, 0x71, 0x66, 0xaa, 0xe7, 0x1e, 0xbe, 0x51, 0x64, 0x37, 0xc4, 0xa2, 0x8b, 0x73, 0xe3, 0x69, 0x5c, 0x6c, 0xe1, 0xf7, 0xf9, 0x54, 0x5d, 0xa8, 0xee, 0x6b}
|
||||
|
||||
// doHandshake implements the Noise_XX_25519_AESGCM_SHA256 handshake for the WhatsApp web API.
|
||||
func (cli *Client) doHandshake(fs *socket.FrameSocket, ephemeralKP keys.KeyPair) error {
|
||||
@@ -76,23 +80,8 @@ func (cli *Client) doHandshake(fs *socket.FrameSocket, ephemeralKP keys.KeyPair)
|
||||
certDecrypted, err := nh.Decrypt(certificateCiphertext)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to decrypt noise certificate ciphertext: %w", err)
|
||||
}
|
||||
var cert waProto.NoiseCertificate
|
||||
err = proto.Unmarshal(certDecrypted, &cert)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal noise certificate: %w", err)
|
||||
}
|
||||
certDetailsRaw := cert.GetDetails()
|
||||
certSignature := cert.GetSignature()
|
||||
if certDetailsRaw == nil || certSignature == nil {
|
||||
return fmt.Errorf("missing parts of noise certificate")
|
||||
}
|
||||
var certDetails waProto.NoiseCertificate_Details
|
||||
err = proto.Unmarshal(certDetailsRaw, &certDetails)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal noise certificate details: %w", err)
|
||||
} else if !bytes.Equal(certDetails.GetKey(), staticDecrypted) {
|
||||
return fmt.Errorf("cert key doesn't match decrypted static")
|
||||
} else if err = verifyServerCert(certDecrypted, staticDecrypted); err != nil {
|
||||
return fmt.Errorf("failed to verify server cert: %w", err)
|
||||
}
|
||||
|
||||
encryptedPubkey := nh.Encrypt(cli.Store.NoiseKey.Pub[:])
|
||||
@@ -101,7 +90,14 @@ func (cli *Client) doHandshake(fs *socket.FrameSocket, ephemeralKP keys.KeyPair)
|
||||
return fmt.Errorf("failed to mix noise private key in: %w", err)
|
||||
}
|
||||
|
||||
clientFinishPayloadBytes, err := proto.Marshal(cli.Store.GetClientPayload())
|
||||
var clientPayload *waProto.ClientPayload
|
||||
if cli.GetClientPayload != nil {
|
||||
clientPayload = cli.GetClientPayload()
|
||||
} else {
|
||||
clientPayload = cli.Store.GetClientPayload()
|
||||
}
|
||||
|
||||
clientFinishPayloadBytes, err := proto.Marshal(clientPayload)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal client finish payload: %w", err)
|
||||
}
|
||||
@@ -129,3 +125,40 @@ func (cli *Client) doHandshake(fs *socket.FrameSocket, ephemeralKP keys.KeyPair)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func verifyServerCert(certDecrypted, staticDecrypted []byte) error {
|
||||
var certChain waProto.CertChain
|
||||
err := proto.Unmarshal(certDecrypted, &certChain)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unmarshal noise certificate: %w", err)
|
||||
}
|
||||
var intermediateCertDetails, leafCertDetails waProto.CertChain_NoiseCertificate_Details
|
||||
intermediateCertDetailsRaw := certChain.GetIntermediate().GetDetails()
|
||||
intermediateCertSignature := certChain.GetIntermediate().GetSignature()
|
||||
leafCertDetailsRaw := certChain.GetLeaf().GetDetails()
|
||||
leafCertSignature := certChain.GetLeaf().GetSignature()
|
||||
if intermediateCertDetailsRaw == nil || intermediateCertSignature == nil || leafCertDetailsRaw == nil || leafCertSignature == nil {
|
||||
return fmt.Errorf("missing parts of noise certificate")
|
||||
} else if len(intermediateCertSignature) != 64 {
|
||||
return fmt.Errorf("unexpected length of intermediate cert signature %d (expected 64)", len(intermediateCertSignature))
|
||||
} else if len(leafCertSignature) != 64 {
|
||||
return fmt.Errorf("unexpected length of leaf cert signature %d (expected 64)", len(leafCertSignature))
|
||||
} else if !ecc.VerifySignature(ecc.NewDjbECPublicKey(WACertPubKey), intermediateCertDetailsRaw, [64]byte(intermediateCertSignature)) {
|
||||
return fmt.Errorf("failed to verify intermediate cert signature")
|
||||
} else if err = proto.Unmarshal(intermediateCertDetailsRaw, &intermediateCertDetails); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal noise certificate details: %w", err)
|
||||
} else if intermediateCertDetails.GetIssuerSerial() != WACertIssuerSerial {
|
||||
return fmt.Errorf("unexpected intermediate issuer serial %d (expected %d)", intermediateCertDetails.GetIssuerSerial(), WACertIssuerSerial)
|
||||
} else if len(intermediateCertDetails.GetKey()) != 32 {
|
||||
return fmt.Errorf("unexpected length of intermediate cert key %d (expected 32)", len(intermediateCertDetails.GetKey()))
|
||||
} else if !ecc.VerifySignature(ecc.NewDjbECPublicKey([32]byte(intermediateCertDetails.GetKey())), leafCertDetailsRaw, [64]byte(leafCertSignature)) {
|
||||
return fmt.Errorf("failed to verify intermediate cert signature")
|
||||
} else if err = proto.Unmarshal(leafCertDetailsRaw, &leafCertDetails); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal noise certificate details: %w", err)
|
||||
} else if leafCertDetails.GetIssuerSerial() != intermediateCertDetails.GetSerial() {
|
||||
return fmt.Errorf("unexpected leaf issuer serial %d (expected %d)", leafCertDetails.GetIssuerSerial(), intermediateCertDetails.GetSerial())
|
||||
} else if !bytes.Equal(leafCertDetails.GetKey(), staticDecrypted) {
|
||||
return fmt.Errorf("cert key doesn't match decrypted static")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user