08e8a834fac5e3b7352e6db0c2c9bfa3ef7d0cc0
[platform/upstream/libzypp.git] / tests / zypp / KeyRing_test.cc
1
2 #include <iostream>
3 #include <fstream>
4 #include <list>
5 #include <string>
6
7 #include "zypp/base/Logger.h"
8 #include "zypp/base/Exception.h"
9 #include "zypp/KeyRing.h"
10 #include "zypp/PublicKey.h"
11 #include "zypp/TmpPath.h"
12
13 #include <boost/test/unit_test.hpp>
14 #include <boost/test/parameterized_test.hpp>
15 #include <boost/test/unit_test_log.hpp>
16
17 #include "KeyRingTestReceiver.h"
18
19 using boost::unit_test::test_suite;
20 using boost::unit_test::test_case;
21 using namespace boost::unit_test::log;
22
23 using namespace std;
24 using namespace zypp;
25 using namespace zypp::filesystem;
26
27 void keyring_test( const string &dir )
28 {
29   PublicKey key( Pathname(dir) + "public.asc" );
30   
31   
32
33  /** 
34   * scenario #1
35   * import a not trusted key
36   * ask for trust, answer yes
37   * ask for import, answer no
38   */
39   {
40     KeyRingTestReceiver keyring_callbacks;
41     KeyRingTestSignalReceiver receiver;
42     // base sandbox for playing
43     TmpDir tmp_dir;
44     KeyRing keyring( tmp_dir.path() );
45
46     BOOST_CHECK_EQUAL( keyring.publicKeys().size(), (unsigned) 0 );
47     BOOST_CHECK_EQUAL( keyring.trustedPublicKeys().size(), (unsigned) 0 );
48   
49     keyring.importKey( key, false );
50     
51     BOOST_CHECK_EQUAL( keyring.publicKeys().size(), (unsigned) 1 );
52     BOOST_CHECK_EQUAL( keyring.trustedPublicKeys().size(), (unsigned) 0 );
53     
54     BOOST_CHECK_MESSAGE( keyring.isKeyKnown( key.id() ), "Imported untrusted key should be known");
55     BOOST_CHECK_MESSAGE( ! keyring.isKeyTrusted( key.id() ), "Imported untrusted key should be untrusted");
56     
57     keyring_callbacks.answerTrustKey(true);
58     bool to_continue = keyring.verifyFileSignatureWorkflow( Pathname(dir) + "repomd.xml", "Blah Blah", Pathname(dir) + "repomd.xml.asc");
59   
60     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptUnknownKey(), "Should not ask for unknown key, it was known");
61     BOOST_CHECK_MESSAGE( keyring_callbacks.askedTrustKey(), "Verify Signature Workflow with only 1 untrusted key should ask user wether to trust");
62     BOOST_CHECK_MESSAGE( keyring_callbacks.askedImportKey(), "Trusting a key should ask for import");
63     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptVerFailed(), "The signature validates");
64     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptUnsignedFile(), "It is a signed file, so dont ask the opposite");
65     
66     BOOST_CHECK_MESSAGE( to_continue, "We did not import, but we trusted and signature validates.");
67   }
68   
69   /** 
70   * scenario #1.1
71   * import a not trusted key
72   * ask for trust, answer yes
73   * ask for import, answer no
74   * vorrupt the file and check
75   */
76   {
77     KeyRingTestReceiver keyring_callbacks;
78     KeyRingTestSignalReceiver receiver;
79     // base sandbox for playing
80     TmpDir tmp_dir;
81     KeyRing keyring( tmp_dir.path() );
82     
83     BOOST_CHECK_EQUAL( keyring.publicKeys().size(), (unsigned) 0 );
84     BOOST_CHECK_EQUAL( keyring.trustedPublicKeys().size(), (unsigned) 0 );
85   
86     keyring.importKey( key, false );
87     
88     keyring_callbacks.answerTrustKey(true);
89     
90     // now we will recheck with a corrupted file
91     bool to_continue = keyring.verifyFileSignatureWorkflow( Pathname(dir) + "repomd.xml.corrupted", "Blah Blah", Pathname(dir) + "repomd.xml.asc");
92     
93     // check wether the user got the right questions
94     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptUnknownKey(), "Should not ask for unknown key, it was known");
95     BOOST_CHECK_MESSAGE( keyring_callbacks.askedTrustKey(), "Verify Signature Workflow with only 1 untrusted key should ask user wether to trust");
96     BOOST_CHECK_MESSAGE( keyring_callbacks.askedImportKey(), "Trusting a key should ask for import");
97     BOOST_CHECK_MESSAGE( keyring_callbacks.askedAcceptVerFailed(), "The signature does not validates");
98     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptUnsignedFile(), "It is a signed file, so dont ask the opposite");
99     
100     BOOST_CHECK_MESSAGE( ! to_continue, "We did not continue with a corrupted file");
101   }
102   
103    /** 
104   * scenario #1.2
105   * import a not trusted key
106   * ask for trust, answer yes
107   * ask for import, answer no
108   * check without signature
109   */
110   {
111     KeyRingTestReceiver keyring_callbacks;
112     KeyRingTestSignalReceiver receiver;
113     // base sandbox for playing
114     TmpDir tmp_dir;
115     KeyRing keyring( tmp_dir.path() );
116     
117     keyring.importKey( key, false );
118     
119     keyring_callbacks.answerTrustKey(true);
120     // now we will recheck with a unsigned file
121     bool to_continue = keyring.verifyFileSignatureWorkflow( Pathname(dir) + "repomd.xml", "Blah Blah", Pathname() );
122     
123     // check wether the user got the right questions
124     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptUnknownKey(), "Should not ask for unknown key, it was known");
125     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedTrustKey(), "No signature, no key to trust");
126     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedImportKey(), "No signature, no key to import");
127     BOOST_CHECK_MESSAGE( keyring_callbacks.askedAcceptUnsignedFile(), "Ask the user wether to accept an unsigned file");
128     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptVerFailed(), "There is no signature to verify");
129     
130     BOOST_CHECK_MESSAGE( ! to_continue, "We did not continue with a unsigned file");
131   }
132   
133  /** scenario #2
134   * empty keyring
135   * should ask for unknown key
136   * answer no
137   */
138   {
139     KeyRingTestReceiver keyring_callbacks;
140     KeyRingTestSignalReceiver receiver;
141     // base sandbox for playing
142     TmpDir tmp_dir;
143     KeyRing keyring( tmp_dir.path() );
144     
145     BOOST_CHECK_MESSAGE( ! keyring.isKeyKnown( key.id() ), "empty keyring has not known keys");
146     
147     //keyring_callbacks.answerAcceptUnknownKey(true);
148     bool to_continue = keyring.verifyFileSignatureWorkflow( Pathname(dir) + "repomd.xml", "Blah Blah", Pathname(dir) + "repomd.xml.asc");
149     BOOST_CHECK_MESSAGE(keyring_callbacks.askedAcceptUnknownKey(), "Should ask to accept unknown key, empty keyring");
150     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedTrustKey(), "Unknown key cant be trusted");
151     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedImportKey(), "Unknown key cant be imported");
152     
153     BOOST_CHECK_MESSAGE( ! to_continue, "We answered no to accept unknown key");
154   }
155   
156   /** scenario #3
157   * import trusted key
158   * should ask nothing
159   * should emit signal
160   */
161   {
162     KeyRingTestReceiver keyring_callbacks;
163     KeyRingTestSignalReceiver receiver;
164     // base sandbox for playing
165     TmpDir tmp_dir;
166     KeyRing keyring( tmp_dir.path() );
167     
168     BOOST_CHECK_EQUAL( keyring.publicKeys().size(), (unsigned) 0 );
169     BOOST_CHECK_EQUAL( keyring.trustedPublicKeys().size(), (unsigned) 0 );
170   
171     keyring.importKey( key, true );
172     
173     BOOST_CHECK_EQUAL( receiver._trusted_key_added_called, true );
174     
175     BOOST_CHECK_EQUAL( keyring.publicKeys().size(), (unsigned) 0 );
176     BOOST_CHECK_EQUAL( keyring.trustedPublicKeys().size(), (unsigned) 1 );
177     
178     BOOST_CHECK_MESSAGE( keyring.isKeyKnown( key.id() ), "Imported trusted key should be known");
179     BOOST_CHECK_MESSAGE( keyring.isKeyTrusted( key.id() ), "Imported trusted key should be trusted");
180     
181     bool to_continue = keyring.verifyFileSignatureWorkflow( Pathname(dir) + "repomd.xml", "Blah Blah", Pathname(dir) + "repomd.xml.asc");
182   
183     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptUnknownKey(), "Should not ask for unknown key, it was known");
184     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedTrustKey(), "Verify Signature Workflow with only 1 untrusted key should ask user wether to trust");
185     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedImportKey(), "Trusting a key should ask for import");
186     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptVerFailed(), "The signature validates");
187     BOOST_CHECK_MESSAGE( ! keyring_callbacks.askedAcceptUnsignedFile(), "It is a signed file, so dont ask the opposite");
188     
189     BOOST_CHECK_MESSAGE( to_continue, "We did not import, but we trusted and signature validates.");
190   }
191   //keyring.importKey( key, true );
192   //BOOST_CHECK_EQUAL( receiver._trusted_key_added_called, true );
193   //BOOST_CHECK_EQUAL( keyring.trustedPublicKeys().size(), 1 );
194
195   /* check signature id can be extracted */
196   
197 }
198
199 void keyring_signature_test( const string &dir )
200 {
201   PublicKey key( Pathname(dir) + "public.asc" );
202
203   {
204     KeyRingTestReceiver keyring_callbacks;
205     KeyRingTestSignalReceiver receiver;
206     // base sandbox for playing
207     TmpDir tmp_dir;
208     KeyRing keyring( tmp_dir.path() );
209     
210     BOOST_CHECK_EQUAL( keyring.readSignatureKeyId( Pathname(dir) + "repomd.xml.asc" ), "BD61D89BD98821BE" );
211     BOOST_CHECK_THROW( keyring.readSignatureKeyId(Pathname()), Exception );
212     TmpFile tmp;
213     BOOST_CHECK_EQUAL( keyring.readSignatureKeyId(tmp.path()), "" );
214
215     keyring.importKey(key);
216
217     BOOST_CHECK(keyring.verifyFileSignature( Pathname(dir) + "repomd.xml", Pathname(dir) + "repomd.xml.asc"));
218     BOOST_CHECK( ! keyring.verifyFileSignature( Pathname(dir) + "repomd.xml.corrupted", Pathname(dir) + "repomd.xml.asc"));
219   }
220 }
221
222 test_suite*
223 init_unit_test_suite( int argc, char* argv[] )
224 {
225   string datadir;
226   if (argc < 2)
227   {
228     datadir = TESTS_SRC_DIR;
229     datadir = (Pathname(datadir) + "/zypp/data/KeyRing").asString();
230     cout << "keyring_test:"
231       " path to directory with test data required as parameter. Using " << datadir  << endl;
232     //return (test_suite *)0;
233   }
234   else
235   {
236     datadir = argv[1];
237   }
238
239   std::string const params[] = { datadir };
240     //set_log_stream( std::cout );
241   test_suite* test= BOOST_TEST_SUITE( "PublicKeyTest" );
242   test->add(BOOST_PARAM_TEST_CASE( &keyring_test,
243                               (std::string const*)params, params+1));
244   test->add(BOOST_PARAM_TEST_CASE( &keyring_signature_test,
245                               (std::string const*)params, params+1));
246   return test;
247 }
248