4 #include "zypp/target/rpm/RpmDb.h"
5 using target::rpm::RpmDb;
7 #define DATADIR (Pathname(TESTS_SRC_DIR) / "/zypp/data/RpmPkgSigCheck")
9 ///////////////////////////////////////////////////////////////////
11 // - RpmDb::checkPackage (legacy) and RpmDb::checkPackageSignature are
12 // expected to produce the same result, except for ...
14 // Result comparison is not very sophisticated. As the detail strings are
15 // user visible (at least in zypper) we want a notification (breaking testcase)
16 // if something in the rpm format changes.
18 ///////////////////////////////////////////////////////////////////
26 CheckResult( RpmDb::CheckPackageResult && result_r )
27 : result { std::move(result_r) }
30 CheckResult( RpmDb::CheckPackageResult && result_r,
31 std::vector<std::pair<RpmDb::CheckPackageResult,std::string>> && detail_r )
32 : result { std::move(result_r) }
33 { static_cast<std::vector<std::pair<RpmDb::CheckPackageResult,std::string>>&>(detail) = std::move(detail_r); }
35 RpmDb::CheckPackageResult result;
36 RpmDb::CheckPackageDetail detail;
39 bool operator==( const CheckResult & lhs, const CheckResult & rhs )
41 if ( lhs.result != rhs.result )
43 // protect against reordered details:
44 if ( lhs.detail.size() != rhs.detail.size() )
46 for ( const auto & l : lhs.detail )
48 if ( std::find( rhs.detail.begin(), rhs.detail.end(), l ) == rhs.detail.end() )
54 std::ostream & operator<<( std::ostream & str, const CheckResult & obj )
56 str << "R: " << obj.result;
57 for ( const auto & el : obj.detail )
58 str << endl << " " << el.first << " | " << el.second;
62 CheckResult gcheckPackage( const Pathname & path_r )
65 res.result = test.target().rpmDb().checkPackage( path_r, res.detail );
66 // cout << "==-" << path_r << endl;
67 // cout << res << endl;
71 CheckResult gcheckPackageSignature( const Pathname & path_r )
74 res.result = test.target().rpmDb().checkPackageSignature( path_r, res.detail );
75 // cout << "==!" << path_r << endl;
76 // cout << res << endl;
82 BOOST_AUTO_TEST_CASE(no_pkg)
84 Pathname rpm { DATADIR/"no.rpm" };
85 CheckResult cp { gcheckPackage( rpm ) };
86 CheckResult cs { gcheckPackageSignature( rpm ) };
87 BOOST_CHECK_EQUAL( cp, cs );
89 CheckResult xpct { RpmDb::CHK_ERROR, {/*empty details*/} };
90 BOOST_CHECK_EQUAL( xpct, cs );
93 BOOST_AUTO_TEST_CASE(unsigned_pkg)
95 Pathname rpm { DATADIR/"unsigned.rpm" };
96 CheckResult cp { gcheckPackage( rpm ) };
97 CheckResult cs { gcheckPackageSignature( rpm ) };
98 // For unsigned packages the final result differs!
99 // (but only if the digests are OK)
100 BOOST_CHECK_EQUAL( cp.result, RpmDb::CHK_OK );
101 BOOST_CHECK_EQUAL( cs.result, RpmDb::CHK_NOSIG );
102 BOOST_CHECK_EQUAL( cp.detail, cs.detail );
104 CheckResult xpct { RpmDb::CHK_NOSIG, {
105 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
106 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
107 { RpmDb::CHK_OK, " Payload SHA256 digest: OK" },
108 { RpmDb::CHK_OK, " MD5 digest: OK" },
109 { RpmDb::CHK_NOSIG, " Package is not signed!" },
111 BOOST_CHECK_EQUAL( xpct, cs );
114 BOOST_AUTO_TEST_CASE(unsigned_broken_pkg)
116 Pathname rpm { DATADIR/"unsigned_broken.rpm" };
117 CheckResult cp { gcheckPackage( rpm ) };
118 CheckResult cs { gcheckPackageSignature( rpm ) };
119 // Unsigned, but a broken digest 'superseeds' CHK_NOSIG
120 BOOST_CHECK_EQUAL( cp, cs );
122 CheckResult xpct { RpmDb::CHK_FAIL, {
123 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
124 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
125 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
126 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected e3f474f75d2d2b267da4ff80fc071dd7 != cebe1e7d39b4356639a0779aa23f6e27)" },
128 BOOST_CHECK_EQUAL( xpct, cs );
131 BOOST_AUTO_TEST_CASE(unsigned_broken_header_pkg)
133 Pathname rpm { DATADIR/"unsigned_broken_header.rpm" };
134 CheckResult cp { gcheckPackage( rpm ) };
135 CheckResult cs { gcheckPackageSignature( rpm ) };
136 // Unsigned, but a broken digest 'superseeds' CHK_NOSIG
137 BOOST_CHECK_EQUAL( cp, cs );
139 CheckResult xpct { RpmDb::CHK_FAIL, {
140 { RpmDb::CHK_FAIL, " Header SHA1 digest: BAD (Expected d6768447e13388b0c35fb151ebfa8f6646a115e9 != dd761ace671a5eb2669b269faf22a3cd72792138)" },
141 { RpmDb::CHK_FAIL, " Header SHA256 digest: BAD (Expected 2ce9f41bc0de68b4cb1aa1e18c1bea43dfaa01299ae61ef3e4466df332c792e5 != 4a9410db7131cead773afe1876f2490023ccc7dc47cbba47807430c53ea9649d)" },
142 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
143 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected e3f474f75d2d2b267da4ff80fc071dd7 != 9afd6b52896d23910280ddded1921071)" },
145 BOOST_CHECK_EQUAL( xpct, cs );
148 BOOST_AUTO_TEST_CASE(signed_pkg_nokey)
150 Pathname rpm { DATADIR/"signed.rpm" };
151 CheckResult cp { gcheckPackage( rpm ) };
152 CheckResult cs { gcheckPackageSignature( rpm ) };
153 BOOST_CHECK_EQUAL( cp, cs );
155 CheckResult xpct { RpmDb::CHK_NOKEY, {
156 { RpmDb::CHK_NOKEY, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY" },
157 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
158 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
159 { RpmDb::CHK_OK, " Payload SHA256 digest: OK" },
160 { RpmDb::CHK_OK, " MD5 digest: OK" },
162 BOOST_CHECK_EQUAL( xpct, cs );
165 BOOST_AUTO_TEST_CASE(signed_broken_pkg_nokey)
167 Pathname rpm { DATADIR/"signed_broken.rpm" };
168 CheckResult cp { gcheckPackage( rpm ) };
169 CheckResult cs { gcheckPackageSignature( rpm ) };
170 BOOST_CHECK_EQUAL( cp, cs );
172 CheckResult xpct { RpmDb::CHK_FAIL, {
173 { RpmDb::CHK_NOKEY, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY" },
174 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
175 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
176 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
177 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected 8e64684e4d5bd90c3c13f76ecbda9ee2 != 442a473472708c39f3ac2b5eb38b476f)" },
179 BOOST_CHECK_EQUAL( xpct, cs );
182 BOOST_AUTO_TEST_CASE(signed_broken_header_pkg_nokey)
184 Pathname rpm { DATADIR/"signed_broken_header.rpm" };
185 CheckResult cp { gcheckPackage( rpm ) };
186 CheckResult cs { gcheckPackageSignature( rpm ) };
187 BOOST_CHECK_EQUAL( cp, cs );
189 CheckResult xpct { RpmDb::CHK_FAIL, {
190 { RpmDb::CHK_FAIL, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: BAD" },
191 { RpmDb::CHK_FAIL, " Header SHA1 digest: BAD (Expected 9ca2e3aec038e562d33442271ee52c08ded0d637 != 95286fd653f927df0a42746e310861d3f89bb75c)" },
192 { RpmDb::CHK_FAIL, " Header SHA256 digest: BAD (Expected e88100656c8e06b6e4bb9155f0dd111ef8042866941f02b623cb46e12a82f732 != 76b343bcb9b8aaf9998fdcf7392e234944a0b078c67667fa0d658208b9a66983)" },
193 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
194 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected 8e64684e4d5bd90c3c13f76ecbda9ee2 != 81df819a7d94638ff3ffe0bb93a7d177)" },
197 BOOST_CHECK_EQUAL( xpct, cs );
201 ///////////////////////////////////////////////////////////////////
202 BOOST_AUTO_TEST_CASE(add_key)
204 PublicKey key { Pathname(DATADIR)/"signed.key" };
205 //cout << key << endl;
206 test.target().rpmDb().importPubkey( key );
208 ///////////////////////////////////////////////////////////////////
211 BOOST_AUTO_TEST_CASE(signed_pkg_withkey)
213 Pathname rpm { DATADIR/"signed.rpm" };
214 CheckResult cp { gcheckPackage( rpm ) };
215 CheckResult cs { gcheckPackageSignature( rpm ) };
216 BOOST_CHECK_EQUAL( cp, cs );
218 CheckResult xpct { RpmDb::CHK_OK, {
219 { RpmDb::CHK_OK, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: OK" },
220 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
221 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
222 { RpmDb::CHK_OK, " Payload SHA256 digest: OK" },
223 { RpmDb::CHK_OK, " MD5 digest: OK" },
225 BOOST_CHECK_EQUAL( xpct, cs );
228 BOOST_AUTO_TEST_CASE(signed_broken_pkg_withkey)
230 Pathname rpm { DATADIR/"signed_broken.rpm" };
231 CheckResult cp { gcheckPackage( rpm ) };
232 CheckResult cs { gcheckPackageSignature( rpm ) };
233 BOOST_CHECK_EQUAL( cp, cs );
235 CheckResult xpct { RpmDb::CHK_FAIL, {
236 { RpmDb::CHK_OK, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: OK" },
237 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
238 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
239 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
240 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected 8e64684e4d5bd90c3c13f76ecbda9ee2 != 442a473472708c39f3ac2b5eb38b476f)" },
242 BOOST_CHECK_EQUAL( xpct, cs );
245 BOOST_AUTO_TEST_CASE(signed_broken_header_pkg_withkey)
247 Pathname rpm { DATADIR/"signed_broken_header.rpm" };
248 CheckResult cp { gcheckPackage( rpm ) };
249 CheckResult cs { gcheckPackageSignature( rpm ) };
250 BOOST_CHECK_EQUAL( cp, cs );
252 CheckResult xpct { RpmDb::CHK_FAIL, {
253 { RpmDb::CHK_FAIL, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: BAD" },
254 { RpmDb::CHK_FAIL, " Header SHA1 digest: BAD (Expected 9ca2e3aec038e562d33442271ee52c08ded0d637 != 95286fd653f927df0a42746e310861d3f89bb75c)" },
255 { RpmDb::CHK_FAIL, " Header SHA256 digest: BAD (Expected e88100656c8e06b6e4bb9155f0dd111ef8042866941f02b623cb46e12a82f732 != 76b343bcb9b8aaf9998fdcf7392e234944a0b078c67667fa0d658208b9a66983)" },
256 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
257 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected 8e64684e4d5bd90c3c13f76ecbda9ee2 != 81df819a7d94638ff3ffe0bb93a7d177)" },
259 BOOST_CHECK_EQUAL( xpct, cs );