Mercurial > vim
comparison src/fileio.c @ 24970:7e9e53a0368f v8.2.3022
patch 8.2.3022: available encryption methods are not strong enough
Commit: https://github.com/vim/vim/commit/f573c6e1ed58d46d694c802eaf5ae3662a952744
Author: Christian Brabandt <cb@256bit.org>
Date: Sun Jun 20 14:02:16 2021 +0200
patch 8.2.3022: available encryption methods are not strong enough
Problem: Available encryption methods are not strong enough.
Solution: Add initial support for xchaha20. (Christian Brabandt,
closes #8394)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sun, 20 Jun 2021 14:15:07 +0200 |
parents | 7334bf933510 |
children | 85d1e82ed134 |
comparison
equal
deleted
inserted
replaced
24969:445ed84ae76a | 24970:7e9e53a0368f |
---|---|
10 /* | 10 /* |
11 * fileio.c: read from and write to a file | 11 * fileio.c: read from and write to a file |
12 */ | 12 */ |
13 | 13 |
14 #include "vim.h" | 14 #include "vim.h" |
15 | |
16 #ifdef FEAT_SODIUM | |
17 # include <sodium.h> | |
18 #endif | |
15 | 19 |
16 #if defined(__TANDEM) | 20 #if defined(__TANDEM) |
17 # include <limits.h> // for SSIZE_MAX | 21 # include <limits.h> // for SSIZE_MAX |
18 #endif | 22 #endif |
19 #if (defined(UNIX) || defined(VMS)) && defined(FEAT_EVAL) | 23 #if (defined(UNIX) || defined(VMS)) && defined(FEAT_EVAL) |
146 colnr_T len; | 150 colnr_T len; |
147 long size = 0; | 151 long size = 0; |
148 char_u *p; | 152 char_u *p; |
149 off_T filesize = 0; | 153 off_T filesize = 0; |
150 int skip_read = FALSE; | 154 int skip_read = FALSE; |
155 off_T filesize_disk = 0; // file size read from disk | |
156 off_T filesize_count = 0; // counter | |
151 #ifdef FEAT_CRYPT | 157 #ifdef FEAT_CRYPT |
152 char_u *cryptkey = NULL; | 158 char_u *cryptkey = NULL; |
153 int did_ask_for_key = FALSE; | 159 int did_ask_for_key = FALSE; |
154 #endif | 160 #endif |
155 #ifdef FEAT_PERSISTENT_UNDO | 161 #ifdef FEAT_PERSISTENT_UNDO |
213 char_u *old_b_ffname; | 219 char_u *old_b_ffname; |
214 char_u *old_b_fname; | 220 char_u *old_b_fname; |
215 int using_b_ffname; | 221 int using_b_ffname; |
216 int using_b_fname; | 222 int using_b_fname; |
217 static char *msg_is_a_directory = N_("is a directory"); | 223 static char *msg_is_a_directory = N_("is a directory"); |
224 int eof; | |
218 | 225 |
219 au_did_filetype = FALSE; // reset before triggering any autocommands | 226 au_did_filetype = FALSE; // reset before triggering any autocommands |
220 | 227 |
221 curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read | 228 curbuf->b_no_eol_lnum = 0; // in case it was set by the previous read |
222 | 229 |
403 // Remember time of file. | 410 // Remember time of file. |
404 if (mch_stat((char *)fname, &st) >= 0) | 411 if (mch_stat((char *)fname, &st) >= 0) |
405 { | 412 { |
406 buf_store_time(curbuf, &st, fname); | 413 buf_store_time(curbuf, &st, fname); |
407 curbuf->b_mtime_read = curbuf->b_mtime; | 414 curbuf->b_mtime_read = curbuf->b_mtime; |
415 filesize_disk = st.st_size; | |
408 #ifdef UNIX | 416 #ifdef UNIX |
409 /* | 417 /* |
410 * Use the protection bits of the original file for the swap file. | 418 * Use the protection bits of the original file for the swap file. |
411 * This makes it possible for others to read the name of the | 419 * This makes it possible for others to read the name of the |
412 * edited file from the swapfile, but only if they can read the | 420 * edited file from the swapfile, but only if they can read the |
1078 | 1086 |
1079 if (!skip_read) | 1087 if (!skip_read) |
1080 { | 1088 { |
1081 linerest = 0; | 1089 linerest = 0; |
1082 filesize = 0; | 1090 filesize = 0; |
1091 filesize_count = 0; | |
1083 skip_count = lines_to_skip; | 1092 skip_count = lines_to_skip; |
1084 read_count = lines_to_read; | 1093 read_count = lines_to_read; |
1085 conv_restlen = 0; | 1094 conv_restlen = 0; |
1086 #ifdef FEAT_PERSISTENT_UNDO | 1095 #ifdef FEAT_PERSISTENT_UNDO |
1087 read_undo_file = (newfile && (flags & READ_KEEP_UNDO) == 0 | 1096 read_undo_file = (newfile && (flags & READ_KEEP_UNDO) == 0 |
1261 else | 1270 else |
1262 { | 1271 { |
1263 /* | 1272 /* |
1264 * Read bytes from the file. | 1273 * Read bytes from the file. |
1265 */ | 1274 */ |
1275 # ifdef FEAT_SODIUM | |
1276 // Let the crypt layer work with a buffer size of 8192 | |
1277 if (filesize == 0) | |
1278 // set size to 8K + Sodium Crypt Metadata | |
1279 size = WRITEBUFSIZE + 36 | |
1280 + crypto_secretstream_xchacha20poly1305_HEADERBYTES | |
1281 + crypto_secretstream_xchacha20poly1305_ABYTES; | |
1282 | |
1283 else if (filesize > 0 && (curbuf->b_cryptstate != NULL && | |
1284 curbuf->b_cryptstate->method_nr == CRYPT_M_SOD)) | |
1285 size = WRITEBUFSIZE + crypto_secretstream_xchacha20poly1305_ABYTES; | |
1286 # endif | |
1287 eof = size; | |
1266 size = read_eintr(fd, ptr, size); | 1288 size = read_eintr(fd, ptr, size); |
1289 filesize_count += size; | |
1290 // hit end of file | |
1291 eof = (size < eof || filesize_count == filesize_disk); | |
1267 } | 1292 } |
1268 | 1293 |
1269 #ifdef FEAT_CRYPT | 1294 #ifdef FEAT_CRYPT |
1270 /* | 1295 /* |
1271 * At start of file: Check for magic number of encryption. | 1296 * At start of file: Check for magic number of encryption. |
1283 { | 1308 { |
1284 # ifdef CRYPT_NOT_INPLACE | 1309 # ifdef CRYPT_NOT_INPLACE |
1285 if (crypt_works_inplace(curbuf->b_cryptstate)) | 1310 if (crypt_works_inplace(curbuf->b_cryptstate)) |
1286 { | 1311 { |
1287 # endif | 1312 # endif |
1288 crypt_decode_inplace(curbuf->b_cryptstate, ptr, size); | 1313 crypt_decode_inplace(curbuf->b_cryptstate, ptr, |
1314 size, eof); | |
1289 # ifdef CRYPT_NOT_INPLACE | 1315 # ifdef CRYPT_NOT_INPLACE |
1290 } | 1316 } |
1291 else | 1317 else |
1292 { | 1318 { |
1293 char_u *newptr = NULL; | 1319 char_u *newptr = NULL; |
1294 int decrypted_size; | 1320 int decrypted_size; |
1295 | 1321 |
1296 decrypted_size = crypt_decode_alloc( | 1322 decrypted_size = crypt_decode_alloc( |
1297 curbuf->b_cryptstate, ptr, size, &newptr); | 1323 curbuf->b_cryptstate, ptr, size, |
1298 | 1324 &newptr, eof); |
1325 | |
1326 if (decrypted_size < 0) | |
1327 { | |
1328 // error message already given | |
1329 error = TRUE; | |
1330 vim_free(newptr); | |
1331 break; | |
1332 } | |
1299 // If the crypt layer is buffering, not producing | 1333 // If the crypt layer is buffering, not producing |
1300 // anything yet, need to read more. | 1334 // anything yet, need to read more. |
1301 if (decrypted_size == 0) | 1335 if (decrypted_size == 0) |
1302 continue; | 1336 continue; |
1303 | 1337 |
1323 | 1357 |
1324 mch_memmove(new_buffer, buffer, linerest); | 1358 mch_memmove(new_buffer, buffer, linerest); |
1325 if (newptr != NULL) | 1359 if (newptr != NULL) |
1326 mch_memmove(new_buffer + linerest, newptr, | 1360 mch_memmove(new_buffer + linerest, newptr, |
1327 decrypted_size); | 1361 decrypted_size); |
1362 vim_free(newptr); | |
1328 } | 1363 } |
1329 | 1364 |
1330 if (new_buffer != NULL) | 1365 if (new_buffer != NULL) |
1331 { | 1366 { |
1332 vim_free(buffer); | 1367 vim_free(buffer); |
1333 buffer = new_buffer; | 1368 buffer = new_buffer; |
1334 new_buffer = NULL; | 1369 new_buffer = NULL; |
1335 line_start = buffer; | 1370 line_start = buffer; |
1336 ptr = buffer + linerest; | 1371 ptr = buffer + linerest; |
1372 real_size = size; | |
1337 } | 1373 } |
1338 size = decrypted_size; | 1374 size = decrypted_size; |
1339 } | 1375 } |
1340 # endif | 1376 # endif |
1341 } | 1377 } |