Skip to content

Commit

Permalink
Merge pull request #256 from edgardoalz/feature/crypto-hmac
Browse files Browse the repository at this point in the history
Add HMAC support to Crypto module
  • Loading branch information
liclac authored Jun 20, 2017
2 parents f5adec5 + e9d5868 commit 2d9184a
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 0 deletions.
39 changes: 39 additions & 0 deletions js/modules/k6/crypto/crypto.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ package crypto

import (
"context"
"crypto/hmac"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
Expand Down Expand Up @@ -151,3 +152,41 @@ func (hasher *Hasher) Digest(outputEncoding string) string {

return ""
}

func (c Crypto) CreateHMAC(ctx context.Context, algorithm string, key string) *Hasher {
hasher := Hasher{}
hasher.ctx = ctx
keyBuffer := []byte(key)

switch algorithm {
case "md4":
hasher.hash = hmac.New(md4.New, keyBuffer)
case "md5":
hasher.hash = hmac.New(md5.New, keyBuffer)
case "sha1":
hasher.hash = hmac.New(sha1.New, keyBuffer)
case "sha256":
hasher.hash = hmac.New(sha256.New, keyBuffer)
case "sha384":
hasher.hash = hmac.New(sha512.New384, keyBuffer)
case "sha512_224":
hasher.hash = hmac.New(sha512.New512_224, keyBuffer)
case "sha512_256":
hasher.hash = hmac.New(sha512.New512_256, keyBuffer)
case "sha512":
hasher.hash = hmac.New(sha512.New, keyBuffer)
case "ripemd160":
hasher.hash = hmac.New(ripemd160.New, keyBuffer)
default:
err := errors.New("Invalid algorithm: " + algorithm)
common.Throw(common.GetRuntime(hasher.ctx), err)
}

return &hasher
}

func (c *Crypto) Hmac(ctx context.Context, algorithm string, key string, input string, outputEncoding string) string {
hasher := c.CreateHMAC(ctx, algorithm, key)
hasher.Update(input)
return hasher.Digest(outputEncoding)
}
89 changes: 89 additions & 0 deletions js/modules/k6/crypto/crypto_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,3 +252,92 @@ func TestOutputEncoding(t *testing.T) {
assert.EqualError(t, err, "GoError: Invalid output encoding: someInvalidEncoding")
})
}

func TestHMac(t *testing.T) {
if testing.Short() {
return
}

rt := goja.New()
rt.SetFieldNameMapper(common.FieldNameMapper{})

root, _ := lib.NewGroup("", nil)
state := &common.State{Group: root}

ctx := context.Background()
ctx = common.WithState(ctx, state)
ctx = common.WithRuntime(ctx, rt)

rt.Set("crypto", common.Bind(rt, &Crypto{}, &ctx))

testData := map[string]string{
"md4": "92d8f5c302cf04cca0144d7a9feb1596",
"md5": "e04f2ec05c8b12e19e46936b171c9d03",
"sha1": "c113b62711ff5d8e8100bbb17b998591af81dc24",
"sha256": "7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e",
"sha384": "d331e169e2dcfc742e80a3bf4dcc76d0e6425ab3777a3ac217ac6b2552aad5529ed4d40135b06e53a495ac7425d1e462",
"sha512_224": "bac4e6256bdbf81d029aec48af4fdd4b14001db6721f07c429a80817",
"sha512_256": "e3d0763ba92a4f40676c3d5b234d9842b71951e6e0767082cfb3f5e14c124b22",
"sha512": "cd3146f96a3005024108ff56b025517552435589a4c218411f165da0a368b6f47228b20a1a4bf081e4aae6f07e2790f27194fc77f0addc890e98ce1951cacc9f",
"ripemd160": "00bb4ce0d6afd4c7424c9d01b8a6caa3e749b08b",
}
for algorithm, value := range testData {
rt.Set("correctHex", rt.ToValue(value))
rt.Set("algorithm", rt.ToValue(algorithm))
t.Run(algorithm+" hasher: valid", func(t *testing.T) {
_, err := common.RunString(rt, `
let hasher = crypto.createHMAC(algorithm, "a secret");
hasher.update("some data to hash");
const resultHex = hasher.digest("hex");
if (resultHex !== correctHex) {
throw new Error("Hex encoding mismatch: " + resultHex);
}`)

assert.NoError(t, err)
})

t.Run(algorithm+" wrapper: valid", func(t *testing.T) {
_, err := common.RunString(rt, `
let resultHex = crypto.hmac(algorithm, "a secret", "some data to hash", "hex");
if (resultHex !== correctHex) {
throw new Error("Hex encoding mismatch: " + resultHex);
}`)

assert.NoError(t, err)
})
}

// Algorithms not supported or typing error
invalidData := map[string]string{
"md6": "e04f2ec05c8b12e19e46936b171c9d03",
"sha526": "7fd04df92f636fd450bc841c9418e5825c17f33ad9c87c518115a45971f7f77e",
"sha348": "d331e169e2dcfc742e80a3bf4dcc76d0e6425ab3777a3ac217ac6b2552aad5529ed4d40135b06e53a495ac7425d1e462",
}
for algorithm, value := range invalidData {
rt.Set("correctHex", rt.ToValue(value))
rt.Set("algorithm", rt.ToValue(algorithm))
t.Run(algorithm+" hasher: invalid", func(t *testing.T) {
_, err := common.RunString(rt, `
let hasher = crypto.createHMAC(algorithm, "a secret");
hasher.update("some data to hash");
const resultHex = hasher.digest("hex");
if (resultHex !== correctHex) {
throw new Error("Hex encoding mismatch: " + resultHex);
}`)

assert.EqualError(t, err, "GoError: Invalid algorithm: "+algorithm)
})

t.Run(algorithm+" wrapper: invalid", func(t *testing.T) {
_, err := common.RunString(rt, `
let resultHex = crypto.hmac(algorithm, "a secret", "some data to hash", "hex");
if (resultHex !== correctHex) {
throw new Error("Hex encoding mismatch: " + resultHex);
}`)

assert.EqualError(t, err, "GoError: Invalid algorithm: "+algorithm)
})
}
}

0 comments on commit 2d9184a

Please sign in to comment.