Files
nim-jwt-full/src/main/jwt_full/private/crypto/hmac.nim
T

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))