checksum.c
1 /*- 2 * Copyright (c) 2015-2022 Baptiste Daroussin <bapt@FreeBSD.org> 3 *~ 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer 9 * in this position and unchanged. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 *~ 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include <atf-c.h> 27 #include <err.h> 28 #include <unistd.h> 29 #include <errno.h> 30 #include <pkg.h> 31 #include <private/pkg.h> 32 33 ATF_TC_WITHOUT_HEAD(check_symlinks); 34 ATF_TC_WITHOUT_HEAD(check_pkg); 35 ATF_TC_WITHOUT_HEAD(check_types); 36 ATF_TC_WITHOUT_HEAD(check_validity); 37 38 ATF_TC_BODY(check_validity, tc) 39 { 40 ATF_REQUIRE_EQ(pkg_checksum_is_valid("mehe", 2), false); 41 ATF_REQUIRE_EQ(pkg_checksum_is_valid("mehe", 4), false); 42 ATF_REQUIRE_EQ(pkg_checksum_is_valid("m$he", 4), false); 43 ATF_REQUIRE_EQ(pkg_checksum_is_valid("2$166004b891d84ee8d263e4fe1ddc3be09a11a053bf8f6c3804bad6ca3248c332d", 66), false); 44 ATF_REQUIRE_EQ(pkg_checksum_is_valid("2$42$66004b891d84ee8d263e4fe1ddc3be09a11a053bf8f6c3804bad6ca3248c332d", 66), false); 45 ATF_REQUIRE_EQ(pkg_checksum_is_valid("2$1$66004b891d84ee8d263e4fe1ddc3be09a11a053bf8f6c3804bad6ca3248c332d", 66), true); 46 } 47 48 ATF_TC_BODY(check_types, tc) 49 { 50 ATF_REQUIRE_EQ(pkg_checksum_type_from_string("sha256_base32"), PKG_HASH_TYPE_SHA256_BASE32); 51 ATF_REQUIRE_EQ(pkg_checksum_type_from_string("sha256_hex"), PKG_HASH_TYPE_SHA256_HEX); 52 ATF_REQUIRE_EQ(pkg_checksum_type_from_string("blake2_base32"), PKG_HASH_TYPE_BLAKE2_BASE32); 53 ATF_REQUIRE_EQ(pkg_checksum_type_from_string("sha256_raw"), PKG_HASH_TYPE_SHA256_RAW); 54 ATF_REQUIRE_EQ(pkg_checksum_type_from_string("blake2_raw"), PKG_HASH_TYPE_BLAKE2_RAW); 55 ATF_REQUIRE_EQ(pkg_checksum_type_from_string("blake2s_base32"), PKG_HASH_TYPE_BLAKE2S_BASE32); 56 ATF_REQUIRE_EQ(pkg_checksum_type_from_string("blake2s_raw"), PKG_HASH_TYPE_BLAKE2S_RAW); 57 ATF_REQUIRE_EQ(pkg_checksum_type_from_string("plop"), PKG_HASH_TYPE_UNKNOWN); 58 59 ATF_REQUIRE_EQ(pkg_checksum_get_type("0$0$", 0), PKG_HASH_TYPE_SHA256_BASE32); 60 ATF_REQUIRE_EQ(pkg_checksum_get_type("0$1$", 0), PKG_HASH_TYPE_SHA256_HEX); 61 ATF_REQUIRE_EQ(pkg_checksum_get_type("0$2$", 0), PKG_HASH_TYPE_BLAKE2_BASE32); 62 ATF_REQUIRE_EQ(pkg_checksum_get_type("0$3$", 0), PKG_HASH_TYPE_SHA256_RAW); 63 ATF_REQUIRE_EQ(pkg_checksum_get_type("0$4$", 0), PKG_HASH_TYPE_BLAKE2_RAW); 64 ATF_REQUIRE_EQ(pkg_checksum_get_type("0$5$", 0), PKG_HASH_TYPE_BLAKE2S_BASE32); 65 ATF_REQUIRE_EQ(pkg_checksum_get_type("0$6$", 0), PKG_HASH_TYPE_BLAKE2S_RAW); 66 ATF_REQUIRE_EQ(pkg_checksum_get_type("0$42$", 0), PKG_HASH_TYPE_UNKNOWN); 67 ATF_REQUIRE_EQ(pkg_checksum_get_type("", 0), PKG_HASH_TYPE_UNKNOWN); 68 69 ATF_REQUIRE_EQ(pkg_checksum_file_get_type("0$", 0), PKG_HASH_TYPE_SHA256_BASE32); 70 ATF_REQUIRE_EQ(pkg_checksum_file_get_type("1$", 0), PKG_HASH_TYPE_SHA256_HEX); 71 ATF_REQUIRE_EQ(pkg_checksum_file_get_type("2$", 0), PKG_HASH_TYPE_BLAKE2_BASE32); 72 ATF_REQUIRE_EQ(pkg_checksum_file_get_type("3$", 0), PKG_HASH_TYPE_SHA256_RAW); 73 ATF_REQUIRE_EQ(pkg_checksum_file_get_type("4$", 0), PKG_HASH_TYPE_BLAKE2_RAW); 74 ATF_REQUIRE_EQ(pkg_checksum_file_get_type("5$", 0), PKG_HASH_TYPE_BLAKE2S_BASE32); 75 ATF_REQUIRE_EQ(pkg_checksum_file_get_type("6$", 0), PKG_HASH_TYPE_BLAKE2S_RAW); 76 ATF_REQUIRE_EQ(pkg_checksum_file_get_type("42$", 0), PKG_HASH_TYPE_UNKNOWN); 77 ATF_REQUIRE_EQ(pkg_checksum_file_get_type("", 0), PKG_HASH_TYPE_UNKNOWN); 78 } 79 80 ATF_TC_BODY(check_symlinks, tc) 81 { 82 char *sum; 83 84 ATF_REQUIRE_EQ(symlink("foo", "bar"), 0); 85 86 sum = pkg_checksum_symlink("bar", PKG_HASH_TYPE_SHA256_HEX); 87 ATF_REQUIRE_STREQ(sum, "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"); 88 89 ATF_CHECK(pkg_checksum_validate_file("bar", "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae") == 0); 90 free(sum); 91 92 sum = pkg_checksum_generate_file("bar", PKG_HASH_TYPE_SHA256_HEX); 93 ATF_REQUIRE_STREQ(sum, "1$2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae"); 94 free(sum); 95 96 sum = pkg_checksum_generate_file("bar", PKG_HASH_TYPE_BLAKE2_BASE32); 97 ATF_REQUIRE_STREQ(sum, "2$kgygnaah7wxsgn1wkuic4j78zq8dicmx53picmma99ogmkbd7k5nhuxr5xxemz6yzjab15oor3tjt7nupj8mh764y7kddbne7qw9agn"); 98 free(sum); 99 sum = pkg_checksum_generate_file("bar", PKG_HASH_TYPE_BLAKE2S_BASE32); 100 ATF_REQUIRE_STREQ(sum, "5$eoiiccdoiuz9acwfo7fxi6abnrfdtg81mz5ccx7tbg5ny9755g7y"); 101 free(sum); 102 103 ATF_CHECK(pkg_checksum_validate_file("bar", "2$kgygnaah7wxsgn1wkuic4j78zq8dicmx53picmma99ogmkbd7k5nhuxr5xxemz6yzjab15oor3tjt7nupj8mh764y7kddbne7qw9agn") == 0); 104 ATF_CHECK(pkg_checksum_validate_file("bar", "5$eoiiccdoiuz9acwfo7fxi6abnrfdtg81mz5ccx7tbg5ny9755g7y") == 0); 105 ATF_CHECK(pkg_checksum_validate_file("bar", "1$2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae") == 0); 106 } 107 108 ATF_TC(check_files); 109 110 ATF_TC_HEAD(check_files, tc) 111 { 112 atf_tc_set_md_var(tc, "descr", "testing checksums on files"); 113 } 114 115 ATF_TC_BODY(check_files, tc) 116 { 117 FILE *f; 118 char *sum; 119 120 f = fopen("foo", "w"); 121 fprintf(f, "bar\n"); 122 fclose(f); 123 124 sum = pkg_checksum_file("foo", PKG_HASH_TYPE_SHA256_HEX); 125 ATF_REQUIRE_STREQ(sum, "7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730"); 126 free(sum); 127 128 ATF_CHECK(pkg_checksum_validate_file("foo", "7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730") == 0); 129 130 sum=pkg_checksum_generate_file("foo", PKG_HASH_TYPE_SHA256_HEX); 131 ATF_REQUIRE_STREQ(sum, "1$7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730"); 132 free(sum); 133 134 sum=pkg_checksum_generate_file("foo", PKG_HASH_TYPE_SHA256_HEX); 135 ATF_CHECK_MSG(pkg_checksum_validate_fileat(AT_FDCWD, "foo", "7d865e959b2466918c9863afca942d0fb89d7c9ac0c99bafc3749504ded97730") == 0, "pkg_checksum_validate_fileat failed (%d,%s)", errno, strerror(errno)); 136 free(sum); 137 138 ATF_REQUIRE_EQ(pkg_checksum_generate_fileat(AT_FDCWD, "nonexistent", PKG_HASH_TYPE_BLAKE2_BASE32), NULL); 139 140 ATF_REQUIRE_EQ(pkg_checksum_symlinkat(AT_FDCWD, "nonexistent", PKG_HASH_TYPE_BLAKE2_BASE32), NULL); 141 ATF_REQUIRE_EQ(pkg_checksum_file("nonexistent", 42), NULL); 142 ATF_REQUIRE_EQ(pkg_checksum_data("a", 1, 42), NULL); 143 144 sum = pkg_checksum_data("a", 0, PKG_HASH_TYPE_BLAKE2_BASE32); 145 ATF_REQUIRE_STREQ(sum, "u3xsc8fhkf9ntjikcz3hcsg1h5n59yqmz8s483emc8gessm4qnpk7ikhgqcmmz98ci391sdx565bazeffh1djkzkep7j1qqgeawsc6y"); 146 free(sum); 147 148 sum = pkg_checksum_file("foo", PKG_HASH_TYPE_BLAKE2_BASE32); 149 ATF_REQUIRE_STREQ(sum, "gf8mcrnmm6p6hg6wa9xkfb98zo8g6nxu8z4q7s93boz8hzf5ogrsr4qgpsb7utd6speio3op18ocyrsa9ms8jj15byttiq7ofbih8gn"); 150 free(sum); 151 152 sum = pkg_checksum_file("foo", PKG_HASH_TYPE_BLAKE2S_BASE32); 153 ATF_REQUIRE_STREQ(sum, "dqi4rzroazhfbq4sd33ektsg3jjsrye7mc37ggsa9bt3mhxsyddy"); 154 free(sum); 155 156 } 157 158 ATF_TC_BODY(check_pkg, tc) 159 { 160 struct pkg *p = NULL; 161 pkg_new(&p, PKG_INSTALLED); 162 pkg_set(p, PKG_ATTR_NAME, "test"); 163 pkg_set(p, PKG_ATTR_ORIGIN, "origin"); 164 pkg_set(p, PKG_ATTR_ARCH, "*"); 165 char *sum = xcalloc(pkg_checksum_type_size(PKG_HASH_TYPE_SHA256_HEX) * 2, sizeof(char)); 166 167 ATF_REQUIRE_EQ(pkg_checksum_generate(NULL, sum, pkg_checksum_type_size(PKG_HASH_TYPE_SHA256_HEX) * 2, PKG_HASH_TYPE_SHA256_HEX, false, false, false), EPKG_FATAL); 168 ATF_REQUIRE_EQ(pkg_checksum_generate(p, sum, pkg_checksum_type_size(PKG_HASH_TYPE_SHA256_HEX) * 2, 42, false, false, false), EPKG_FATAL); 169 ATF_REQUIRE_EQ(pkg_checksum_generate(p, sum, 2, PKG_HASH_TYPE_SHA256_HEX, false, false, false), EPKG_FATAL); 170 ATF_CHECK(pkg_checksum_generate(p, sum, pkg_checksum_type_size(PKG_HASH_TYPE_SHA256_HEX) * 2, PKG_HASH_TYPE_SHA256_HEX, false, false, false) == EPKG_OK); 171 ATF_REQUIRE_STREQ(sum, "2$1$c92e2953e828678424ea69eec32ee18b233fcbe3007c35fc7f742710f12b2d86"); 172 ATF_REQUIRE_EQ(pkg_checksum_get_type(sum, -1), PKG_HASH_TYPE_SHA256_HEX); 173 free(sum); 174 175 sum = xcalloc(pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2_BASE32) * 2, sizeof(char)); 176 ATF_CHECK(pkg_checksum_generate(p, sum, pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2_BASE32) * 2, PKG_HASH_TYPE_BLAKE2_BASE32, false, false, false) == EPKG_OK); 177 ATF_REQUIRE_STREQ(sum, "2$2$cpshbd67gsbe1ds1rr17wya3onw5k75fpqeh1dj6ftpgizsiozd7tqkok3zhinzk3sp7dqk1unko7hzghx65m1o7nwhkgom6rbzno8y"); 178 ATF_REQUIRE_EQ(pkg_checksum_get_type(sum, -1), PKG_HASH_TYPE_BLAKE2_BASE32); 179 free(sum); 180 181 sum = xcalloc(pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2S_BASE32) * 2, sizeof(char)); 182 ATF_CHECK(pkg_checksum_generate(p, sum, pkg_checksum_type_size(PKG_HASH_TYPE_BLAKE2S_BASE32) * 2, PKG_HASH_TYPE_BLAKE2S_BASE32, false, false, false) == EPKG_OK); 183 ATF_REQUIRE_STREQ(sum, "2$5$ea9pqrut8o9q7oin9ddd5gxcx4j5a99negxmfxxrx1swih4n7gzb"); 184 ATF_REQUIRE_EQ(pkg_checksum_get_type(sum, -1), PKG_HASH_TYPE_BLAKE2S_BASE32); 185 free(sum); 186 187 pkg_free(p); 188 } 189 190 ATF_TP_ADD_TCS(tp) 191 { 192 ATF_TP_ADD_TC(tp, check_symlinks); 193 ATF_TP_ADD_TC(tp, check_files); 194 ATF_TP_ADD_TC(tp, check_pkg); 195 ATF_TP_ADD_TC(tp, check_types); 196 ATF_TP_ADD_TC(tp, check_validity); 197 198 return (atf_no_error()); 199 }