diff --git a/bearssl/pem.nim b/bearssl/pem.nim index 37b7ffd..1ddd937 100644 --- a/bearssl/pem.nim +++ b/bearssl/pem.nim @@ -1,4 +1,45 @@ import + typetraits, ./abi/bearssl_pem export bearssl_pem + +func init*(v: var PemDecoderContext) = + # Careful, PemDecoderContext items are not copyable! + # TODO prevent copying + pemDecoderInit(v) + +func push*(ctx: var PemDecoderContext, data: openArray[byte|char]): int = + if data.len > 0: + let consumed = pemDecoderPush( + ctx, unsafeAddr data[0], uint data.len) + int(consumed) + else: + 0 + +func setdest*( + ctx: var PemDecoderContext; + dest: proc (destCtx: pointer; + src: pointer; len: uint) {.cdecl, gcsafe, noSideEffect, raises: [].}; + destCtx: pointer) = + pemDecoderSetdest(ctx, dest, destCtx) + +func lastEvent*(ctx: var PemDecoderContext): cint = + pemDecoderEvent(ctx) + +func banner*(ctx: PemDecoderContext): string = + ## Return the `name` field as a string + if ctx.name[ctx.name.high] == char(0): + $(unsafeAddr ctx.name) + else: + var res = newString(ctx.name.len) + for i, c in ctx.name: res[i] = ctx.name[i] + res + +func pemEncode*( + data: openArray[byte|char], banner: cstring, flags: cuint = 0): string = + let bytes = pemEncode(nil, nil, uint data.len, banner, flags) + result.setLen(int bytes + 1) + discard pemEncode( + addr result[0], unsafeAddr data[0], uint data.len, banner, flags) + result.setLen(int bytes) diff --git a/tests/test_pem.nim b/tests/test_pem.nim new file mode 100644 index 0000000..c68734f --- /dev/null +++ b/tests/test_pem.nim @@ -0,0 +1,32 @@ +import + unittest2, + ../bearssl/pem + +suite "PEM": + test "roundtrip": + let + data = [byte 0, 1, 2, 3] + pem = pemEncode(data, "") + + var + ctx: PemDecoderContext + called = false + + ctx.init() + + proc test(dctx: pointer, data: pointer, len: uint) {.cdecl.} = + cast[ptr bool](dctx)[] = true + + ctx.setdest(test, addr called) + + var read = 0 + while read < pem.len: + let + consumed = ctx.push(pem.toOpenArray(read, pem.high)) + read += consumed + if read < pem.len: + check: ctx.lastEvent > 0 + + check: + pem.len > data.len + called