Software /
code /
prosody
Comparison
spec/util_crypto_spec.lua @ 12802:4a8740e01813
Merge 0.12->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Mon, 12 Dec 2022 07:10:54 +0100 |
parent | 12737:924bc1c8d0d9 |
child | 12837:d3ae47d8a7a7 |
comparison
equal
deleted
inserted
replaced
12801:ebd6b4d8bf04 | 12802:4a8740e01813 |
---|---|
1 local test_keys = require "spec.inputs.test_keys"; | |
2 | |
3 describe("util.crypto", function () | |
4 local crypto = require "util.crypto"; | |
5 local random = require "util.random"; | |
6 | |
7 describe("generate_ed25519_keypair", function () | |
8 local keypair = crypto.generate_ed25519_keypair(); | |
9 assert.is_not_nil(keypair); | |
10 assert.equal("ED25519", keypair:get_type()); | |
11 end) | |
12 | |
13 describe("import_private_pem", function () | |
14 it("can import ECDSA keys", function () | |
15 local ecdsa_key = crypto.import_private_pem(test_keys.ecdsa_private_pem); | |
16 assert.equal("id-ecPublicKey", ecdsa_key:get_type()); | |
17 end); | |
18 | |
19 it("can import EdDSA (Ed25519) keys", function () | |
20 local ed25519_key = crypto.import_private_pem(crypto.generate_ed25519_keypair():private_pem()); | |
21 assert.equal("ED25519", ed25519_key:get_type()); | |
22 end); | |
23 | |
24 it("can import RSA keys", function () | |
25 -- TODO | |
26 end); | |
27 | |
28 it("rejects invalid keys", function () | |
29 assert.is_nil(crypto.import_private_pem(test_keys.eddsa_public_pem)); | |
30 assert.is_nil(crypto.import_private_pem(test_keys.ecdsa_public_pem)); | |
31 assert.is_nil(crypto.import_private_pem("foo")); | |
32 assert.is_nil(crypto.import_private_pem("")); | |
33 end); | |
34 end); | |
35 | |
36 describe("import_public_pem", function () | |
37 it("can import ECDSA public keys", function () | |
38 local ecdsa_key = crypto.import_public_pem(test_keys.ecdsa_public_pem); | |
39 assert.equal("id-ecPublicKey", ecdsa_key:get_type()); | |
40 end); | |
41 | |
42 it("can import EdDSA (Ed25519) public keys", function () | |
43 local ed25519_key = crypto.import_public_pem(test_keys.eddsa_public_pem); | |
44 assert.equal("ED25519", ed25519_key:get_type()); | |
45 end); | |
46 | |
47 it("can import RSA public keys", function () | |
48 -- TODO | |
49 end); | |
50 end); | |
51 | |
52 describe("PEM export", function () | |
53 it("works", function () | |
54 local ecdsa_key = crypto.import_public_pem(test_keys.ecdsa_public_pem); | |
55 assert.equal("id-ecPublicKey", ecdsa_key:get_type()); | |
56 assert.equal(test_keys.ecdsa_public_pem, ecdsa_key:public_pem()); | |
57 | |
58 assert.has_error(function () | |
59 -- Fails because private key is not available | |
60 ecdsa_key:private_pem(); | |
61 end); | |
62 | |
63 local ecdsa_private_key = crypto.import_private_pem(test_keys.ecdsa_private_pem); | |
64 assert.equal(test_keys.ecdsa_private_pem, ecdsa_private_key:private_pem()); | |
65 end); | |
66 end); | |
67 | |
68 describe("sign/verify with", function () | |
69 local test_cases = { | |
70 ed25519 = { | |
71 crypto.ed25519_sign, crypto.ed25519_verify; | |
72 key = crypto.import_private_pem(test_keys.eddsa_private_pem); | |
73 sig_length = 64; | |
74 }; | |
75 ecdsa = { | |
76 crypto.ecdsa_sha256_sign, crypto.ecdsa_sha256_verify; | |
77 key = crypto.import_private_pem(test_keys.ecdsa_private_pem); | |
78 }; | |
79 }; | |
80 for test_name, test in pairs(test_cases) do | |
81 local key = test.key; | |
82 describe(test_name, function () | |
83 it("works", function () | |
84 local sign, verify = test[1], test[2]; | |
85 local sig = assert(sign(key, "Hello world")); | |
86 assert.is_string(sig); | |
87 if test.sig_length then | |
88 assert.equal(test.sig_length, #sig); | |
89 end | |
90 | |
91 do | |
92 local ok = verify(key, "Hello world", sig); | |
93 assert.is_truthy(ok); | |
94 end | |
95 do -- Incorrect signature | |
96 local ok = verify(key, "Hello world", sig:sub(1, -2)..string.char((sig:byte(-1)+1)%255)); | |
97 assert.is_falsy(ok); | |
98 end | |
99 do -- Incorrect message | |
100 local ok = verify(key, "Hello earth", sig); | |
101 assert.is_falsy(ok); | |
102 end | |
103 do -- Incorrect message (embedded NUL) | |
104 local ok = verify(key, "Hello world\0foo", sig); | |
105 assert.is_falsy(ok); | |
106 end | |
107 end); | |
108 end); | |
109 end | |
110 end); | |
111 | |
112 describe("ECDSA signatures", function () | |
113 local hex = require "util.hex"; | |
114 local sig = hex.decode((([[ | |
115 304402203e936e7b0bc62887e0e9d675afd08531a930384cfcf301 | |
116 f25d13053a2ebf141d02205a5a7c7b7ac5878d004cb79b17b39346 | |
117 6b0cd1043718ffc31c153b971d213a8e | |
118 ]]):gsub("%s+", ""))); | |
119 it("can be parsed", function () | |
120 local r, s = crypto.parse_ecdsa_signature(sig, 32); | |
121 assert.is_string(r); | |
122 assert.is_string(s); | |
123 assert.equal(32, #r); | |
124 assert.equal(32, #s); | |
125 end); | |
126 it("fails to parse invalid signatures", function () | |
127 local invalid_sigs = { | |
128 ""; | |
129 "\000"; | |
130 string.rep("\000", 64); | |
131 string.rep("\000", 72); | |
132 string.rep("\000", 256); | |
133 string.rep("\255", 72); | |
134 string.rep("\255", 3); | |
135 }; | |
136 for _, invalid_sig in ipairs(invalid_sigs) do | |
137 local r, s = crypto.parse_ecdsa_signature(invalid_sig, 32); | |
138 assert.is_nil(r); | |
139 assert.is_nil(s); | |
140 end | |
141 end); | |
142 it("can be built", function () | |
143 local r, s = crypto.parse_ecdsa_signature(sig, 32); | |
144 local rebuilt_sig = crypto.build_ecdsa_signature(r, s); | |
145 assert.equal(sig, rebuilt_sig); | |
146 end); | |
147 end); | |
148 | |
149 describe("AES-GCM encryption", function () | |
150 it("works", function () | |
151 local message = "foo\0bar"; | |
152 local key_128_bit = random.bytes(16); | |
153 local key_256_bit = random.bytes(32); | |
154 local test_cases = { | |
155 { crypto.aes_128_gcm_encrypt, crypto.aes_128_gcm_decrypt, key = key_128_bit }; | |
156 { crypto.aes_256_gcm_encrypt, crypto.aes_256_gcm_decrypt, key = key_256_bit }; | |
157 }; | |
158 for _, params in pairs(test_cases) do | |
159 local iv = params.iv or random.bytes(12); | |
160 local encrypted = params[1](params.key, iv, message); | |
161 assert.not_equal(message, encrypted); | |
162 local decrypted = params[2](params.key, iv, encrypted); | |
163 assert.equal(message, decrypted); | |
164 end | |
165 end); | |
166 end); | |
167 end); |