harden `ecnist` byte export against uninitialized key (#671)

Currently, `ecnist`'s `toBytes` and `getBytes` methods operate only on
properly initialized keys. If an un-initialized key is given, an
`IndexError` may be raised if the key's `xlen` / `qlen` property is
larger than the maximum buffer size. This patch hardens those functions
to report a proper error in that case.
Note that the library functions called by `init` and `initRaw` already
reject data that does not have the expected length, so these new checks
should not be reachable in practice.
This commit is contained in:
Etan Kissling 2021-12-13 19:46:25 +01:00 committed by GitHub
parent 0be9180977
commit 2373ee0061
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 0 deletions

View File

@ -381,11 +381,15 @@ proc toBytes*(seckey: EcPrivateKey, data: var openarray[byte]): EcResult[int] =
c0.write(Asn1Tag.Oid, Asn1OidSecp521r1)
c0.finish()
offset = pubkey.getOffset()
if offset < 0:
return err(EcKeyIncorrectError)
length = pubkey.key.qlen
c1.write(Asn1Tag.BitString,
pubkey.buffer.toOpenArray(offset, offset + length - 1))
c1.finish()
offset = seckey.getOffset()
if offset < 0:
return err(EcKeyIncorrectError)
length = seckey.key.xlen
p.write(1'u64)
p.write(Asn1Tag.OctetString,
@ -426,6 +430,8 @@ proc toBytes*(pubkey: EcPublicKey, data: var openarray[byte]): EcResult[int] =
c.finish()
p.write(c)
let offset = getOffset(pubkey)
if offset < 0:
return err(EcKeyIncorrectError)
let length = pubkey.key.qlen
p.write(Asn1Tag.BitString,
pubkey.buffer.toOpenArray(offset, offset + length - 1))

View File

@ -315,6 +315,9 @@ suite "EC NIST-P256/384/521 test suite":
rkey2 == key
rkey3 == key
rkey4 == key
rkey1.key.xlen = rkey1.buffer.len + 1
check:
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
test "[secp256r1] Public key serialize/deserialize test":
for i in 0..<TestsCount:
@ -333,6 +336,9 @@ suite "EC NIST-P256/384/521 test suite":
rkey2 == pair.pubkey
rkey3 == pair.pubkey
rkey4 == pair.pubkey
rkey1.key.qlen = rkey1.buffer.len + 1
check:
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
test "[secp256r1] ECDHE test":
for i in 0..<TestsCount:
@ -422,6 +428,9 @@ suite "EC NIST-P256/384/521 test suite":
rkey2 == key
rkey3 == key
rkey4 == key
rkey1.key.xlen = rkey1.buffer.len + 1
check:
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
test "[secp384r1] Public key serialize/deserialize test":
for i in 0..<TestsCount:
@ -440,6 +449,9 @@ suite "EC NIST-P256/384/521 test suite":
rkey2 == pair.pubkey
rkey3 == pair.pubkey
rkey4 == pair.pubkey
rkey1.key.qlen = rkey1.buffer.len + 1
check:
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
test "[secp384r1] ECDHE test":
for i in 0..<TestsCount:
@ -529,6 +541,9 @@ suite "EC NIST-P256/384/521 test suite":
rkey2 == key
rkey3 == key
rkey4 == key
rkey1.key.xlen = rkey1.buffer.len + 1
check:
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
test "[secp521r1] Public key serialize/deserialize test":
for i in 0..<TestsCount:
@ -547,6 +562,9 @@ suite "EC NIST-P256/384/521 test suite":
rkey2 == pair.pubkey
rkey3 == pair.pubkey
rkey4 == pair.pubkey
rkey1.key.qlen = rkey1.buffer.len + 1
check:
rkey1.getBytes == EcResult[seq[byte]].err(EcKeyIncorrectError)
test "[secp521r1] ECDHE test":
for i in 0..<TestsCount: