Hi,

The "openssl certhash" comparision function hashinfo_compare uses
subtraction to compare two "long" hash values, but the result is
stored into an integer variable, resulting in an inconstent ordering.

This makes it happen that two certificates with same hash get same
index (because they do not end up next to each other), and the
symlink() step fails with EEXIST.

When we replace the subtraction with, e.g. the method described by tedu
in http://www.tedunangst.com/flak/post/subtraction-is-not-comparison
the sorting will work correctly.

Bug discovered in the wild on Void Linux.
Diffed against portable libressl 2.1.4.

-- 
Christian Neukirchen  <chneukirc...@gmail.com>  http://chneukirchen.org

subtraction is not comparison
http://www.tedunangst.com/flak/post/subtraction-is-not-comparison

--- apps/certhash.c     2015-02-27 16:11:46.000000000 +0100
+++ apps/certhash.c     2015-03-05 13:45:15.832647817 +0100
@@ -121,7 +121,7 @@
        struct hashinfo *hib = *(struct hashinfo **)b;
        int rv;
 
-       rv = hia->hash - hib->hash;
+       rv = hia->hash < hib->hash ? -1 : hia->hash > hib->hash;
        if (rv != 0)
                return (rv);
        rv = memcmp(hia->fingerprint, hib->fingerprint,

Reply via email to