1 /*---------------------------------------------------------------------\
3 | |__ / \ / / . \ . \ |
8 \---------------------------------------------------------------------*/
9 /** \file zypp/PublicKey.cc
15 //#include "zypp/base/Logger.h"
17 #include "zypp/base/String.h"
18 #include "zypp/base/Regex.h"
19 #include "zypp/PublicKey.h"
20 #include "zypp/ExternalProgram.h"
21 #include "zypp/TmpPath.h"
22 #include "zypp/PathInfo.h"
23 #include "zypp/base/Exception.h"
24 #include "zypp/base/Logger.h"
25 #include "zypp/Date.h"
26 #include "zypp/TmpPath.h"
32 ///////////////////////////////////////////////////////////////////
34 { /////////////////////////////////////////////////////////////////
36 /////////////////////////////////////////////////////////////////
38 // CLASS NAME : PublicKey::Impl
40 /** PublicKey implementation. */
41 struct PublicKey::Impl
46 Impl( const Pathname & keyfile )
48 PathInfo info( keyfile );
49 MIL << "Takeing pubkey from " << keyfile << " of size " << info.size() << " and sha1 " << filesystem::checksum(keyfile, "sha1") << endl;
51 if ( !info.isExist() )
52 ZYPP_THROW(Exception("Can't read public key from " + keyfile.asString() + ", file not found"));
54 if ( copy( keyfile, _data_file.path() ) != 0 )
55 ZYPP_THROW(Exception("Can't copy public key data from " + keyfile.asString() + " to " + _data_file.path().asString() ));
60 Impl( const filesystem::TmpFile & sharedfile )
61 : _data_file( sharedfile )
65 /** Offer default Impl. */
66 static shared_ptr<Impl> nullimpl()
68 static shared_ptr<Impl> _nullimpl( new Impl );
72 std::string asString() const
73 { return "[" + id() + "-" + str::hexstring(created(),8).substr(2) + "] [" + name() + "] [" + fingerprint() + "]"; }
75 std::string armoredData() const
78 std::string id() const
81 std::string name() const
84 std::string fingerprint() const
85 { return _fingerprint; }
94 { return _data_file.path(); }
100 PathInfo info( _data_file.path() );
101 MIL << "Reading pubkey from " << info.path() << " of size " << info.size() << " and sha1 " << filesystem::checksum(info.path(), "sha1") << endl;
103 static filesystem::TmpDir dir;
108 "--no-default-keyring",
110 "--with-fingerprint",
113 dir.path().asString().c_str(),
120 _data_file.path().asString().c_str(),
124 ExternalProgram prog(argv,ExternalProgram::Discard_Stderr, false, -1, true);
130 // pub:-:1024:17:A84EDAE89C800ACA:971961473:1214043198::-:SuSE Package Signing Key <build@suse.de>:
131 // fpr:::::::::79C179B2E1C820C1890F9994A84EDAE89C800ACA:
132 // sig:::17:A84EDAE89C800ACA:1087899198:::::[selfsig]::13x:
133 // sig:::17:9E40E310000AABA4:980442706::::[User ID not found]:10x:
134 // sig:::1:77B2E6003D25D3D9:980443247::::[User ID not found]:10x:
135 // sub:-:2048:16:197448E88495160C:971961490:1214043258::: [expires: 2008-06-21]
136 // sig:::17:A84EDAE89C800ACA:1087899258:::::[keybind]::18x:
138 for ( line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
143 if ( line[line.size()-1] == '\n' )
144 line.erase( line.size()-1 );
147 std::vector<std::string> words;
148 str::splitFields( line, std::back_inserter(words), ":" );
152 if ( words[0] == "pub" )
157 // take default from pub
160 _created = Date(str::strtonum<Date::ValueType>(words[5]));
161 _expires = Date(str::strtonum<Date::ValueType>(words[6]));
164 else if ( words[0] == "sig" )
166 if ( sawsig || words[words.size()-2] != "13x" )
169 // update creation and expire dates from 1st signature type "13x"
170 if ( ! words[5].empty() )
171 _created = Date(str::strtonum<Date::ValueType>(words[5]));
172 if ( ! words[6].empty() )
173 _expires = Date(str::strtonum<Date::ValueType>(words[6]));
175 else if ( words[0] == "fpr" )
177 _fingerprint = words[9];
179 else if ( words[0] == "uid" )
181 if ( ! words[9].empty() )
187 if ( _id.size() == 0 )
188 ZYPP_THROW( BadKeyException( "File " + _data_file.path().asString() + " doesn't contain public key data" , _data_file.path() ) );
190 //replace all escaped semicolon with real ':'
191 str::replaceAll( _name, "\\x3a", ":" );
193 MIL << "Read pubkey from " << info.path() << ": " << asString() << endl;
197 filesystem::TmpFile _data_file;
201 std::string _fingerprint;
207 friend Impl * rwcowClone<Impl>( const Impl * rhs );
208 /** clone for RWCOW_pointer */
210 { return new Impl( *this ); }
212 ///////////////////////////////////////////////////////////////////
214 ///////////////////////////////////////////////////////////////////
216 // METHOD NAME : PublicKey::PublicKey
217 // METHOD TYPE : Ctor
219 PublicKey::PublicKey()
220 : _pimpl( Impl::nullimpl() )
223 PublicKey::PublicKey( const Pathname & file )
224 : _pimpl( new Impl(file) )
227 PublicKey::PublicKey( const filesystem::TmpFile & sharedfile )
228 : _pimpl( new Impl(sharedfile) )
231 ///////////////////////////////////////////////////////////////////
233 // METHOD NAME : PublicKey::~PublicKey
234 // METHOD TYPE : Dtor
236 PublicKey::~PublicKey()
239 ///////////////////////////////////////////////////////////////////
241 // Forward to implementation:
243 ///////////////////////////////////////////////////////////////////
245 std::string PublicKey::asString() const
246 { return _pimpl->asString(); }
248 std::string PublicKey::armoredData() const
249 { return _pimpl->armoredData(); }
251 std::string PublicKey::id() const
252 { return _pimpl->id(); }
254 std::string PublicKey::name() const
255 { return _pimpl->name(); }
257 std::string PublicKey::fingerprint() const
258 { return _pimpl->fingerprint(); }
260 Date PublicKey::created() const
261 { return _pimpl->created(); }
263 Date PublicKey::expires() const
264 { return _pimpl->expires(); }
266 Pathname PublicKey::path() const
267 { return _pimpl->path(); }
269 bool PublicKey::operator==( PublicKey b ) const
271 return ( b.id() == id()
272 && b.fingerprint() == fingerprint()
273 && b.created() == created() );
276 bool PublicKey::operator==( std::string sid ) const
281 std::ostream & dumpOn( std::ostream & str, const PublicKey & obj )
283 str << "[" << obj.name() << "]" << endl;
284 str << " fpr " << obj.fingerprint() << endl;
285 str << " id " << obj.id() << endl;
286 str << " cre " << obj.created() << endl;
287 str << " exp " << obj.expires() << endl;
292 /////////////////////////////////////////////////////////////////
294 ///////////////////////////////////////////////////////////////////