diff options
author | Stefan Kangas <stefan@marxist.se> | 2020-09-07 07:31:56 +0200 |
---|---|---|
committer | Stefan Kangas <stefan@marxist.se> | 2020-11-22 00:38:35 +0100 |
commit | bcde5f86c5a7f3a84115807520631a4f12fb6f70 (patch) | |
tree | 6254f8d19ef474f965567ce7922b84ed93312a19 /test/lisp/emacs-lisp | |
parent | 733e674af4f66ba7e9f0614b931c44484acce2b9 (diff) | |
download | emacs-scratch/package-security.tar.gz |
Support expiration of metadata by package archivesscratch/package-security
Expiring package metadata is done by checking the timestamp in package
archive file. This is intended to limit the effectiveness of a replay
attack. The onus is on the package archives to implement a secure and
reasonable policy. (Debian uses 7 days before metadata expires.)
Together with package checksums, this adds sufficient protection
against metadata replay attacks. (Bug#19479)
* lisp/emacs-lisp/package.el (package-check-timestamp): New defcustom.
(bad-timestamp): New error.
(package--parse-header-from-buffer)
(package--parse-valid-until-from-buffer)
(package--parse-last-updated-from-buffer)
(package--archive-verify-timestamp)
(package--archive-verify-not-expired)
(package--compare-archive-timestamps)
(package--check-archive-timestamp): New defuns.
(package--download-one-archive): Check timestamp of the
'archive-contents' file using above functions. It is only checked if
it exists, which makes this change backwards compatible.
* lisp/calendar/iso8601.el (iso8601-parse): Add autoload cookie.
* test/lisp/emacs-lisp/package-tests.el
(package-test-parse-valid-until-from-buffer)
(package-test-parse-last-updated-from-buffer)
(package-test-archive-verify-timestamp)
(package-test-check-archive-timestamp)
(package-test-check-archive-timestamp/not-expired)
(package-test-check-archive-timestamp/expired): New tests.
* test/lisp/emacs-lisp/package-resources/archives/older/archive-contents:
* test/lisp/emacs-lisp/package-resources/archives/newer/archive-contents:
New files.
* doc/lispref/package.texi (Package Archives, Archive Web Server):
Document how to increase the security of a package archive using
checksums, signing and timestamps.
Diffstat (limited to 'test/lisp/emacs-lisp')
3 files changed, 63 insertions, 0 deletions
diff --git a/test/lisp/emacs-lisp/package-resources/archives/newer/archive-contents b/test/lisp/emacs-lisp/package-resources/archives/newer/archive-contents new file mode 100644 index 00000000000..59a79970b6b --- /dev/null +++ b/test/lisp/emacs-lisp/package-resources/archives/newer/archive-contents @@ -0,0 +1 @@ +;; Last-Updated: 2020-06-01T00:00:00.000Z diff --git a/test/lisp/emacs-lisp/package-resources/archives/older/archive-contents b/test/lisp/emacs-lisp/package-resources/archives/older/archive-contents new file mode 100644 index 00000000000..193a6b5ab94 --- /dev/null +++ b/test/lisp/emacs-lisp/package-resources/archives/older/archive-contents @@ -0,0 +1 @@ +;; Last-Updated: 2019-01-01T00:00:00.000Z diff --git a/test/lisp/emacs-lisp/package-tests.el b/test/lisp/emacs-lisp/package-tests.el index a81506d626b..b0da54a3015 100644 --- a/test/lisp/emacs-lisp/package-tests.el +++ b/test/lisp/emacs-lisp/package-tests.el @@ -857,6 +857,67 @@ If the rest succeed, just ignore the unsupported one." (insert "7") (should-error (package--verify-package-size pkg-desc))))) +(ert-deftest package-test-parse-valid-until-from-buffer () + (with-temp-buffer + (insert ";; Valid-Until: 2020-05-01T15:43:35.000Z\n(foo bar baz)") + (should (equal (package--parse-valid-until-from-buffer "foo") + '(24236 17319))))) + +(ert-deftest package-test-parse-last-updated-from-buffer () + (with-temp-buffer + (insert ";; Last-Updated: 2020-05-01T15:43:35.000Z\n(foo bar baz)") + (should (equal (package--parse-last-updated-from-buffer "foo") + '(24236 17319))))) + +(defun package-tests--parse-last-updated (timestamp) + (with-temp-buffer + (insert timestamp) + (package--parse-last-updated-from-buffer "test"))) + +(ert-deftest package-test-archive-verify-timestamp () + (let ((a (package-tests--parse-last-updated + ";; Last-Updated: 2020-05-01T15:43:35.000Z\n")) + (b (package-tests--parse-last-updated + ";; Last-Updated: 2020-06-01T15:43:35.000Z\n")) + (c (package-tests--parse-last-updated + ";; Last-Updated: 2020-07-01T15:43:35.000Z\n"))) + (should (package--archive-verify-timestamp b nil "foo")) + (should (package--archive-verify-timestamp b a "foo")) + (should (package--archive-verify-timestamp c a "foo")) + (should (package--archive-verify-timestamp c b "foo")) + ;; Signal error. + (should-error (package--archive-verify-timestamp a b "foo") + :type 'bad-timestamp) + (should-error (package--archive-verify-timestamp a c "foo") + :type 'bad-timestamp) + (should-error (package--archive-verify-timestamp b c "foo") + :type 'bad-timestamp) + (should-error (package--archive-verify-timestamp nil a "foo") + :type 'bad-timestamp))) + +(ert-deftest package-test-check-archive-timestamp () + (let ((package-user-dir package-test-data-dir)) + (with-temp-buffer + (insert ";; Last-Updated: 2020-01-01T00:00:00.000Z\n") + (package--check-archive-timestamp "older") + (package--check-archive-timestamp "missing") + (should-error (package--check-archive-timestamp "newer") + :type 'bad-timestamp)))) + +(ert-deftest package-test-check-archive-timestamp/not-expired () + (let ((package-user-dir package-test-data-dir)) + (with-temp-buffer + (insert ";; Last-Updated: 2020-01-01T00:00:00.000Z\n" + ";; Valid-Until: 2999-01-02T00:00:00.000Z\n") + (should-not (package--check-archive-timestamp "older"))))) + +(ert-deftest package-test-check-archive-timestamp/expired () + (let ((package-user-dir package-test-data-dir)) + (with-temp-buffer + (insert ";; Last-Updated: 2020-01-01T00:00:00.000Z\n" + ";; Valid-Until: 2020-01-02T00:00:00.000Z\n") + (should-error (package--check-archive-timestamp "older"))))) + ;;; Tests for package-x features. |