summaryrefslogtreecommitdiff
path: root/test/lisp/emacs-lisp
diff options
context:
space:
mode:
authorStefan Kangas <stefan@marxist.se>2020-09-07 07:31:56 +0200
committerStefan Kangas <stefan@marxist.se>2020-11-22 00:38:35 +0100
commitbcde5f86c5a7f3a84115807520631a4f12fb6f70 (patch)
tree6254f8d19ef474f965567ce7922b84ed93312a19 /test/lisp/emacs-lisp
parent733e674af4f66ba7e9f0614b931c44484acce2b9 (diff)
downloademacs-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')
-rw-r--r--test/lisp/emacs-lisp/package-resources/archives/newer/archive-contents1
-rw-r--r--test/lisp/emacs-lisp/package-resources/archives/older/archive-contents1
-rw-r--r--test/lisp/emacs-lisp/package-tests.el61
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.