Update to track current version of bearssl.

This commit is contained in:
Jonathan Bernard 2023-02-03 20:38:33 -06:00
parent 0870073f08
commit ac61d90585
7 changed files with 59 additions and 60 deletions

View File

@ -1,6 +1,6 @@
# Package # Package
version = "0.1.0" version = "0.2.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"

View File

@ -1,5 +1,5 @@
# jwt_full/jwt.nim # jwt_full/jwt.nim
# Copyright 2021 Jonathan Bernard # Copyright © 2021 Jonathan Bernard
## =============================== ## ===============================
## jwt ## jwt

View File

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

View File

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

View File

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

View File

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

View File

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