PublicKeyData trustedPublicKeyExists( const std::string & id )
{ return publicKeyExists(id, trustedKeyRing());}
+ bool provideAndImportKeyFromRepositoryWorkflow (const std::string &id_r , const RepoInfo &info_r );
+
private:
bool verifyFile( const Pathname & file, const Pathname & signature, const Pathname & keyring );
void importKey( const Pathname & keyfile, const Pathname & keyring );
// get the id of the signature (it might be a subkey id!)
std::string id = readSignatureKeyId( signature );
- // does key exists in trusted keyring
- PublicKeyData trustedKeyData( publicKeyExists( id, trustedKeyRing() ) );
- if ( trustedKeyData )
- {
- MIL << "Key is trusted: " << trustedKeyData << endl;
+ PublicKeyData foundKey;
+ Pathname whichKeyring;
- // lets look if there is an updated key in the
- // general keyring
- PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
- if ( generalKeyData )
+ if ( !id.empty() ) {
+
+ // does key exists in trusted keyring
+ PublicKeyData trustedKeyData( publicKeyExists( id, trustedKeyRing() ) );
+ if ( trustedKeyData )
{
- // bnc #393160: Comment #30: Compare at least the fingerprint
- // in case an attacker created a key the the same id.
- //
- // FIXME: bsc#1008325: For keys using subkeys, we'd actually need
- // to compare the subkey sets, to tell whether a key was updated.
- // because created() remains unchanged if the primary key is not touched.
- // For now we wait until a new subkey signs the data and treat it as a
- // new key (else part below).
- if ( trustedKeyData.fingerprint() == generalKeyData.fingerprint()
- && trustedKeyData.created() < generalKeyData.created() )
+ MIL << "Key is trusted: " << trustedKeyData << endl;
+
+ // lets look if there is an updated key in the
+ // general keyring
+ PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
+ if ( generalKeyData )
{
- MIL << "Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
- importKey( exportKey( generalKeyData, generalKeyRing() ), true );
- trustedKeyData = publicKeyExists( id, trustedKeyRing() ); // re-read: invalidated by import?
- }
- }
+ // bnc #393160: Comment #30: Compare at least the fingerprint
+ // in case an attacker created a key the the same id.
+ //
+ // FIXME: bsc#1008325: For keys using subkeys, we'd actually need
+ // to compare the subkey sets, to tell whether a key was updated.
+ // because created() remains unchanged if the primary key is not touched.
+ // For now we wait until a new subkey signs the data and treat it as a
+ // new key (else part below).
+ if ( trustedKeyData.fingerprint() == generalKeyData.fingerprint()
+ && trustedKeyData.created() < generalKeyData.created() )
+ {
+ MIL << "Key was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
+ importKey( exportKey( generalKeyData, generalKeyRing() ), true );
+ trustedKeyData = publicKeyExists( id, trustedKeyRing() ); // re-read: invalidated by import?
+ }
+ }
- // it exists, is trusted, does it validate?
- report->infoVerify( filedesc, trustedKeyData, context );
- if ( verifyFile( file, signature, trustedKeyRing() ) )
- {
- return (sigValid_r=true); // signature is actually successfully validated!
+ foundKey = trustedKeyData;
+ whichKeyring = trustedKeyRing();
}
else
{
- bool res = report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
- MIL << "askUserToAcceptVerificationFailed: " << res << endl;
- return res;
- }
- }
- else
- {
- PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
- if ( generalKeyData )
- {
- PublicKey key( exportKey( generalKeyData, generalKeyRing() ) );
- MIL << "Key [" << id << "] " << key.name() << " is not trusted" << endl;
-
- // ok the key is not trusted, ask the user to trust it or not
- KeyRingReport::KeyTrust reply = report->askUserToAcceptKey( key, context );
- if ( reply == KeyRingReport::KEY_TRUST_TEMPORARILY ||
- reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
+ PublicKeyData generalKeyData( publicKeyExists( id, generalKeyRing() ) );
+ if ( generalKeyData )
{
- MIL << "User wants to trust key [" << id << "] " << key.name() << endl;
+ PublicKey key( exportKey( generalKeyData, generalKeyRing() ) );
+ MIL << "Key [" << id << "] " << key.name() << " is not trusted" << endl;
- Pathname whichKeyring;
- if ( reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
+ // ok the key is not trusted, ask the user to trust it or not
+ KeyRingReport::KeyTrust reply = report->askUserToAcceptKey( key, context );
+ if ( reply == KeyRingReport::KEY_TRUST_TEMPORARILY ||
+ reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
{
- MIL << "User wants to import key [" << id << "] " << key.name() << endl;
- importKey( key, true );
- whichKeyring = trustedKeyRing();
- }
- else
- whichKeyring = generalKeyRing();
+ MIL << "User wants to trust key [" << id << "] " << key.name() << endl;
- // does it validate?
- report->infoVerify( filedesc, generalKeyData, context );
- if ( verifyFile( file, signature, whichKeyring ) )
- {
- return (sigValid_r=true); // signature is actually successfully validated!
+ if ( reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
+ {
+ MIL << "User wants to import key [" << id << "] " << key.name() << endl;
+ importKey( key, true );
+ whichKeyring = trustedKeyRing();
+ }
+ else
+ whichKeyring = generalKeyRing();
+
+ foundKey = generalKeyData;
}
else
{
- bool res = report->askUserToAcceptVerificationFailed( filedesc, key, context );
- MIL << "askUserToAcceptVerificationFailed: " << res << endl;
- return res;
+ MIL << "User does not want to trust key [" << id << "] " << key.name() << endl;
+ return false;
}
}
- else
+ else if ( ! context.empty() )
{
- MIL << "User does not want to trust key [" << id << "] " << key.name() << endl;
- return false;
+ // try to find the key in the repository info
+ if ( provideAndImportKeyFromRepositoryWorkflow( id, context.repoInfo() ) ) {
+ whichKeyring = trustedKeyRing();
+ foundKey = PublicKeyData( publicKeyExists( id, trustedKeyRing() ) );
+ }
}
}
+ }
+
+ if ( foundKey ) {
+ // it exists, is trusted, does it validate?
+ report->infoVerify( filedesc, foundKey, context );
+ if ( verifyFile( file, signature, whichKeyring ) )
+ {
+ return (sigValid_r=true); // signature is actually successfully validated!
+ }
else
{
- // signed with an unknown key...
- MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << endl;
- bool res = report->askUserToAcceptUnknownKey( filedesc, id, context );
- MIL << "askUserToAcceptUnknownKey: " << res << endl;
- return res;
+ bool res = report->askUserToAcceptVerificationFailed( filedesc, exportKey( foundKey, whichKeyring ), context );
+ MIL << "askUserToAcceptVerificationFailed: " << res << endl;
+ return res;
}
+ } else {
+ // signed with an unknown key...
+ MIL << "File [" << file << "] ( " << filedesc << " ) signed with unknown key [" << id << "]" << endl;
+ bool res = report->askUserToAcceptUnknownKey( filedesc, id, context );
+ MIL << "askUserToAcceptUnknownKey: " << res << endl;
+ return res;
}
+
return false;
}
+ bool KeyRing::Impl::provideAndImportKeyFromRepositoryWorkflow(const std::string &id_r, const RepoInfo &info_r)
+ {
+ if ( id_r.empty() )
+ return false;
+
+ const ZConfig &conf = ZConfig::instance();
+ Pathname cacheDir = conf.repoManagerRoot() / conf.pubkeyCachePath();
+
+ Pathname myKey = info_r.provideKey( id_r, cacheDir );
+ if ( myKey.empty() )
+ // if we did not find any keys, there is no point in checking again, break
+ return false;
+
+ callback::SendReport<KeyRingReport> report;
+
+ PublicKey key;
+ try {
+ key = PublicKey( myKey );
+ } catch ( const Exception &e ) {
+ ZYPP_CAUGHT(e);
+ return false;
+ }
+
+ if ( !key.isValid() ) {
+ ERR << "Key [" << id_r << "] from cache: " << cacheDir << " is not valid" << endl;
+ return false;
+ }
+
+ MIL << "Key [" << id_r << "] " << key.name() << " loaded from cache" << endl;
+
+ KeyContext context;
+ context.setRepoInfo( info_r );
+ if ( ! report->askUserToAcceptPackageKey( key, context ) ) {
+ return false;
+ }
+
+ MIL << "User wants to import key [" << id_r << "] " << key.name() << " from cache" << endl;
+ try {
+ importKey( key, true );
+ } catch ( const KeyRingException &e ) {
+ ZYPP_CAUGHT(e);
+ ERR << "Failed to import key: "<<id_r;
+ return false;
+ }
+
+ return true;
+ }
+
std::list<PublicKey> KeyRing::Impl::publicKeys( const Pathname & keyring )
{
const std::list<PublicKeyData> & keys( publicKeyData( keyring ) );
bool KeyRing::verifyFileTrustedSignature( const Pathname & file, const Pathname & signature )
{ return _pimpl->verifyFileTrustedSignature( file, signature ); }
+ bool KeyRing::provideAndImportKeyFromRepositoryWorkflow(const std::string &id, const RepoInfo &info)
+ {
+ return _pimpl->provideAndImportKeyFromRepositoryWorkflow( id, info );
+ }
+
void KeyRing::dumpPublicKey( const std::string & id, bool trusted, std::ostream & stream )
{ _pimpl->dumpPublicKey( id, trusted, stream ); }