qtkeychain/keychain_win.cpp

128 lines
4.6 KiB
C++
Raw Normal View History

2011-10-27 16:15:46 +00:00
/******************************************************************************
* Copyright (C) 2011 Frank Osterfeld <frank.osterfeld@gmail.com> *
* *
* This program is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE. For licensing and distribution *
* details, check the accompanying file 'COPYING'. *
*****************************************************************************/
2011-10-27 16:14:37 +00:00
#include "keychain_p.h"
2011-10-28 23:21:07 +00:00
#include <QSettings>
#include <Windows.h>
#include <WinCrypt.h>
2011-10-28 07:38:02 +00:00
using namespace QKeychain;
Keychain::Error Keychain::Private::readEntryImpl( QByteArray* pw,
2011-10-28 23:21:07 +00:00
const QString& key,
2011-10-28 07:38:02 +00:00
QString* err ) {
Q_ASSERT( pw );
Q_ASSERT( err );
err->clear();
2011-10-28 23:21:07 +00:00
QSettings settings( service );
QByteArray encrypted = settings.value( key ).toByteArray();
if ( encrypted.isNull() ) {
*err = tr("Entry not found");
return EntryNotFound;
}
DATA_BLOB blob_in, blob_out;
blob_in.pbData = reinterpret_cast<BYTE*>( encrypted.data() );
blob_in.cbData = encrypted.size();
const BOOL ret = CryptUnprotectData( &blob_in,
NULL,
NULL,
NULL,
NULL,
0,
&blob_out );
if ( !ret ) {
*err = tr("Could not decrypt data");
return OtherError;
}
*pw = QByteArray( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
SecureZeroMemory( blob_out.pbData, blob_out.cbData );
LocalFree( blob_out.pbData );
return NoError;
2011-10-28 07:38:02 +00:00
}
2011-10-28 23:21:07 +00:00
Keychain::Error Keychain::Private::writeEntryImpl( const QString& key,
const QByteArray& data_,
2011-10-28 07:38:02 +00:00
QString* err ) {
Q_ASSERT( err );
err->clear();
2011-10-28 23:21:07 +00:00
QByteArray data = data_;
DATA_BLOB blob_in, blob_out;
blob_in.pbData = reinterpret_cast<BYTE*>( data.data() );
blob_in.cbData = data.size();
const BOOL res = CryptProtectData( &blob_in,
L"QKeychain-encrypted data",
NULL,
NULL,
NULL,
0,
&blob_out );
if ( !res ) {
*err = tr("Encryption failed"); //TODO more details available?
return OtherError;
}
const QByteArray encrypted( reinterpret_cast<char*>( blob_out.pbData ), blob_out.cbData );
LocalFree( blob_out.pbData );
QSettings settings( service );
settings.setValue( key, encrypted );
settings.sync();
if ( settings.status() != QSettings::NoError ) {
*err = settings.status() == QSettings::AccessError
? tr("Could not store encrypted data in settings: access error")
: tr("Could not store encrypted data in settings: format error");
return OtherError;
}
return NoError;
2011-10-27 16:14:37 +00:00
}
2011-10-28 23:21:07 +00:00
Keychain::Error Keychain::Private::deleteEntryImpl( const QString& key,
2011-10-28 07:38:02 +00:00
QString* err ) {
Q_ASSERT( err );
err->clear();
2011-10-28 23:21:07 +00:00
QSettings settings( service );
settings.remove( key );
settings.sync();
if ( settings.status() != QSettings::NoError ) {
*err = settings.status() == QSettings::AccessError
? tr("Could not delete encrypted data from settings: access error")
: tr("Could not delete encrypted data from settings: format error");
return OtherError;
}
return NoError;
2011-10-27 16:14:37 +00:00
}
2011-10-28 07:38:02 +00:00
Keychain::Error Keychain::Private::entryExistsImpl( bool* exists,
2011-10-28 23:21:07 +00:00
const QString& key,
2011-10-28 07:38:02 +00:00
QString* err ) {
Q_ASSERT( exists );
Q_ASSERT( err );
err->clear();
2011-10-28 23:21:07 +00:00
*exists = false;
QSettings settings( service );
const bool ex = settings.contains( key );
if ( settings.status() != QSettings::NoError ) {
*err = settings.status() == QSettings::AccessError
? tr("Could not read settings: access error")
: tr("Could not read settings: format error");
return OtherError;
}
*exists = ex;
return NoError;
2011-10-28 07:38:02 +00:00
}