PublicKeyData KeyRing::Impl::publicKeyExists( const std::string & id, const Pathname & keyring )
{
MIL << "Searching key [" << id << "] in keyring " << keyring << endl;
- PublicKeyData ret;
- for ( const PublicKeyData & key : publicKeyData( keyring ) )
+ const std::list<PublicKeyData> & keys( publicKeyData( keyring ) );
+ for_( it, keys.begin(), keys.end() )
{
- if ( key.providesKey( id ) )
+ if ( id == (*it).id() )
{
- ret = key;
- break;
+ return *it;
}
}
- return ret;
+ return PublicKeyData();
}
PublicKey KeyRing::Impl::exportKey( const PublicKeyData & keyData, const Pathname & keyring )
if( signature.empty() || (!PathInfo( signature ).isExist()) )
{
bool res = report->askUserToAcceptUnsignedFile( filedesc, context );
- MIL << "askUserToAcceptUnsignedFile: " << res << endl;
+ MIL << "User decision on unsigned file: " << res << endl;
return res;
}
- // get the id of the signature (it might be a subkey id!)
+ // get the id of the signature
std::string id = readSignatureKeyId( signature );
- // does key exists in trusted keyring
+ // doeskey 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 was updated. Saving new version into trusted keyring: " << generalKeyData << endl;
importKey( exportKey( generalKeyData, generalKeyRing() ), true );
- trustedKeyData = publicKeyExists( id, trustedKeyRing() ); // re-read: invalidated by import?
+ trustedKeyData = generalKeyData = PublicKeyData(); // invalidated by import.
}
}
- // it exists, is trusted, does it validate?
+ if ( ! trustedKeyData ) // invalidated by previous import
+ trustedKeyData = publicKeyExists( id, trustedKeyRing() );
report->infoVerify( filedesc, trustedKeyData, context );
+
+ // it exists, is trusted, does it validates?
if ( verifyFile( file, signature, trustedKeyRing() ) )
{
return (sigValid_r=true); // signature is actually successfully validated!
}
else
{
- bool res = report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
- MIL << "askUserToAcceptVerificationFailed: " << res << endl;
- return res;
+ return report->askUserToAcceptVerificationFailed( filedesc, exportKey( trustedKeyData, trustedKeyRing() ), context );
}
}
else
reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
{
MIL << "User wants to trust key " << id << " " << key.name() << endl;
+ //dumpFile( unKey.path() );
Pathname whichKeyring;
if ( reply == KeyRingReport::KEY_TRUST_AND_IMPORT )
else
whichKeyring = generalKeyRing();
- // does it validate?
- report->infoVerify( filedesc, generalKeyData, context );
+ // emit key added
if ( verifyFile( file, signature, whichKeyring ) )
{
+ MIL << "File signature is verified" << endl;
return (sigValid_r=true); // signature is actually successfully validated!
}
else
{
- bool res = report->askUserToAcceptVerificationFailed( filedesc, key, context );
- MIL << "askUserToAcceptVerificationFailed: " << res << endl;
- return res;
+ MIL << "File signature check fails" << endl;
+ if ( report->askUserToAcceptVerificationFailed( filedesc, key, context ) )
+ {
+ MIL << "User continues anyway." << endl;
+ return true;
+ }
+ else
+ {
+ MIL << "User does not want to continue" << endl;
+ return false;
+ }
}
}
else
}
else
{
- // signed with an unknown key...
+ // 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;
+ if ( report->askUserToAcceptUnknownKey( filedesc, id, context ) )
+ {
+ MIL << "User wants to accept unknown key " << id << endl;
+ return true;
+ }
+ else
+ {
+ MIL << "User does not want to accept unknown key " << id << endl;
+ return false;
+ }
}
}
return false;
MIL << "Deleted key " << id << " from keyring " << keyring << endl;
}
+
std::string KeyRing::Impl::readSignatureKeyId( const Pathname & signature )
{
if ( ! PathInfo( signature ).isFile() )
ZYPP_THROW(Exception( str::Format(_("Signature file %s not found")) % signature.asString() ));
- MIL << "Determining key id of signature " << signature << endl;
+ MIL << "Determining key id if signature " << signature << endl;
+ // HACK create a tmp keyring with no keys
+ filesystem::TmpDir dir( _base_dir, "fake-keyring" );
+ std::string tmppath( dir.path().asString() );
+
const char* argv[] =
{
GPG_BINARY,
- "--list-packets",
+ "--homedir", tmppath.c_str(),
+ "--no-default-keyring",
+ "--quiet",
+ "--no-tty",
+ "--no-greeting",
+ "--batch",
+ "--status-fd", "1",
signature.asString().c_str(),
NULL
};
- ExternalProgram prog( argv ,ExternalProgram::Discard_Stderr, false, -1, true );
-
- // :signature packet: algo 1, keyid 1397BC53640DB551
- // version 4, created 1501094968, md5len 0, sigclass 0x00
- // digest algo 8, begin of digest 15 89
- // hashed subpkt 2 len 4 (sig created 2017-07-26)
- // subpkt 16 len 8 (issuer key ID 1397BC53640DB551)
- // data: [4095 bits]
+
+ ExternalProgram prog( argv,ExternalProgram::Discard_Stderr, false, -1, true );
+
+ std::string line;
+ int count = 0;
+
+ str::regex rxNoKey( "^\\[GNUPG:\\] NO_PUBKEY (.+)\n$" );
std::string id;
- for( std::string line = prog.receiveLine(); !line.empty(); line = prog.receiveLine() )
+ for( line = prog.receiveLine(), count=0; !line.empty(); line = prog.receiveLine(), count++ )
{
- if ( id.empty() && str::startsWith( line, ":signature packet:" ) )
+ //MIL << "[" << line << "]" << endl;
+ str::smatch what;
+ if( str::regex_match( line, what, rxNoKey ) )
{
- static const str::regex rxKeyId( " keyid +([0-9A-Z]+)" );
- str::smatch what;
- if( str::regex_match( line, what, rxKeyId ) )
- id = what[1];
+ if ( what.size() >= 1 )
+ {
+ id = what[1];
+ break;
+ }
+ //dumpRegexpResults( what );
}
}
+ if ( count == 0 )
+ {
+ MIL << "no output" << endl;
+ }
+
MIL << "Determined key id [" << id << "] for signature " << signature << endl;
prog.close();
return id;