mirror of
https://github.com/wismna/ModernKeePass.git
synced 2025-10-03 15:40:18 -04:00
Removed User Account from composite key (probably never going to work as intended)
Changed copy URL to navigate to URL in entry quick menu
This commit is contained in:
@@ -1,62 +1,10 @@
|
||||
using System;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Security.Cryptography.DataProtection;
|
||||
using Windows.Storage.Streams;
|
||||
using ModernKeePassLib.Native;
|
||||
|
||||
namespace ModernKeePassLib.Cryptography
|
||||
{
|
||||
public static class ProtectedData
|
||||
{
|
||||
public static async Task ProtectStream(byte[] buffer, IOutputStream stream)
|
||||
{
|
||||
//instantiate a DataProtectionProvider for decryption
|
||||
var dpp = new DataProtectionProvider("LOCAL=user");
|
||||
|
||||
//Open a stream to load data in
|
||||
using (var inputStream = new InMemoryRandomAccessStream())
|
||||
{
|
||||
//cteate data writer to write data to the input stream
|
||||
using (var dw = new DataWriter(inputStream))
|
||||
{
|
||||
//write data to the stream
|
||||
dw.WriteBuffer(buffer.AsBuffer());
|
||||
await dw.StoreAsync();
|
||||
|
||||
//encrypt the intput stream into the file stream
|
||||
await dpp.ProtectStreamAsync(inputStream.GetInputStreamAt(0),
|
||||
stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static async Task<byte[]> UnprotectStream(IInputStream stream)
|
||||
{
|
||||
//instantiate a DataProtectionProvider for decryption
|
||||
var dpp = new DataProtectionProvider();
|
||||
|
||||
//create a stream to decrypte the data to
|
||||
using (var outputStream = new InMemoryRandomAccessStream())
|
||||
{
|
||||
//decrypt the data
|
||||
await dpp.UnprotectStreamAsync(stream, outputStream);
|
||||
|
||||
//fill the data reader with the content of the outputStream,
|
||||
//but from position 0
|
||||
using (var dr = new DataReader(outputStream.GetInputStreamAt(0)))
|
||||
{
|
||||
//load data from the stream to the dataReader
|
||||
await dr.LoadAsync((uint)outputStream.Size);
|
||||
|
||||
//load the data from the datareader into a buffer
|
||||
IBuffer data = dr.ReadBuffer((uint)outputStream.Size);
|
||||
|
||||
return data.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] Unprotect(byte[] pbEnc, byte[] mPbOptEnt, DataProtectionScope currentUser)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
@@ -20,7 +20,6 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using System.Security;
|
||||
|
||||
#if ModernKeePassLib
|
||||
@@ -36,136 +35,132 @@ using ModernKeePassLib.Utility;
|
||||
|
||||
namespace ModernKeePassLib.Keys
|
||||
{
|
||||
/// <summary>
|
||||
/// A user key depending on the currently logged on Windows user account.
|
||||
/// </summary>
|
||||
public sealed class KcpUserAccount : IUserKey
|
||||
{
|
||||
private ProtectedBinary m_pbKeyData = null;
|
||||
/// <summary>
|
||||
/// A user key depending on the currently logged on Windows user account.
|
||||
/// </summary>
|
||||
public sealed class KcpUserAccount : IUserKey
|
||||
{
|
||||
private ProtectedBinary m_pbKeyData = null;
|
||||
|
||||
// Constant initialization vector (unique for KeePass)
|
||||
private static readonly byte[] m_pbEntropy = new byte[] {
|
||||
0xDE, 0x13, 0x5B, 0x5F, 0x18, 0xA3, 0x46, 0x70,
|
||||
0xB2, 0x57, 0x24, 0x29, 0x69, 0x88, 0x98, 0xE6
|
||||
};
|
||||
// Constant initialization vector (unique for KeePass)
|
||||
private static readonly byte[] m_pbEntropy = new byte[] {
|
||||
0xDE, 0x13, 0x5B, 0x5F, 0x18, 0xA3, 0x46, 0x70,
|
||||
0xB2, 0x57, 0x24, 0x29, 0x69, 0x88, 0x98, 0xE6
|
||||
};
|
||||
|
||||
private const string UserKeyFileName = "ProtectedUserKey.bin";
|
||||
private const string UserKeyFileName = "ProtectedUserKey.bin";
|
||||
|
||||
/// <summary>
|
||||
/// Get key data. Querying this property is fast (it returns a
|
||||
/// reference to a cached <c>ProtectedBinary</c> object).
|
||||
/// If no key data is available, <c>null</c> is returned.
|
||||
/// </summary>
|
||||
public ProtectedBinary KeyData
|
||||
{
|
||||
get { return m_pbKeyData; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Get key data. Querying this property is fast (it returns a
|
||||
/// reference to a cached <c>ProtectedBinary</c> object).
|
||||
/// If no key data is available, <c>null</c> is returned.
|
||||
/// </summary>
|
||||
public ProtectedBinary KeyData
|
||||
{
|
||||
get { return m_pbKeyData; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a user account key.
|
||||
/// </summary>
|
||||
public KcpUserAccount()
|
||||
{
|
||||
// Test if ProtectedData is supported -- throws an exception
|
||||
// when running on an old system (Windows 98 / ME).
|
||||
/*byte[] pbDummyData = new byte[128];
|
||||
ProtectedData.Protect(pbDummyData, m_pbEntropy,
|
||||
DataProtectionScope.CurrentUser);*/
|
||||
/// <summary>
|
||||
/// Construct a user account key.
|
||||
/// </summary>
|
||||
public KcpUserAccount()
|
||||
{
|
||||
// Test if ProtectedData is supported -- throws an exception
|
||||
// when running on an old system (Windows 98 / ME).
|
||||
byte[] pbDummyData = new byte[128];
|
||||
ProtectedData.Protect(pbDummyData, m_pbEntropy,
|
||||
DataProtectionScope.CurrentUser);
|
||||
|
||||
byte[] pbKey = LoadUserKey(false);
|
||||
if(pbKey == null) pbKey = CreateUserKey();
|
||||
if(pbKey == null) // Should never happen
|
||||
{
|
||||
Debug.Assert(false);
|
||||
throw new SecurityException(KLRes.UserAccountKeyError);
|
||||
}
|
||||
byte[] pbKey = LoadUserKey(false);
|
||||
if (pbKey == null) pbKey = CreateUserKey();
|
||||
if (pbKey == null) // Should never happen
|
||||
{
|
||||
Debug.Assert(false);
|
||||
throw new SecurityException(KLRes.UserAccountKeyError);
|
||||
}
|
||||
|
||||
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
||||
MemUtil.ZeroByteArray(pbKey);
|
||||
}
|
||||
m_pbKeyData = new ProtectedBinary(true, pbKey);
|
||||
MemUtil.ZeroByteArray(pbKey);
|
||||
}
|
||||
|
||||
// public void Clear()
|
||||
// {
|
||||
// m_pbKeyData = null;
|
||||
// }
|
||||
// public void Clear()
|
||||
// {
|
||||
// m_pbKeyData = null;
|
||||
// }
|
||||
|
||||
private static string GetUserKeyFilePath(bool bCreate)
|
||||
{
|
||||
private static string GetUserKeyFilePath(bool bCreate)
|
||||
{
|
||||
#if ModernKeePassLib
|
||||
string strUserDir = Windows.Storage.ApplicationData.Current.RoamingFolder.Path;
|
||||
string strUserDir = Windows.Storage.ApplicationData.Current.RoamingFolder.Path;
|
||||
#else
|
||||
string strUserDir = Environment.GetFolderPath(
|
||||
Environment.SpecialFolder.ApplicationData);
|
||||
#endif
|
||||
|
||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||
|
||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||
strUserDir += PwDefs.ShortProductName;
|
||||
#if !ModernKeePassLib
|
||||
strUserDir += PwDefs.ShortProductName;
|
||||
|
||||
if(bCreate && !Directory.Exists(strUserDir))
|
||||
Directory.CreateDirectory(strUserDir);
|
||||
#endif
|
||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||
return (strUserDir + UserKeyFileName);
|
||||
}
|
||||
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
|
||||
return (strUserDir + UserKeyFileName);
|
||||
}
|
||||
|
||||
private static byte[] LoadUserKey(bool bThrow)
|
||||
{
|
||||
byte[] pbKey = null;
|
||||
private static byte[] LoadUserKey(bool bThrow)
|
||||
{
|
||||
byte[] pbKey = null;
|
||||
|
||||
#if !KeePassLibSD
|
||||
try
|
||||
{
|
||||
string strFilePath = GetUserKeyFilePath(false);
|
||||
try
|
||||
{
|
||||
string strFilePath = GetUserKeyFilePath(false);
|
||||
#if ModernKeePassLib
|
||||
var file = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult();
|
||||
using (var fileStream = file.OpenReadAsync().GetAwaiter().GetResult())
|
||||
{
|
||||
pbKey = ProtectedData.UnprotectStream(fileStream).GetAwaiter().GetResult();
|
||||
}
|
||||
var fileStream = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult().OpenStreamForReadAsync().GetAwaiter().GetResult();
|
||||
var pbProtectedKey = new byte[(int)fileStream.Length];
|
||||
fileStream.Read(pbProtectedKey, 0, (int)fileStream.Length);
|
||||
fileStream.Dispose();
|
||||
#else
|
||||
byte[] pbProtectedKey = File.ReadAllBytes(strFilePath);
|
||||
#endif
|
||||
pbKey = ProtectedData.Unprotect(pbProtectedKey, m_pbEntropy,
|
||||
DataProtectionScope.CurrentUser);
|
||||
#endif
|
||||
}
|
||||
catch(Exception)
|
||||
{
|
||||
if(bThrow) throw;
|
||||
pbKey = null;
|
||||
}
|
||||
DataProtectionScope.CurrentUser);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
if (bThrow) throw;
|
||||
pbKey = null;
|
||||
}
|
||||
#endif
|
||||
|
||||
return pbKey;
|
||||
}
|
||||
return pbKey;
|
||||
}
|
||||
|
||||
private static byte[] CreateUserKey()
|
||||
{
|
||||
private static byte[] CreateUserKey()
|
||||
{
|
||||
#if KeePassLibSD
|
||||
return null;
|
||||
#else
|
||||
string strFilePath = GetUserKeyFilePath(true);
|
||||
string strFilePath = GetUserKeyFilePath(true);
|
||||
|
||||
byte[] pbRandomKey = CryptoRandom.Instance.GetRandomBytes(64);
|
||||
byte[] pbRandomKey = CryptoRandom.Instance.GetRandomBytes(64);
|
||||
byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey,
|
||||
m_pbEntropy, DataProtectionScope.CurrentUser);
|
||||
#if ModernKeePassLib
|
||||
var file = ApplicationData.Current.RoamingFolder.CreateFileAsync(UserKeyFileName, CreationCollisionOption.ReplaceExisting).GetAwaiter().GetResult();
|
||||
using (var fileStream = file.OpenAsync(FileAccessMode.ReadWrite).GetAwaiter().GetResult())
|
||||
{
|
||||
ProtectedData.ProtectStream(pbRandomKey, fileStream).GetAwaiter().GetResult();
|
||||
}
|
||||
var fileStream = StorageFile.GetFileFromPathAsync(strFilePath).GetAwaiter().GetResult().OpenStreamForWriteAsync().GetAwaiter().GetResult();
|
||||
fileStream.Write(pbProtectedKey, 0, (int)fileStream.Length);
|
||||
fileStream.Dispose();
|
||||
#else
|
||||
byte[] pbProtectedKey = ProtectedData.Protect(pbRandomKey,
|
||||
m_pbEntropy, DataProtectionScope.CurrentUser);
|
||||
File.WriteAllBytes(strFilePath, pbProtectedKey);
|
||||
#endif
|
||||
|
||||
byte[] pbKey = LoadUserKey(true);
|
||||
Debug.Assert(MemUtil.ArraysEqual(pbKey, pbRandomKey));
|
||||
Debug.Assert(MemUtil.ArraysEqual(pbKey, pbRandomKey));
|
||||
|
||||
MemUtil.ZeroByteArray(pbRandomKey);
|
||||
return pbKey;
|
||||
MemUtil.ZeroByteArray(pbRandomKey);
|
||||
return pbKey;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
<package >
|
||||
<metadata>
|
||||
<id>ModernKeePassLib</id>
|
||||
<version>2.37.9000</version>
|
||||
<version>2.37.8000</version>
|
||||
<title>ModernKeePassLib</title>
|
||||
<authors>Geoffroy Bonneville</authors>
|
||||
<owners>Geoffroy Bonneville</owners>
|
||||
@@ -10,7 +10,7 @@
|
||||
<projectUrl>https://github.com/wismna/ModernKeePass</projectUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<description>Portable KeePass Password Management Library that targets .Net Standard and WinRT. Allows reading, editing and writing to KeePass 2.x databases.</description>
|
||||
<releaseNotes>Implements Windows User Accounts</releaseNotes>
|
||||
<releaseNotes></releaseNotes>
|
||||
<copyright>Copyright © 2017 Geoffroy Bonneville</copyright>
|
||||
<tags>KeePass KeePassLib Portable PCL NetStandard</tags>
|
||||
<dependencies>
|
||||
|
Reference in New Issue
Block a user