47 lines
1.4 KiB
Nim
47 lines
1.4 KiB
Nim
import std/logging
|
|
|
|
import bearssl
|
|
|
|
import ../../encoding
|
|
import ../../jwa
|
|
import ../../jwk
|
|
|
|
proc bearHMAC(message: string, alg: JwtAlgorithm, key: string): string =
|
|
|
|
var vtable: ptr HashClass
|
|
var hashSize: int
|
|
|
|
case alg:
|
|
of HS256: vtable = addr sha256Vtable; hashSize = sha256Size
|
|
of HS384: vtable = addr sha384Vtable; hashSize = sha384Size
|
|
of HS512: vtable = addr sha512Vtable; hashSize = sha512Size
|
|
else: raise newException(ValueError,
|
|
"Unsupported HMAC algorithm '" & $alg & "'")
|
|
|
|
if key.len < hashSize:
|
|
warn( "Computing an HMAC with a small key (" & $key.len & " bytes). It " &
|
|
"is recommended to use keys of at least " & $hashSize & " bytes for " &
|
|
$alg)
|
|
|
|
var keyCtx: HmacKeyContext
|
|
var hmacCtx: HmacContext
|
|
|
|
hmacKeyInit(keyCtx, vtable, key.cstring, uint key.len)
|
|
hmacInit(hmacCtx, keyCtx, uint 0)
|
|
hmacUpdate(hmacCtx, message.cstring, uint message.len)
|
|
|
|
let resLen = hmacSize(hmacCtx)
|
|
result = newString(resLen)
|
|
discard hmacOut(hmacCtx, addr result[0])
|
|
|
|
proc hmac*(message: string, alg: JwtAlgorithm, key: string): string =
|
|
return bearHMAC(message, alg, key)
|
|
|
|
proc hmac*(message: string, alg: JwtAlgorithm, key: JWK): string =
|
|
if key.keyKind != Octet:
|
|
raise newException(ValueError,
|
|
$alg & " requires an octet key (\"typ\"=\"oct\"), not a \"typ\"=\"" &
|
|
$(key.keyKind) & "\" key.")
|
|
|
|
return bearHMAC(message, alg, b64UrlDecode(key.octKey.k))
|