appstate,handshake,pair: use constant-time byte comparisons
This commit is contained in:
+7
-6
@@ -9,6 +9,7 @@ package appstate
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -122,7 +123,7 @@ func (out *patchOutput) RemoveMAC(indexMAC []byte) {
|
||||
out.RemovedMACs = append(out.RemovedMACs, indexMAC)
|
||||
// If the mutation was previously added in this patch, remove it from AddedMACs
|
||||
out.AddedMACs = slices.DeleteFunc(out.AddedMACs, func(mac store.AppStateMutationMAC) bool {
|
||||
return bytes.Equal(mac.IndexMAC, indexMAC)
|
||||
return hmac.Equal(mac.IndexMAC, indexMAC)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -149,7 +150,7 @@ func (proc *Processor) decodeMutation(
|
||||
content, valueMAC = content[:len(content)-32], content[len(content)-32:]
|
||||
if validateMACs {
|
||||
expectedValueMAC := generateContentMAC(mutation.GetOperation(), content, keyID, keys.ValueMAC)
|
||||
if !bytes.Equal(expectedValueMAC, valueMAC) {
|
||||
if !hmac.Equal(expectedValueMAC, valueMAC) {
|
||||
err = fmt.Errorf("failed to verify mutation #%d: %w", i+1, ErrMismatchingContentMAC)
|
||||
return
|
||||
}
|
||||
@@ -169,7 +170,7 @@ func (proc *Processor) decodeMutation(
|
||||
indexMAC = mutation.GetRecord().GetIndex().GetBlob()
|
||||
if validateMACs {
|
||||
expectedIndexMAC := concatAndHMAC(sha256.New, keys.Index, syncAction.Index)
|
||||
if !bytes.Equal(expectedIndexMAC, indexMAC) {
|
||||
if !hmac.Equal(expectedIndexMAC, indexMAC) {
|
||||
err = fmt.Errorf("failed to verify mutation #%d: %w", i+1, ErrMismatchingIndexMAC)
|
||||
return
|
||||
}
|
||||
@@ -248,7 +249,7 @@ func (proc *Processor) validateSnapshotMAC(ctx context.Context, name WAPatchName
|
||||
return
|
||||
}
|
||||
snapshotMAC := currentState.generateSnapshotMAC(name, keys.SnapshotMAC)
|
||||
if !bytes.Equal(snapshotMAC, expectedSnapshotMAC) {
|
||||
if !hmac.Equal(snapshotMAC, expectedSnapshotMAC) {
|
||||
err = fmt.Errorf("failed to verify patch v%d: %w", currentState.Version, ErrMismatchingLTHash)
|
||||
}
|
||||
return
|
||||
@@ -321,7 +322,7 @@ func (proc *Processor) validatePatch(
|
||||
newState.Version = version
|
||||
warn, err = newState.updateHash(patch.GetMutations(), func(indexMAC []byte, maxIndex int) ([]byte, error) {
|
||||
for i := maxIndex - 1; i >= 0; i-- {
|
||||
if bytes.Equal(patch.Mutations[i].GetRecord().GetIndex().GetBlob(), indexMAC) {
|
||||
if hmac.Equal(patch.Mutations[i].GetRecord().GetIndex().GetBlob(), indexMAC) {
|
||||
if patch.Mutations[i].GetOperation() == waServerSync.SyncdMutation_SET {
|
||||
value := patch.Mutations[i].GetRecord().GetValue().GetBlob()
|
||||
return value[len(value)-32:], nil
|
||||
@@ -345,7 +346,7 @@ func (proc *Processor) validatePatch(
|
||||
return
|
||||
}
|
||||
patchMAC := generatePatchMAC(patch, patchName, keys.PatchMAC, patch.GetVersion().GetVersion())
|
||||
if !bytes.Equal(patchMAC, patch.GetPatchMAC()) {
|
||||
if !hmac.Equal(patchMAC, patch.GetPatchMAC()) {
|
||||
err = fmt.Errorf("failed to verify patch v%d: %w", version, ErrMismatchingPatchMAC)
|
||||
return
|
||||
}
|
||||
|
||||
+2
-2
@@ -7,8 +7,8 @@
|
||||
package whatsmeow
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
@@ -173,7 +173,7 @@ func verifyServerCert(certDecrypted, staticDecrypted []byte) error {
|
||||
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) {
|
||||
} else if !hmac.Equal(leafCertDetails.GetKey(), staticDecrypted) {
|
||||
return fmt.Errorf("cert key doesn't match decrypted static")
|
||||
} else if err = checkCertValidity(&leafCertDetails); err != nil {
|
||||
return fmt.Errorf("leaf cert cert %w", err)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
package whatsmeow
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/hmac"
|
||||
"crypto/sha256"
|
||||
@@ -125,7 +124,7 @@ func (cli *Client) handlePair(ctx context.Context, deviceIdentityBytes []byte, r
|
||||
}
|
||||
h.Write(deviceIdentityContainer.Details)
|
||||
|
||||
if !bytes.Equal(h.Sum(nil), deviceIdentityContainer.HMAC) {
|
||||
if !hmac.Equal(h.Sum(nil), deviceIdentityContainer.HMAC) {
|
||||
cli.Log.Warnf("Invalid HMAC from pair success message")
|
||||
cli.sendPairError(ctx, reqID, 401, "hmac-mismatch")
|
||||
return ErrPairInvalidDeviceIdentityHMAC
|
||||
|
||||
Reference in New Issue
Block a user