xref: /vim-8.2.3635/src/testdir/test_crypt.vim (revision 4d8f4761)
1" Tests for encryption.
2
3source check.vim
4CheckFeature cryptv
5
6func Common_head_only(text)
7  " This was crashing Vim
8  split Xtest.txt
9  call setline(1, a:text)
10  wq
11  call feedkeys(":split Xtest.txt\<CR>foobar\<CR>", "tx")
12  call delete('Xtest.txt')
13  call assert_match('VimCrypt', getline(1))
14  bwipe!
15endfunc
16
17func Test_head_only_2()
18  call Common_head_only('VimCrypt~02!abc')
19endfunc
20
21func Test_head_only_3()
22  call Common_head_only('VimCrypt~03!abc')
23endfunc
24
25func Test_head_only_4()
26  CheckFeature sodium
27  call Common_head_only('VimCrypt~04!abc')
28endfunc
29
30func Crypt_uncrypt(method)
31  exe "set cryptmethod=" . a:method
32  " If the blowfish test fails 'cryptmethod' will be 'zip' now.
33  call assert_equal(a:method, &cryptmethod)
34
35  split Xtest.txt
36  let text = ['01234567890123456789012345678901234567',
37	\ 'line 2  foo bar blah',
38	\ 'line 3 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx']
39  call setline(1, text)
40  call feedkeys(":X\<CR>foobar\<CR>foobar\<CR>", 'xt')
41  call assert_equal('*****', &key)
42  w!
43  bwipe!
44  call feedkeys(":split Xtest.txt\<CR>foobar\<CR>", 'xt')
45  call assert_equal(text, getline(1, 3))
46  set key= cryptmethod&
47  bwipe!
48  call delete('Xtest.txt')
49endfunc
50
51func Test_crypt_zip()
52  call Crypt_uncrypt('zip')
53endfunc
54
55func Test_crypt_blowfish()
56  call Crypt_uncrypt('blowfish')
57endfunc
58
59func Test_crypt_blowfish2()
60  call Crypt_uncrypt('blowfish2')
61endfunc
62
63func Test_crypt_sodium()
64  CheckFeature sodium
65  call Crypt_uncrypt('xchacha20')
66endfunc
67
68func Uncrypt_stable(method, crypted_text, key, uncrypted_text)
69  split Xtest.txt
70  set bin noeol key= fenc=latin1
71  exe "set cryptmethod=" . a:method
72  call setline(1, a:crypted_text)
73  w!
74  bwipe!
75  set nobin
76  call feedkeys(":split Xtest.txt\<CR>" . a:key . "\<CR>", 'xt')
77  call assert_equal(a:uncrypted_text, getline(1, len(a:uncrypted_text)))
78  bwipe!
79  call delete('Xtest.txt')
80  set key=
81endfunc
82
83func Uncrypt_stable_xxd(method, hex, key, uncrypted_text)
84  " use xxd to write the binary content
85  call system('xxd -r >Xtest.txt', a:hex)
86  call feedkeys(":split Xtest.txt\<CR>" . a:key . "\<CR>", 'xt')
87  call assert_equal(a:uncrypted_text, getline(1, len(a:uncrypted_text)))
88  bwipe!
89  call delete('Xtest.txt')
90  set key=
91endfunc
92
93func Test_uncrypt_zip()
94  call Uncrypt_stable('zip', "VimCrypt~01!\u0006\u001clV'\u00de}Mg\u00a0\u00ea\u00a3V\u00a9\u00e7\u0007E#3\u008e2U\u00e9\u0097", "foofoo", ["1234567890", "aábbccddeëff"])
95endfunc
96
97func Test_uncrypt_blowfish()
98  call Uncrypt_stable('blowfish', "VimCrypt~02!k)\u00be\u0017\u0097#\u0016\u00ddS\u009c\u00f5=\u00ba\u00e0\u00c8#\u00a5M\u00b4\u0086J\u00c3A\u00cd\u00a5M\u00b4\u0086!\u0080\u0015\u009b\u00f5\u000f\u00e1\u00d2\u0019\u0082\u0016\u0098\u00f7\u000d\u00da", "barbar", ["asdfasdfasdf", "0001112223333"])
99endfunc
100
101func Test_uncrypt_blowfish2a()
102  call Uncrypt_stable('blowfish', "VimCrypt~03!\u001e\u00d1N\u00e3;\u00d3\u00c0\u00a0^C)\u0004\u00f7\u007f.\u00b6\u00abF\u000eS\u0019\u00e0\u008b6\u00d2[T\u00cb\u00a7\u0085\u00d8\u00be9\u000b\u00812\u000bQ\u00b3\u00cc@\u0097\u000f\u00df\u009a\u00adIv\u00aa.\u00d8\u00c9\u00ee\u009e`\u00bd$\u00af%\u00d0", "barburp", ["abcdefghijklmnopqrstuvwxyz", "!@#$%^&*()_+=-`~"])
103endfunc
104
105func Test_uncrypt_blowfish2()
106  call Uncrypt_stable('blowfish2', "VimCrypt~03!\u001e\u00d1N\u00e3;\u00d3\u00c0\u00a0^C)\u0004\u00f7\u007f.\u00b6\u00abF\u000eS\u0019\u00e0\u008b6\u00d2[T\u00cb\u00a7\u0085\u00d8\u00be9\u000b\u00812\u000bQ\u00b3\u00cc@\u0097\u000f\u00df\u009a\u00adIv\u00aa.\u00d8\u00c9\u00ee\u009e`\u00bd$\u00af%\u00d0", "barburp", ["abcdefghijklmnopqrstuvwxyz", "!@#$%^&*()_+=-`~"])
107endfunc
108
109func Test_uncrypt_xchacha20()
110  CheckFeature sodium
111  let hex=['00000000: 5669 6d43 7279 7074 7e30 3421 6b7d e607  vimCrypt~04!k}..',
112        \  '00000010: 4ea4 e99f 923e f67f 7b59 a80d 3bca 2f06  N....>..{Y..;./.',
113        \  '00000020: fa11 b951 8d09 0dc9 470f e7cf 8b90 4310  ...Q....G.....C.',
114        \  '00000030: 653b b83b e493 378b 0390 0e38 f912 626b  e;.;..7....8..bk',
115        \  '00000040: a02e 4697 0254 2625 2d8e 3a0b 784b e89c  ..F..T&%-.:.xK..',
116        \  '00000050: 0c67 a975 3c17 9319 8ffd 1463 7783 a1f3  .g.u<......cw...',
117        \  '00000060: d917 dcb3 8b3e ecd7 c7d4 086b 6059 7ead  .....>.....k`Y~.',
118        \  '00000070: 9b07 f96b 5c1b 4d08 cd91 f208 5221 7484  ...k\.M.....R!t.',
119        \  '00000080: 72be 0136 84a1 d3                        r..6...']
120  " the file should be in latin1 encoding, this makes sure that readfile()
121  " retries several times converting the multi-byte characters
122  call Uncrypt_stable_xxd('xchacha20', hex, "sodium_crypt", ["abcdefghijklmnopqrstuvwxyzäöü", "ZZZ_äüöÄÜÖ_!@#$%^&*()_+=-`~"])
123endfunc
124
125func Test_uncrypt_xchacha20_invalid()
126  CheckFeature sodium
127  " load an invalid encrypted file and verify it can be decrypted with an
128  " error message
129  try
130    call feedkeys(":split samples/crypt_sodium_invalid.txt\<CR>sodium\<CR>", 'xt')
131    call assert_false(1, 'should not happen')
132  catch
133    call assert_exception('pre-mature')
134  endtry
135  call assert_match("Note: Encryption of swapfile not supported, disabling swap- and undofile", execute(':5messages'))
136
137  call assert_equal(0, &swapfile)
138  call assert_equal("xchacha20", &cryptmethod)
139  call assert_equal('311111111111111111111111', getline('$'))
140  bw!
141endfunc
142
143func Test_uncrypt_xchacha20_2()
144  CheckFeature sodium
145  sp Xcrypt_sodium.txt
146  " Create a larger file, so that Vim will write in several blocks
147  call setline(1, range(1,4000))
148  call assert_equal(1, &swapfile)
149  set cryptmethod=xchacha20
150  call feedkeys(":X\<CR>sodium\<CR>sodium\<CR>", 'xt')
151  " swapfile disabled
152  call assert_equal(0, &swapfile)
153  call assert_match("Note: Encryption of swapfile not supported, disabling swap- and undofile", execute(':messages'))
154  w!
155  " encrypted using xchacha20
156  call assert_match("\[xchacha20\]", execute(':messages'))
157  bw!
158  call feedkeys(":sp Xcrypt_sodium.txt\<CR>sodium\<CR>", 'xt')
159  " successfully decrypted
160  call assert_equal(range(1, 4000)->map( {_, v -> string(v)}), getline(1,'$'))
161  set key=
162  w!
163  " enryption removed
164  call assert_match('"Xcrypt_sodium.txt" 4000L, 18893B written', execute(':message'))
165  bw!
166  call delete('Xcrypt_sodium.txt')
167  set cryptmethod&vim
168endfunc
169
170func Test_uncrypt_xchacha20_3_persistent_undo()
171  CheckFeature sodium
172  CheckFeature persistent_undo
173  sp Xcrypt_sodium_undo.txt
174  set cryptmethod=xchacha20 undofile
175  call feedkeys(":X\<CR>sodium\<CR>sodium\<CR>", 'xt')
176  call assert_equal(0, &undofile)
177  let ufile=undofile(@%)
178  call append(0, ['monday', 'tuesday', 'wednesday', 'thursday', 'friday'])
179  call cursor(1, 1)
180
181  set undolevels=100
182  normal dd
183  set undolevels=100
184  normal dd
185  set undolevels=100
186  normal dd
187  set undolevels=100
188  w!
189  bw!
190  call feedkeys(":sp Xcrypt_sodium_undo.txt\<CR>sodium\<CR>", 'xt')
191  " should fail
192  norm! u
193  call assert_match('Already at oldest change', execute(':1mess'))
194  call assert_fails('verbose rundo' .. fnameescape(ufile), 'E822')
195  bw!
196  set undolevels& cryptmethod& undofile&
197  call delete('Xcrypt_sodium_undo.txt')
198endfunc
199
200func Test_encrypt_xchacha20_missing()
201  if has("sodium")
202    return
203  endif
204  sp Xcrypt_sodium_undo.txt
205  call assert_fails(':set cryptmethod=xchacha20', 'E474')
206  bw!
207  set cm&
208endfunc
209
210func Test_uncrypt_unknown_method()
211  split Xuncrypt_unknown.txt
212  set bin noeol key= fenc=latin1
213  call setline(1, "VimCrypt~93!\u001e\u00d1")
214  w!
215  bwipe!
216  set nobin
217  call assert_fails(":split Xuncrypt_unknown.txt", 'E821:')
218
219  bwipe!
220  call delete('Xuncrypt_unknown.txt')
221  set key=
222endfunc
223
224func Test_crypt_key_mismatch()
225  set cryptmethod=blowfish
226
227  split Xtest.txt
228  call setline(1, 'nothing')
229  call feedkeys(":X\<CR>foobar\<CR>nothing\<CR>", 'xt')
230  call assert_match("Keys don't match!", execute(':2messages'))
231  call assert_equal('', &key)
232  call feedkeys("\<CR>\<CR>", 'xt')
233
234  set cryptmethod&
235  bwipe!
236endfunc
237
238func Test_crypt_set_key_changes_buffer()
239
240  new Xtest1.txt
241  call setline(1, 'nothing')
242  set cryptmethod=blowfish2
243  call feedkeys(":X\<CR>foobar\<CR>foobar\<CR>", 'xt')
244  call assert_fails(":q", "E37:")
245  w
246  set key=anotherkey
247  call assert_fails(":bw")
248  w
249  call feedkeys(":X\<CR>foobar\<CR>foobar\<CR>", 'xt')
250  call assert_fails(":bw")
251  w
252  let winnr = winnr()
253  wincmd p
254  call setwinvar(winnr, '&key', 'yetanotherkey')
255  wincmd p
256  call assert_fails(":bw")
257  w
258
259  set cryptmethod&
260  set key=
261  bwipe!
262  call delete('Xtest1.txt')
263endfunc
264
265" vim: shiftwidth=2 sts=2 expandtab
266