summary refs log tree commit diff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2014-04-22 01:36:31 +0200
committerLudovic Courtès <ludo@gnu.org>2014-04-22 01:39:31 +0200
commit6030d8493e13af81be63c3cee530d44b4dff1ad6 (patch)
tree2d0760d036839dd31647d35517c80040be4fabcb
parent50db7d82b3f3ab8ec382132b06a1400c0044b89e (diff)
downloadguix-6030d8493e13af81be63c3cee530d44b4dff1ad6.tar.gz
pk-crypto: Use ISO-8859-1 for strings passed to 'gcry_sexp_new'.
* guix/pk-crypto.scm (string->canonical-sexp): Pass "ISO-8859-1" as the
  2nd argument to 'string->pointer'.
* tests/pk-crypto.scm ("version"): New test.
  ("hash corrupt due to restrictive locale encoding"): New test.
-rw-r--r--guix/pk-crypto.scm7
-rw-r--r--tests/pk-crypto.scm24
2 files changed, 30 insertions, 1 deletions
diff --git a/guix/pk-crypto.scm b/guix/pk-crypto.scm
index 481d3f2463..351bf929c5 100644
--- a/guix/pk-crypto.scm
+++ b/guix/pk-crypto.scm
@@ -134,8 +134,13 @@ thrown along with 'gcry-error'."
          (proc (pointer->procedure int ptr `(* * ,size_t ,int))))
     (lambda (str)
       "Parse STR and return the corresponding gcrypt s-expression."
+
+      ;; When STR comes from 'canonical-sexp->string', it may contain
+      ;; characters that are really meant to be interpreted as bytes as in a C
+      ;; 'char *'.  Thus, convert STR to ISO-8859-1 so the byte values of the
+      ;; characters are preserved.
       (let* ((sexp (bytevector->pointer (make-bytevector (sizeof '*))))
-             (err  (proc sexp (string->pointer str) 0 1)))
+             (err  (proc sexp (string->pointer str "ISO-8859-1") 0 1)))
         (if (= 0 err)
             (pointer->canonical-sexp (dereference-pointer sexp))
             (throw 'gcry-error err))))))
diff --git a/tests/pk-crypto.scm b/tests/pk-crypto.scm
index 294c7f3df8..67bbc83d49 100644
--- a/tests/pk-crypto.scm
+++ b/tests/pk-crypto.scm
@@ -64,6 +64,9 @@
 
 (test-begin "pk-crypto")
 
+(test-assert "version"
+  (gcrypt-version))
+
 (let ((sexps '("(foo bar)"
 
                ;; In Libgcrypt 1.5.3 the following integer is rendered as
@@ -142,6 +145,27 @@
             1+
             0)))
 
+(let ((bv (base16-string->bytevector
+           "5eff0b55c9c5f5e87b4e34cd60a2d5654ca1eb78c7b3c67c3179fed1cff07b4c")))
+  (test-equal "hash corrupt due to restrictive locale encoding"
+    bv
+
+    ;; In Guix up to 0.6 included this test would fail because at some point
+    ;; the hash value would be cropped to ASCII.  In practice 'guix
+    ;; authenticate' would produce invalid signatures that would fail
+    ;; signature verification.
+    (let ((locale (setlocale LC_ALL)))
+     (dynamic-wind
+       (lambda ()
+         (setlocale LC_ALL "C"))
+       (lambda ()
+         (hash-data->bytevector
+          (string->canonical-sexp
+           (canonical-sexp->string
+            (bytevector->hash-data bv "sha256")))))
+       (lambda ()
+         (setlocale LC_ALL locale))))))
+
 (gc)
 
 ;; XXX: The test below is typically too long as it needs to gather enough entropy.