Use Result construct in minasn1 (#144)

This commit is contained in:
Giovanni Petrantoni 2020-04-23 21:10:20 +09:00 committed by GitHub
parent 6ae92eb21a
commit 1c4d72f5e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 240 additions and 272 deletions

View File

@ -12,6 +12,8 @@ import rsa, ecnist, ed25519/ed25519, secp
import ../protobuf/minprotobuf, ../vbuffer, ../multihash, ../multicodec
import nimcrypto/[rijndael, blowfish, twofish, sha, sha2, hash, hmac, utils]
import ../utility
import stew/results
export results
# This is workaround for Nim's `import` bug
export rijndael, blowfish, twofish, sha, sha2, hash, hmac, utils
@ -263,7 +265,7 @@ proc init*(key: var PrivateKey, data: openarray[byte]): bool =
var scheme = cast[PKScheme](cast[int8](id))
var nkey = PrivateKey(scheme: scheme)
if scheme == RSA:
if init(nkey.rsakey, buffer) == Asn1Status.Success:
if init(nkey.rsakey, buffer).isOk:
key = nkey
result = true
elif scheme == Ed25519:
@ -271,7 +273,7 @@ proc init*(key: var PrivateKey, data: openarray[byte]): bool =
key = nkey
result = true
elif scheme == ECDSA:
if init(nkey.eckey, buffer) == Asn1Status.Success:
if init(nkey.eckey, buffer).isOk:
key = nkey
result = true
elif scheme == Secp256k1:
@ -294,7 +296,7 @@ proc init*(key: var PublicKey, data: openarray[byte]): bool =
var scheme = cast[PKScheme](cast[int8](id))
var nkey = PublicKey(scheme: scheme)
if scheme == RSA:
if init(nkey.rsakey, buffer) == Asn1Status.Success:
if init(nkey.rsakey, buffer).isOk:
key = nkey
result = true
elif scheme == Ed25519:
@ -302,7 +304,7 @@ proc init*(key: var PublicKey, data: openarray[byte]): bool =
key = nkey
result = true
elif scheme == ECDSA:
if init(nkey.eckey, buffer) == Asn1Status.Success:
if init(nkey.eckey, buffer).isOk:
key = nkey
result = true
elif scheme == Secp256k1:
@ -484,7 +486,7 @@ proc verify*(sig: Signature, message: openarray[byte],
## Return ``true`` if message signature is valid.
if key.scheme == RSA:
var signature: RsaSignature
if signature.init(sig.data) == Asn1Status.Success:
if signature.init(sig.data).isOk:
result = signature.verify(message, key.rsakey)
elif key.scheme == Ed25519:
var signature: EdSignature
@ -492,7 +494,7 @@ proc verify*(sig: Signature, message: openarray[byte],
result = signature.verify(message, key.edkey)
elif key.scheme == ECDSA:
var signature: EcSignature
if signature.init(sig.data) == Asn1Status.Success:
if signature.init(sig.data).isOk:
result = signature.verify(message, key.eckey)
elif key.scheme == Secp256k1:
var signature: SkSignature

View File

@ -17,7 +17,9 @@
import bearssl
import nimcrypto/utils
import minasn1
export minasn1.Asn1Status
export minasn1.Asn1Error
import stew/results
export results
const
PubKey256Length* = 65
@ -529,43 +531,39 @@ proc `==`*(sig1, sig2: EcSignature): bool =
else:
result = (sig1.buffer == sig2.buffer)
proc init*(key: var EcPrivateKey, data: openarray[byte]): Asn1Status =
proc init*(key: var EcPrivateKey, data: openarray[byte]): Result[void, Asn1Error] =
## Initialize EC `private key` or `signature` ``key`` from ASN.1 DER binary
## representation ``data``.
##
## Procedure returns ``Asn1Status``.
## Procedure returns ``Result[void, Asn1Error]``.
var raw, oid, field: Asn1Field
var curve: cint
var ab = Asn1Buffer.init(data)
result = ab.read(field)
if result != Asn1Status.Success:
return
field = ? ab.read()
if field.kind != Asn1Tag.Sequence:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
var ib = field.getBuffer()
result = ib.read(field)
if result != Asn1Status.Success:
return
field = ? ib.read()
if field.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
if field.vint != 1'u64:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
raw = ? ib.read()
result = ib.read(raw)
if result != Asn1Status.Success:
return
if raw.kind != Asn1Tag.OctetString:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
oid = ? ib.read()
result = ib.read(oid)
if result != Asn1Status.Success:
return
if oid.kind != Asn1Tag.Oid:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
if oid == Asn1OidSecp256r1:
curve = cast[cint](Secp256r1)
@ -574,7 +572,7 @@ proc init*(key: var EcPrivateKey, data: openarray[byte]): Asn1Status =
elif oid == Asn1OidSecp521r1:
curve = cast[cint](Secp521r1)
else:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
if checkScalar(raw.toOpenArray(), curve) == 1'u32:
key = new EcPrivateKey
@ -583,47 +581,44 @@ proc init*(key: var EcPrivateKey, data: openarray[byte]): Asn1Status =
key.key.x = cast[ptr cuchar](addr key.buffer[0])
key.key.xlen = raw.length
key.key.curve = curve
result = Asn1Status.Success
ok()
else:
result = Asn1Status.Incorrect
err(Asn1Error.Incorrect)
proc init*(pubkey: var EcPublicKey, data: openarray[byte]): Asn1Status =
proc init*(pubkey: var EcPublicKey, data: openarray[byte]): Result[void, Asn1Error] =
## Initialize EC public key ``pubkey`` from ASN.1 DER binary representation
## ``data``.
##
## Procedure returns ``Asn1Status``.
## Procedure returns ``Result[void, Asn1Error]``.
var raw, oid, field: Asn1Field
var curve: cint
var ab = Asn1Buffer.init(data)
result = ab.read(field)
if result != Asn1Status.Success:
return
field = ? ab.read()
if field.kind != Asn1Tag.Sequence:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
var ib = field.getBuffer()
result = ib.read(field)
if result != Asn1Status.Success:
return
field = ? ib.read()
if field.kind != Asn1Tag.Sequence:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
var ob = field.getBuffer()
result = ob.read(oid)
if result != Asn1Status.Success:
return
oid = ? ob.read()
if oid.kind != Asn1Tag.Oid:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
if oid != Asn1OidEcPublicKey:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
oid = ? ob.read()
result = ob.read(oid)
if result != Asn1Status.Success:
return
if oid.kind != Asn1Tag.Oid:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
if oid == Asn1OidSecp256r1:
curve = cast[cint](Secp256r1)
@ -632,13 +627,12 @@ proc init*(pubkey: var EcPublicKey, data: openarray[byte]): Asn1Status =
elif oid == Asn1OidSecp521r1:
curve = cast[cint](Secp521r1)
else:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
raw = ? ib.read()
result = ib.read(raw)
if result != Asn1Status.Success:
return
if raw.kind != Asn1Tag.BitString:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
if checkPublic(raw.toOpenArray(), curve) != 0:
pubkey = new EcPublicKey
@ -647,50 +641,51 @@ proc init*(pubkey: var EcPublicKey, data: openarray[byte]): Asn1Status =
pubkey.key.q = cast[ptr cuchar](addr pubkey.buffer[0])
pubkey.key.qlen = raw.length
pubkey.key.curve = curve
result = Asn1Status.Success
ok()
else:
result = Asn1Status.Incorrect
err(Asn1Error.Incorrect)
proc init*(sig: var EcSignature, data: openarray[byte]): Asn1Status =
proc init*(sig: var EcSignature, data: openarray[byte]): Result[void, Asn1Error] =
## Initialize EC signature ``sig`` from raw binary representation ``data``.
##
## Procedure returns ``Asn1Status``.
result = Asn1Status.Incorrect
## Procedure returns ``Result[void, Asn1Error]``.
if len(data) > 0:
sig = new EcSignature
sig.buffer = @data
result = Asn1Status.Success
ok()
else:
err(Asn1Error.Incorrect)
proc init*[T: EcPKI](sospk: var T, data: string): Asn1Status {.inline.} =
proc init*[T: EcPKI](sospk: var T, data: string): Result[void, Asn1Error] {.inline.} =
## Initialize EC `private key`, `public key` or `signature` ``sospk`` from
## ASN.1 DER hexadecimal string representation ``data``.
##
## Procedure returns ``Asn1Status``.
result = sospk.init(fromHex(data))
sospk.init(fromHex(data))
proc init*(t: typedesc[EcPrivateKey], data: openarray[byte]): EcPrivateKey =
## Initialize EC private key from ASN.1 DER binary representation ``data`` and
## return constructed object.
let res = result.init(data)
if res != Asn1Status.Success:
if res.isErr:
raise newException(EcKeyIncorrectError,
"Incorrect private key (" & $res & ")")
"Incorrect private key (" & $res.error & ")")
proc init*(t: typedesc[EcPublicKey], data: openarray[byte]): EcPublicKey =
## Initialize EC public key from ASN.1 DER binary representation ``data`` and
## return constructed object.
let res = result.init(data)
if res != Asn1Status.Success:
if res.isErr:
raise newException(EcKeyIncorrectError,
"Incorrect public key (" & $res & ")")
"Incorrect public key (" & $res.error & ")")
proc init*(t: typedesc[EcSignature], data: openarray[byte]): EcSignature =
## Initialize EC signature from raw binary representation ``data`` and
## return constructed object.
let res = result.init(data)
if res != Asn1Status.Success:
if res.isErr:
raise newException(EcKeyIncorrectError,
"Incorrect signature (" & $res & ")")
"Incorrect signature (" & $res.error & ")")
proc init*[T: EcPKI](t: typedesc[T], data: string): T {.inline.} =
## Initialize EC `private key`, `public key` or `signature` from hexadecimal

