Give JWK independent value semantics for thread-safe copies
This commit is contained in:
1 parent
47393ec84f
commit
d037c84e8c
8 files changed
+220
-9
No files matched your search
@@ -11,7 +11,7 @@
|
||||
##
|
||||
## Nim implementation of the data structures and constants defined in RFC 7518.
|
||||
|
||||
import std/json, std/options, std/sequtils, std/strutils
|
||||
import std/json, std/options, std/sequtils, std/strutils, std/tables
|
||||
|
||||
import ./jwa
|
||||
import ./private/jsonutils
|
||||
@@ -56,7 +56,12 @@ type
|
||||
k*: string
|
||||
|
||||
JWK* = object
|
||||
json: JsonNode
|
||||
## Owns its key material and metadata with value semantics. Copies may be
|
||||
## handed to separate threads; synchronize access to a source being mutated.
|
||||
## JSON member access returns a fresh node, independent of the key.
|
||||
jsonMembers: Table[string, string]
|
||||
# Keep arbitrary JSON members as encoded values, without JsonNode refs.
|
||||
# Cryptographic operations use the parsed fields below, without decoding.
|
||||
kty: string
|
||||
use: Option[string]
|
||||
key_ops: Option[string]
|
||||
@@ -96,8 +101,18 @@ func rsaPrv*(jwk: JWK): RsaPrvKey = jwk.rsaPrv
|
||||
func octKey*(jwk: JWK): OctetKey = jwk.octKey
|
||||
|
||||
func `[]`*(jwk: JWK, key: string): Option[JsonNode] =
|
||||
if jwk.json.hasKey(key): some(jwk.json[key])
|
||||
else: none[JsonNode]()
|
||||
## Return an independent JSON value for a member, or none if it is absent.
|
||||
if jwk.jsonMembers.hasKey(key):
|
||||
# The string parser only touches a newly allocated in-memory stream, but
|
||||
# its stream-based implementation is not annotated noSideEffect in std/json.
|
||||
{.cast(noSideEffect).}:
|
||||
result = some(parseJson(jwk.jsonMembers[key]))
|
||||
|
||||
func `%`*(jwk: JWK): JsonNode =
|
||||
## Serialize the key and its extension members to an independent JSON object.
|
||||
result = newJObject()
|
||||
for name in jwk.jsonMembers.keys:
|
||||
result[name] = jwk[name].get
|
||||
|
||||
# Public Parsing Functions
|
||||
# ------------------------
|
||||
@@ -143,7 +158,9 @@ func parseOctetKey*(n: JsonNode): OctetKey =
|
||||
OctetKey(k: n.reqStrVal("k"))
|
||||
|
||||
func initJwk*(n: JsonNode): JWK =
|
||||
# TODO: documentation, example, handle encrypted keys (JWEs)
|
||||
## Parse an owned snapshot of a key, including its extension metadata.
|
||||
## Later changes to n or to nodes returned by [] do not affect the key.
|
||||
# TODO: example, handle encrypted keys (JWEs)
|
||||
case n["kty"].getStr(""):
|
||||
|
||||
of $ktyEC:
|
||||
@@ -179,7 +196,8 @@ func initJwk*(n: JsonNode): JWK =
|
||||
else: raise newException(ValueError,
|
||||
"Unrecognized or missing kty: '" & n["kty"].getStr("") & "'")
|
||||
|
||||
result.json = n
|
||||
for name, value in n.pairs:
|
||||
result.jsonMembers[name] = $value
|
||||
result.use = n.optStrVal("use")
|
||||
result.key_ops = n.optStrVal("key_ops")
|
||||
result.alg = n.optStrVal("alg")
|
||||
|
||||
Reference in new issue
Block a user