nip/tests/test_signature_verifier.nim

284 lines
9.4 KiB
Nim

import std/[unittest, times, base64, json, os, tempfiles, strutils, options]
import ../src/nimpak/security/signature_verifier
suite "Signature Algorithm Detection":
test "detect Ed25519 signature formats":
check detectSignatureAlgorithm("ed25519-abc123") == SigEd25519
check detectSignatureAlgorithm("a".repeat(128)) == SigEd25519 # 128 hex chars
test "detect Dilithium signature formats":
expect ValueError:
discard detectSignatureAlgorithm("dilithium-abc123") # Not implemented yet
test "invalid signature formats":
expect ValueError:
discard detectSignatureAlgorithm("invalid-sig")
expect ValueError:
discard detectSignatureAlgorithm("abc") # Too short
suite "Signature String Parsing":
test "parse Ed25519 signature strings":
let (alg1, sig1) = parseSignatureString("ed25519-abc123def456")
check alg1 == SigEd25519
check sig1 == "abc123def456"
let (alg2, sig2) = parseSignatureString("a".repeat(128))
check alg2 == SigEd25519
check sig2 == "a".repeat(128)
test "format signature strings":
check formatSignatureString(SigEd25519, "abc123") == "ed25519-abc123"
check formatSignatureString(SigDilithium, "def456") == "dilithium-def456"
check formatSignatureString(SigRSA, "789abc") == "rsa-789abc"
suite "Ed25519 Signature Verification":
# Test vectors for Ed25519 (RFC 8032)
const ED25519_TEST_VECTORS = [
(
message: "",
publicKey: "11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=",
signature: "hgyY0il+MGCjP0JzlnkSPjt9HQjyOh1XBL2QX5AjXtYzOjIh2+3IfGG07fAuNqq41PvvRMzFRuV+DqbpBRlHBg==",
valid: true
),
(
message: "test message",
publicKey: "11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=",
signature: "invalid-signature-data",
valid: false
)
]
test "Ed25519 signature verification with test vectors":
for vector in ED25519_TEST_VECTORS:
let result = verifyEd25519Signature(vector.message, vector.signature, vector.publicKey)
if vector.valid:
check result == true
else:
check result == false
test "Ed25519 signature with invalid inputs":
# Invalid signature length
check verifyEd25519Signature("test", "short", "validkey") == false
# Invalid public key length
check verifyEd25519Signature("test", "valid-sig", "short") == false
# Invalid base64
check verifyEd25519Signature("test", "invalid-base64!", "invalid-base64!") == false
suite "Signature Verifier":
test "create signature verifier":
let verifier = newSignatureVerifier()
check verifier.trustedKeys.len == 0
check verifier.requireValidTimestamp == true
check SigEd25519 in verifier.allowedAlgorithms
test "add trusted key":
var verifier = newSignatureVerifier()
let key = createPublicKey(
SigEd25519,
"test-key-1",
"test-key-data",
now().utc() - initDuration(days = 1),
now().utc() + initDuration(days = 365)
)
verifier.addTrustedKey(key)
check verifier.trustedKeys.len == 1
check verifier.trustedKeys[0].keyId == "test-key-1"
test "find trusted key":
var verifier = newSignatureVerifier()
let key = createPublicKey(
SigEd25519,
"findable-key",
"test-key-data",
now().utc() - initDuration(days = 1),
now().utc() + initDuration(days = 365)
)
verifier.addTrustedKey(key)
let foundKey = verifier.findTrustedKey("findable-key")
check foundKey.isSome()
check foundKey.get().keyId == "findable-key"
let notFoundKey = verifier.findTrustedKey("nonexistent-key")
check notFoundKey.isNone()
suite "Key Validation":
test "key validity checks":
let now = times.now().utc()
# Valid key
let validKey = createPublicKey(
SigEd25519,
"valid-key",
"key-data",
now - initDuration(days = 1),
now + initDuration(days = 365)
)
check isKeyValid(validKey, now) == true
# Expired key
let expiredKey = createPublicKey(
SigEd25519,
"expired-key",
"key-data",
now - initDuration(days = 365),
now - initDuration(days = 1)
)
check isKeyValid(expiredKey, now) == false
# Not yet valid key
let futureKey = createPublicKey(
SigEd25519,
"future-key",
"key-data",
now + initDuration(days = 1),
now + initDuration(days = 365)
)
check isKeyValid(futureKey, now) == false
# Revoked key
var revokedKey = validKey
revokedKey.revoked = true
check isKeyValid(revokedKey, now) == false
suite "Digital Signature Objects":
test "create digital signature":
let timestamp = now().utc()
let sig = createDigitalSignature(SigEd25519, "test-key", "signature-data", timestamp)
check sig.algorithm == SigEd25519
check sig.keyId == "test-key"
check sig.signature == "signature-data"
check sig.timestamp == timestamp
test "create public key":
let validFrom = now().utc()
let validUntil = validFrom + initDuration(days = 365)
let key = createPublicKey(SigEd25519, "test-key", "key-data", validFrom, validUntil)
check key.algorithm == SigEd25519
check key.keyId == "test-key"
check key.keyData == "key-data"
check key.validFrom == validFrom
check key.validUntil == validUntil
check key.revoked == false
test "signature validation":
let validSig = createDigitalSignature(SigEd25519, "key-1", "sig-data")
check isSignatureValid(validSig) == true
let invalidSig = createDigitalSignature(SigEd25519, "", "sig-data")
check isSignatureValid(invalidSig) == false
let invalidSig2 = createDigitalSignature(SigEd25519, "key-1", "")
check isSignatureValid(invalidSig2) == false
suite "Signature Policy":
test "create signature policy":
let policy = newSignaturePolicy()
check policy.requireSignatures == true
check SigEd25519 in policy.allowedAlgorithms
check policy.minimumKeySize == 256
check policy.maxSignatureAge == 86400
check policy.requireTimestamp == true
check policy.allowSelfSigned == false
test "validate signature against policy":
let policy = newSignaturePolicy()
# Valid signature
let validSig = createDigitalSignature(SigEd25519, "key-1", "sig-data", now().utc())
check validateSignaturePolicy(validSig, policy) == true
# Invalid algorithm
let invalidAlgSig = createDigitalSignature(SigRSA, "key-1", "sig-data", now().utc())
check validateSignaturePolicy(invalidAlgSig, policy) == false
# Too old signature
let oldSig = createDigitalSignature(SigEd25519, "key-1", "sig-data",
now().utc() - initDuration(days = 2))
check validateSignaturePolicy(oldSig, policy) == false
suite "File Signature Verification":
test "verify file signature":
# Create a temporary file
let (tempFile, tempPath) = createTempFile("nimpak_sig_test_", ".txt")
tempFile.write("Test file content for signature verification")
tempFile.close()
try:
# This test would require actual Ed25519 key generation and signing
# For now, we test the error handling
expect IOError:
let verifier = newSignatureVerifier()
let sig = createDigitalSignature(SigEd25519, "test-key", "fake-signature")
discard verifier.verifyFileSignature("/nonexistent/file.txt", sig)
finally:
removeFile(tempPath)
suite "Hybrid Signature Support":
test "create hybrid signature":
let classicalSig = createDigitalSignature(SigEd25519, "classical-key", "classical-sig")
let quantumSig = createDigitalSignature(SigDilithium, "quantum-key", "quantum-sig")
let hybridSig = HybridSignature(
classicalSig: classicalSig,
quantumSig: some(quantumSig),
requireBoth: true
)
check hybridSig.classicalSig.algorithm == SigEd25519
check hybridSig.quantumSig.isSome()
check hybridSig.quantumSig.get().algorithm == SigDilithium
check hybridSig.requireBoth == true
suite "Signature Information":
test "get signature info":
let timestamp = now().utc()
let sig = createDigitalSignature(SigEd25519, "info-key", "info-sig", timestamp)
let info = getSignatureInfo(sig)
check "ed25519" in info.toLower()
check "info-key" in info
check $timestamp in info
suite "Error Handling":
test "signature verification errors":
let verifier = newSignatureVerifier()
let sig = createDigitalSignature(SigEd25519, "nonexistent-key", "fake-signature")
expect SignatureVerificationError:
discard verifier.verifySignature("test message", sig)
test "unsupported algorithm errors":
expect ValueError:
discard verifyDilithiumSignature("test", "sig", "key")
expect ValueError:
discard verifyRSASignature("test", "sig", "key")
suite "Integration with Hash Verifier":
test "verify hash signature":
let verifier = newSignatureVerifier()
let hash = "blake2b-abc123def456"
let sig = createDigitalSignature(SigEd25519, "hash-key", "hash-signature")
# This would fail because we don't have the trusted key
expect SignatureVerificationError:
discard verifier.verifyHashSignature(hash, sig)
suite "Performance and Statistics":
test "signature verification timing":
# Create a mock signature that will fail verification
let verifier = newSignatureVerifier()
let sig = createDigitalSignature(SigEd25519, "timing-key", "timing-signature")
expect SignatureVerificationError:
let result = verifier.verifySignature("timing test", sig)
# Even failed verification should have timing information
check result.verificationTime >= 0.0