View File

@ -8,13 +8,17 @@
## those terms.
## This module implements minimal ASN.1 encoding/decoding primitives.
import stew/endians2
{.push raises: [Defect].}
import stew/[endians2, results]
export results
import nimcrypto/utils
type
Asn1Status* {.pure.} = enum
Asn1Error* {.pure.} = enum
None,
Error,
Success,
Overflow,
Incomplete,
Indefinite,
@ -22,6 +26,8 @@ type
NoSupport,
Overrun
Asn1Result*[T] = Result[T, Asn1Error]
Asn1Class* {.pure.} = enum
Universal = 0x00,
Application = 0x01
@ -406,54 +412,51 @@ proc asn1EncodeContextTag*(dest: var openarray[byte], value: openarray[byte],
copyMem(addr dest[1], addr buffer[0], lenlen)
copyMem(addr dest[1 + lenlen], unsafeAddr value[0], len(value))
proc getLength(ab: var Asn1Buffer, length: var uint64): Asn1Status =
proc getLength(ab: var Asn1Buffer): Asn1Result[uint64] =
## Decode length part of ASN.1 TLV triplet.
result = Asn1Status.Incomplete
if not ab.isEmpty():
let b = ab.buffer[ab.offset]
if (b and 0x80'u8) == 0x00'u8:
length = cast[uint64](b)
let length = cast[uint64](b)
ab.offset += 1
result = Asn1Status.Success
return
return ok(length)
if b == 0x80'u8:
length = 0'u64
result = Asn1Status.Indefinite
return
return err(Asn1Error.Indefinite)
if b == 0xFF'u8:
length = 0'u64
result = Asn1Status.Incorrect
return
return err(Asn1Error.Incorrect)
let octets = cast[uint64](b and 0x7F'u8)
if octets > 8'u64:
length = 0'u64
result = Asn1Status.Overflow
return
length = 0'u64
return err(Asn1Error.Overflow)
if ab.isEnough(int(octets)):
var length: uint64 = 0
for i in 0..<int(octets):
length = (length shl 8) or cast[uint64](ab.buffer[ab.offset + i + 1])
ab.offset = ab.offset + int(octets) + 1
result = Asn1Status.Success
proc getTag(ab: var Asn1Buffer, tag: var int,
klass: var Asn1Class): Asn1Status =
## Decode tag part of ASN.1 TLV triplet.
result = Asn1Status.Incomplete
if not ab.isEmpty():
let b = ab.buffer[ab.offset]
var c = int((b and 0xC0'u8) shr 6)
if c >= 0 and c < 4:
klass = cast[Asn1Class](c)
return ok(length)
else:
return Asn1Status.Incorrect
return err(Asn1Error.Incomplete)
else:
return err(Asn1Error.Incomplete)
proc getTag(ab: var Asn1Buffer, tag: var int): Asn1Result[Asn1Class] =
## Decode tag part of ASN.1 TLV triplet.
if not ab.isEmpty():
let
b = ab.buffer[ab.offset]
c = int((b and 0xC0'u8) shr 6)
tag = int(b and 0x3F)
ab.offset += 1
result = Asn1Status.Success
if c >= 0 and c < 4:
ok(cast[Asn1Class](c))
else:
err(Asn1Error.Incorrect)
else:
err(Asn1Error.Incomplete)
proc read*(ab: var Asn1Buffer, field: var Asn1Field): Asn1Status =
proc read*(ab: var Asn1Buffer): Asn1Result[Asn1Field] =
## Decode value part of ASN.1 TLV triplet.
var
field: Asn1Field
tag, ttag, offset: int
length, tlength: uint64
klass: Asn1Class
@ -462,55 +465,44 @@ proc read*(ab: var Asn1Buffer, field: var Asn1Field): Asn1Status =
inclass = false
while true:
offset = ab.offset
result = ab.getTag(tag, klass)
if result != Asn1Status.Success:
break
klass = ? ab.getTag(tag)
if klass == Asn1Class.ContextSpecific:
if inclass:
result = Asn1Status.Incorrect
break
return err(Asn1Error.Incorrect)
inclass = true
ttag = tag
result = ab.getLength(tlength)
if result != Asn1Status.Success:
break
tlength = ? ab.getLength()
elif klass == Asn1Class.Universal:
result = ab.getLength(length)
if result != Asn1Status.Success:
break
length = ? ab.getLength()
if inclass:
if length >= tlength:
result = Asn1Status.Incorrect
break
return err(Asn1Error.Incorrect)
if cast[byte](tag) == Asn1Tag.Boolean.code():
# BOOLEAN
if length != 1:
result = Asn1Status.Incorrect
break
return err(Asn1Error.Incorrect)
if not ab.isEnough(cast[int](length)):
result = Asn1Status.Incomplete
break
return err(Asn1Error.Incomplete)
let b = ab.buffer[ab.offset]
if b != 0xFF'u8 and b != 0x00'u8:
result = Asn1Status.Incorrect
break
return err(Asn1Error.Incorrect)
field = Asn1Field(kind: Asn1Tag.Boolean, klass: klass,
index: ttag, offset: cast[int](ab.offset),
length: 1)
shallowCopy(field.buffer, ab.buffer)
field.vbool = (b == 0xFF'u8)
ab.offset += 1
result = Asn1Status.Success
break
return ok(field)
elif cast[byte](tag) == Asn1Tag.Integer.code():
# INTEGER
if not ab.isEnough(cast[int](length)):
result = Asn1Status.Incomplete
break
return err(Asn1Error.Incomplete)
if ab.buffer[ab.offset] == 0x00'u8:
length -= 1
ab.offset += 1
@ -523,77 +515,64 @@ proc read*(ab: var Asn1Buffer, field: var Asn1Field): Asn1Status =
field.vint = (field.vint shl 8) or
cast[uint64](ab.buffer[ab.offset + i])
ab.offset += cast[int](length)
result = Asn1Status.Success
break
return ok(field)
elif cast[byte](tag) == Asn1Tag.BitString.code():
# BIT STRING
if not ab.isEnough(cast[int](length)):
result = Asn1Status.Incomplete
break
return err(Asn1Error.Incomplete)
field = Asn1Field(kind: Asn1Tag.BitString, klass: klass,
index: ttag, offset: cast[int](ab.offset + 1),
length: cast[int](length - 1))
shallowCopy(field.buffer, ab.buffer)
field.ubits = cast[int](((length - 1) shl 3) - ab.buffer[ab.offset])
ab.offset += cast[int](length)
result = Asn1Status.Success
break
return ok(field)
elif cast[byte](tag) == Asn1Tag.OctetString.code():
# OCT STRING
if not ab.isEnough(cast[int](length)):
result = Asn1Status.Incomplete
break
return err(Asn1Error.Incomplete)
field = Asn1Field(kind: Asn1Tag.OctetString, klass: klass,
index: ttag, offset: cast[int](ab.offset),
length: cast[int](length))
shallowCopy(field.buffer, ab.buffer)
ab.offset += cast[int](length)
result = Asn1Status.Success
break
return ok(field)
elif cast[byte](tag) == Asn1Tag.Null.code():
# NULL
if length != 0:
result = Asn1Status.Incorrect
break
return err(Asn1Error.Incorrect)
field = Asn1Field(kind: Asn1Tag.Null, klass: klass,
index: ttag, offset: cast[int](ab.offset),
length: 0)
shallowCopy(field.buffer, ab.buffer)
ab.offset += cast[int](length)
result = Asn1Status.Success
break
return ok(field)
elif cast[byte](tag) == Asn1Tag.Oid.code():
# OID
if not ab.isEnough(cast[int](length)):
result = Asn1Status.Incomplete
break
return err(Asn1Error.Incomplete)
field = Asn1Field(kind: Asn1Tag.Oid, klass: klass,
index: ttag, offset: cast[int](ab.offset),
length: cast[int](length))
shallowCopy(field.buffer, ab.buffer)
ab.offset += cast[int](length)
result = Asn1Status.Success
break
return ok(field)
elif cast[byte](tag) == Asn1Tag.Sequence.code():
# SEQUENCE
if not ab.isEnough(cast[int](length)):
result = Asn1Status.Incomplete
break
return err(Asn1Error.Incomplete)
field = Asn1Field(kind: Asn1Tag.Sequence, klass: klass,
index: ttag, offset: cast[int](ab.offset),
length: cast[int](length))
shallowCopy(field.buffer, ab.buffer)
ab.offset += cast[int](length)
result = Asn1Status.Success
break
return ok(field)
else:
result = Asn1Status.NoSupport
break
return err(Asn1Error.NoSupport)
inclass = false
ttag = 0
else:
result = Asn1Status.NoSupport
break
return err(Asn1Error.NoSupport)
proc getBuffer*(field: Asn1Field): Asn1Buffer =
## Return ``field`` as Asn1Buffer to enter composite types.

View File

@ -15,7 +15,9 @@
import nimcrypto/utils
import bearssl
import minasn1
export Asn1Status
export Asn1Error
import stew/results
export results
const
DefaultPublicExponent* = 3'u32
@ -379,7 +381,7 @@ proc getBytes*(sig: RsaSignature): seq[byte] =
else:
raise newException(RsaSignatureError, "Incorrect signature")
proc init*(key: var RsaPrivateKey, data: openarray[byte]): Asn1Status =
proc init*(key: var RsaPrivateKey, data: openarray[byte]): Result[void, Asn1Error] =
## Initialize RSA private key ``key`` from ASN.1 DER binary representation
## ``data``.
##
@ -387,71 +389,63 @@ proc init*(key: var RsaPrivateKey, data: openarray[byte]): Asn1Status =
var
field, rawn, rawpube, rawprie, rawp, rawq, rawdp, rawdq, rawiq: Asn1Field
# Asn1Field is not trivial so avoid too much Result
var ab = Asn1Buffer.init(data)
result = ab.read(field)
if result != Asn1Status.Success:
return
field = ? ab.read()
if field.kind != Asn1Tag.Sequence:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
var ib = field.getBuffer()
result = ib.read(field)
if result != Asn1Status.Success:
return
field = ? ib.read()
if field.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
if field.vint != 0'u64:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
rawn = ? ib.read()
result = ib.read(rawn)
if result != Asn1Status.Success:
return
if rawn.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
rawpube = ? ib.read()
result = ib.read(rawpube)
if result != Asn1Status.Success:
return
if rawpube.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
rawprie = ? ib.read()
result = ib.read(rawprie)
if result != Asn1Status.Success:
return
if rawprie.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
rawp = ? ib.read()
result = ib.read(rawp)
if result != Asn1Status.Success:
return
if rawp.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
rawq = ? ib.read()
result = ib.read(rawq)
if result != Asn1Status.Success:
return
if rawq.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
rawdp = ? ib.read()
result = ib.read(rawdp)
if result != Asn1Status.Success:
return
if rawdp.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
rawdq = ? ib.read()
result = ib.read(rawdq)
if result != Asn1Status.Success:
return
if rawdq.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
rawiq = ? ib.read()
result = ib.read(rawiq)
if result != Asn1Status.Success:
return
if rawiq.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
if len(rawn) >= (MinKeySize shr 3) and len(rawp) > 0 and len(rawq) > 0 and
len(rawdp) > 0 and len(rawdq) > 0 and len(rawiq) > 0:
@ -474,11 +468,11 @@ proc init*(key: var RsaPrivateKey, data: openarray[byte]): Asn1Status =
key.seck.iqlen = len(rawiq)
key.pexplen = len(rawprie)
key.seck.nBitlen = cast[uint32](len(rawn) shl 3)
result = Asn1Status.Success
ok()
else:
result = Asn1Status.Incorrect
err(Asn1Error.Incorrect)
proc init*(key: var RsaPublicKey, data: openarray[byte]): Asn1Status =
proc init*(key: var RsaPublicKey, data: openarray[byte]): Result[void, Asn1Error] =
## Initialize RSA public key ``key`` from ASN.1 DER binary representation
## ``data``.
##
@ -486,59 +480,55 @@ proc init*(key: var RsaPublicKey, data: openarray[byte]): Asn1Status =
var field, rawn, rawe: Asn1Field
var ab = Asn1Buffer.init(data)
result = ab.read(field)
if result != Asn1Status.Success:
return
field = ? ab.read()
if field.kind != Asn1Tag.Sequence:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
var ib = field.getBuffer()
result = ib.read(field)
if result != Asn1Status.Success:
return
field = ? ib.read()
if field.kind != Asn1Tag.Sequence:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
var ob = field.getBuffer()
result = ob.read(field)
if result != Asn1Status.Success:
return
field = ? ob.read()
if field.kind != Asn1Tag.Oid:
return Asn1Status.Incorrect
if field != Asn1OidRsaEncryption:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
elif field != Asn1OidRsaEncryption:
return err(Asn1Error.Incorrect)
field = ? ob.read()
result = ob.read(field)
if result != Asn1Status.Success:
return
if field.kind != Asn1Tag.Null:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
field = ? ib.read()
result = ib.read(field)
if result != Asn1Status.Success:
return
if field.kind != Asn1Tag.BitString:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
var vb = field.getBuffer()
result = vb.read(field)
if result != Asn1Status.Success:
return
field = ? vb.read()
if field.kind != Asn1Tag.Sequence:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
var sb = field.getBuffer()
result = sb.read(rawn)
if result != Asn1Status.Success:
return
if rawn.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
rawn = ? sb.read()
result = sb.read(rawe)
if result != Asn1Status.Success:
return
if rawn.kind != Asn1Tag.Integer:
return Asn1Status.Incorrect
return err(Asn1Error.Incorrect)
rawe = ? sb.read()
if rawe.kind != Asn1Tag.Integer:
return err(Asn1Error.Incorrect)
if len(rawn) >= (MinKeySize shr 3) and len(rawe) > 0:
key = new RsaPublicKey
@ -547,51 +537,52 @@ proc init*(key: var RsaPublicKey, data: openarray[byte]): Asn1Status =
key.key.e = cast[ptr cuchar](addr key.buffer[rawe.offset])
key.key.nlen = len(rawn)
key.key.elen = len(rawe)
result = Asn1Status.Success
ok()
else:
result = Asn1Status.Incorrect
err(Asn1Error.Incorrect)
proc init*(sig: var RsaSignature, data: openarray[byte]): Asn1Status =
proc init*(sig: var RsaSignature, data: openarray[byte]): Result[void, Asn1Error] =
## Initialize RSA signature ``sig`` from ASN.1 DER binary representation
## ``data``.
##
## Procedure returns ``Asn1Status``.
result = Asn1Status.Incorrect
## Procedure returns ``Result[void, Asn1Status]``.
if len(data) > 0:
sig = new RsaSignature
sig.buffer = @data
result = Asn1Status.Success
ok()
else:
err(Asn1Error.Incorrect)
proc init*[T: RsaPKI](sospk: var T, data: string): Asn1Status {.inline.} =
proc init*[T: RsaPKI](sospk: var T, data: string): Result[void, Asn1Error] {.inline.} =
## Initialize EC `private key`, `public key` or `scalar` ``sospk`` from
## hexadecimal string representation ``data``.
##
## Procedure returns ``Asn1Status``.
result = sospk.init(fromHex(data))
## Procedure returns ``Result[void, Asn1Status]``.
sospk.init(fromHex(data))
proc init*(t: typedesc[RsaPrivateKey], data: openarray[byte]): RsaPrivateKey =
## Initialize RSA private key from ASN.1 DER binary representation ``data``
## and return constructed object.
let res = result.init(data)
if res != Asn1Status.Success:
if res.isErr:
raise newException(RsaKeyIncorrectError,
"Incorrect private key (" & $res & ")")
"Incorrect private key (" & $res.error & ")")
proc init*(t: typedesc[RsaPublicKey], data: openarray[byte]): RsaPublicKey =
## Initialize RSA public key from ASN.1 DER binary representation ``data``
## and return constructed object.
let res = result.init(data)
if res != Asn1Status.Success:
if res.isErr:
raise newException(RsaKeyIncorrectError,
"Incorrect public key (" & $res & ")")
"Incorrect public key (" & $res.error & ")")
proc init*(t: typedesc[RsaSignature], data: openarray[byte]): RsaSignature =
## Initialize RSA signature from raw binary representation ``data`` and
## return constructed object.
let res = result.init(data)
if res != Asn1Status.Success:
if res.isErr:
raise newException(RsaKeyIncorrectError,
"Incorrect signature (" & $res & ")")
"Incorrect signature (" & $res.error & ")")
proc init*[T: RsaPKI](t: typedesc[T], data: string): T {.inline.} =
## Initialize RSA `private key`, `public key` or `signature` from hexadecimal

View File

@ -9,6 +9,7 @@
import unittest
import nimcrypto/utils
import ../libp2p/crypto/ecnist
import stew/results
when defined(nimHasUsed): {.used.}
@ -304,8 +305,8 @@ suite "EC NIST-P256/384/521 test suite":
check:
key.toBytes(skey2) > 0
check:
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPrivateKey.init(skey1)
var rkey4 = EcPrivateKey.init(skey2)
check:
@ -322,8 +323,8 @@ suite "EC NIST-P256/384/521 test suite":
var skey1 = pair.pubkey.getBytes()
check:
pair.pubkey.toBytes(skey2) > 0
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPublicKey.init(skey1)
var rkey4 = EcPublicKey.init(skey2)
check:
@ -411,8 +412,8 @@ suite "EC NIST-P256/384/521 test suite":
check:
key.toBytes(skey2) > 0
check:
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPrivateKey.init(skey1)
var rkey4 = EcPrivateKey.init(skey2)
check:
@ -429,8 +430,8 @@ suite "EC NIST-P256/384/521 test suite":
var skey1 = pair.pubkey.getBytes()
check:
pair.pubkey.toBytes(skey2) > 0
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPublicKey.init(skey1)
var rkey4 = EcPublicKey.init(skey2)
check:
@ -518,8 +519,8 @@ suite "EC NIST-P256/384/521 test suite":
check:
key.toBytes(skey2) > 0
check:
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPrivateKey.init(skey1)
var rkey4 = EcPrivateKey.init(skey2)
check:
@ -536,8 +537,8 @@ suite "EC NIST-P256/384/521 test suite":
var skey1 = pair.pubkey.getBytes()
check:
pair.pubkey.toBytes(skey2) > 0
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk
rkey2.init(skey2).isOk
var rkey3 = EcPublicKey.init(skey1)
var rkey4 = EcPublicKey.init(skey2)
check:

View File

@ -277,8 +277,8 @@ suite "RSA 512/1024/2048/4096 test suite":
var skey1 = key.getBytes()
check key.toBytes(skey2) > 0
check:
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPrivateKey.init(skey1)
var rkey4 = RsaPrivateKey.init(skey2)
check:
@ -295,8 +295,8 @@ suite "RSA 512/1024/2048/4096 test suite":
var skey1 = key.getBytes()
check key.toBytes(skey2) > 0
check:
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPrivateKey.init(skey1)
var rkey4 = RsaPrivateKey.init(skey2)
check:
@ -312,8 +312,8 @@ suite "RSA 512/1024/2048/4096 test suite":
var skey1 = key.getBytes()
check key.toBytes(skey2) > 0
check:
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPrivateKey.init(skey1)
var rkey4 = RsaPrivateKey.init(skey2)
check:
@ -331,8 +331,8 @@ suite "RSA 512/1024/2048/4096 test suite":
var skey1 = key.getBytes()
check key.toBytes(skey2) > 0
check:
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPrivateKey.init(skey1)
var rkey4 = RsaPrivateKey.init(skey2)
check:
@ -349,8 +349,8 @@ suite "RSA 512/1024/2048/4096 test suite":
var skey1 = pair.pubkey().getBytes()
check:
pair.pubkey.toBytes(skey2) > 0
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPublicKey.init(skey1)
var rkey4 = RsaPublicKey.init(skey2)
check:
@ -367,8 +367,8 @@ suite "RSA 512/1024/2048/4096 test suite":
var skey1 = pair.pubkey.getBytes()
check:
pair.pubkey.toBytes(skey2) > 0
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPublicKey.init(skey1)
var rkey4 = RsaPublicKey.init(skey2)
check:
@ -384,8 +384,8 @@ suite "RSA 512/1024/2048/4096 test suite":
var skey1 = pair.pubkey.getBytes()
check:
pair.pubkey.toBytes(skey2) > 0
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPublicKey.init(skey1)
var rkey4 = RsaPublicKey.init(skey2)
check:
@ -402,8 +402,8 @@ suite "RSA 512/1024/2048/4096 test suite":
var skey1 = pair.pubkey.getBytes()
check:
pair.pubkey.toBytes(skey2) > 0
rkey1.init(skey1) == Asn1Status.Success
rkey2.init(skey2) == Asn1Status.Success
rkey1.init(skey1).isOk()
rkey2.init(skey2).isOk()
var rkey3 = RsaPublicKey.init(skey1)
var rkey4 = RsaPublicKey.init(skey2)
check: