summaryrefslogtreecommitdiff
path: root/vendor/github.com/pion/stun/fingerprint.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/pion/stun/fingerprint.go')
-rw-r--r--vendor/github.com/pion/stun/fingerprint.go67
1 files changed, 67 insertions, 0 deletions
diff --git a/vendor/github.com/pion/stun/fingerprint.go b/vendor/github.com/pion/stun/fingerprint.go
new file mode 100644
index 0000000..aef80a2
--- /dev/null
+++ b/vendor/github.com/pion/stun/fingerprint.go
@@ -0,0 +1,67 @@
+package stun
+
+import (
+ "errors"
+ "hash/crc32"
+)
+
+// FingerprintAttr represents FINGERPRINT attribute.
+//
+// RFC 5389 Section 15.5
+type FingerprintAttr struct{}
+
+// ErrFingerprintMismatch means that computed fingerprint differs from expected.
+var ErrFingerprintMismatch = errors.New("fingerprint check failed")
+
+// Fingerprint is shorthand for FingerprintAttr.
+//
+// Example:
+//
+// m := New()
+// Fingerprint.AddTo(m)
+var Fingerprint FingerprintAttr
+
+const (
+ fingerprintXORValue uint32 = 0x5354554e //nolint:staticcheck
+ fingerprintSize = 4 // 32 bit
+)
+
+// FingerprintValue returns CRC-32 of b XOR-ed by 0x5354554e.
+//
+// The value of the attribute is computed as the CRC-32 of the STUN message
+// up to (but excluding) the FINGERPRINT attribute itself, XOR'ed with
+// the 32-bit value 0x5354554e (the XOR helps in cases where an
+// application packet is also using CRC-32 in it).
+func FingerprintValue(b []byte) uint32 {
+ return crc32.ChecksumIEEE(b) ^ fingerprintXORValue // XOR
+}
+
+// AddTo adds fingerprint to message.
+func (FingerprintAttr) AddTo(m *Message) error {
+ l := m.Length
+ // length in header should include size of fingerprint attribute
+ m.Length += fingerprintSize + attributeHeaderSize // increasing length
+ m.WriteLength() // writing Length to Raw
+ b := make([]byte, fingerprintSize)
+ val := FingerprintValue(m.Raw)
+ bin.PutUint32(b, val)
+ m.Length = l
+ m.Add(AttrFingerprint, b)
+ return nil
+}
+
+// Check reads fingerprint value from m and checks it, returning error if any.
+// Can return *AttrLengthErr, ErrAttributeNotFound, and *CRCMismatch.
+func (FingerprintAttr) Check(m *Message) error {
+ b, err := m.Get(AttrFingerprint)
+ if err != nil {
+ return err
+ }
+ if err = CheckSize(AttrFingerprint, len(b), fingerprintSize); err != nil {
+ return err
+ }
+ val := bin.Uint32(b)
+ attrStart := len(m.Raw) - (fingerprintSize + attributeHeaderSize)
+ expected := FingerprintValue(m.Raw[:attrStart])
+ return checkFingerprint(val, expected)
+}