4 #include "zypp/target/rpm/RpmDb.h"
5 using target::rpm::RpmDb;
7 #define DATADIR (Pathname(TESTS_SRC_DIR) / "/zypp/data/RpmPkgSigCheck")
9 #ifndef HAVE_NO_RPMTSSETVFYFLAGS
10 #define HAVE_RPMTSSETVFYFLAGS
13 ///////////////////////////////////////////////////////////////////
15 // - RpmDb::checkPackage (legacy) and RpmDb::checkPackageSignature are
16 // expected to produce the same result, except for ...
18 // Result comparison is not very sophisticated. As the detail strings are
19 // user visible (at least in zypper) we want a notification (breaking testcase)
20 // if something in the rpm format changes.
22 ///////////////////////////////////////////////////////////////////
30 CheckResult( RpmDb::CheckPackageResult && result_r )
31 : result { std::move(result_r) }
34 CheckResult( RpmDb::CheckPackageResult && result_r,
35 std::vector<std::pair<RpmDb::CheckPackageResult,std::string>> && detail_r )
36 : result { std::move(result_r) }
37 { static_cast<std::vector<std::pair<RpmDb::CheckPackageResult,std::string>>&>(detail) = std::move(detail_r); }
39 RpmDb::CheckPackageResult result;
40 RpmDb::CheckPackageDetail detail;
43 bool operator==( const CheckResult & lhs, const CheckResult & rhs )
45 if ( lhs.result != rhs.result )
47 // protect against reordered details:
48 if ( lhs.detail.size() != rhs.detail.size() )
50 for ( const auto & l : lhs.detail )
52 if ( std::find( rhs.detail.begin(), rhs.detail.end(), l ) == rhs.detail.end() )
58 std::ostream & operator<<( std::ostream & str, const CheckResult & obj )
60 str << "R: " << obj.result;
61 for ( const auto & el : obj.detail )
62 str << endl << " " << el.first << " | " << el.second;
66 CheckResult gcheckPackage( const Pathname & path_r )
69 res.result = test.target().rpmDb().checkPackage( path_r, res.detail );
70 // cout << "==-" << path_r << endl;
71 // cout << res << endl;
75 CheckResult gcheckPackageSignature( const Pathname & path_r )
78 res.result = test.target().rpmDb().checkPackageSignature( path_r, res.detail );
79 // cout << "==!" << path_r << endl;
80 // cout << res << endl;
86 BOOST_AUTO_TEST_CASE(no_pkg)
88 Pathname rpm { DATADIR/"no.rpm" };
89 CheckResult cp { gcheckPackage( rpm ) };
90 CheckResult cs { gcheckPackageSignature( rpm ) };
91 BOOST_CHECK_EQUAL( cp, cs );
93 CheckResult xpct { RpmDb::CHK_ERROR, {/*empty details*/} };
94 BOOST_CHECK_EQUAL( xpct, cs );
97 BOOST_AUTO_TEST_CASE(unsigned_pkg)
99 Pathname rpm { DATADIR/"unsigned.rpm" };
100 CheckResult cp { gcheckPackage( rpm ) };
101 CheckResult cs { gcheckPackageSignature( rpm ) };
102 // For unsigned packages the final result differs!
103 // (but only if the digests are OK)
104 BOOST_CHECK_EQUAL( cp.result, RpmDb::CHK_OK );
105 BOOST_CHECK_EQUAL( cs.result, RpmDb::CHK_NOSIG );
106 BOOST_CHECK_EQUAL( cp.detail, cs.detail );
108 CheckResult xpct { RpmDb::CHK_NOSIG, {
109 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
110 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
111 { RpmDb::CHK_OK, " Payload SHA256 digest: OK" },
112 { RpmDb::CHK_OK, " MD5 digest: OK" },
113 { RpmDb::CHK_NOSIG, " Package is not signed!" },
115 BOOST_CHECK_EQUAL( xpct, cs );
118 BOOST_AUTO_TEST_CASE(unsigned_broken_pkg)
120 Pathname rpm { DATADIR/"unsigned_broken.rpm" };
121 CheckResult cp { gcheckPackage( rpm ) };
122 CheckResult cs { gcheckPackageSignature( rpm ) };
123 // Unsigned, but a broken digest 'superseeds' CHK_NOSIG
124 BOOST_CHECK_EQUAL( cp, cs );
126 CheckResult xpct { RpmDb::CHK_FAIL, {
127 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
128 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
129 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
130 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected e3f474f75d2d2b267da4ff80fc071dd7 != cebe1e7d39b4356639a0779aa23f6e27)" },
132 BOOST_CHECK_EQUAL( xpct, cs );
135 BOOST_AUTO_TEST_CASE(unsigned_broken_header_pkg)
137 Pathname rpm { DATADIR/"unsigned_broken_header.rpm" };
138 CheckResult cp { gcheckPackage( rpm ) };
139 CheckResult cs { gcheckPackageSignature( rpm ) };
140 // Unsigned, but a broken digest 'superseeds' CHK_NOSIG
141 BOOST_CHECK_EQUAL( cp, cs );
143 CheckResult xpct { RpmDb::CHK_FAIL, {
144 { RpmDb::CHK_FAIL, " Header SHA1 digest: BAD (Expected d6768447e13388b0c35fb151ebfa8f6646a115e9 != dd761ace671a5eb2669b269faf22a3cd72792138)" },
145 { RpmDb::CHK_FAIL, " Header SHA256 digest: BAD (Expected 2ce9f41bc0de68b4cb1aa1e18c1bea43dfaa01299ae61ef3e4466df332c792e5 != 4a9410db7131cead773afe1876f2490023ccc7dc47cbba47807430c53ea9649d)" },
146 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
147 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected e3f474f75d2d2b267da4ff80fc071dd7 != 9afd6b52896d23910280ddded1921071)" },
149 BOOST_CHECK_EQUAL( xpct, cs );
152 BOOST_AUTO_TEST_CASE(signed_pkg_nokey)
154 Pathname rpm { DATADIR/"signed.rpm" };
155 CheckResult cp { gcheckPackage( rpm ) };
156 CheckResult cs { gcheckPackageSignature( rpm ) };
157 BOOST_CHECK_EQUAL( cp, cs );
159 CheckResult xpct { RpmDb::CHK_NOKEY, {
160 { RpmDb::CHK_NOKEY, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY" },
161 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
162 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
163 { RpmDb::CHK_OK, " Payload SHA256 digest: OK" },
164 { RpmDb::CHK_OK, " MD5 digest: OK" },
165 #ifdef HAVE_RPMTSSETVFYFLAGS
166 { RpmDb::CHK_NOKEY, " V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY" },
169 BOOST_CHECK_EQUAL( xpct, cs );
172 BOOST_AUTO_TEST_CASE(signed_broken_pkg_nokey)
174 Pathname rpm { DATADIR/"signed_broken.rpm" };
175 CheckResult cp { gcheckPackage( rpm ) };
176 CheckResult cs { gcheckPackageSignature( rpm ) };
177 BOOST_CHECK_EQUAL( cp, cs );
179 CheckResult xpct { RpmDb::CHK_FAIL, {
180 { RpmDb::CHK_NOKEY, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: NOKEY" },
181 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
182 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
183 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
184 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected 8e64684e4d5bd90c3c13f76ecbda9ee2 != 442a473472708c39f3ac2b5eb38b476f)" },
185 #ifdef HAVE_RPMTSSETVFYFLAGS
186 { RpmDb::CHK_FAIL, " V3 RSA/SHA256 Signature, key ID 3dbdc284: BAD" },
189 BOOST_CHECK_EQUAL( xpct, cs );
192 BOOST_AUTO_TEST_CASE(signed_broken_header_pkg_nokey)
194 Pathname rpm { DATADIR/"signed_broken_header.rpm" };
195 CheckResult cp { gcheckPackage( rpm ) };
196 CheckResult cs { gcheckPackageSignature( rpm ) };
197 BOOST_CHECK_EQUAL( cp, cs );
199 CheckResult xpct { RpmDb::CHK_FAIL, {
200 { RpmDb::CHK_FAIL, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: BAD" },
201 { RpmDb::CHK_FAIL, " Header SHA1 digest: BAD (Expected 9ca2e3aec038e562d33442271ee52c08ded0d637 != 95286fd653f927df0a42746e310861d3f89bb75c)" },
202 { RpmDb::CHK_FAIL, " Header SHA256 digest: BAD (Expected e88100656c8e06b6e4bb9155f0dd111ef8042866941f02b623cb46e12a82f732 != 76b343bcb9b8aaf9998fdcf7392e234944a0b078c67667fa0d658208b9a66983)" },
203 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
204 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected 8e64684e4d5bd90c3c13f76ecbda9ee2 != 81df819a7d94638ff3ffe0bb93a7d177)" },
205 #ifdef HAVE_RPMTSSETVFYFLAGS
206 { RpmDb::CHK_FAIL, " V3 RSA/SHA256 Signature, key ID 3dbdc284: BAD" },
209 BOOST_CHECK_EQUAL( xpct, cs );
213 ///////////////////////////////////////////////////////////////////
214 BOOST_AUTO_TEST_CASE(add_key)
216 PublicKey key { Pathname(DATADIR)/"signed.key" };
217 //cout << key << endl;
218 test.target().rpmDb().importPubkey( key );
220 ///////////////////////////////////////////////////////////////////
223 BOOST_AUTO_TEST_CASE(signed_pkg_withkey)
225 Pathname rpm { DATADIR/"signed.rpm" };
226 CheckResult cp { gcheckPackage( rpm ) };
227 CheckResult cs { gcheckPackageSignature( rpm ) };
228 BOOST_CHECK_EQUAL( cp, cs );
230 CheckResult xpct { RpmDb::CHK_OK, {
231 { RpmDb::CHK_OK, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: OK" },
232 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
233 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
234 { RpmDb::CHK_OK, " Payload SHA256 digest: OK" },
235 { RpmDb::CHK_OK, " MD5 digest: OK" },
236 #ifdef HAVE_RPMTSSETVFYFLAGS
237 { RpmDb::CHK_OK, " V3 RSA/SHA256 Signature, key ID 3dbdc284: OK" },
240 BOOST_CHECK_EQUAL( xpct, cs );
243 BOOST_AUTO_TEST_CASE(signed_broken_pkg_withkey)
245 Pathname rpm { DATADIR/"signed_broken.rpm" };
246 CheckResult cp { gcheckPackage( rpm ) };
247 CheckResult cs { gcheckPackageSignature( rpm ) };
248 BOOST_CHECK_EQUAL( cp, cs );
250 CheckResult xpct { RpmDb::CHK_FAIL, {
251 { RpmDb::CHK_OK, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: OK" },
252 { RpmDb::CHK_OK, " Header SHA1 digest: OK" },
253 { RpmDb::CHK_OK, " Header SHA256 digest: OK" },
254 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
255 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected 8e64684e4d5bd90c3c13f76ecbda9ee2 != 442a473472708c39f3ac2b5eb38b476f)" },
256 #ifdef HAVE_RPMTSSETVFYFLAGS
257 { RpmDb::CHK_FAIL, " V3 RSA/SHA256 Signature, key ID 3dbdc284: BAD" },
260 BOOST_CHECK_EQUAL( xpct, cs );
263 BOOST_AUTO_TEST_CASE(signed_broken_header_pkg_withkey)
265 Pathname rpm { DATADIR/"signed_broken_header.rpm" };
266 CheckResult cp { gcheckPackage( rpm ) };
267 CheckResult cs { gcheckPackageSignature( rpm ) };
268 BOOST_CHECK_EQUAL( cp, cs );
270 CheckResult xpct { RpmDb::CHK_FAIL, {
271 { RpmDb::CHK_FAIL, " Header V3 RSA/SHA256 Signature, key ID 3dbdc284: BAD" },
272 { RpmDb::CHK_FAIL, " Header SHA1 digest: BAD (Expected 9ca2e3aec038e562d33442271ee52c08ded0d637 != 95286fd653f927df0a42746e310861d3f89bb75c)" },
273 { RpmDb::CHK_FAIL, " Header SHA256 digest: BAD (Expected e88100656c8e06b6e4bb9155f0dd111ef8042866941f02b623cb46e12a82f732 != 76b343bcb9b8aaf9998fdcf7392e234944a0b078c67667fa0d658208b9a66983)" },
274 { RpmDb::CHK_FAIL, " Payload SHA256 digest: BAD (Expected 6632dfb6e78fd3346baa860da339acdedf6f019fb1b5448ba1baa6cef67de795 != 85156c232f4c76273bbbb134d8d869e93bbfc845dd0d79016856e5356dd33727)" },
275 { RpmDb::CHK_FAIL, " MD5 digest: BAD (Expected 8e64684e4d5bd90c3c13f76ecbda9ee2 != 81df819a7d94638ff3ffe0bb93a7d177)" },
276 #ifdef HAVE_RPMTSSETVFYFLAGS
277 { RpmDb::CHK_FAIL, " V3 RSA/SHA256 Signature, key ID 3dbdc284: BAD" },
280 BOOST_CHECK_EQUAL( xpct, cs );