51 lines
1.4 KiB
Nim
51 lines
1.4 KiB
Nim
import std/options
|
|
import bearssl
|
|
|
|
import ../jwa
|
|
import ../jwk
|
|
|
|
import ./crypto/ecdsa
|
|
import ./crypto/hmac
|
|
import ./crypto/rsa
|
|
|
|
proc validateAlgMatchesKey(alg: JwtAlgorithm, key: JWK) =
|
|
if key.alg.isSome and key.alg.get != $alg:
|
|
raise newException(ValueError,
|
|
"requested signature algorithm (" & $alg & ") does not match the " &
|
|
"algorithm intended for use with this key (" & key.alg.get & ")")
|
|
|
|
proc computeSignature*(
|
|
payload: string,
|
|
alg: JwtAlgorithm,
|
|
key: JWK | string
|
|
): string =
|
|
|
|
if typeof(key) is JWK: validateAlgMatchesKey(alg, cast[JWK](key))
|
|
|
|
case alg:
|
|
of HS256, HS384, HS512: return hmac(payload, alg, key)
|
|
of RS256, RS384, RS512: return rsaSign(payload, alg, key)
|
|
of ES256, ES384, ES512: return ecSign(payload, alg, key)
|
|
else:
|
|
raise newException(Exception,
|
|
"unsupported signature algorithm: " & $alg)
|
|
|
|
proc verifySignature*(
|
|
payload: string,
|
|
signature: string,
|
|
alg: JwtAlgorithm,
|
|
key: JWK | string
|
|
): bool =
|
|
|
|
if typeof(key) is JWK: validateAlgMatchesKey(alg, cast[JWK](key))
|
|
|
|
case alg:
|
|
of HS256, HS384, HS512:
|
|
let hash = hmac(payload, alg, key)
|
|
return hash == signature
|
|
of RS256, RS384, RS512: return rsaVerify(payload, signature, alg, key)
|
|
of ES256, ES384, ES512: return ecVerify(payload, signature, alg, key)
|
|
else:
|
|
raise newException(Exception,
|
|
"unsupported signature algorithm: " & $alg)
|