Skip to content

Commit

Permalink
feat: add digest verification
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexanderTar committed Jan 12, 2024
1 parent 19f9b8f commit 9d5fb50
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 0 deletions.
36 changes: 36 additions & 0 deletions digest.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ package httpsig
import (
"crypto/sha256"
"crypto/sha512"
"crypto/subtle"
"errors"
"net/http"

Expand Down Expand Up @@ -97,6 +98,41 @@ func (d *digestor) Digest(body []byte) (http.Header, error) {
return hdr, nil
}

func (d *digestor) Verify(body []byte, header http.Header) error {
dict, err := httpsfv.UnmarshalDictionary(header.Values(ContentDigestHeader))
if err != nil {
return err
}

for _, algorithm := range d.config.Algorithms {
item, ok := dict.Get(string(algorithm))
if !ok {
continue
}

digest, err := calculateDigest(body, algorithm)
if err != nil {
return err
}

valueItem, ok := item.(httpsfv.Item)
if !ok {
return errors.New("invalid digest header")
}

value, ok := valueItem.Value.([]byte)
if !ok {
return errors.New("invalid digest header")
}

if subtle.ConstantTimeCompare([]byte(digest), []byte(value)) != 1 {
return errors.New("digest mismatch")
}
}

return nil
}

func calculateDigest(body []byte, algorithm DigestAlgorithm) ([]byte, error) {
switch algorithm {
case DigestAlgorithmSha256:
Expand Down
117 changes: 117 additions & 0 deletions digest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,120 @@ func TestDigest_SHA256(t *testing.T) {

assert.Equal(t, `sha-256=:RK/0qy18MlBSVnWgjwz6lZEWjP/lF5HF9bvEF8FabDg=:`, hdr.Get(ContentDigestHeader))
}

func TestVerify_SHA256(t *testing.T) {
body := []byte("{\"hello\": \"world\"}\n")

d := NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha256),
)

hdr, err := d.Digest(body)
assert.NoError(t, err)

err = d.Verify(body, hdr)
assert.NoError(t, err)
}

func TestVerify_SHA512(t *testing.T) {
body := []byte("{\"hello\": \"world\"}\n")

d := NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha512),
)

hdr, err := d.Digest(body)
assert.NoError(t, err)

err = d.Verify(body, hdr)
assert.NoError(t, err)
}

func TestDigest_SHA256_Verify_SHA256_SHA512(t *testing.T) {
body := []byte("{\"hello\": \"world\"}\n")

d := NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha256),
)

hdr, err := d.Digest(body)
assert.NoError(t, err)

err = d.Verify(body, hdr)
assert.NoError(t, err)

d = NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha256),
WithDigestAlgorithms(DigestAlgorithmSha512),
)

err = d.Verify(body, hdr)
assert.NoError(t, err)
}

func TestDigest_SHA256_SHA512_Verify_SHA256_SHA512(t *testing.T) {
body := []byte("{\"hello\": \"world\"}\n")

d := NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha256),
WithDigestAlgorithms(DigestAlgorithmSha512),
)

hdr, err := d.Digest(body)
assert.NoError(t, err)

err = d.Verify(body, hdr)
assert.NoError(t, err)

d = NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha256),
WithDigestAlgorithms(DigestAlgorithmSha512),
)

err = d.Verify(body, hdr)
assert.NoError(t, err)
}

func TestDigest_SHA256_SHA512_Verify_SHA256(t *testing.T) {
body := []byte("{\"hello\": \"world\"}\n")

d := NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha256),
WithDigestAlgorithms(DigestAlgorithmSha512),
)

hdr, err := d.Digest(body)
assert.NoError(t, err)

err = d.Verify(body, hdr)
assert.NoError(t, err)

d = NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha256),
)

err = d.Verify(body, hdr)
assert.NoError(t, err)
}

func TestDigest_SHA256_SHA512_Verify_SHA512(t *testing.T) {
body := []byte("{\"hello\": \"world\"}\n")

d := NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha256),
WithDigestAlgorithms(DigestAlgorithmSha512),
)

hdr, err := d.Digest(body)
assert.NoError(t, err)

err = d.Verify(body, hdr)
assert.NoError(t, err)

d = NewDigestor(
WithDigestAlgorithms(DigestAlgorithmSha512),
)

err = d.Verify(body, hdr)
assert.NoError(t, err)
}

0 comments on commit 9d5fb50

Please sign in to comment.