Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
0f3b9bfe9a | |||
ac61d90585 |
@ -1,6 +1,6 @@
|
|||||||
# Package
|
# Package
|
||||||
|
|
||||||
version = "0.1.0"
|
version = "0.3.0"
|
||||||
author = "Jonathan Bernard"
|
author = "Jonathan Bernard"
|
||||||
description = "Full JWT, JWS, JWE, and JWK implementation for Nim, compliant with RFCs 7515-7519."
|
description = "Full JWT, JWS, JWE, and JWK implementation for Nim, compliant with RFCs 7515-7519."
|
||||||
license = "GPL-3.0-or-later"
|
license = "GPL-3.0-or-later"
|
||||||
|
@ -25,25 +25,29 @@ type
|
|||||||
JwtClaims* = object
|
JwtClaims* = object
|
||||||
rawB64: string
|
rawB64: string
|
||||||
json: JsonNode
|
json: JsonNode
|
||||||
iss: Option[string]
|
|
||||||
sub: Option[string]
|
|
||||||
aud: Option[string]
|
aud: Option[string]
|
||||||
exp: Option[DateTime]
|
exp: Option[DateTime]
|
||||||
nbf: Option[DateTime]
|
|
||||||
iat: Option[DateTime]
|
iat: Option[DateTime]
|
||||||
|
iss: Option[string]
|
||||||
jti: Option[string]
|
jti: Option[string]
|
||||||
|
nbf: Option[DateTime]
|
||||||
|
sid: Option[string]
|
||||||
|
sub: Option[string]
|
||||||
|
typ: Option[string]
|
||||||
|
|
||||||
# Public read-only accessors to JwtClaims members
|
# Public read-only accessors to JwtClaims members
|
||||||
# -----------------------------------------------
|
# -----------------------------------------------
|
||||||
|
|
||||||
func rawB64*(c: JwtClaims): string = c.rawB64
|
func rawB64*(c: JwtClaims): string = c.rawB64
|
||||||
func iss*(c: JwtClaims): Option[string] = c.iss
|
|
||||||
func sub*(c: JwtClaims): Option[string] = c.sub
|
|
||||||
func aud*(c: JwtClaims): Option[string] = c.aud
|
func aud*(c: JwtClaims): Option[string] = c.aud
|
||||||
func exp*(c: JwtClaims): Option[DateTime] = c.exp
|
func exp*(c: JwtClaims): Option[DateTime] = c.exp
|
||||||
func nbf*(c: JwtClaims): Option[DateTime] = c.nbf
|
|
||||||
func iat*(c: JwtClaims): Option[DateTime] = c.iat
|
func iat*(c: JwtClaims): Option[DateTime] = c.iat
|
||||||
|
func iss*(c: JwtClaims): Option[string] = c.iss
|
||||||
func jti*(c: JwtClaims): Option[string] = c.jti
|
func jti*(c: JwtClaims): Option[string] = c.jti
|
||||||
|
func nbf*(c: JwtClaims): Option[DateTime] = c.nbf
|
||||||
|
func sid*(c: JwtClaims): Option[string] = c.sid
|
||||||
|
func sub*(c: JwtClaims): Option[string] = c.sub
|
||||||
|
func typ*(c: JwtClaims): Option[string] = c.typ
|
||||||
|
|
||||||
func `[]`*(c: JwtClaims, key: string): Option[JsonNode] =
|
func `[]`*(c: JwtClaims, key: string): Option[JsonNode] =
|
||||||
## Generic accessor to claim values by name
|
## Generic accessor to claim values by name
|
||||||
@ -61,13 +65,15 @@ proc initJwtClaims*(n: JsonNode): JwtClaims =
|
|||||||
return JwtClaims(
|
return JwtClaims(
|
||||||
rawB64: b64UrlEncode($n),
|
rawB64: b64UrlEncode($n),
|
||||||
json: n,
|
json: n,
|
||||||
iss: n.optStrVal("iss"),
|
|
||||||
sub: n.optStrVal("sub"),
|
|
||||||
aud: n.optStrVal("aud"),
|
aud: n.optStrVal("aud"),
|
||||||
exp: n.optNumericDate("exp"),
|
exp: n.optNumericDate("exp"),
|
||||||
nbf: n.optNumericDate("nbf"),
|
|
||||||
iat: n.optNumericDate("iat"),
|
iat: n.optNumericDate("iat"),
|
||||||
jti: n.optStrVal("jtu"))
|
iss: n.optStrVal("iss"),
|
||||||
|
jti: n.optStrVal("jtu"),
|
||||||
|
nbf: n.optNumericDate("nbf"),
|
||||||
|
sid: n.optStrVal("sid"),
|
||||||
|
sub: n.optStrVal("sub"),
|
||||||
|
typ: n.optStrVal("typ"))
|
||||||
|
|
||||||
proc initJwtClaims*(encoded: string): JwtClaims =
|
proc initJwtClaims*(encoded: string): JwtClaims =
|
||||||
## Parse a Base64url-encoded set of claims into a JwtClaims object
|
## Parse a Base64url-encoded set of claims into a JwtClaims object
|
||||||
@ -77,13 +83,15 @@ proc initJwtClaims*(encoded: string): JwtClaims =
|
|||||||
result.rawB64 = encoded
|
result.rawB64 = encoded
|
||||||
|
|
||||||
proc initJwtClaims*(
|
proc initJwtClaims*(
|
||||||
iss: Option[string] = none[string](),
|
|
||||||
sub: Option[string] = none[string](),
|
|
||||||
aud: Option[string] = none[string](),
|
aud: Option[string] = none[string](),
|
||||||
exp: Option[DateTime] = none[DateTime](),
|
exp: Option[DateTime] = none[DateTime](),
|
||||||
nbf: Option[DateTime] = none[DateTime](),
|
|
||||||
iat: Option[DateTime] = none[DateTime](),
|
iat: Option[DateTime] = none[DateTime](),
|
||||||
|
iss: Option[string] = none[string](),
|
||||||
jti: Option[string] = none[string](),
|
jti: Option[string] = none[string](),
|
||||||
|
nbf: Option[DateTime] = none[DateTime](),
|
||||||
|
sid: Option[string] = none[string](),
|
||||||
|
sub: Option[string] = none[string](),
|
||||||
|
typ: Option[string] = none[string](),
|
||||||
moreClaims: seq[tuple[k, v: string]] = @[]
|
moreClaims: seq[tuple[k, v: string]] = @[]
|
||||||
): JwtClaims =
|
): JwtClaims =
|
||||||
## Convenience method to initialize a new JwtClaims object by specifying
|
## Convenience method to initialize a new JwtClaims object by specifying
|
||||||
@ -99,12 +107,14 @@ proc initJwtClaims*(
|
|||||||
let json = newJObject()
|
let json = newJObject()
|
||||||
for claim in moreClaims: json[claim.k] = %claim.v
|
for claim in moreClaims: json[claim.k] = %claim.v
|
||||||
|
|
||||||
if iss.isSome: json["iss"] = %iss.get
|
|
||||||
if sub.isSome: json["sub"] = %sub.get
|
|
||||||
if aud.isSome: json["aud"] = %aud.get
|
if aud.isSome: json["aud"] = %aud.get
|
||||||
if exp.isSome: json["exp"] = %toNumericDate(exp.get)
|
if exp.isSome: json["exp"] = %toNumericDate(exp.get)
|
||||||
if nbf.isSome: json["nbf"] = %toNumericDate(nbf.get)
|
|
||||||
if iat.isSome: json["iat"] = %toNumericDate(iat.get)
|
if iat.isSome: json["iat"] = %toNumericDate(iat.get)
|
||||||
|
if iss.isSome: json["iss"] = %iss.get
|
||||||
if jti.isSome: json["jti"] = %jti.get
|
if jti.isSome: json["jti"] = %jti.get
|
||||||
|
if nbf.isSome: json["nbf"] = %toNumericDate(nbf.get)
|
||||||
|
if sid.isSome: json["sid"] = %sid.get
|
||||||
|
if sub.isSome: json["sub"] = %sub.get
|
||||||
|
if typ.isSome: json["typ"] = %typ.get
|
||||||
|
|
||||||
return initJwtClaims(json)
|
return initJwtClaims(json)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# jwt_full/jwt.nim
|
# jwt_full/jwt.nim
|
||||||
# Copyright 2021 Jonathan Bernard
|
# Copyright © 2021 Jonathan Bernard
|
||||||
|
|
||||||
## ===============================
|
## ===============================
|
||||||
## jwt
|
## jwt
|
||||||
@ -57,7 +57,7 @@ proc initJWT*(encoded: string): JWT =
|
|||||||
jws: jws)
|
jws: jws)
|
||||||
else:
|
else:
|
||||||
# TODO
|
# TODO
|
||||||
raise newException(Exception, "not yet implemented")
|
raise newException(Exception, "partial JWT construction is not yet implemented")
|
||||||
|
|
||||||
proc toJWT*(encoded: string): JWT = initJWT(encoded)
|
proc toJWT*(encoded: string): JWT = initJWT(encoded)
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import std/tables
|
|
||||||
import bearssl, bearssl_pkey_decoder
|
import bearssl, bearssl_pkey_decoder
|
||||||
|
|
||||||
import ../../encoding
|
import ../../encoding
|
||||||
@ -35,14 +34,14 @@ func fromBearSslCurveConst(curve: int32): EcCurve =
|
|||||||
func initEcPublicKeyObj(curve: EcCurve, q: string): EcPublicKeyObj =
|
func initEcPublicKeyObj(curve: EcCurve, q: string): EcPublicKeyObj =
|
||||||
result = EcPublicKeyObj(curve: curve, q: q)
|
result = EcPublicKeyObj(curve: curve, q: q)
|
||||||
result.bearKey.curve = curve.toBearSslCurveConst
|
result.bearKey.curve = curve.toBearSslCurveConst
|
||||||
result.bearKey.q = cast[ptr char](result.q.cstring)
|
result.bearKey.q = cast[ptr byte](result.q.cstring)
|
||||||
result.bearKey.qlen = q.len
|
result.bearKey.qlen = uint q.len
|
||||||
|
|
||||||
func initEcPrivateKeyObj(curve: EcCurve, x: string): EcPrivateKeyObj =
|
func initEcPrivateKeyObj(curve: EcCurve, x: string): EcPrivateKeyObj =
|
||||||
result = EcPrivateKeyObj(curve: curve, x: x)
|
result = EcPrivateKeyObj(curve: curve, x: x)
|
||||||
result.bearKey.curve = curve.toBearSslCurveConst
|
result.bearKey.curve = curve.toBearSslCurveConst
|
||||||
result.bearKey.x = cast[ptr char](result.x.cstring)
|
result.bearKey.x = cast[ptr byte](result.x.cstring)
|
||||||
result.bearKey.xlen = x.len
|
result.bearKey.xlen = uint x.len
|
||||||
|
|
||||||
proc toEcPublicKey(jwk: JWK): EcPublicKeyObj =
|
proc toEcPublicKey(jwk: JWK): EcPublicKeyObj =
|
||||||
## Convert an ECDSA public key in JWK format to the wrapper for BearSSL's
|
## Convert an ECDSA public key in JWK format to the wrapper for BearSSL's
|
||||||
@ -66,7 +65,7 @@ proc toEcPublicKey(pem: string): EcPublicKeyObj =
|
|||||||
cast[BearPemDecoderCallback](pkeyDecoderPush))
|
cast[BearPemDecoderCallback](pkeyDecoderPush))
|
||||||
|
|
||||||
let k = pkCtx.key.ec
|
let k = pkCtx.key.ec
|
||||||
return initEcPublicKeyObj(k.curve.fromBearSslCurveConst, $cstring(k.q))
|
return initEcPublicKeyObj(k.curve.fromBearSslCurveConst, $cast[cstring](k.q))
|
||||||
|
|
||||||
proc toEcPrivateKey(jwk: JWK): EcPrivateKeyObj =
|
proc toEcPrivateKey(jwk: JWK): EcPrivateKeyObj =
|
||||||
## Convert an ECDSA private key in JWK format to the wrapper for BearSSL's
|
## Convert an ECDSA private key in JWK format to the wrapper for BearSSL's
|
||||||
@ -81,12 +80,12 @@ proc toEcPrivateKey(jwk: JWK): EcPrivateKeyObj =
|
|||||||
|
|
||||||
proc toEcPrivateKey(pem: string): EcPrivateKeyObj =
|
proc toEcPrivateKey(pem: string): EcPrivateKeyObj =
|
||||||
var skCtx: SkeyDecoderContext
|
var skCtx: SkeyDecoderContext
|
||||||
skeyDecoderInit(addr skCtx)
|
skeyDecoderInit(skCtx)
|
||||||
decodePem(pem, "EC PRIVATE KEY", addr skCtx,
|
decodePem(pem, "EC PRIVATE KEY", addr skCtx,
|
||||||
cast[BearPemDecoderCallback](skeyDecoderPush))
|
cast[BearPemDecoderCallback](skeyDecoderPush))
|
||||||
|
|
||||||
let k = skCtx.key.ec
|
let k = skCtx.key.ec
|
||||||
return initEcPrivateKeyObj(k.curve.fromBearSslCurveConst, $cstring(k.x))
|
return initEcPrivateKeyObj(k.curve.fromBearSslCurveConst, $cast[cstring](k.x))
|
||||||
|
|
||||||
proc getEcHashCfg(alg: JwtAlgorithm): HashCfg =
|
proc getEcHashCfg(alg: JwtAlgorithm): HashCfg =
|
||||||
let hashAlg = case alg:
|
let hashAlg = case alg:
|
||||||
@ -137,11 +136,11 @@ proc bearEcVerify(
|
|||||||
let ecVerifyImpl = ecdsaVrfyRawGetDefault()
|
let ecVerifyImpl = ecdsaVrfyRawGetDefault()
|
||||||
let resultCode = ecVerifyImpl(
|
let resultCode = ecVerifyImpl(
|
||||||
addr ecAllM15,
|
addr ecAllM15,
|
||||||
cast[ptr char](unsafeAddr hashed[0]),
|
hashed.cstring,
|
||||||
hashed.len,
|
uint hashed.len,
|
||||||
unsafeAddr key.bearKey,
|
unsafeAddr key.bearKey,
|
||||||
cast[ptr char](unsafeAddr signature[0]),
|
signature.cstring,
|
||||||
signature.len)
|
uint signature.len)
|
||||||
|
|
||||||
result = resultCode == 1
|
result = resultCode == 1
|
||||||
|
|
||||||
|
@ -66,5 +66,5 @@ proc hash*(data: string, alg: HashAlgorithm): string =
|
|||||||
let hashCfg = hashConfig(alg)
|
let hashCfg = hashConfig(alg)
|
||||||
result = newString(hashCfg.size)
|
result = newString(hashCfg.size)
|
||||||
hashCfg.vtable.init(pCtx)
|
hashCfg.vtable.init(pCtx)
|
||||||
hashCfg.vtable.update(pCtx, unsafeAddr data[0], data.len)
|
hashCfg.vtable.update(pCtx, data.cstring, uint data.len)
|
||||||
hashCfg.vtable.output(pCtx, addr result[0])
|
hashCfg.vtable.out(pCtx, addr result[0])
|
||||||
|
@ -26,13 +26,13 @@ proc bearHMAC(message: string, alg: JwtAlgorithm, key: string): string =
|
|||||||
var keyCtx: HmacKeyContext
|
var keyCtx: HmacKeyContext
|
||||||
var hmacCtx: HmacContext
|
var hmacCtx: HmacContext
|
||||||
|
|
||||||
hmacKeyInit(addr keyCtx, vtable, key.cstring, key.len)
|
hmacKeyInit(keyCtx, vtable, key.cstring, uint key.len)
|
||||||
hmacInit(addr hmacCtx, addr keyCtx, 0)
|
hmacInit(hmacCtx, keyCtx, uint 0)
|
||||||
hmacUpdate(addr hmacCtx, message.cstring, message.len)
|
hmacUpdate(hmacCtx, message.cstring, uint message.len)
|
||||||
|
|
||||||
let resLen = hmacSize(addr hmacCtx)
|
let resLen = hmacSize(hmacCtx)
|
||||||
result = newString(resLen)
|
result = newString(resLen)
|
||||||
discard hmacOut(addr hmacCtx, addr result[0])
|
discard hmacOut(hmacCtx, addr result[0])
|
||||||
|
|
||||||
proc hmac*(message: string, alg: JwtAlgorithm, key: string): string =
|
proc hmac*(message: string, alg: JwtAlgorithm, key: string): string =
|
||||||
return bearHMAC(message, alg, key)
|
return bearHMAC(message, alg, key)
|
||||||
|
@ -3,7 +3,7 @@ import bearssl
|
|||||||
# Taken from nim-bearssl/decls.nim
|
# Taken from nim-bearssl/decls.nim
|
||||||
{.pragma: bearSslFunc, cdecl, gcsafe, noSideEffect, raises: [].}
|
{.pragma: bearSslFunc, cdecl, gcsafe, noSideEffect, raises: [].}
|
||||||
|
|
||||||
type BearPemDecoderCallback* = proc(keyCtx: pointer, data: pointer, dataLen: int) {.bearSslFunc.}
|
type BearPemDecoderCallback* = proc(destCtx: pointer, src: pointer, dataLen: uint) {.bearSslFunc.}
|
||||||
|
|
||||||
proc decodePem*(
|
proc decodePem*(
|
||||||
pem: string,
|
pem: string,
|
||||||
@ -13,30 +13,30 @@ proc decodePem*(
|
|||||||
) =
|
) =
|
||||||
|
|
||||||
var pemCtx: PemDecoderContext
|
var pemCtx: PemDecoderContext
|
||||||
pemDecoderInit(addr pemCtx)
|
pemDecoderInit(pemCtx)
|
||||||
|
|
||||||
var offset = 0
|
var offset: uint = 0
|
||||||
var bytesRemaining = len(pem)
|
var bytesRemaining: uint = uint len(pem)
|
||||||
var readingObj = false
|
var readingObj = false
|
||||||
|
|
||||||
while bytesRemaining > 0:
|
while bytesRemaining > 0:
|
||||||
let bytesRead = pemDecoderPush(addr pemCtx, unsafeAddr pem[offset], bytesRemaining)
|
let bytesRead = pemDecoderPush(pemCtx, unsafeAddr pem[offset], uint bytesRemaining)
|
||||||
offset += bytesRead
|
offset += bytesRead
|
||||||
bytesRemaining -= bytesRead
|
bytesRemaining -= bytesRead
|
||||||
|
|
||||||
case pemDecoderEvent(addr pemCtx):
|
case pemDecoderEvent(pemCtx):
|
||||||
of PEM_BEGIN_OBJ:
|
of PEM_BEGIN_OBJ:
|
||||||
if readingObj:
|
if readingObj:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Invalid PEM: saw a second BEGIN before seeing END.")
|
"Invalid PEM: saw a second BEGIN before seeing END.")
|
||||||
|
|
||||||
if pemDecoderName(addr pemCtx) != expectedObjectName:
|
if pemDecoderName(pemCtx) != expectedObjectName:
|
||||||
raise newException(ValueError,
|
raise newException(ValueError,
|
||||||
"Invalid PEM: expected BEGIN " & expectedObjectName &
|
"Invalid PEM: expected BEGIN " & expectedObjectName &
|
||||||
" but got BEGIN " & $pemDecoderName(addr pemCtx))
|
" but got BEGIN " & $pemDecoderName(pemCtx))
|
||||||
|
|
||||||
readingObj = true
|
readingObj = true
|
||||||
pemDecoderSetdest(addr pemCtx, callback, keyCtx)
|
pemDecoderSetdest(pemCtx, callback, keyCtx)
|
||||||
|
|
||||||
of PEM_END_OBJ:
|
of PEM_END_OBJ:
|
||||||
if readingObj: readingObj = false
|
if readingObj: readingObj = false
|
||||||
|
@ -19,24 +19,24 @@ type
|
|||||||
|
|
||||||
func initRsaPublicKeyObj(n, e: string): RsaPublicKeyObj =
|
func initRsaPublicKeyObj(n, e: string): RsaPublicKeyObj =
|
||||||
result = RsaPublicKeyObj(n: n, e: e)
|
result = RsaPublicKeyObj(n: n, e: e)
|
||||||
result.bearKey.n = cast[ptr char](result.n.cstring)
|
result.bearKey.n = cast[ptr byte](result.n.cstring)
|
||||||
result.bearKey.nlen = result.n.len
|
result.bearKey.nlen = uint result.n.len
|
||||||
result.bearKey.e = cast[ptr char](result.e.cstring)
|
result.bearKey.e = cast[ptr byte](result.e.cstring)
|
||||||
result.bearKey.elen = result.e.len
|
result.bearKey.elen = uint result.e.len
|
||||||
|
|
||||||
func initRsaPrivateKeyObj(nBitLen: int, p, q, dp, dq, iq: string): RsaPrivateKeyObj =
|
func initRsaPrivateKeyObj(nBitLen: int, p, q, dp, dq, iq: string): RsaPrivateKeyObj =
|
||||||
result = RsaPrivateKeyObj(p: p, q: q, dp: dp, dq: dq, iq: iq)
|
result = RsaPrivateKeyObj(p: p, q: q, dp: dp, dq: dq, iq: iq)
|
||||||
result.bearKey.nBitLen = cast[uint32](nBitLen)
|
result.bearKey.nBitLen = cast[uint32](nBitLen)
|
||||||
result.bearKey.p = cast[ptr char](result.p.cstring)
|
result.bearKey.p = cast[ptr byte](result.p.cstring)
|
||||||
result.bearKey.plen = result.p.len
|
result.bearKey.plen = uint result.p.len
|
||||||
result.bearKey.q = cast[ptr char](result.q.cstring)
|
result.bearKey.q = cast[ptr byte](result.q.cstring)
|
||||||
result.bearKey.qlen = result.q.len
|
result.bearKey.qlen = uint result.q.len
|
||||||
result.bearKey.dp = cast[ptr char](result.dp.cstring)
|
result.bearKey.dp = cast[ptr byte](result.dp.cstring)
|
||||||
result.bearKey.dplen = result.dp.len
|
result.bearKey.dplen = uint result.dp.len
|
||||||
result.bearKey.dq = cast[ptr char](result.dq.cstring)
|
result.bearKey.dq = cast[ptr byte](result.dq.cstring)
|
||||||
result.bearKey.dqlen = result.dq.len
|
result.bearKey.dqlen = uint result.dq.len
|
||||||
result.bearKey.iq = cast[ptr char](result.iq.cstring)
|
result.bearKey.iq = cast[ptr byte](result.iq.cstring)
|
||||||
result.bearKey.iqlen = result.iq.len
|
result.bearKey.iqlen = uint result.iq.len
|
||||||
|
|
||||||
proc toRsaPublicKey(jwk: JWK): RsaPublicKeyObj =
|
proc toRsaPublicKey(jwk: JWK): RsaPublicKeyObj =
|
||||||
## Convert an RSA public key in JWK format to the wrapper for BearSSL's
|
## Convert an RSA public key in JWK format to the wrapper for BearSSL's
|
||||||
@ -60,7 +60,7 @@ proc toRsaPublicKey(pem: string): RsaPublicKeyObj =
|
|||||||
cast[BearPemDecoderCallback](pkeyDecoderPush))
|
cast[BearPemDecoderCallback](pkeyDecoderPush))
|
||||||
|
|
||||||
let k = pkCtx.key.rsa
|
let k = pkCtx.key.rsa
|
||||||
return initRsaPublicKeyObj($cstring(k.n), $cstring(k.e))
|
return initRsaPublicKeyObj($cast[cstring](k.n), $cast[cstring](k.e))
|
||||||
|
|
||||||
|
|
||||||
proc toRsaPrivateKey(jwk: JWK): RsaPrivateKeyObj =
|
proc toRsaPrivateKey(jwk: JWK): RsaPrivateKeyObj =
|
||||||
@ -111,7 +111,7 @@ proc toRsaPrivateKey(jwk: JWK): RsaPrivateKeyObj =
|
|||||||
|
|
||||||
proc toRsaPrivateKey(pem: string): RsaPrivateKeyObj =
|
proc toRsaPrivateKey(pem: string): RsaPrivateKeyObj =
|
||||||
var skCtx: SkeyDecoderContext
|
var skCtx: SkeyDecoderContext
|
||||||
skeyDecoderInit(addr skCtx)
|
skeyDecoderInit(skCtx)
|
||||||
decodePem(pem, "RSA PRIVATE KEY", addr skCtx,
|
decodePem(pem, "RSA PRIVATE KEY", addr skCtx,
|
||||||
cast[BearPemDecoderCallback](skeyDecoderPush))
|
cast[BearPemDecoderCallback](skeyDecoderPush))
|
||||||
|
|
||||||
@ -119,11 +119,11 @@ proc toRsaPrivateKey(pem: string): RsaPrivateKeyObj =
|
|||||||
|
|
||||||
return initRsaPrivateKeyObj(
|
return initRsaPrivateKeyObj(
|
||||||
cast[int](k.nBitLen),
|
cast[int](k.nBitLen),
|
||||||
$cstring(k.p),
|
$cast[cstring](k.p),
|
||||||
$cstring(k.q),
|
$cast[cstring](k.q),
|
||||||
$cstring(k.dp),
|
$cast[cstring](k.dp),
|
||||||
$cstring(k.dq),
|
$cast[cstring](k.dq),
|
||||||
$cstring(k.iq))
|
$cast[cstring](k.iq))
|
||||||
|
|
||||||
proc getRsaHashCfg(alg: JwtAlgorithm): HashCfg =
|
proc getRsaHashCfg(alg: JwtAlgorithm): HashCfg =
|
||||||
let hashAlg = case alg:
|
let hashAlg = case alg:
|
||||||
@ -148,11 +148,11 @@ proc bearRsaSign(
|
|||||||
result = newString((key.bearKey.nBitLen + 7) div 8)
|
result = newString((key.bearKey.nBitLen + 7) div 8)
|
||||||
|
|
||||||
let errCode = rsaSignImpl(
|
let errCode = rsaSignImpl(
|
||||||
cast[ptr char](hashCfg.oid),
|
cast[ptr byte](hashCfg.oid),
|
||||||
cast[ptr char](unsafeAddr hashed[0]),
|
cast[ptr byte](unsafeAddr hashed[0]),
|
||||||
hashed.len,
|
uint hashed.len,
|
||||||
unsafeAddr key.bearKey,
|
unsafeAddr key.bearKey,
|
||||||
cast[ptr char](addr result[0]))
|
cast[ptr byte](addr result[0]))
|
||||||
|
|
||||||
if errCode != 1: raise newException(Exception, "RSA signature failed")
|
if errCode != 1: raise newException(Exception, "RSA signature failed")
|
||||||
|
|
||||||
@ -169,12 +169,12 @@ proc bearRsaVerify(
|
|||||||
var recoveredHash = newString(hashCfg.size)
|
var recoveredHash = newString(hashCfg.size)
|
||||||
|
|
||||||
let errCode = rsaVerifyImpl(
|
let errCode = rsaVerifyImpl(
|
||||||
cast[ptr char](unsafeAddr signature[0]),
|
cast[ptr byte](unsafeAddr signature[0]),
|
||||||
signature.len,
|
uint signature.len,
|
||||||
cast[ptr char](hashCfg.oid),
|
cast[ptr byte](hashCfg.oid),
|
||||||
hashed.len,
|
uint hashed.len,
|
||||||
unsafeAddr key.bearKey,
|
unsafeAddr key.bearKey,
|
||||||
cast[ptr char](addr recoveredHash[0]))
|
cast[ptr byte](addr recoveredHash[0]))
|
||||||
|
|
||||||
if errCode != 1: return false
|
if errCode != 1: return false
|
||||||
return hashed == recoveredHash
|
return hashed == recoveredHash
|
||||||
|
Loading…
x
Reference in New Issue
Block a user