Compare commits

..

1 Commits

Author SHA1 Message Date
Philipp Crocoll
c130e9697f remove online-dependencies 2016-08-20 20:56:17 +02:00
512 changed files with 17106 additions and 26480 deletions

49
.gitignore vendored
View File

@@ -131,51 +131,4 @@ Thumbs.db
/src/java/JavaFileStorage/.gradle/2.2.1/taskArtifacts/outputFileStates.bin
/src/java/JavaFileStorage/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin
/src/java/JavaFileStorage/.idea/workspace.xml
/src/java/JavaFileStorage/local.properties
/src/FtpClientTest/FtpClientExamples
/src/FtpClientTest
/src/FtpClientWinTest
/src/Kp2aUnitTests2
/src/MaterialTest2
/src/ResourceGrabberTest
/src/WebDavAndroid
/src/java/InputStickAPI/app/build/
/src/java/KP2ASoftkeyboard_AS/app/build/
/src/java/PluginInputStick3/pluginInputStick/build/
/src/java/android-filechooser-AS/app/build/
/src/java/android-filechooser/out/
/src/java/PluginInputStick3/inputStickAPI/build/
/src/java/android-filechooser-AS/.gradle/2.2.1/taskArtifacts/cache.properties
/src/java/android-filechooser-AS/.gradle/2.2.1/taskArtifacts/cache.properties.lock
/src/*.bak
/src/java/Keepass2AndroidPluginSDK2/app/build/
/src/java/PluginInputStick3/keepass2AndroidPluginSDK/build/
/src/java/KP2ASoftkeyboard_AS/.gradle/2.2.1/taskArtifacts/cache.properties
/src/java/KP2ASoftkeyboard_AS/.gradle/2.2.1/taskArtifacts/cache.properties.lock
/src/java/JavaFileStorageTest-AS/.idea/.name
/src/java/JavaFileStorageTest-AS/.idea/compiler.xml
/src/java/JavaFileStorageTest-AS/.idea/copyright/profiles_settings.xml
/src/java/JavaFileStorageTest-AS/.idea/encodings.xml
/src/java/JavaFileStorageTest-AS/.idea/gradle.xml
/src/java/JavaFileStorageTest-AS/.idea/misc.xml
/src/java/JavaFileStorageTest-AS/.idea/modules.xml
/src/java/JavaFileStorageTest-AS/.idea/runConfigurations.xml
/src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/cache.properties
/src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/cache.properties.lock
/src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/fileHashes.bin
/src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/fileSnapshots.bin
/src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/outputFileStates.bin
/src/java/Keepass2AndroidPluginSDK2/.gradle/2.2.1/taskArtifacts/taskArtifacts.bin
/src/java/Keepass2AndroidPluginSDK2/.idea/.name
/src/java/Keepass2AndroidPluginSDK2/.idea/compiler.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/copyright/profiles_settings.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/encodings.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/gradle.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/libraries/effects_android_23.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/libraries/maps_android_23.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/libraries/mockable_Google_Inc__Google_APIs_23.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/libraries/usb_android_23.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/misc.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/modules.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/runConfigurations.xml
/src/java/Keepass2AndroidPluginSDK2/.idea/workspace.xml
/src/java/JavaFileStorage/local.properties

5
.gitmodules vendored
View File

@@ -1,6 +1,9 @@
[submodule "SamsungPass"]
path = SamsungPass
url = https://github.com/sraiteri/Xamarin-Samsung-Pass.git
[submodule "src/SamsungPass"]
path = src/SamsungPass
url = https://github.com/PhilippC/Xamarin-Samsung-Pass.git
url = https://github.com/sraiteri/Xamarin-Samsung-Pass.git
[submodule "src/netftpandroid"]
path = src/netftpandroid
url = https://git01.codeplex.com/forks/philippc/netftpandroid

View File

@@ -1 +0,0 @@
8933bad161af4178b1185d1a37fbf41ea5269c55

View File

@@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Xamarin.GooglePlayServices" version="27.0.0.0" />
</packages>

View File

@@ -14,7 +14,7 @@
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile>
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies>
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">

View File

@@ -10,8 +10,7 @@
<RootNamespace>AndroidFileChooserBinding</RootNamespace>
<AssemblyName>AndroidFileChooserBinding</AssemblyName>
<FileAlignment>512</FileAlignment>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -55,8 +54,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<LibraryProjectZip Include="..\java\android-filechooser-AS\app\build\outputs\aar\android-filechooser-release.aar">
<Link>Jars\android-filechooser-release.aar</Link>
<LibraryProjectZip Include="..\java\android-filechooser-AS\app\build\outputs\aar\app-debug.aar">
<Link>Jars\app-debug.aar</Link>
</LibraryProjectZip>
<None Include="Jars\AboutJars.txt" />
<None Include="Additions\AboutAdditions.txt" />

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/search"
android:icon="@android:drawable/ic_menu_search"
android:title="Search"
android:showAsAction="ifRoom"
android:actionViewClass="android.widget.SearchView"
/>
</menu>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/search_label"
android:hint="@string/search_hint"
android:searchMode="showSearchLabelAsBadge"
android:searchSuggestAuthority="App1.SearchProvider"
android:searchSuggestSelection=" ?"
android:searchSuggestThreshold="2"
android:searchSuggestIntentAction="android.intent.action.VIEW"
android:searchSuggestIntentData="content://keepass2android.EntryActivity"
>
</searchable>

View File

@@ -1,27 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.microsoft.aad.adal"
android:versionCode="1"
android:versionName="0.1.1" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<application>
<activity android:name="com.microsoft.aad.adal.AuthenticationActivity" >
</activity>
<receiver
android:name = "com.microsoft.aad.adal.ApplicationReceiver">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_INSTALL"/>
<data android:scheme="package"/>
</intent-filter>
</receiver>
</application>
</manifest>

View File

@@ -1,21 +0,0 @@
int dimen activity_horizontal_margin 0x7f030000
int dimen activity_vertical_margin 0x7f030001
int id LinearLayout1 0x7f060004
int id com_microsoft_aad_adal_editDummyText 0x7f060002
int id com_microsoft_aad_adal_progressBar 0x7f060003
int id com_microsoft_aad_adal_webView1 0x7f060001
int id editPassword 0x7f060006
int id editUserName 0x7f060005
int id webView1 0x7f060000
int layout activity_authentication 0x7f020000
int layout dialog_authentication 0x7f020001
int layout http_auth_dialog 0x7f020002
int string app_loading 0x7f040000
int string broker_processing 0x7f040001
int string http_auth_dialog_cancel 0x7f040006
int string http_auth_dialog_login 0x7f040005
int string http_auth_dialog_password 0x7f040003
int string http_auth_dialog_title 0x7f040004
int string http_auth_dialog_username 0x7f040002
int style AppBaseTheme 0x7f050000
int style AppTheme 0x7f050001

View File

@@ -1,17 +0,0 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".AuthenticationActivity" >
<WebView
android:id="@+id/webView1"
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true" />
</RelativeLayout>

View File

@@ -1,40 +0,0 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<WebView
android:id="@+id/com_microsoft_aad_adal_webView1"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:paddingBottom="0dp"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:paddingTop="0dp" />
<EditText
android:id="@+id/com_microsoft_aad_adal_editDummyText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/com_microsoft_aad_adal_webView1"
android:layout_alignLeft="@+id/com_microsoft_aad_adal_webView1"
android:layout_alignStart="@+id/com_microsoft_aad_adal_webView1"
android:layout_marginBottom="124dp"
android:layout_marginLeft="86dp"
android:layout_marginStart="86dp"
android:ems="10"
android:inputType="textEmailAddress"
android:visibility="gone" >
</EditText>
<ProgressBar
android:id="@+id/com_microsoft_aad_adal_progressBar"
style="?android:attr/progressBarStyleLarge"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" />
</RelativeLayout>

View File

@@ -1,31 +0,0 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/LinearLayout1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<EditText
android:id="@+id/editUserName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/http_auth_dialog_username"
android:paddingTop="10dp" >
<requestFocus />
</EditText>
<EditText
android:id="@+id/editPassword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="@string/http_auth_dialog_password"
android:inputType="textPassword"
android:paddingTop="10dp"
android:paddingBottom="20dp" />
</LinearLayout>

View File

@@ -1,8 +0,0 @@
<resources>
<!--
Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw600dp devices (e.g. 7" tablets) here.
-->
</resources>

View File

@@ -1,9 +0,0 @@
<resources>
<!--
Customize dimensions originally defined in res/values/dimens.xml (such as
screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
-->
<dimen name="activity_horizontal_margin">128dp</dimen>
</resources>

View File

@@ -1,11 +0,0 @@
<resources>
<!--
Base application theme for API 11+. This theme completely replaces
AppBaseTheme from res/values/styles.xml on API 11+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
<!-- API 11 theme customizations can go here. -->
</style>
</resources>

View File

@@ -1,12 +0,0 @@
<resources>
<!--
Base application theme for API 14+. This theme completely replaces
AppBaseTheme from BOTH res/values/styles.xml and
res/values-v11/styles.xml on API 14+ devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
</style>
</resources>

View File

@@ -1,7 +0,0 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>

View File

@@ -1,12 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools" tools:ignore="MissingTranslation">
<string name="app_loading">Loading&#8230;</string>
<string name="broker_processing">Broker is processing</string>
<string name="http_auth_dialog_username">Username</string>
<string name="http_auth_dialog_password">Password</string>
<string name="http_auth_dialog_title">Enter your credentials</string>
<string name="http_auth_dialog_login">Login</string>
<string name="http_auth_dialog_cancel">Cancel</string>
</resources>

View File

@@ -1,20 +0,0 @@
<resources>
<!--
Base application theme, dependent on API level. This theme is replaced
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
-->
<style name="AppBaseTheme" parent="android:Theme.Light">
<!--
Theme customizations available in newer API levels can go in
res/values-vXX/styles.xml, while customizations related to
backward-compatibility can go here.
-->
</style>
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<!-- All customizations that are NOT specific to a particular API-level can go here. -->
</style>
</resources>

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.microsoft.services.msa"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="22" />
<uses-permission android:name="com.sony.mobile.permission.SYSTEM_UI_VISIBILITY_EXTENSION" />
</manifest>

View File

@@ -1 +0,0 @@
int string app_name 0x7f020000

View File

@@ -1,13 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.microsoft.services.msa"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="22" />
<uses-permission android:name="com.sony.mobile.permission.SYSTEM_UI_VISIBILITY_EXTENSION" />
</manifest>

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- From: file:/C:/Users/pnied/Documents/git/msa-auth-for-android/src/main/res/values/strings.xml -->
<eat-comment/>
<string name="app_name">msa-auth</string>
</resources>

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.microsoft.onedrivesdk"
android:versionCode="10202"
android:versionName="1.2.2" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
</manifest>

View File

@@ -1,22 +0,0 @@
int dimen activity_horizontal_margin 0x7f030000
int dimen activity_vertical_margin 0x7f030001
int id LinearLayout1 0x7f060004
int id com_microsoft_aad_adal_editDummyText 0x7f060002
int id com_microsoft_aad_adal_progressBar 0x7f060003
int id com_microsoft_aad_adal_webView1 0x7f060001
int id editPassword 0x7f060006
int id editUserName 0x7f060005
int id webView1 0x7f060000
int layout activity_authentication 0x7f020000
int layout dialog_authentication 0x7f020001
int layout http_auth_dialog 0x7f020002
int string app_loading 0x7f050000
int string app_name 0x7f050001
int string broker_processing 0x7f050002
int string http_auth_dialog_cancel 0x7f050003
int string http_auth_dialog_login 0x7f050004
int string http_auth_dialog_password 0x7f050005
int string http_auth_dialog_title 0x7f050006
int string http_auth_dialog_username 0x7f050007
int style AppBaseTheme 0x7f040000
int style AppTheme 0x7f040001

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.microsoft.onedrivesdk"
android:versionCode="10202"
android:versionName="1.2.2" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
</manifest>

View File

@@ -11,7 +11,7 @@
<AssemblyName>JavaFileStorageBindings</AssemblyName>
<FileAlignment>512</FileAlignment>
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -20,7 +20,7 @@
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>0</WarningLevel>
<WarningLevel>4</WarningLevel>
<AndroidLinkMode>None</AndroidLinkMode>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
@@ -64,8 +64,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<LibraryProjectZip Include="..\java\JavaFileStorage\app\build\outputs\aar\JavaFileStorage-debug.aar">
<Link>Jars\JavaFileStorage-debug.aar</Link>
<LibraryProjectZip Include="..\java\JavaFileStorage\app\build\outputs\aar\app-debug.aar">
<Link>Jars\app-debug.aar</Link>
</LibraryProjectZip>
<None Include="Jars\AboutJars.txt" />
<None Include="Additions\AboutAdditions.txt" />
@@ -75,6 +75,81 @@
<TransformFile Include="Transforms\EnumFields.xml" />
<TransformFile Include="Transforms\EnumMethods.xml" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\json_simple-1.1.jar">
<Link>Jars\json_simple-1.1.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-api-client-1.16.0-rc.jar">
<Link>Jars\google-api-client-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-api-client-android-1.16.0-rc.jar">
<Link>Jars\google-api-client-android-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-api-services-drive-v2-rev102-1.16.0-rc.jar">
<Link>Jars\google-api-services-drive-v2-rev102-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-1.16.0-rc.jar">
<Link>Jars\google-http-client-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-android-1.16.0-rc.jar">
<Link>Jars\google-http-client-android-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-gson-1.16.0-rc.jar">
<Link>Jars\google-http-client-gson-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-jackson-1.16.0-rc.jar">
<Link>Jars\google-http-client-jackson-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-http-client-jackson2-1.16.0-rc.jar">
<Link>Jars\google-http-client-jackson2-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\google-oauth-client-1.16.0-rc.jar">
<Link>Jars\google-oauth-client-1.16.0-rc.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\gson-2.1.jar">
<Link>Jars\gson-2.1.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\httpmime-4.0.3.jar">
<Link>Jars\httpmime-4.0.3.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\jackson-core-2.1.3.jar">
<Link>Jars\jackson-core-2.1.3.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\jackson-core-asl-1.9.11.jar">
<Link>Jars\jackson-core-asl-1.9.11.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="..\java\JavaFileStorage\libs\jsr305-1.3.9.jar">
<Link>Jars\jsr305-1.3.9.jar</Link>
</EmbeddedReferenceJar>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.Bindings.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
@@ -89,76 +164,4 @@
<Visible>False</Visible>
</XamarinComponentReference>
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\okhttp-3.4.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\okhttp-digest-1.7.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gson-2.3.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\msa-auth-0.8.6\classes-msa-auth.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\onedrive-sdk-android-1.2.2\classes-onedrive-sdk.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\adal-1.1.19\classes-adal.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\commons-logging-1.1.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-api-client-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-api-client-android-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-api-services-drive-v2-rev102-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-android-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-jackson-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-jackson2-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-oauth-client-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\httpclient-4.0.3.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\httpcore-4.0.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\httpmime-4.0.3.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\json_simple-1.1.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\jsr305-1.3.9.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\gdrive\google-http-client-gson-1.16.0-rc.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\jackson-core-2.7.4.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedReferenceJar Include="Jars\okio-1.9.0.jar" />
</ItemGroup>
<ItemGroup>
<EmbeddedJar Include="Jars\dropbox-core-sdk-3.0.3.jar" />
</ItemGroup>
</Project>

View File

@@ -6,17 +6,31 @@
This sample removes the method: android.support.v4.content.CursorLoader.loadInBackground:
<remove-node path="/api/package[@name='android.support.v4.content']/class[@name='CursorLoader']/method[@name='loadInBackground']" />
-->
<remove-node path="/api/package[starts-with(@name, 'org.apache')]" />
<remove-node path="/api/package[starts-with(@name, 'org.codehaus')]" />
<remove-node path="/api/package[starts-with(@name, 'com.fasterxml')]" />
<remove-node path="/api/package[starts-with(@name, 'com.google')]" />
<remove-node path="/api/package[@name='org.apache.http']" />
<remove-node path="/api/package[@name='org.apache.http.entity']" />
<remove-node path="/api/package[@name='org.apache.http.impl']" />
<remove-node path="/api/package[@name='org.apache.http.impl.client']" />
<remove-node path="/api/package[@name='org.apache.http.impl.entity']" />
<remove-node path="/api/package[@name='org.apache.http.impl.io']" />
<remove-node path="/api/package[@name='org.apache.http.io']" />
<remove-node path="/api/package[@name='org.apache.http.message']" />
<remove-node path="/api/package[@name='org.apache.http.params']" />
<remove-node path="/api/package[@name='org.apache.http.protocol']" />
<remove-node path="/api/package[@name='org.apache.http.ui']" />
<remove-node path="/api/package[@name='com.jcraft.jsch']" />
<remove-node path="/api/package[@name='com.jcraft.jsch.jce']" />
<remove-node path="/api/package[@name='com.jcraft.jsch.jcraft']" />
<remove-node path="/api/package[@name='com.jcraft.jzlib']" />
<remove-node path="/api/package[@name='com.dropbox.core']" />
<remove-node path="/api/package[@name='com.dropbox.core.util']" />
<remove-node path="/api/package[@name='com.dropbox.core.http']" />
<remove-node path="/api/package[@name='com.dropbox.core.v2.sharing']" />
<remove-node path="/api/package[@name='com.dropbox.core.v2.team']" />
<remove-node path="/api/package[@name='keepass2android.javafilestorage.webdav']" />
<remove-node path="/api/package[@name='keepass2android.javafilestorage.onedrive']" />
<remove-node path="/api/package[@name='com.microsoft.live']" />
<remove-node path="/api/package[@name='com.dropbox.client']" />
<remove-node path="/api/package[@name='com.dropbox.client2']" />
<remove-node path="/api/package[@name='com.dropbox.client2.session']" />
<remove-node path="/api/package[@name='com.dropbox.client2.android']" />
<remove-node path="/api/package[@name='com.dropbox.client2.jsonextract']" />
<remove-node path="/api/package[@name='com.dropbox.client2.exception']" />
</metadata>

View File

@@ -10,8 +10,7 @@
<RootNamespace>KP2AKdbLibraryBinding</RootNamespace>
<AssemblyName>KP2AKdbLibraryBinding</AssemblyName>
<FileAlignment>512</FileAlignment>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>

View File

@@ -11,6 +11,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aKeyboardBinding", "Kp2a
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aBusinessLogic", "Kp2aBusinessLogic\Kp2aBusinessLogic.csproj", "{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MonoDroidUnitTesting", "monodroid-unittesting\MonoDroidUnitTesting\MonoDroidUnitTesting.csproj", "{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Kp2aUnitTests", "Kp2aUnitTests\Kp2aUnitTests.csproj", "{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TwofishCipher", "TwofishCipher\TwofishCipher.csproj", "{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "JavaFileStorageBindings", "JavaFileStorageBindings\JavaFileStorageBindings.csproj", "{48574278-4779-4B3A-A9E4-9CF1BC285D0B}"
@@ -19,15 +23,33 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AndroidFileChooserBinding",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KP2AKdbLibraryBinding", "KP2AKdbLibraryBinding\KP2AKdbLibraryBinding.csproj", "{70D3844A-D9FA-4A64-B205-A84C6A822196}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArtTestApp", "ArtTestApp\ArtTestApp.csproj", "{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginSdkBinding", "PluginSdkBinding\PluginSdkBinding.csproj", "{3DA3911E-36DE-465E-8F15-F1991B6437E5}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "MasterKee", "MasterKee", "{CAC7DBC4-E21F-41E1-B33A-E3A04585F6A3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasterPassword", "MasterPassword\MasterPassword.csproj", "{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MPTest", "MPTest\MPTest.csproj", "{96A3EA5A-7024-479F-A5B1-06654D0867A3}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasterKeePlugin", "MasterKeePlugin\MasterKeePlugin.csproj", "{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZlibAndroid", "ZlibAndroid\ZlibAndroid.csproj", "{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MaterialTest2", "MaterialTest2\MaterialTest2.csproj", "{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoFillPlugin", "AutoFillPlugin\AutoFillPlugin.csproj", "{6FF440E6-E8FF-4E43-8221-9E3972F14812}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResourceGrabberTest", "ResourceGrabberTest\ResourceGrabberTest.csproj", "{5020E3AD-C420-42D5-BD57-374EE3B7FE49}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AncientIconSet", "AncientIconSet\AncientIconSet.csproj", "{7F059603-7041-4BBB-93A2-DAA7AB5CA528}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.FtpClient.Android", "netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj", "{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FingerprintTest", "FingerprintTest\FingerprintTest.csproj", "{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SamsungPass", "SamsungPass\Xamarin.SamsungPass\SamsungPass\SamsungPass.csproj", "{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FtpClientTest", "FtpClientTest\FtpClientTest.csproj", "{8230EA71-1DC2-426A-A820-3B94E1678379}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "System.Net.FtpClient.Android", "netftpandroid\System.Net.FtpClient\System.Net.FtpClient.Android.csproj", "{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -135,6 +157,48 @@ Global
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{53A9CB7F-6553-4BC0-B56B-9410BB2E59AA}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|Win32.ActiveCfg = Debug|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Debug|x64.ActiveCfg = Debug|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Any CPU.Build.0 = Release|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|Win32.ActiveCfg = Release|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.Release|x64.ActiveCfg = Release|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
{A5F8FB02-00E0-4335-91EF-AEAA2C2F3C48}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|Win32.ActiveCfg = Debug|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Debug|x64.ActiveCfg = Debug|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Any CPU.Build.0 = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Any CPU.Deploy.0 = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|Win32.ActiveCfg = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.Release|x64.ActiveCfg = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Mixed Platforms.Deploy.0 = ReleaseNoNet|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{46B769B8-2C58-4138-9CC0-70E3AE3C9A3A}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -207,6 +271,30 @@ Global
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{70D3844A-D9FA-4A64-B205-A84C6A822196}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Debug|Win32.ActiveCfg = Debug|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Debug|x64.ActiveCfg = Debug|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Release|Any CPU.Build.0 = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Release|Any CPU.Deploy.0 = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Release|Win32.ActiveCfg = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.Release|x64.ActiveCfg = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{1FF6C335-A627-43C9-AAA7-CBAC2E74CD18}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -225,6 +313,66 @@ Global
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{3DA3911E-36DE-465E-8F15-F1991B6437E5}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Any CPU.Build.0 = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|Win32.ActiveCfg = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Debug|x64.ActiveCfg = Debug|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Any CPU.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Any CPU.Build.0 = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|Win32.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.Release|x64.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|Win32.ActiveCfg = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Debug|x64.ActiveCfg = Debug|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Any CPU.Build.0 = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|Win32.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.Release|x64.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{96A3EA5A-7024-479F-A5B1-06654D0867A3}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|Win32.ActiveCfg = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Debug|x64.ActiveCfg = Debug|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Any CPU.Build.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Any CPU.Deploy.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|Win32.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.Release|x64.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -249,6 +397,90 @@ Global
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Debug|Win32.ActiveCfg = Debug|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Debug|x64.ActiveCfg = Debug|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Release|Any CPU.Build.0 = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Release|Any CPU.Deploy.0 = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Release|Win32.ActiveCfg = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.Release|x64.ActiveCfg = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{B7BBC4A2-0301-4DFF-B03C-C88CD4F1F890}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Win32.ActiveCfg = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Win32.Build.0 = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|Win32.Deploy.0 = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|x64.ActiveCfg = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|x64.Build.0 = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Debug|x64.Deploy.0 = Debug|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Any CPU.Build.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Any CPU.Deploy.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Win32.ActiveCfg = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Win32.Build.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|Win32.Deploy.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|x64.ActiveCfg = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|x64.Build.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.Release|x64.Deploy.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|Win32.Deploy.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
{6FF440E6-E8FF-4E43-8221-9E3972F14812}.ReleaseNoNet|x64.Deploy.0 = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Debug|Win32.ActiveCfg = Debug|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Debug|x64.ActiveCfg = Debug|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Release|Any CPU.Build.0 = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Release|Any CPU.Deploy.0 = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Release|Win32.ActiveCfg = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.Release|x64.ActiveCfg = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{5020E3AD-C420-42D5-BD57-374EE3B7FE49}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{7F059603-7041-4BBB-93A2-DAA7AB5CA528}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F059603-7041-4BBB-93A2-DAA7AB5CA528}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F059603-7041-4BBB-93A2-DAA7AB5CA528}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -273,6 +505,54 @@ Global
{7F059603-7041-4BBB-93A2-DAA7AB5CA528}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU
{7F059603-7041-4BBB-93A2-DAA7AB5CA528}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{7F059603-7041-4BBB-93A2-DAA7AB5CA528}.ReleaseNoNet|x64.Build.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Debug|Win32.ActiveCfg = Debug|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Debug|x64.ActiveCfg = Debug|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Release|Any CPU.Build.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Release|Any CPU.Deploy.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Release|Win32.ActiveCfg = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.Release|x64.ActiveCfg = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{52C0A0E7-D625-44BE-948E-D98BC6C82F0F}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Debug|Mixed Platforms.Deploy.0 = Debug|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Debug|Win32.ActiveCfg = Debug|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Debug|x64.ActiveCfg = Debug|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Release|Any CPU.Build.0 = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Release|Any CPU.Deploy.0 = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Release|Mixed Platforms.Deploy.0 = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Release|Win32.ActiveCfg = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.Release|x64.ActiveCfg = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.ReleaseNoNet|Any CPU.Deploy.0 = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.ReleaseNoNet|Mixed Platforms.Deploy.0 = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{8230EA71-1DC2-426A-A820-3B94E1678379}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
@@ -291,28 +571,15 @@ Global
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU
{146FD497-BA03-4740-B6C5-5C84EA8FCDE2}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|Win32.ActiveCfg = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Debug|x64.ActiveCfg = Debug|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Any CPU.Build.0 = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|Win32.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.Release|x64.ActiveCfg = Release|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Any CPU.ActiveCfg = ReleaseNoNet|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Any CPU.Build.0 = ReleaseNoNet|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.ActiveCfg = ReleaseNoNet|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|Win32.ActiveCfg = ReleaseNoNet|Any CPU
{3A4B8E88-FA9B-4663-BCDA-21C12E3AF98A}.ReleaseNoNet|x64.ActiveCfg = ReleaseNoNet|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5} = {CAC7DBC4-E21F-41E1-B33A-E3A04585F6A3}
{96A3EA5A-7024-479F-A5B1-06654D0867A3} = {CAC7DBC4-E21F-41E1-B33A-E3A04585F6A3}
{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C} = {CAC7DBC4-E21F-41E1-B33A-E3A04585F6A3}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
$0.DotNetNamingPolicy = $1

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -194,6 +194,13 @@ namespace KeePassLib.Collections
return true;
}
public void Add(AutoTypeAssociation a)
{
Debug.Assert(a != null); if(a == null) throw new ArgumentNullException("a");
m_lWindowAssocs.Add(a);
}
public AutoTypeAssociation GetAt(int iIndex)
{
if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count))
@@ -202,22 +209,6 @@ namespace KeePassLib.Collections
return m_lWindowAssocs[iIndex];
}
public void Add(AutoTypeAssociation a)
{
if(a == null) { Debug.Assert(false); throw new ArgumentNullException("a"); }
m_lWindowAssocs.Add(a);
}
public void Insert(int iIndex, AutoTypeAssociation a)
{
if((iIndex < 0) || (iIndex > m_lWindowAssocs.Count))
throw new ArgumentOutOfRangeException("iIndex");
if(a == null) { Debug.Assert(false); throw new ArgumentNullException("a"); }
m_lWindowAssocs.Insert(iIndex, a);
}
public void RemoveAt(int iIndex)
{
if((iIndex < 0) || (iIndex >= m_lWindowAssocs.Count))
@@ -225,20 +216,5 @@ namespace KeePassLib.Collections
m_lWindowAssocs.RemoveAt(iIndex);
}
// public void Sort()
// {
// m_lWindowAssocs.Sort(AutoTypeConfig.AssocCompareFn);
// }
// private static int AssocCompareFn(AutoTypeAssociation x,
// AutoTypeAssociation y)
// {
// if(x == null) { Debug.Assert(false); return ((y == null) ? 0 : -1); }
// if(y == null) { Debug.Assert(false); return 1; }
// int cn = x.WindowName.CompareTo(y.WindowName);
// if(cn != 0) return cn;
// return x.Sequence.CompareTo(y.Sequence);
// }
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -25,6 +25,7 @@ using System.Diagnostics;
using KeePassLib.Interfaces;
using KeePassLib.Security;
using KeePassLib.Utility;
#if KeePassLibSD
using KeePassLibSD;

View File

@@ -1,174 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using KeePassLib.Delegates;
using KeePassLib.Security;
namespace KeePassLib.Collections
{
internal sealed class ProtectedBinarySet : IEnumerable<KeyValuePair<int, ProtectedBinary>>
{
private Dictionary<int, ProtectedBinary> m_d =
new Dictionary<int, ProtectedBinary>();
public ProtectedBinarySet()
{
}
IEnumerator IEnumerable.GetEnumerator()
{
return m_d.GetEnumerator();
}
public IEnumerator<KeyValuePair<int, ProtectedBinary>> GetEnumerator()
{
return m_d.GetEnumerator();
}
public void Clear()
{
m_d.Clear();
}
private int GetFreeID()
{
int i = m_d.Count;
while(m_d.ContainsKey(i)) { ++i; }
Debug.Assert(i == m_d.Count); // m_d.Count should be free
return i;
}
public ProtectedBinary Get(int iID)
{
ProtectedBinary pb;
if(m_d.TryGetValue(iID, out pb)) return pb;
// Debug.Assert(false); // No assert
return null;
}
public int Find(ProtectedBinary pb)
{
if(pb == null) { Debug.Assert(false); return -1; }
// Fast search by reference
foreach(KeyValuePair<int, ProtectedBinary> kvp in m_d)
{
if(object.ReferenceEquals(pb, kvp.Value))
{
Debug.Assert(pb.Equals(kvp.Value));
return kvp.Key;
}
}
// Slow search by content
foreach(KeyValuePair<int, ProtectedBinary> kvp in m_d)
{
if(pb.Equals(kvp.Value)) return kvp.Key;
}
// Debug.Assert(false); // No assert
return -1;
}
public void Set(int iID, ProtectedBinary pb)
{
if(iID < 0) { Debug.Assert(false); return; }
if(pb == null) { Debug.Assert(false); return; }
m_d[iID] = pb;
}
public void Add(ProtectedBinary pb)
{
if(pb == null) { Debug.Assert(false); return; }
int i = Find(pb);
if(i >= 0) return; // Exists already
i = GetFreeID();
m_d[i] = pb;
}
public void AddFrom(ProtectedBinaryDictionary d)
{
if(d == null) { Debug.Assert(false); return; }
foreach(KeyValuePair<string, ProtectedBinary> kvp in d)
{
Add(kvp.Value);
}
}
public void AddFrom(PwGroup pg)
{
if(pg == null) { Debug.Assert(false); return; }
EntryHandler eh = delegate(PwEntry pe)
{
if(pe == null) { Debug.Assert(false); return true; }
AddFrom(pe.Binaries);
foreach(PwEntry peHistory in pe.History)
{
if(peHistory == null) { Debug.Assert(false); continue; }
AddFrom(peHistory.Binaries);
}
return true;
};
pg.TraverseTree(TraversalMethod.PreOrder, null, eh);
}
public ProtectedBinary[] ToArray()
{
int n = m_d.Count;
ProtectedBinary[] v = new ProtectedBinary[n];
foreach(KeyValuePair<int, ProtectedBinary> kvp in m_d)
{
if((kvp.Key < 0) || (kvp.Key >= n))
{
Debug.Assert(false);
throw new InvalidOperationException();
}
v[kvp.Key] = kvp.Value;
}
for(int i = 0; i < n; ++i)
{
if(v[i] == null)
{
Debug.Assert(false);
throw new InvalidOperationException();
}
}
return v;
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -284,7 +284,11 @@ namespace KeePassLib.Collections
public List<string> GetKeys()
{
return new List<string>(m_vStrings.Keys);
List<string> v = new List<string>();
foreach(string strKey in m_vStrings.Keys) v.Add(strKey);
return v;
}
public void EnableProtection(string strField, bool bProtect)
@@ -296,8 +300,7 @@ namespace KeePassLib.Collections
{
byte[] pbData = ps.ReadUtf8();
Set(strField, new ProtectedString(bProtect, pbData));
if(bProtect) MemUtil.ZeroByteArray(pbData);
MemUtil.ZeroByteArray(pbData);
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -233,7 +233,7 @@ namespace KeePassLib.Collections
if(nCount <= 1) return;
int nIndex = m_vObjects.IndexOf(tObject);
if(nIndex < 0) { Debug.Assert(false); return; }
Debug.Assert(nIndex >= 0);
if(bUp && (nIndex > 0)) // No assert for top item
{
@@ -249,68 +249,6 @@ namespace KeePassLib.Collections
}
}
public void MoveOne(T[] vObjects, bool bUp)
{
Debug.Assert(vObjects != null);
if(vObjects == null) throw new ArgumentNullException("vObjects");
/// <summary>
List<int> lIndices = new List<int>();
foreach(T t in vObjects)
{
if(t == null) { Debug.Assert(false); continue; }
/// Move some of the objects in this list to the top/bottom.
int p = IndexOf(t);
if(p >= 0) lIndices.Add(p);
else { Debug.Assert(false); }
}
/// </summary>
MoveOne(lIndices.ToArray(), bUp);
}
/// <param name="vObjects">List of objects to be moved.</param>
public void MoveOne(int[] vIndices, bool bUp)
{
Debug.Assert(vIndices != null);
if(vIndices == null) throw new ArgumentNullException("vIndices");
/// <param name="bTop">Move to top. If <c>false</c>, move to bottom.</param>
int n = m_vObjects.Count;
if(n <= 1) return; // No moving possible
int m = vIndices.Length;
if(m == 0) return; // Nothing to move
int[] v = new int[m];
Array.Copy(vIndices, v, m);
Array.Sort<int>(v);
if((bUp && (v[0] <= 0)) || (!bUp && (v[m - 1] >= (n - 1))))
return; // Moving as a block is not possible
int iStart = (bUp ? 0 : (m - 1));
int iExcl = (bUp ? m : -1);
int iStep = (bUp ? 1 : -1);
for(int i = iStart; i != iExcl; i += iStep)
{
int p = v[i];
if((p < 0) || (p >= n)) { Debug.Assert(false); continue; }
T t = m_vObjects[p];
if(bUp)
{
Debug.Assert(p > 0);
m_vObjects.RemoveAt(p);
m_vObjects.Insert(p - 1, t);
}
else // Down
{
Debug.Assert(p < (n - 1));
m_vObjects.RemoveAt(p);
m_vObjects.Insert(p + 1, t);
}
}
}
/// <summary>
/// Move some of the objects in this list to the top/bottom.
/// </summary>

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,14 +18,12 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Diagnostics;
using KeePassLib.Delegates;
using KeePassLib.Interfaces;
using KeePassLib.Utility;
#if KeePassLibSD
using KeePassLibSD;
@@ -79,154 +77,4 @@ namespace KeePassLib.Collections
return true;
}
}
internal sealed class PwObjectPoolEx
{
private Dictionary<PwUuid, ulong> m_dUuidToId =
new Dictionary<PwUuid, ulong>();
private Dictionary<ulong, IStructureItem> m_dIdToItem =
new Dictionary<ulong, IStructureItem>();
private PwObjectPoolEx()
{
}
public static PwObjectPoolEx FromGroup(PwGroup pg)
{
PwObjectPoolEx p = new PwObjectPoolEx();
if(pg == null) { Debug.Assert(false); return p; }
ulong uFreeId = 2; // 0 = "not found", 1 is a hole
p.m_dUuidToId[pg.Uuid] = uFreeId;
p.m_dIdToItem[uFreeId] = pg;
uFreeId += 2; // Make hole
p.AddGroupRec(pg, ref uFreeId);
return p;
}
private void AddGroupRec(PwGroup pg, ref ulong uFreeId)
{
if(pg == null) { Debug.Assert(false); return; }
ulong uId = uFreeId;
// Consecutive entries must have consecutive IDs
foreach(PwEntry pe in pg.Entries)
{
Debug.Assert(!m_dUuidToId.ContainsKey(pe.Uuid));
Debug.Assert(!m_dIdToItem.ContainsValue(pe));
m_dUuidToId[pe.Uuid] = uId;
m_dIdToItem[uId] = pe;
++uId;
}
++uId; // Make hole
// Consecutive groups must have consecutive IDs
foreach(PwGroup pgSub in pg.Groups)
{
Debug.Assert(!m_dUuidToId.ContainsKey(pgSub.Uuid));
Debug.Assert(!m_dIdToItem.ContainsValue(pgSub));
m_dUuidToId[pgSub.Uuid] = uId;
m_dIdToItem[uId] = pgSub;
++uId;
}
++uId; // Make hole
foreach(PwGroup pgSub in pg.Groups)
{
AddGroupRec(pgSub, ref uId);
}
uFreeId = uId;
}
public ulong GetIdByUuid(PwUuid pwUuid)
{
if(pwUuid == null) { Debug.Assert(false); return 0; }
ulong uId;
m_dUuidToId.TryGetValue(pwUuid, out uId);
return uId;
}
public IStructureItem GetItemByUuid(PwUuid pwUuid)
{
if(pwUuid == null) { Debug.Assert(false); return null; }
ulong uId;
if(!m_dUuidToId.TryGetValue(pwUuid, out uId)) return null;
Debug.Assert(uId != 0);
return GetItemById(uId);
}
public IStructureItem GetItemById(ulong uId)
{
IStructureItem p;
m_dIdToItem.TryGetValue(uId, out p);
return p;
}
}
internal sealed class PwObjectBlock<T> : IEnumerable<T>
where T : class, ITimeLogger, IStructureItem, IDeepCloneable<T>
{
private List<T> m_l = new List<T>();
public T PrimaryItem
{
get { return ((m_l.Count > 0) ? m_l[0] : null); }
}
private DateTime m_dtLocationChanged = TimeUtil.SafeMinValueUtc;
public DateTime LocationChanged
{
get { return m_dtLocationChanged; }
}
private PwObjectPoolEx m_poolAssoc = null;
public PwObjectPoolEx PoolAssoc
{
get { return m_poolAssoc; }
}
public PwObjectBlock()
{
}
#if DEBUG
public override string ToString()
{
return ("PwObjectBlock, Count = " + m_l.Count.ToString());
}
#endif
IEnumerator IEnumerable.GetEnumerator()
{
return m_l.GetEnumerator();
}
public IEnumerator<T> GetEnumerator()
{
return m_l.GetEnumerator();
}
public void Add(T t, DateTime dtLoc, PwObjectPoolEx pool)
{
if(t == null) { Debug.Assert(false); return; }
m_l.Add(t);
if(dtLoc > m_dtLocationChanged)
{
m_dtLocationChanged = dtLoc;
m_poolAssoc = pool;
}
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -32,14 +32,14 @@ using KeePassLibSD;
namespace KeePassLib.Collections
{
public sealed class StringDictionaryEx : IDeepCloneable<StringDictionaryEx>,
IEnumerable<KeyValuePair<string, string>>, IEquatable<StringDictionaryEx>
IEnumerable<KeyValuePair<string, string>>
{
private SortedDictionary<string, string> m_dict =
private SortedDictionary<string, string> m_vDict =
new SortedDictionary<string, string>();
public int Count
{
get { return m_dict.Count; }
get { return m_vDict.Count; }
}
public StringDictionaryEx()
@@ -48,53 +48,39 @@ namespace KeePassLib.Collections
IEnumerator IEnumerable.GetEnumerator()
{
return m_dict.GetEnumerator();
return m_vDict.GetEnumerator();
}
public IEnumerator<KeyValuePair<string, string>> GetEnumerator()
{
return m_dict.GetEnumerator();
return m_vDict.GetEnumerator();
}
public StringDictionaryEx CloneDeep()
{
StringDictionaryEx sdNew = new StringDictionaryEx();
StringDictionaryEx plNew = new StringDictionaryEx();
foreach(KeyValuePair<string, string> kvp in m_dict)
sdNew.m_dict[kvp.Key] = kvp.Value; // Strings are immutable
foreach(KeyValuePair<string, string> kvpStr in m_vDict)
plNew.Set(kvpStr.Key, kvpStr.Value);
return sdNew;
}
public bool Equals(StringDictionaryEx sdOther)
{
if(sdOther == null) { Debug.Assert(false); return false; }
if(m_dict.Count != sdOther.m_dict.Count) return false;
foreach(KeyValuePair<string, string> kvp in sdOther.m_dict)
{
string str = Get(kvp.Key);
if((str == null) || (str != kvp.Value)) return false;
}
return true;
return plNew;
}
public string Get(string strName)
{
if(strName == null) { Debug.Assert(false); throw new ArgumentNullException("strName"); }
Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
string s;
if(m_dict.TryGetValue(strName, out s)) return s;
if(m_vDict.TryGetValue(strName, out s)) return s;
return null;
}
public bool Exists(string strName)
{
if(strName == null) { Debug.Assert(false); throw new ArgumentNullException("strName"); }
Debug.Assert(strName != null); if(strName == null) throw new ArgumentNullException("strName");
return m_dict.ContainsKey(strName);
return m_vDict.ContainsKey(strName);
}
/// <summary>
@@ -106,10 +92,10 @@ namespace KeePassLib.Collections
/// parameters is <c>null</c>.</exception>
public void Set(string strField, string strNewValue)
{
if(strField == null) { Debug.Assert(false); throw new ArgumentNullException("strField"); }
if(strNewValue == null) { Debug.Assert(false); throw new ArgumentNullException("strNewValue"); }
Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField");
Debug.Assert(strNewValue != null); if(strNewValue == null) throw new ArgumentNullException("strNewValue");
m_dict[strField] = strNewValue;
m_vDict[strField] = strNewValue;
}
/// <summary>
@@ -122,9 +108,9 @@ namespace KeePassLib.Collections
/// parameter is <c>null</c>.</exception>
public bool Remove(string strField)
{
if(strField == null) { Debug.Assert(false); throw new ArgumentNullException("strField"); }
Debug.Assert(strField != null); if(strField == null) throw new ArgumentNullException("strField");
return m_dict.Remove(strField);
return m_vDict.Remove(strField);
}
}
}

View File

@@ -1,415 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using KeePassLib.Resources;
using KeePassLib.Utility;
namespace KeePassLib.Collections
{
public class VariantDictionary : ICloneable
{
private const ushort VdVersion = 0x0100;
private const ushort VdmCritical = 0xFF00;
private const ushort VdmInfo = 0x00FF;
private Dictionary<string, object> m_d = new Dictionary<string, object>();
private enum VdType : byte
{
None = 0,
// Byte = 0x02,
// UInt16 = 0x03,
UInt32 = 0x04,
UInt64 = 0x05,
// Signed mask: 0x08
Bool = 0x08,
// SByte = 0x0A,
// Int16 = 0x0B,
Int32 = 0x0C,
Int64 = 0x0D,
// Float = 0x10,
// Double = 0x11,
// Decimal = 0x12,
// Char = 0x17, // 16-bit Unicode character
String = 0x18,
// Array mask: 0x40
ByteArray = 0x42
}
public int Count
{
get { return m_d.Count; }
}
public VariantDictionary()
{
Debug.Assert((VdmCritical & VdmInfo) == ushort.MinValue);
Debug.Assert((VdmCritical | VdmInfo) == ushort.MaxValue);
}
private bool Get<T>(string strName, out T t)
{
t = default(T);
if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return false; }
object o;
if(!m_d.TryGetValue(strName, out o)) return false; // No assert
if(o == null) { Debug.Assert(false); return false; }
if(o.GetType() != typeof(T)) { Debug.Assert(false); return false; }
t = (T)o;
return true;
}
private void SetStruct<T>(string strName, T t)
where T : struct
{
if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return; }
#if DEBUG
T tEx;
Get<T>(strName, out tEx); // Assert same type
#endif
m_d[strName] = t;
}
private void SetRef<T>(string strName, T t)
where T : class
{
if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return; }
if(t == null) { Debug.Assert(false); return; }
#if DEBUG
T tEx;
Get<T>(strName, out tEx); // Assert same type
#endif
m_d[strName] = t;
}
public bool Remove(string strName)
{
if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return false; }
return m_d.Remove(strName);
}
public void CopyTo(VariantDictionary d)
{
if(d == null) { Debug.Assert(false); return; }
// Do not clear the target
foreach(KeyValuePair<string, object> kvp in m_d)
{
d.m_d[kvp.Key] = kvp.Value;
}
}
public Type GetTypeOf(string strName)
{
if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return null; }
object o;
m_d.TryGetValue(strName, out o);
if(o == null) return null; // No assert
return o.GetType();
}
public uint GetUInt32(string strName, uint uDefault)
{
uint u;
if(Get<uint>(strName, out u)) return u;
return uDefault;
}
public void SetUInt32(string strName, uint uValue)
{
SetStruct<uint>(strName, uValue);
}
public ulong GetUInt64(string strName, ulong uDefault)
{
ulong u;
if(Get<ulong>(strName, out u)) return u;
return uDefault;
}
public void SetUInt64(string strName, ulong uValue)
{
SetStruct<ulong>(strName, uValue);
}
public bool GetBool(string strName, bool bDefault)
{
bool b;
if(Get<bool>(strName, out b)) return b;
return bDefault;
}
public void SetBool(string strName, bool bValue)
{
SetStruct<bool>(strName, bValue);
}
public int GetInt32(string strName, int iDefault)
{
int i;
if(Get<int>(strName, out i)) return i;
return iDefault;
}
public void SetInt32(string strName, int iValue)
{
SetStruct<int>(strName, iValue);
}
public long GetInt64(string strName, long lDefault)
{
long l;
if(Get<long>(strName, out l)) return l;
return lDefault;
}
public void SetInt64(string strName, long lValue)
{
SetStruct<long>(strName, lValue);
}
public string GetString(string strName)
{
string str;
Get<string>(strName, out str);
return str;
}
public void SetString(string strName, string strValue)
{
SetRef<string>(strName, strValue);
}
public byte[] GetByteArray(string strName)
{
byte[] pb;
Get<byte[]>(strName, out pb);
return pb;
}
public void SetByteArray(string strName, byte[] pbValue)
{
SetRef<byte[]>(strName, pbValue);
}
/// <summary>
/// Create a deep copy.
/// </summary>
public virtual object Clone()
{
VariantDictionary vdNew = new VariantDictionary();
foreach(KeyValuePair<string, object> kvp in m_d)
{
object o = kvp.Value;
if(o == null) { Debug.Assert(false); continue; }
Type t = o.GetType();
if(t == typeof(byte[]))
{
byte[] p = (byte[])o;
byte[] pNew = new byte[p.Length];
if(p.Length > 0) Array.Copy(p, pNew, p.Length);
o = pNew;
}
vdNew.m_d[kvp.Key] = o;
}
return vdNew;
}
public static byte[] Serialize(VariantDictionary p)
{
if(p == null) { Debug.Assert(false); return null; }
byte[] pbRet;
using(MemoryStream ms = new MemoryStream())
{
MemUtil.Write(ms, MemUtil.UInt16ToBytes(VdVersion));
foreach(KeyValuePair<string, object> kvp in p.m_d)
{
string strName = kvp.Key;
if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); continue; }
byte[] pbName = StrUtil.Utf8.GetBytes(strName);
object o = kvp.Value;
if(o == null) { Debug.Assert(false); continue; }
Type t = o.GetType();
VdType vt = VdType.None;
byte[] pbValue = null;
if(t == typeof(uint))
{
vt = VdType.UInt32;
pbValue = MemUtil.UInt32ToBytes((uint)o);
}
else if(t == typeof(ulong))
{
vt = VdType.UInt64;
pbValue = MemUtil.UInt64ToBytes((ulong)o);
}
else if(t == typeof(bool))
{
vt = VdType.Bool;
pbValue = new byte[1];
pbValue[0] = ((bool)o ? (byte)1 : (byte)0);
}
else if(t == typeof(int))
{
vt = VdType.Int32;
pbValue = MemUtil.Int32ToBytes((int)o);
}
else if(t == typeof(long))
{
vt = VdType.Int64;
pbValue = MemUtil.Int64ToBytes((long)o);
}
else if(t == typeof(string))
{
vt = VdType.String;
pbValue = StrUtil.Utf8.GetBytes((string)o);
}
else if(t == typeof(byte[]))
{
vt = VdType.ByteArray;
pbValue = (byte[])o;
}
else { Debug.Assert(false); continue; } // Unknown type
ms.WriteByte((byte)vt);
MemUtil.Write(ms, MemUtil.Int32ToBytes(pbName.Length));
MemUtil.Write(ms, pbName);
MemUtil.Write(ms, MemUtil.Int32ToBytes(pbValue.Length));
MemUtil.Write(ms, pbValue);
}
ms.WriteByte((byte)VdType.None);
pbRet = ms.ToArray();
}
return pbRet;
}
public static VariantDictionary Deserialize(byte[] pb)
{
if(pb == null) { Debug.Assert(false); return null; }
VariantDictionary d = new VariantDictionary();
using(MemoryStream ms = new MemoryStream(pb, false))
{
ushort uVersion = MemUtil.BytesToUInt16(MemUtil.Read(ms, 2));
if((uVersion & VdmCritical) > (VdVersion & VdmCritical))
throw new FormatException(KLRes.FileNewVerReq);
while(true)
{
int iType = ms.ReadByte();
if(iType < 0) throw new EndOfStreamException(KLRes.FileCorrupted);
byte btType = (byte)iType;
if(btType == (byte)VdType.None) break;
int cbName = MemUtil.BytesToInt32(MemUtil.Read(ms, 4));
byte[] pbName = MemUtil.Read(ms, cbName);
if(pbName.Length != cbName)
throw new EndOfStreamException(KLRes.FileCorrupted);
string strName = StrUtil.Utf8.GetString(pbName);
int cbValue = MemUtil.BytesToInt32(MemUtil.Read(ms, 4));
byte[] pbValue = MemUtil.Read(ms, cbValue);
if(pbValue.Length != cbValue)
throw new EndOfStreamException(KLRes.FileCorrupted);
switch(btType)
{
case (byte)VdType.UInt32:
if(cbValue == 4)
d.SetUInt32(strName, MemUtil.BytesToUInt32(pbValue));
else { Debug.Assert(false); }
break;
case (byte)VdType.UInt64:
if(cbValue == 8)
d.SetUInt64(strName, MemUtil.BytesToUInt64(pbValue));
else { Debug.Assert(false); }
break;
case (byte)VdType.Bool:
if(cbValue == 1)
d.SetBool(strName, (pbValue[0] != 0));
else { Debug.Assert(false); }
break;
case (byte)VdType.Int32:
if(cbValue == 4)
d.SetInt32(strName, MemUtil.BytesToInt32(pbValue));
else { Debug.Assert(false); }
break;
case (byte)VdType.Int64:
if(cbValue == 8)
d.SetInt64(strName, MemUtil.BytesToInt64(pbValue));
else { Debug.Assert(false); }
break;
case (byte)VdType.String:
d.SetString(strName, StrUtil.Utf8.GetString(pbValue));
break;
case (byte)VdType.ByteArray:
d.SetByteArray(strName, pbValue);
break;
default:
Debug.Assert(false); // Unknown type
break;
}
}
Debug.Assert(ms.ReadByte() < 0);
}
return d;
}
}
}

View File

@@ -1,254 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using KeePassLib.Resources;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.Cipher
{
/// <summary>
/// Implementation of the ChaCha20 cipher with a 96-bit nonce,
/// as specified in RFC 7539.
/// https://tools.ietf.org/html/rfc7539
/// </summary>
public sealed class ChaCha20Cipher : CtrBlockCipher
{
private uint[] m_s = new uint[16]; // State
private uint[] m_x = new uint[16]; // Working buffer
private bool m_bLargeCounter; // See constructor documentation
private static readonly uint[] g_sigma = new uint[4] {
0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
};
private const string StrNameRfc = "ChaCha20 (RFC 7539)";
public override int BlockSize
{
get { return 64; }
}
public ChaCha20Cipher(byte[] pbKey32, byte[] pbIV12) :
this(pbKey32, pbIV12, false)
{
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="pbKey32">Key (32 bytes).</param>
/// <param name="pbIV12">Nonce (12 bytes).</param>
/// <param name="bLargeCounter">If <c>false</c>, the RFC 7539 version
/// of ChaCha20 is used. In this case, only 256 GB of data can be
/// encrypted securely (because the block counter is a 32-bit variable);
/// an attempt to encrypt more data throws an exception.
/// If <paramref name="bLargeCounter" /> is <c>true</c>, the 32-bit
/// counter overflows to another 32-bit variable (i.e. the counter
/// effectively is a 64-bit variable), like in the original ChaCha20
/// specification by D. J. Bernstein (which has a 64-bit counter and a
/// 64-bit nonce). To be compatible with this version, the 64-bit nonce
/// must be stored in the last 8 bytes of <paramref name="pbIV12" />
/// and the first 4 bytes must be 0.
/// If the IV was generated randomly, a 12-byte IV and a large counter
/// can be used to securely encrypt more than 256 GB of data (but note
/// this is incompatible with RFC 7539 and the original specification).</param>
public ChaCha20Cipher(byte[] pbKey32, byte[] pbIV12, bool bLargeCounter) :
base()
{
if(pbKey32 == null) throw new ArgumentNullException("pbKey32");
if(pbKey32.Length != 32) throw new ArgumentOutOfRangeException("pbKey32");
if(pbIV12 == null) throw new ArgumentNullException("pbIV12");
if(pbIV12.Length != 12) throw new ArgumentOutOfRangeException("pbIV12");
m_bLargeCounter = bLargeCounter;
// Key setup
m_s[4] = MemUtil.BytesToUInt32(pbKey32, 0);
m_s[5] = MemUtil.BytesToUInt32(pbKey32, 4);
m_s[6] = MemUtil.BytesToUInt32(pbKey32, 8);
m_s[7] = MemUtil.BytesToUInt32(pbKey32, 12);
m_s[8] = MemUtil.BytesToUInt32(pbKey32, 16);
m_s[9] = MemUtil.BytesToUInt32(pbKey32, 20);
m_s[10] = MemUtil.BytesToUInt32(pbKey32, 24);
m_s[11] = MemUtil.BytesToUInt32(pbKey32, 28);
m_s[0] = g_sigma[0];
m_s[1] = g_sigma[1];
m_s[2] = g_sigma[2];
m_s[3] = g_sigma[3];
// IV setup
m_s[12] = 0; // Counter
m_s[13] = MemUtil.BytesToUInt32(pbIV12, 0);
m_s[14] = MemUtil.BytesToUInt32(pbIV12, 4);
m_s[15] = MemUtil.BytesToUInt32(pbIV12, 8);
}
protected override void Dispose(bool bDisposing)
{
if(bDisposing)
{
MemUtil.ZeroArray<uint>(m_s);
MemUtil.ZeroArray<uint>(m_x);
}
base.Dispose(bDisposing);
}
protected override void NextBlock(byte[] pBlock)
{
if(pBlock == null) throw new ArgumentNullException("pBlock");
if(pBlock.Length != 64) throw new ArgumentOutOfRangeException("pBlock");
// x is a local alias for the working buffer; with this,
// the compiler/runtime might remove some checks
uint[] x = m_x;
if(x == null) throw new InvalidOperationException();
if(x.Length < 16) throw new InvalidOperationException();
uint[] s = m_s;
if(s == null) throw new InvalidOperationException();
if(s.Length < 16) throw new InvalidOperationException();
Array.Copy(s, x, 16);
unchecked
{
// 10 * 8 quarter rounds = 20 rounds
for(int i = 0; i < 10; ++i)
{
// Column quarter rounds
x[ 0] += x[ 4];
x[12] = MemUtil.RotateLeft32(x[12] ^ x[ 0], 16);
x[ 8] += x[12];
x[ 4] = MemUtil.RotateLeft32(x[ 4] ^ x[ 8], 12);
x[ 0] += x[ 4];
x[12] = MemUtil.RotateLeft32(x[12] ^ x[ 0], 8);
x[ 8] += x[12];
x[ 4] = MemUtil.RotateLeft32(x[ 4] ^ x[ 8], 7);
x[ 1] += x[ 5];
x[13] = MemUtil.RotateLeft32(x[13] ^ x[ 1], 16);
x[ 9] += x[13];
x[ 5] = MemUtil.RotateLeft32(x[ 5] ^ x[ 9], 12);
x[ 1] += x[ 5];
x[13] = MemUtil.RotateLeft32(x[13] ^ x[ 1], 8);
x[ 9] += x[13];
x[ 5] = MemUtil.RotateLeft32(x[ 5] ^ x[ 9], 7);
x[ 2] += x[ 6];
x[14] = MemUtil.RotateLeft32(x[14] ^ x[ 2], 16);
x[10] += x[14];
x[ 6] = MemUtil.RotateLeft32(x[ 6] ^ x[10], 12);
x[ 2] += x[ 6];
x[14] = MemUtil.RotateLeft32(x[14] ^ x[ 2], 8);
x[10] += x[14];
x[ 6] = MemUtil.RotateLeft32(x[ 6] ^ x[10], 7);
x[ 3] += x[ 7];
x[15] = MemUtil.RotateLeft32(x[15] ^ x[ 3], 16);
x[11] += x[15];
x[ 7] = MemUtil.RotateLeft32(x[ 7] ^ x[11], 12);
x[ 3] += x[ 7];
x[15] = MemUtil.RotateLeft32(x[15] ^ x[ 3], 8);
x[11] += x[15];
x[ 7] = MemUtil.RotateLeft32(x[ 7] ^ x[11], 7);
// Diagonal quarter rounds
x[ 0] += x[ 5];
x[15] = MemUtil.RotateLeft32(x[15] ^ x[ 0], 16);
x[10] += x[15];
x[ 5] = MemUtil.RotateLeft32(x[ 5] ^ x[10], 12);
x[ 0] += x[ 5];
x[15] = MemUtil.RotateLeft32(x[15] ^ x[ 0], 8);
x[10] += x[15];
x[ 5] = MemUtil.RotateLeft32(x[ 5] ^ x[10], 7);
x[ 1] += x[ 6];
x[12] = MemUtil.RotateLeft32(x[12] ^ x[ 1], 16);
x[11] += x[12];
x[ 6] = MemUtil.RotateLeft32(x[ 6] ^ x[11], 12);
x[ 1] += x[ 6];
x[12] = MemUtil.RotateLeft32(x[12] ^ x[ 1], 8);
x[11] += x[12];
x[ 6] = MemUtil.RotateLeft32(x[ 6] ^ x[11], 7);
x[ 2] += x[ 7];
x[13] = MemUtil.RotateLeft32(x[13] ^ x[ 2], 16);
x[ 8] += x[13];
x[ 7] = MemUtil.RotateLeft32(x[ 7] ^ x[ 8], 12);
x[ 2] += x[ 7];
x[13] = MemUtil.RotateLeft32(x[13] ^ x[ 2], 8);
x[ 8] += x[13];
x[ 7] = MemUtil.RotateLeft32(x[ 7] ^ x[ 8], 7);
x[ 3] += x[ 4];
x[14] = MemUtil.RotateLeft32(x[14] ^ x[ 3], 16);
x[ 9] += x[14];
x[ 4] = MemUtil.RotateLeft32(x[ 4] ^ x[ 9], 12);
x[ 3] += x[ 4];
x[14] = MemUtil.RotateLeft32(x[14] ^ x[ 3], 8);
x[ 9] += x[14];
x[ 4] = MemUtil.RotateLeft32(x[ 4] ^ x[ 9], 7);
}
for(int i = 0; i < 16; ++i) x[i] += s[i];
for(int i = 0; i < 16; ++i)
{
int i4 = i << 2;
uint xi = x[i];
pBlock[i4] = (byte)xi;
pBlock[i4 + 1] = (byte)(xi >> 8);
pBlock[i4 + 2] = (byte)(xi >> 16);
pBlock[i4 + 3] = (byte)(xi >> 24);
}
++s[12];
if(s[12] == 0)
{
if(!m_bLargeCounter)
throw new InvalidOperationException(
KLRes.EncDataTooLarge.Replace(@"{PARAM}", StrNameRfc));
++s[13]; // Increment high half of large counter
}
}
}
public long Seek(long lOffset, SeekOrigin so)
{
if(so != SeekOrigin.Begin) throw new NotSupportedException();
if((lOffset < 0) || ((lOffset & 63) != 0) ||
((lOffset >> 6) > (long)uint.MaxValue))
throw new ArgumentOutOfRangeException("lOffset");
m_s[12] = (uint)(lOffset >> 6);
InvalidateBlock();
return lOffset;
}
}
}

View File

@@ -1,177 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using KeePassLib.Resources;
namespace KeePassLib.Cryptography.Cipher
{
public sealed class ChaCha20Engine : ICipherEngine2
{
private PwUuid m_uuid = new PwUuid(new byte[] {
0xD6, 0x03, 0x8A, 0x2B, 0x8B, 0x6F, 0x4C, 0xB5,
0xA5, 0x24, 0x33, 0x9A, 0x31, 0xDB, 0xB5, 0x9A
});
public PwUuid CipherUuid
{
get { return m_uuid; }
}
public string DisplayName
{
get
{
return ("ChaCha20 (" + KLRes.KeyBits.Replace(@"{PARAM}",
"256") + ", RFC 7539)");
}
}
public int KeyLength
{
get { return 32; }
}
public int IVLength
{
get { return 12; } // 96 bits
}
public Stream EncryptStream(Stream sPlainText, byte[] pbKey, byte[] pbIV)
{
return new ChaCha20Stream(sPlainText, true, pbKey, pbIV);
}
public Stream DecryptStream(Stream sEncrypted, byte[] pbKey, byte[] pbIV)
{
return new ChaCha20Stream(sEncrypted, false, pbKey, pbIV);
}
}
internal sealed class ChaCha20Stream : Stream
{
private Stream m_sBase;
private readonly bool m_bWriting;
private ChaCha20Cipher m_c;
private byte[] m_pbBuffer = null;
public override bool CanRead
{
get { return !m_bWriting; }
}
public override bool CanSeek
{
get { return false; }
}
public override bool CanWrite
{
get { return m_bWriting; }
}
public override long Length
{
get { Debug.Assert(false); throw new NotSupportedException(); }
}
public override long Position
{
get { Debug.Assert(false); throw new NotSupportedException(); }
set { Debug.Assert(false); throw new NotSupportedException(); }
}
public ChaCha20Stream(Stream sBase, bool bWriting, byte[] pbKey32,
byte[] pbIV12)
{
if(sBase == null) throw new ArgumentNullException("sBase");
m_sBase = sBase;
m_bWriting = bWriting;
m_c = new ChaCha20Cipher(pbKey32, pbIV12);
}
protected override void Dispose(bool bDisposing)
{
if(bDisposing)
{
if(m_sBase != null)
{
m_c.Dispose();
m_c = null;
m_sBase.Close();
m_sBase = null;
}
m_pbBuffer = null;
}
base.Dispose(bDisposing);
}
public override void Flush()
{
Debug.Assert(m_sBase != null);
if(m_bWriting && (m_sBase != null)) m_sBase.Flush();
}
public override long Seek(long lOffset, SeekOrigin soOrigin)
{
Debug.Assert(false);
throw new NotImplementedException();
}
public override void SetLength(long lValue)
{
Debug.Assert(false);
throw new NotImplementedException();
}
public override int Read(byte[] pbBuffer, int iOffset, int nCount)
{
if(m_bWriting) throw new InvalidOperationException();
int cbRead = m_sBase.Read(pbBuffer, iOffset, nCount);
m_c.Decrypt(pbBuffer, iOffset, cbRead);
return cbRead;
}
public override void Write(byte[] pbBuffer, int iOffset, int nCount)
{
if(nCount < 0) throw new ArgumentOutOfRangeException("nCount");
if(nCount == 0) return;
if(!m_bWriting) throw new InvalidOperationException();
if((m_pbBuffer == null) || (m_pbBuffer.Length < nCount))
m_pbBuffer = new byte[nCount];
Array.Copy(pbBuffer, iOffset, m_pbBuffer, 0, nCount);
m_c.Encrypt(m_pbBuffer, 0, nCount);
m_sBase.Write(m_pbBuffer, 0, nCount);
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,6 +22,7 @@ using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Security;
namespace KeePassLib.Cryptography.Cipher
{
@@ -40,16 +41,12 @@ namespace KeePassLib.Cryptography.Cipher
{
get
{
CipherPool cp = m_poolGlobal;
if(cp == null)
{
cp = new CipherPool();
cp.AddCipher(new StandardAesEngine());
cp.AddCipher(new ChaCha20Engine());
m_poolGlobal = cp;
}
if(m_poolGlobal != null) return m_poolGlobal;
return cp;
m_poolGlobal = new CipherPool();
m_poolGlobal.AddCipher(new StandardAesEngine());
return m_poolGlobal;
}
}
@@ -160,12 +157,5 @@ namespace KeePassLib.Cryptography.Cipher
return m_vCiphers[nIndex];
}
}
public IEnumerable<ICipherEngine> Engines
{
get {
return m_vCiphers;
}
}
}
}

View File

@@ -1,104 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.Cipher
{
public abstract class CtrBlockCipher : IDisposable
{
private byte[] m_pBlock;
private int m_iBlockPos;
public abstract int BlockSize
{
get;
}
public CtrBlockCipher()
{
int cb = this.BlockSize;
if(cb <= 0) throw new InvalidOperationException("this.BlockSize");
m_pBlock = new byte[cb];
m_iBlockPos = cb;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool bDisposing)
{
if(bDisposing)
{
MemUtil.ZeroByteArray(m_pBlock);
m_iBlockPos = m_pBlock.Length;
}
}
protected void InvalidateBlock()
{
m_iBlockPos = m_pBlock.Length;
}
protected abstract void NextBlock(byte[] pBlock);
public void Encrypt(byte[] m, int iOffset, int cb)
{
if(m == null) throw new ArgumentNullException("m");
if(iOffset < 0) throw new ArgumentOutOfRangeException("iOffset");
if(cb < 0) throw new ArgumentOutOfRangeException("cb");
if(iOffset > (m.Length - cb)) throw new ArgumentOutOfRangeException("cb");
int cbBlock = m_pBlock.Length;
while(cb > 0)
{
Debug.Assert(m_iBlockPos <= cbBlock);
if(m_iBlockPos == cbBlock)
{
NextBlock(m_pBlock);
m_iBlockPos = 0;
}
int cbCopy = Math.Min(cbBlock - m_iBlockPos, cb);
Debug.Assert(cbCopy > 0);
MemUtil.XorArray(m_pBlock, m_iBlockPos, m, iOffset, cbCopy);
m_iBlockPos += cbCopy;
iOffset += cbCopy;
cb -= cbCopy;
}
}
public void Decrypt(byte[] m, int iOffset, int cb)
{
Encrypt(m, iOffset, cb);
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -63,25 +63,4 @@ namespace KeePassLib.Cryptography.Cipher
/// <returns>Stream, from which the decrypted data can be read.</returns>
Stream DecryptStream(Stream sEncrypted, byte[] pbKey, byte[] pbIV);
}
public interface ICipherEngine2 : ICipherEngine
{
/// <summary>
/// Length of an encryption key in bytes.
/// The base <c>ICipherEngine</c> assumes 32.
/// </summary>
int KeyLength
{
get;
}
/// <summary>
/// Length of the initialization vector in bytes.
/// The base <c>ICipherEngine</c> assumes 16.
/// </summary>
int IVLength
{
get;
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,146 +19,169 @@
// Implementation of the Salsa20 cipher, based on the eSTREAM submission.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.Cipher
{
public sealed class Salsa20Cipher : CtrBlockCipher
public sealed class Salsa20Cipher
{
private uint[] m_s = new uint[16]; // State
private uint[] m_state = new uint[16];
private uint[] m_x = new uint[16]; // Working buffer
private static readonly uint[] g_sigma = new uint[4] {
private byte[] m_output = new byte[64];
private int m_outputPos = 64;
private static readonly uint[] m_sigma = new uint[4]{
0x61707865, 0x3320646E, 0x79622D32, 0x6B206574
};
public override int BlockSize
public Salsa20Cipher(byte[] pbKey32, byte[] pbIV8)
{
get { return 64; }
KeySetup(pbKey32);
IvSetup(pbIV8);
}
public Salsa20Cipher(byte[] pbKey32, byte[] pbIV8) : base()
~Salsa20Cipher()
{
if(pbKey32 == null) throw new ArgumentNullException("pbKey32");
if(pbKey32.Length != 32) throw new ArgumentOutOfRangeException("pbKey32");
if(pbIV8 == null) throw new ArgumentNullException("pbIV8");
if(pbIV8.Length != 8) throw new ArgumentOutOfRangeException("pbIV8");
// Clear sensitive data
// Key setup
m_s[1] = MemUtil.BytesToUInt32(pbKey32, 0);
m_s[2] = MemUtil.BytesToUInt32(pbKey32, 4);
m_s[3] = MemUtil.BytesToUInt32(pbKey32, 8);
m_s[4] = MemUtil.BytesToUInt32(pbKey32, 12);
m_s[11] = MemUtil.BytesToUInt32(pbKey32, 16);
m_s[12] = MemUtil.BytesToUInt32(pbKey32, 20);
m_s[13] = MemUtil.BytesToUInt32(pbKey32, 24);
m_s[14] = MemUtil.BytesToUInt32(pbKey32, 28);
m_s[0] = g_sigma[0];
m_s[5] = g_sigma[1];
m_s[10] = g_sigma[2];
m_s[15] = g_sigma[3];
// IV setup
m_s[6] = MemUtil.BytesToUInt32(pbIV8, 0);
m_s[7] = MemUtil.BytesToUInt32(pbIV8, 4);
m_s[8] = 0; // Counter, low
m_s[9] = 0; // Counter, high
Array.Clear(m_state, 0, m_state.Length);
Array.Clear(m_x, 0, m_x.Length);
}
protected override void Dispose(bool bDisposing)
private void NextOutput()
{
if(bDisposing)
{
MemUtil.ZeroArray<uint>(m_s);
MemUtil.ZeroArray<uint>(m_x);
}
uint[] x = m_x; // Local alias for working buffer
base.Dispose(bDisposing);
}
// Compiler/runtime might remove array bound checks after this
protected override void NextBlock(byte[] pBlock)
{
if(pBlock == null) throw new ArgumentNullException("pBlock");
if(pBlock.Length != 64) throw new ArgumentOutOfRangeException("pBlock");
// x is a local alias for the working buffer; with this,
// the compiler/runtime might remove some checks
uint[] x = m_x;
if(x == null) throw new InvalidOperationException();
if(x.Length < 16) throw new InvalidOperationException();
uint[] s = m_s;
if(s == null) throw new InvalidOperationException();
if(s.Length < 16) throw new InvalidOperationException();
Array.Copy(s, x, 16);
Array.Copy(m_state, x, 16);
unchecked
{
// 10 * 8 quarter rounds = 20 rounds
for(int i = 0; i < 10; ++i) // (int i = 20; i > 0; i -= 2)
{
x[ 4] ^= MemUtil.RotateLeft32(x[ 0] + x[12], 7);
x[ 8] ^= MemUtil.RotateLeft32(x[ 4] + x[ 0], 9);
x[12] ^= MemUtil.RotateLeft32(x[ 8] + x[ 4], 13);
x[ 0] ^= MemUtil.RotateLeft32(x[12] + x[ 8], 18);
x[ 9] ^= MemUtil.RotateLeft32(x[ 5] + x[ 1], 7);
x[13] ^= MemUtil.RotateLeft32(x[ 9] + x[ 5], 9);
x[ 1] ^= MemUtil.RotateLeft32(x[13] + x[ 9], 13);
x[ 5] ^= MemUtil.RotateLeft32(x[ 1] + x[13], 18);
x[14] ^= MemUtil.RotateLeft32(x[10] + x[ 6], 7);
x[ 2] ^= MemUtil.RotateLeft32(x[14] + x[10], 9);
x[ 6] ^= MemUtil.RotateLeft32(x[ 2] + x[14], 13);
x[10] ^= MemUtil.RotateLeft32(x[ 6] + x[ 2], 18);
x[ 3] ^= MemUtil.RotateLeft32(x[15] + x[11], 7);
x[ 7] ^= MemUtil.RotateLeft32(x[ 3] + x[15], 9);
x[11] ^= MemUtil.RotateLeft32(x[ 7] + x[ 3], 13);
x[15] ^= MemUtil.RotateLeft32(x[11] + x[ 7], 18);
x[ 1] ^= MemUtil.RotateLeft32(x[ 0] + x[ 3], 7);
x[ 2] ^= MemUtil.RotateLeft32(x[ 1] + x[ 0], 9);
x[ 3] ^= MemUtil.RotateLeft32(x[ 2] + x[ 1], 13);
x[ 0] ^= MemUtil.RotateLeft32(x[ 3] + x[ 2], 18);
x[ 6] ^= MemUtil.RotateLeft32(x[ 5] + x[ 4], 7);
x[ 7] ^= MemUtil.RotateLeft32(x[ 6] + x[ 5], 9);
x[ 4] ^= MemUtil.RotateLeft32(x[ 7] + x[ 6], 13);
x[ 5] ^= MemUtil.RotateLeft32(x[ 4] + x[ 7], 18);
x[11] ^= MemUtil.RotateLeft32(x[10] + x[ 9], 7);
x[ 8] ^= MemUtil.RotateLeft32(x[11] + x[10], 9);
x[ 9] ^= MemUtil.RotateLeft32(x[ 8] + x[11], 13);
x[10] ^= MemUtil.RotateLeft32(x[ 9] + x[ 8], 18);
x[12] ^= MemUtil.RotateLeft32(x[15] + x[14], 7);
x[13] ^= MemUtil.RotateLeft32(x[12] + x[15], 9);
x[14] ^= MemUtil.RotateLeft32(x[13] + x[12], 13);
x[15] ^= MemUtil.RotateLeft32(x[14] + x[13], 18);
}
for(int i = 0; i < 16; ++i) x[i] += s[i];
x[ 4] ^= Rotl32(x[ 0] + x[12], 7);
x[ 8] ^= Rotl32(x[ 4] + x[ 0], 9);
x[12] ^= Rotl32(x[ 8] + x[ 4], 13);
x[ 0] ^= Rotl32(x[12] + x[ 8], 18);
x[ 9] ^= Rotl32(x[ 5] + x[ 1], 7);
x[13] ^= Rotl32(x[ 9] + x[ 5], 9);
x[ 1] ^= Rotl32(x[13] + x[ 9], 13);
x[ 5] ^= Rotl32(x[ 1] + x[13], 18);
x[14] ^= Rotl32(x[10] + x[ 6], 7);
x[ 2] ^= Rotl32(x[14] + x[10], 9);
x[ 6] ^= Rotl32(x[ 2] + x[14], 13);
x[10] ^= Rotl32(x[ 6] + x[ 2], 18);
x[ 3] ^= Rotl32(x[15] + x[11], 7);
x[ 7] ^= Rotl32(x[ 3] + x[15], 9);
x[11] ^= Rotl32(x[ 7] + x[ 3], 13);
x[15] ^= Rotl32(x[11] + x[ 7], 18);
x[ 1] ^= Rotl32(x[ 0] + x[ 3], 7);
x[ 2] ^= Rotl32(x[ 1] + x[ 0], 9);
x[ 3] ^= Rotl32(x[ 2] + x[ 1], 13);
x[ 0] ^= Rotl32(x[ 3] + x[ 2], 18);
x[ 6] ^= Rotl32(x[ 5] + x[ 4], 7);
x[ 7] ^= Rotl32(x[ 6] + x[ 5], 9);
x[ 4] ^= Rotl32(x[ 7] + x[ 6], 13);
x[ 5] ^= Rotl32(x[ 4] + x[ 7], 18);
x[11] ^= Rotl32(x[10] + x[ 9], 7);
x[ 8] ^= Rotl32(x[11] + x[10], 9);
x[ 9] ^= Rotl32(x[ 8] + x[11], 13);
x[10] ^= Rotl32(x[ 9] + x[ 8], 18);
x[12] ^= Rotl32(x[15] + x[14], 7);
x[13] ^= Rotl32(x[12] + x[15], 9);
x[14] ^= Rotl32(x[13] + x[12], 13);
x[15] ^= Rotl32(x[14] + x[13], 18);
}
for(int i = 0; i < 16; ++i)
{
int i4 = i << 2;
uint xi = x[i];
x[i] += m_state[i];
pBlock[i4] = (byte)xi;
pBlock[i4 + 1] = (byte)(xi >> 8);
pBlock[i4 + 2] = (byte)(xi >> 16);
pBlock[i4 + 3] = (byte)(xi >> 24);
for(int i = 0; i < 16; ++i)
{
m_output[i << 2] = (byte)x[i];
m_output[(i << 2) + 1] = (byte)(x[i] >> 8);
m_output[(i << 2) + 2] = (byte)(x[i] >> 16);
m_output[(i << 2) + 3] = (byte)(x[i] >> 24);
}
m_outputPos = 0;
++m_state[8];
if(m_state[8] == 0) ++m_state[9];
}
}
++s[8];
if(s[8] == 0) ++s[9];
private static uint Rotl32(uint x, int b)
{
unchecked
{
return ((x << b) | (x >> (32 - b)));
}
}
private static uint U8To32Little(byte[] pb, int iOffset)
{
unchecked
{
return ((uint)pb[iOffset] | ((uint)pb[iOffset + 1] << 8) |
((uint)pb[iOffset + 2] << 16) | ((uint)pb[iOffset + 3] << 24));
}
}
private void KeySetup(byte[] k)
{
if(k == null) throw new ArgumentNullException("k");
if(k.Length != 32) throw new ArgumentException();
m_state[1] = U8To32Little(k, 0);
m_state[2] = U8To32Little(k, 4);
m_state[3] = U8To32Little(k, 8);
m_state[4] = U8To32Little(k, 12);
m_state[11] = U8To32Little(k, 16);
m_state[12] = U8To32Little(k, 20);
m_state[13] = U8To32Little(k, 24);
m_state[14] = U8To32Little(k, 28);
m_state[0] = m_sigma[0];
m_state[5] = m_sigma[1];
m_state[10] = m_sigma[2];
m_state[15] = m_sigma[3];
}
private void IvSetup(byte[] pbIV)
{
if(pbIV == null) throw new ArgumentNullException("pbIV");
if(pbIV.Length != 8) throw new ArgumentException();
m_state[6] = U8To32Little(pbIV, 0);
m_state[7] = U8To32Little(pbIV, 4);
m_state[8] = 0;
m_state[9] = 0;
}
public void Encrypt(byte[] m, int nByteCount, bool bXor)
{
if(m == null) throw new ArgumentNullException("m");
if(nByteCount > m.Length) throw new ArgumentException();
int nBytesRem = nByteCount, nOffset = 0;
while(nBytesRem > 0)
{
Debug.Assert((m_outputPos >= 0) && (m_outputPos <= 64));
if(m_outputPos == 64) NextOutput();
Debug.Assert(m_outputPos < 64);
int nCopy = Math.Min(64 - m_outputPos, nBytesRem);
if(bXor) MemUtil.XorArray(m_output, m_outputPos, m, nOffset, nCopy);
else Array.Copy(m_output, m_outputPos, m, nOffset, nCopy);
m_outputPos += nCopy;
nBytesRem -= nCopy;
nOffset += nCopy;
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -24,8 +24,15 @@ using System.IO;
using System.Security;
using System.Diagnostics;
#if !KeePassUAP
#if !KeePassRT
using System.Security.Cryptography;
#else
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.IO;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;
#endif
using KeePassLib.Resources;
@@ -37,12 +44,12 @@ namespace KeePassLib.Cryptography.Cipher
/// </summary>
public sealed class StandardAesEngine : ICipherEngine
{
#if !KeePassUAP
#if !KeePassRT
private const CipherMode m_rCipherMode = CipherMode.CBC;
private const PaddingMode m_rCipherPadding = PaddingMode.PKCS7;
#endif
private static PwUuid g_uuidAes = null;
private static PwUuid m_uuidAes = null;
/// <summary>
/// UUID of the cipher engine. This ID uniquely identifies the
@@ -52,16 +59,14 @@ namespace KeePassLib.Cryptography.Cipher
{
get
{
PwUuid pu = g_uuidAes;
if(pu == null)
if(m_uuidAes == null)
{
pu = new PwUuid(new byte[] {
m_uuidAes = new PwUuid(new byte[]{
0x31, 0xC1, 0xF2, 0xE6, 0xBF, 0x71, 0x43, 0x50,
0xBE, 0x58, 0x05, 0x21, 0x6A, 0xFC, 0x5A, 0xFF });
g_uuidAes = pu;
}
return pu;
return m_uuidAes;
}
}
@@ -76,14 +81,7 @@ namespace KeePassLib.Cryptography.Cipher
/// <summary>
/// Get a displayable name describing this cipher engine.
/// </summary>
public string DisplayName
{
get
{
return ("AES/Rijndael (" + KLRes.KeyBits.Replace(@"{PARAM}",
"256") + ", FIPS 197)");
}
}
public string DisplayName { get { return KLRes.EncAlgorithmAes; } }
private static void ValidateArguments(Stream stream, bool bEncrypt, byte[] pbKey, byte[] pbIV)
{
@@ -100,12 +98,12 @@ namespace KeePassLib.Cryptography.Cipher
if(bEncrypt)
{
Debug.Assert(stream.CanWrite);
if(!stream.CanWrite) throw new ArgumentException("Stream must be writable!");
if(stream.CanWrite == false) throw new ArgumentException("Stream must be writable!");
}
else // Decrypt
{
Debug.Assert(stream.CanRead);
if(!stream.CanRead) throw new ArgumentException("Encrypted stream must be readable!");
if(stream.CanRead == false) throw new ArgumentException("Encrypted stream must be readable!");
}
}
@@ -119,9 +117,7 @@ namespace KeePassLib.Cryptography.Cipher
byte[] pbLocalKey = new byte[32];
Array.Copy(pbKey, pbLocalKey, 32);
#if KeePassUAP
return StandardAesEngineExt.CreateStream(s, bEncrypt, pbLocalKey, pbLocalIV);
#else
#if !KeePassRT
RijndaelManaged r = new RijndaelManaged();
if(r.BlockSize != 128) // AES block size
{
@@ -141,6 +137,18 @@ namespace KeePassLib.Cryptography.Cipher
return new CryptoStream(s, iTransform, bEncrypt ? CryptoStreamMode.Write :
CryptoStreamMode.Read);
#else
AesEngine aes = new AesEngine();
CbcBlockCipher cbc = new CbcBlockCipher(aes);
PaddedBufferedBlockCipher bc = new PaddedBufferedBlockCipher(cbc,
new Pkcs7Padding());
KeyParameter kp = new KeyParameter(pbLocalKey);
ParametersWithIV prmIV = new ParametersWithIV(kp, pbLocalIV);
bc.Init(bEncrypt, prmIV);
IBufferedCipher cpRead = (bEncrypt ? null : bc);
IBufferedCipher cpWrite = (bEncrypt ? bc : null);
return new CipherStream(s, cpRead, cpWrite);
#endif
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2016 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
@@ -20,16 +20,11 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
#if !KeePassUAP
using System.Drawing;
using System.Security;
using System.Security.Cryptography;
#endif
using System.IO;
using System.Diagnostics;
using System.Drawing;
using KeePassLib.Native;
using KeePassLib.Utility;
@@ -37,37 +32,28 @@ using KeePassLib.Utility;
namespace KeePassLib.Cryptography
{
/// <summary>
/// Cryptographically secure pseudo-random number generator.
/// The returned values are unpredictable and cannot be reproduced.
/// Cryptographically strong random number generator. The returned values
/// are unpredictable and cannot be reproduced.
/// <c>CryptoRandom</c> is a singleton class.
/// </summary>
public sealed class CryptoRandom
{
private byte[] m_pbEntropyPool = new byte[64];
private ulong m_uCounter;
private uint m_uCounter;
private RNGCryptoServiceProvider m_rng = new RNGCryptoServiceProvider();
private ulong m_uGeneratedBytesCount = 0;
private static object g_oSyncRoot = new object();
private object m_oSyncRoot = new object();
private static CryptoRandom g_pInstance = null;
private static CryptoRandom m_pInstance = null;
public static CryptoRandom Instance
{
get
{
CryptoRandom cr;
lock(g_oSyncRoot)
{
cr = g_pInstance;
if(cr == null)
{
cr = new CryptoRandom();
g_pInstance = cr;
}
}
if(m_pInstance != null) return m_pInstance;
return cr;
m_pInstance = new CryptoRandom();
return m_pInstance;
}
}
@@ -94,13 +80,10 @@ namespace KeePassLib.Cryptography
private CryptoRandom()
{
Random r = new Random();
m_uCounter = (uint)r.Next();
// byte[] pb = new byte[8];
// rWeak.NextBytes(pb);
// m_uCounter = MemUtil.BytesToUInt64(pb);
m_uCounter = (ulong)DateTime.UtcNow.ToBinary();
AddEntropy(GetSystemData());
AddEntropy(GetSystemData(r));
AddEntropy(GetCspData());
}
@@ -116,181 +99,110 @@ namespace KeePassLib.Cryptography
if(pbEntropy.Length == 0) { Debug.Assert(false); return; }
byte[] pbNewData = pbEntropy;
if(pbEntropy.Length > 64)
if(pbEntropy.Length >= 64)
{
#if KeePassLibSD
using(SHA256Managed shaNew = new SHA256Managed())
#if !KeePassLibSD
SHA512Managed shaNew = new SHA512Managed();
#else
using(SHA512Managed shaNew = new SHA512Managed())
SHA256Managed shaNew = new SHA256Managed();
#endif
{
pbNewData = shaNew.ComputeHash(pbEntropy);
}
}
MemoryStream ms = new MemoryStream();
lock(m_oSyncRoot)
{
int cbPool = m_pbEntropyPool.Length;
int cbNew = pbNewData.Length;
ms.Write(m_pbEntropyPool, 0, m_pbEntropyPool.Length);
ms.Write(pbNewData, 0, pbNewData.Length);
byte[] pbCmp = new byte[cbPool + cbNew];
Array.Copy(m_pbEntropyPool, pbCmp, cbPool);
Array.Copy(pbNewData, 0, pbCmp, cbPool, cbNew);
MemUtil.ZeroByteArray(m_pbEntropyPool);
#if KeePassLibSD
using(SHA256Managed shaPool = new SHA256Managed())
byte[] pbFinal = ms.ToArray();
#if !KeePassLibSD
Debug.Assert(pbFinal.Length == (64 + pbNewData.Length));
SHA512Managed shaPool = new SHA512Managed();
#else
using(SHA512Managed shaPool = new SHA512Managed())
SHA256Managed shaPool = new SHA256Managed();
#endif
{
m_pbEntropyPool = shaPool.ComputeHash(pbCmp);
m_pbEntropyPool = shaPool.ComputeHash(pbFinal);
}
MemUtil.ZeroByteArray(pbCmp);
}
ms.Close();
}
private static byte[] GetSystemData()
private static byte[] GetSystemData(Random rWeak)
{
MemoryStream ms = new MemoryStream();
byte[] pb;
pb = MemUtil.Int32ToBytes(Environment.TickCount);
MemUtil.Write(ms, pb);
pb = MemUtil.UInt32ToBytes((uint)Environment.TickCount);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.Int64ToBytes(DateTime.UtcNow.ToBinary());
MemUtil.Write(ms, pb);
pb = TimeUtil.PackTime(DateTime.Now);
ms.Write(pb, 0, pb.Length);
#if !KeePassLibSD
/*Not supported on Android
// In try-catch for systems without GUI;
// https://sourceforge.net/p/keepass/discussion/329221/thread/20335b73/
try
{
Point pt = Cursor.Position;
pb = MemUtil.Int32ToBytes(pt.X);
MemUtil.Write(ms, pb);
pb = MemUtil.Int32ToBytes(pt.Y);
MemUtil.Write(ms, pb);
}
catch(Exception) { }
*/
#endif
pb = MemUtil.UInt32ToBytes((uint)rWeak.Next());
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt32ToBytes((uint)NativeLib.GetPlatformID());
MemUtil.Write(ms, pb);
ms.Write(pb, 0, pb.Length);
#if (!KeePassLibSD && !KeePassRT)
try
{
#if KeePassUAP
string strOS = EnvironmentExt.OSVersion.VersionString;
#else
string strOS = Environment.OSVersion.VersionString;
#endif
AddStrHash(ms, strOS);
pb = MemUtil.UInt32ToBytes((uint)Environment.ProcessorCount);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)Environment.WorkingSet);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.Int32ToBytes(Environment.ProcessorCount);
MemUtil.Write(ms, pb);
Version v = Environment.OSVersion.Version;
int nv = (v.Major << 28) + (v.MajorRevision << 24) +
(v.Minor << 20) + (v.MinorRevision << 16) +
(v.Revision << 12) + v.Build;
pb = MemUtil.UInt32ToBytes((uint)nv);
ms.Write(pb, 0, pb.Length);
#if !KeePassUAP
AddStrHash(ms, Environment.CommandLine);
Process p = Process.GetCurrentProcess();
pb = MemUtil.UInt64ToBytes((ulong)p.Handle.ToInt64());
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt32ToBytes((uint)p.HandleCount);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt32ToBytes((uint)p.Id);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.NonpagedSystemMemorySize64);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.PagedMemorySize64);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.PagedSystemMemorySize64);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.PeakPagedMemorySize64);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.PeakVirtualMemorySize64);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.PeakWorkingSet64);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.PrivateMemorySize64);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.StartTime.ToBinary());
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.VirtualMemorySize64);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.UInt64ToBytes((ulong)p.WorkingSet64);
ms.Write(pb, 0, pb.Length);
pb = MemUtil.Int64ToBytes(Environment.WorkingSet);
MemUtil.Write(ms, pb);
#endif
}
catch(Exception) { Debug.Assert(false); }
try
{
foreach(DictionaryEntry de in Environment.GetEnvironmentVariables())
{
AddStrHash(ms, (de.Key as string));
AddStrHash(ms, (de.Value as string));
}
}
catch(Exception) { Debug.Assert(false); }
#if KeePassUAP
pb = DiagnosticsExt.GetProcessEntropy();
MemUtil.Write(ms, pb);
#elif !KeePassLibSD
Process p = null;
try
{
p = Process.GetCurrentProcess();
// Not supported in Mono 1.2.6:
pb = MemUtil.Int64ToBytes(p.Handle.ToInt64());
MemUtil.Write(ms, pb);
pb = MemUtil.Int32ToBytes(p.HandleCount);
MemUtil.Write(ms, pb);
pb = MemUtil.Int32ToBytes(p.Id);
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.NonpagedSystemMemorySize64);
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.PagedMemorySize64);
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.PagedSystemMemorySize64);
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.PeakPagedMemorySize64);
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.PeakVirtualMemorySize64);
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.PeakWorkingSet64);
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.PrivateMemorySize64);
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.StartTime.ToBinary());
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.VirtualMemorySize64);
MemUtil.Write(ms, pb);
pb = MemUtil.Int64ToBytes(p.WorkingSet64);
MemUtil.Write(ms, pb);
// pb = MemUtil.UInt32ToBytes((uint)p.SessionId);
// ms.Write(pb, 0, pb.Length);
// pb = MemUtil.UInt32ToBytes((uint)p.SessionId);
// MemUtil.Write(ms, pb);
}
catch(Exception) { Debug.Assert(NativeLib.IsUnix()); }
finally
{
try { if(p != null) p.Dispose(); }
catch(Exception) { Debug.Assert(false); }
}
catch(Exception) { }
#endif
try
{
CultureInfo ci = CultureInfo.CurrentCulture;
if(ci != null)
{
pb = MemUtil.Int32ToBytes(ci.GetHashCode());
MemUtil.Write(ms, pb);
}
else { Debug.Assert(false); }
}
catch(Exception) { Debug.Assert(false); }
pb = Guid.NewGuid().ToByteArray();
MemUtil.Write(ms, pb);
ms.Write(pb, 0, pb.Length);
byte[] pbAll = ms.ToArray();
ms.Close();
return pbAll;
}
private static void AddStrHash(Stream s, string str)
{
if(s == null) { Debug.Assert(false); return; }
if(string.IsNullOrEmpty(str)) return;
byte[] pbUtf8 = StrUtil.Utf8.GetBytes(str);
byte[] pbHash = CryptoUtil.HashSha256(pbUtf8);
MemUtil.Write(s, pbHash);
}
private byte[] GetCspData()
{
byte[] pbCspRandom = new byte[32];
@@ -303,31 +215,28 @@ namespace KeePassLib.Cryptography
if(this.GenerateRandom256Pre != null)
this.GenerateRandom256Pre(this, EventArgs.Empty);
byte[] pbCmp;
byte[] pbFinal;
lock(m_oSyncRoot)
{
m_uCounter += 0x74D8B29E4D38E161UL; // Prime number
byte[] pbCounter = MemUtil.UInt64ToBytes(m_uCounter);
unchecked { m_uCounter += 386047; } // Prime number
byte[] pbCounter = MemUtil.UInt32ToBytes(m_uCounter);
byte[] pbCspRandom = GetCspData();
int cbPool = m_pbEntropyPool.Length;
int cbCtr = pbCounter.Length;
int cbCsp = pbCspRandom.Length;
pbCmp = new byte[cbPool + cbCtr + cbCsp];
Array.Copy(m_pbEntropyPool, pbCmp, cbPool);
Array.Copy(pbCounter, 0, pbCmp, cbPool, cbCtr);
Array.Copy(pbCspRandom, 0, pbCmp, cbPool + cbCtr, cbCsp);
MemUtil.ZeroByteArray(pbCspRandom);
MemoryStream ms = new MemoryStream();
ms.Write(m_pbEntropyPool, 0, m_pbEntropyPool.Length);
ms.Write(pbCounter, 0, pbCounter.Length);
ms.Write(pbCspRandom, 0, pbCspRandom.Length);
pbFinal = ms.ToArray();
Debug.Assert(pbFinal.Length == (m_pbEntropyPool.Length +
pbCounter.Length + pbCspRandom.Length));
ms.Close();
m_uGeneratedBytesCount += 32;
}
byte[] pbRet = CryptoUtil.HashSha256(pbCmp);
MemUtil.ZeroByteArray(pbCmp);
return pbRet;
SHA256Managed sha256 = new SHA256Managed();
return sha256.ComputeHash(pbFinal);
}
/// <summary>
@@ -339,32 +248,29 @@ namespace KeePassLib.Cryptography
/// random bytes.</returns>
public byte[] GetRandomBytes(uint uRequestedBytes)
{
if(uRequestedBytes == 0) return MemUtil.EmptyByteArray;
if(uRequestedBytes > (uint)int.MaxValue)
{
Debug.Assert(false);
throw new ArgumentOutOfRangeException("uRequestedBytes");
}
if(uRequestedBytes == 0) return new byte[0]; // Allow zero-length array
int cbRem = (int)uRequestedBytes;
byte[] pbRes = new byte[cbRem];
int iPos = 0;
byte[] pbRes = new byte[uRequestedBytes];
long lPos = 0;
while(cbRem != 0)
while(uRequestedBytes != 0)
{
byte[] pbRandom256 = GenerateRandom256();
Debug.Assert(pbRandom256.Length == 32);
int cbCopy = Math.Min(cbRem, pbRandom256.Length);
Array.Copy(pbRandom256, 0, pbRes, iPos, cbCopy);
long lCopy = (long)((uRequestedBytes < 32) ? uRequestedBytes : 32);
MemUtil.ZeroByteArray(pbRandom256);
#if (!KeePassLibSD && !KeePassRT)
Array.Copy(pbRandom256, 0, pbRes, lPos, lCopy);
#else
Array.Copy(pbRandom256, 0, pbRes, (int)lPos, (int)lCopy);
#endif
iPos += cbCopy;
cbRem -= cbCopy;
lPos += lCopy;
uRequestedBytes -= (uint)lCopy;
}
Debug.Assert(iPos == pbRes.Length);
Debug.Assert((int)lPos == pbRes.Length);
return pbRes;
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,13 +19,9 @@
using System;
using System.Diagnostics;
#if !KeePassUAP
using System.Security.Cryptography;
#endif
using KeePassLib.Cryptography.Cipher;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography
{
@@ -42,7 +38,6 @@ namespace KeePassLib.Cryptography
/// <summary>
/// A variant of the ARCFour algorithm (RC4 incompatible).
/// </summary>
/// </summary>
ArcFourVariant = 1,
/// <summary>
@@ -50,12 +45,7 @@ namespace KeePassLib.Cryptography
/// </summary>
Salsa20 = 2,
/// <summary>
/// ChaCha20 stream cipher algorithm.
/// </summary>
ChaCha20 = 3,
Count = 4
Count = 3
}
/// <summary>
@@ -64,16 +54,15 @@ namespace KeePassLib.Cryptography
/// properties, but for the same seed always the same stream
/// is produced, i.e. this class can be used as stream cipher.
/// </summary>
public sealed class CryptoRandomStream : IDisposable
public sealed class CryptoRandomStream
{
private readonly CrsAlgorithm m_crsAlgorithm;
private CrsAlgorithm m_crsAlgorithm;
private byte[] m_pbState = null;
private byte m_i = 0;
private byte m_j = 0;
private Salsa20Cipher m_salsa20 = null;
private ChaCha20Cipher m_chacha20 = null;
/// <summary>
/// Construct a new cryptographically secure random stream object.
@@ -81,53 +70,31 @@ namespace KeePassLib.Cryptography
/// <param name="genAlgorithm">Algorithm to use.</param>
/// <param name="pbKey">Initialization key. Must not be <c>null</c> and
/// must contain at least 1 byte.</param>
public CryptoRandomStream(CrsAlgorithm a, byte[] pbKey)
{
if(pbKey == null) { Debug.Assert(false); throw new ArgumentNullException("pbKey"); }
/// <exception cref="System.ArgumentNullException">Thrown if the
int cbKey = pbKey.Length;
if(cbKey <= 0)
{
Debug.Assert(false); // Need at least one byte
throw new ArgumentOutOfRangeException("pbKey");
}
/// <paramref name="pbKey" /> parameter is <c>null</c>.</exception>
m_crsAlgorithm = a;
/// <exception cref="System.ArgumentException">Thrown if the
if(a == CrsAlgorithm.ChaCha20)
{
byte[] pbKey32 = new byte[32];
byte[] pbIV12 = new byte[12];
/// <paramref name="pbKey" /> parameter contains no bytes or the
using(SHA512Managed h = new SHA512Managed())
{
byte[] pbHash = h.ComputeHash(pbKey);
Array.Copy(pbHash, pbKey32, 32);
Array.Copy(pbHash, 32, pbIV12, 0, 12);
MemUtil.ZeroByteArray(pbHash);
}
/// algorithm is unknown.</exception>
m_chacha20 = new ChaCha20Cipher(pbKey32, pbIV12, true);
}
else if(a == CrsAlgorithm.Salsa20)
public CryptoRandomStream(CrsAlgorithm genAlgorithm, byte[] pbKey)
{
byte[] pbKey32 = CryptoUtil.HashSha256(pbKey);
byte[] pbIV8 = new byte[8] { 0xE8, 0x30, 0x09, 0x4B,
0x97, 0x20, 0x5D, 0x2A }; // Unique constant
m_crsAlgorithm = genAlgorithm;
m_salsa20 = new Salsa20Cipher(pbKey32, pbIV8);
}
else if(a == CrsAlgorithm.ArcFourVariant)
Debug.Assert(pbKey != null); if(pbKey == null) throw new ArgumentNullException("pbKey");
uint uKeyLen = (uint)pbKey.Length;
Debug.Assert(uKeyLen != 0); if(uKeyLen == 0) throw new ArgumentException();
if(genAlgorithm == CrsAlgorithm.ArcFourVariant)
{
// Fill the state linearly
m_pbState = new byte[256];
for(int w = 0; w < 256; ++w) m_pbState[w] = (byte)w;
for(uint w = 0; w < 256; ++w) m_pbState[w] = (byte)w;
unchecked
{
byte j = 0, t;
int inxKey = 0;
for(int w = 0; w < 256; ++w) // Key setup
uint inxKey = 0;
for(uint w = 0; w < 256; ++w) // Key setup
{
j += (byte)(m_pbState[w] + pbKey[inxKey]);
@@ -136,40 +103,25 @@ namespace KeePassLib.Cryptography
m_pbState[j] = t;
++inxKey;
if(inxKey >= cbKey) inxKey = 0;
if(inxKey >= uKeyLen) inxKey = 0;
}
}
GetRandomBytes(512); // Increases security, see cryptanalysis
}
else if(genAlgorithm == CrsAlgorithm.Salsa20)
{
SHA256Managed sha256 = new SHA256Managed();
byte[] pbKey32 = sha256.ComputeHash(pbKey);
byte[] pbIV = new byte[]{ 0xE8, 0x30, 0x09, 0x4B,
0x97, 0x20, 0x5D, 0x2A }; // Unique constant
m_salsa20 = new Salsa20Cipher(pbKey32, pbIV);
}
else // Unknown algorithm
{
Debug.Assert(false);
throw new ArgumentOutOfRangeException("a");
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if(disposing)
{
if(m_crsAlgorithm == CrsAlgorithm.ChaCha20)
m_chacha20.Dispose();
else if(m_crsAlgorithm == CrsAlgorithm.Salsa20)
m_salsa20.Dispose();
else if(m_crsAlgorithm == CrsAlgorithm.ArcFourVariant)
{
MemUtil.ZeroByteArray(m_pbState);
m_i = 0;
m_j = 0;
}
else { Debug.Assert(false); }
throw new ArgumentException();
}
}
@@ -180,23 +132,15 @@ namespace KeePassLib.Cryptography
/// <returns>Returns <paramref name="uRequestedCount" /> random bytes.</returns>
public byte[] GetRandomBytes(uint uRequestedCount)
{
if(uRequestedCount == 0) return MemUtil.EmptyByteArray;
if(uRequestedCount == 0) return new byte[0];
if(uRequestedCount > (uint)int.MaxValue)
throw new ArgumentOutOfRangeException("uRequestedCount");
int cb = (int)uRequestedCount;
byte[] pbRet = new byte[uRequestedCount];
byte[] pbRet = new byte[cb];
if(m_crsAlgorithm == CrsAlgorithm.ChaCha20)
m_chacha20.Encrypt(pbRet, 0, cb);
else if(m_crsAlgorithm == CrsAlgorithm.Salsa20)
m_salsa20.Encrypt(pbRet, 0, cb);
else if(m_crsAlgorithm == CrsAlgorithm.ArcFourVariant)
if(m_crsAlgorithm == CrsAlgorithm.ArcFourVariant)
{
unchecked
{
for(int w = 0; w < cb; ++w)
for(uint w = 0; w < uRequestedCount; ++w)
{
++m_i;
m_j += m_pbState[m_i];
@@ -210,6 +154,8 @@ namespace KeePassLib.Cryptography
}
}
}
else if(m_crsAlgorithm == CrsAlgorithm.Salsa20)
m_salsa20.Encrypt(pbRet, pbRet.Length, false);
else { Debug.Assert(false); }
return pbRet;
@@ -218,8 +164,15 @@ namespace KeePassLib.Cryptography
public ulong GetRandomUInt64()
{
byte[] pb = GetRandomBytes(8);
return MemUtil.BytesToUInt64(pb);
unchecked
{
return ((ulong)pb[0]) | ((ulong)pb[1] << 8) |
((ulong)pb[2] << 16) | ((ulong)pb[3] << 24) |
((ulong)pb[4] << 32) | ((ulong)pb[5] << 40) |
((ulong)pb[6] << 48) | ((ulong)pb[7] << 56);
}
}
#if CRSBENCHMARK
public static string Benchmark()
@@ -244,10 +197,8 @@ namespace KeePassLib.Cryptography
int nStart = Environment.TickCount;
for(int i = 0; i < nRounds; ++i)
{
using(CryptoRandomStream c = new CryptoRandomStream(cra, pbKey))
{
c.GetRandomBytes((uint)nDataSize);
}
CryptoRandomStream c = new CryptoRandomStream(cra, pbKey);
c.GetRandomBytes((uint)nDataSize);
}
int nEnd = Environment.TickCount;

View File

@@ -1,129 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
#if !KeePassUAP
using System.Security.Cryptography;
#endif
using KeePassLib.Utility;
namespace KeePassLib.Cryptography
{
public static class CryptoUtil
{
public static byte[] HashSha256(byte[] pbData)
{
if(pbData == null) throw new ArgumentNullException("pbData");
return HashSha256(pbData, 0, pbData.Length);
}
public static byte[] HashSha256(byte[] pbData, int iOffset, int cbCount)
{
if(pbData == null) throw new ArgumentNullException("pbData");
#if DEBUG
byte[] pbCopy = new byte[pbData.Length];
Array.Copy(pbData, pbCopy, pbData.Length);
#endif
byte[] pbHash;
using(SHA256Managed h = new SHA256Managed())
{
pbHash = h.ComputeHash(pbData, iOffset, cbCount);
}
#if DEBUG
// Ensure the data has not been modified
Debug.Assert(MemUtil.ArraysEqual(pbData, pbCopy));
Debug.Assert((pbHash != null) && (pbHash.Length == 32));
byte[] pbZero = new byte[32];
Debug.Assert(!MemUtil.ArraysEqual(pbHash, pbZero));
#endif
return pbHash;
}
/// <summary>
/// Create a cryptographic key of length <paramref name="cbOut" />
/// (in bytes) from <paramref name="pbIn" />.
/// </summary>
public static byte[] ResizeKey(byte[] pbIn, int iInOffset,
int cbIn, int cbOut)
{
if(pbIn == null) throw new ArgumentNullException("pbIn");
if(cbOut < 0) throw new ArgumentOutOfRangeException("cbOut");
if(cbOut == 0) return MemUtil.EmptyByteArray;
byte[] pbHash;
if(cbOut <= 32) pbHash = HashSha256(pbIn, iInOffset, cbIn);
else
{
using(SHA512Managed h = new SHA512Managed())
{
pbHash = h.ComputeHash(pbIn, iInOffset, cbIn);
}
}
if(cbOut == pbHash.Length) return pbHash;
byte[] pbRet = new byte[cbOut];
if(cbOut < pbHash.Length)
Array.Copy(pbHash, pbRet, cbOut);
else
{
int iPos = 0;
ulong r = 0;
while(iPos < cbOut)
{
Debug.Assert(pbHash.Length == 64);
using(HMACSHA256 h = new HMACSHA256(pbHash))
{
byte[] pbR = MemUtil.UInt64ToBytes(r);
byte[] pbPart = h.ComputeHash(pbR);
int cbCopy = Math.Min(cbOut - iPos, pbPart.Length);
Debug.Assert(cbCopy > 0);
Array.Copy(pbPart, 0, pbRet, iPos, cbCopy);
iPos += cbCopy;
++r;
MemUtil.ZeroByteArray(pbPart);
}
}
Debug.Assert(iPos == cbOut);
}
#if DEBUG
byte[] pbZero = new byte[pbHash.Length];
Debug.Assert(!MemUtil.ArraysEqual(pbHash, pbZero));
#endif
MemUtil.ZeroByteArray(pbHash);
return pbRet;
}
}
}

View File

@@ -1,232 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// This implementation is based on the official reference C
// implementation by Samuel Neves (CC0 1.0 Universal).
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
#if !KeePassUAP
using System.Security.Cryptography;
#endif
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.Hash
{
public sealed class Blake2b : HashAlgorithm
{
private const int NbRounds = 12;
private const int NbBlockBytes = 128;
private const int NbMaxOutBytes = 64;
private static readonly ulong[] g_vIV = new ulong[8] {
0x6A09E667F3BCC908UL, 0xBB67AE8584CAA73BUL,
0x3C6EF372FE94F82BUL, 0xA54FF53A5F1D36F1UL,
0x510E527FADE682D1UL, 0x9B05688C2B3E6C1FUL,
0x1F83D9ABFB41BD6BUL, 0x5BE0CD19137E2179UL
};
private static readonly int[] g_vSigma = new int[NbRounds * 16] {
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3,
11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4,
7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8,
9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13,
2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9,
12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11,
13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10,
6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5,
10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3
};
private readonly int m_cbHashLength;
private ulong[] m_h = new ulong[8];
private ulong[] m_t = new ulong[2];
private ulong[] m_f = new ulong[2];
private byte[] m_buf = new byte[NbBlockBytes];
private int m_cbBuf = 0;
private ulong[] m_m = new ulong[16];
private ulong[] m_v = new ulong[16];
public Blake2b()
{
m_cbHashLength = NbMaxOutBytes;
this.HashSizeValue = NbMaxOutBytes * 8; // Bits
Initialize();
}
public Blake2b(int cbHashLength)
{
if((cbHashLength < 0) || (cbHashLength > NbMaxOutBytes))
throw new ArgumentOutOfRangeException("cbHashLength");
m_cbHashLength = cbHashLength;
this.HashSizeValue = cbHashLength * 8; // Bits
Initialize();
}
public override void Initialize()
{
Debug.Assert(m_h.Length == g_vIV.Length);
Array.Copy(g_vIV, m_h, m_h.Length);
// Fan-out = 1, depth = 1
m_h[0] ^= 0x0000000001010000UL ^ (ulong)m_cbHashLength;
Array.Clear(m_t, 0, m_t.Length);
Array.Clear(m_f, 0, m_f.Length);
Array.Clear(m_buf, 0, m_buf.Length);
m_cbBuf = 0;
Array.Clear(m_m, 0, m_m.Length);
Array.Clear(m_v, 0, m_v.Length);
}
private static void G(ulong[] v, ulong[] m, int r16, int i,
int a, int b, int c, int d)
{
int p = r16 + i;
v[a] += v[b] + m[g_vSigma[p]];
v[d] = MemUtil.RotateRight64(v[d] ^ v[a], 32);
v[c] += v[d];
v[b] = MemUtil.RotateRight64(v[b] ^ v[c], 24);
v[a] += v[b] + m[g_vSigma[p + 1]];
v[d] = MemUtil.RotateRight64(v[d] ^ v[a], 16);
v[c] += v[d];
v[b] = MemUtil.RotateRight64(v[b] ^ v[c], 63);
}
private void Compress(byte[] pb, int iOffset)
{
ulong[] v = m_v;
ulong[] m = m_m;
ulong[] h = m_h;
for(int i = 0; i < 16; ++i)
m[i] = MemUtil.BytesToUInt64(pb, iOffset + (i << 3));
Array.Copy(h, v, 8);
v[8] = g_vIV[0];
v[9] = g_vIV[1];
v[10] = g_vIV[2];
v[11] = g_vIV[3];
v[12] = g_vIV[4] ^ m_t[0];
v[13] = g_vIV[5] ^ m_t[1];
v[14] = g_vIV[6] ^ m_f[0];
v[15] = g_vIV[7] ^ m_f[1];
for(int r = 0; r < NbRounds; ++r)
{
int r16 = r << 4;
G(v, m, r16, 0, 0, 4, 8, 12);
G(v, m, r16, 2, 1, 5, 9, 13);
G(v, m, r16, 4, 2, 6, 10, 14);
G(v, m, r16, 6, 3, 7, 11, 15);
G(v, m, r16, 8, 0, 5, 10, 15);
G(v, m, r16, 10, 1, 6, 11, 12);
G(v, m, r16, 12, 2, 7, 8, 13);
G(v, m, r16, 14, 3, 4, 9, 14);
}
for(int i = 0; i < 8; ++i)
h[i] ^= v[i] ^ v[i + 8];
}
private void IncrementCounter(ulong cb)
{
m_t[0] += cb;
if(m_t[0] < cb) ++m_t[1];
}
protected override void HashCore(byte[] array, int ibStart, int cbSize)
{
Debug.Assert(m_f[0] == 0);
if((m_cbBuf + cbSize) > NbBlockBytes) // Not '>=' (buffer must not be empty)
{
int cbFill = NbBlockBytes - m_cbBuf;
if(cbFill > 0) Array.Copy(array, ibStart, m_buf, m_cbBuf, cbFill);
IncrementCounter((ulong)NbBlockBytes);
Compress(m_buf, 0);
m_cbBuf = 0;
cbSize -= cbFill;
ibStart += cbFill;
while(cbSize > NbBlockBytes) // Not '>=' (buffer must not be empty)
{
IncrementCounter((ulong)NbBlockBytes);
Compress(array, ibStart);
cbSize -= NbBlockBytes;
ibStart += NbBlockBytes;
}
}
if(cbSize > 0)
{
Debug.Assert((m_cbBuf + cbSize) <= NbBlockBytes);
Array.Copy(array, ibStart, m_buf, m_cbBuf, cbSize);
m_cbBuf += cbSize;
}
}
protected override byte[] HashFinal()
{
if(m_f[0] != 0) { Debug.Assert(false); throw new InvalidOperationException(); }
Debug.Assert(((m_t[1] == 0) && (m_t[0] == 0)) ||
(m_cbBuf > 0)); // Buffer must not be empty for last block processing
m_f[0] = ulong.MaxValue; // Indicate last block
int cbFill = NbBlockBytes - m_cbBuf;
if(cbFill > 0) Array.Clear(m_buf, m_cbBuf, cbFill);
IncrementCounter((ulong)m_cbBuf);
Compress(m_buf, 0);
byte[] pbHash = new byte[NbMaxOutBytes];
for(int i = 0; i < m_h.Length; ++i)
MemUtil.UInt64ToBytesEx(m_h[i], pbHash, i << 3);
if(m_cbHashLength == NbMaxOutBytes) return pbHash;
Debug.Assert(m_cbHashLength < NbMaxOutBytes);
byte[] pbShort = new byte[m_cbHashLength];
if(m_cbHashLength > 0)
Array.Copy(pbHash, pbShort, m_cbHashLength);
MemUtil.ZeroByteArray(pbHash);
return pbShort;
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -30,7 +30,7 @@ namespace KeePassLib.Cryptography
{
public sealed class HashingStreamEx : Stream
{
private readonly Stream m_sBaseStream;
private Stream m_sBaseStream;
private bool m_bWriting;
private HashAlgorithm m_hash;
@@ -96,10 +96,20 @@ namespace KeePassLib.Cryptography
m_hash = null;
}
}
public override void Flush()
{
m_sBaseStream.Flush();
}
#if KeePassRT
protected override void Dispose(bool disposing)
{
if(disposing)
if(!disposing) return;
#else
public override void Close()
{
#endif
if(m_hash != null)
{
try
@@ -116,14 +126,6 @@ namespace KeePassLib.Cryptography
m_sBaseStream.Close();
}
base.Dispose(disposing);
}
public override void Flush()
{
m_sBaseStream.Flush();
}
public override long Seek(long lOffset, SeekOrigin soOrigin)
{
throw new NotSupportedException();

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,277 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
#if KeePassUAP
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
#else
using System.Security.Cryptography;
#endif
using KeePassLib.Cryptography;
using KeePassLib.Native;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.KeyDerivation
{
public sealed class AesKdf : KdfEngine
{
private static readonly PwUuid g_uuid = new PwUuid(new byte[] {
0xC9, 0xD9, 0xF3, 0x9A, 0x62, 0x8A, 0x44, 0x60,
0xBF, 0x74, 0x0D, 0x08, 0xC1, 0x8A, 0x4F, 0xEA });
public const string ParamRounds = "R"; // UInt64
public const string ParamSeed = "S"; // Byte[32]
public override PwUuid Uuid
{
get { return g_uuid; }
}
public override string Name
{
get { return "AES-KDF"; }
}
public AesKdf()
{
}
public override KdfParameters GetDefaultParameters()
{
KdfParameters p = base.GetDefaultParameters();
p.SetUInt64(ParamRounds, PwDefs.DefaultKeyEncryptionRounds);
return p;
}
public override void Randomize(KdfParameters p)
{
if(p == null) { Debug.Assert(false); return; }
Debug.Assert(g_uuid.Equals(p.KdfUuid));
byte[] pbSeed = CryptoRandom.Instance.GetRandomBytes(32);
p.SetByteArray(ParamSeed, pbSeed);
}
public override byte[] Transform(byte[] pbMsg, KdfParameters p)
{
if(pbMsg == null) throw new ArgumentNullException("pbMsg");
if(p == null) throw new ArgumentNullException("p");
Type tRounds = p.GetTypeOf(ParamRounds);
if(tRounds == null) throw new ArgumentNullException("p.Rounds");
if(tRounds != typeof(ulong)) throw new ArgumentOutOfRangeException("p.Rounds");
ulong uRounds = p.GetUInt64(ParamRounds, 0);
byte[] pbSeed = p.GetByteArray(ParamSeed);
if(pbSeed == null) throw new ArgumentNullException("p.Seed");
if(pbMsg.Length != 32)
{
Debug.Assert(false);
pbMsg = CryptoUtil.HashSha256(pbMsg);
}
if(pbSeed.Length != 32)
{
Debug.Assert(false);
pbSeed = CryptoUtil.HashSha256(pbSeed);
}
return TransformKey(pbMsg, pbSeed, uRounds);
}
private static byte[] TransformKey(byte[] pbOriginalKey32, byte[] pbKeySeed32,
ulong uNumRounds)
{
Debug.Assert((pbOriginalKey32 != null) && (pbOriginalKey32.Length == 32));
if(pbOriginalKey32 == null) throw new ArgumentNullException("pbOriginalKey32");
if(pbOriginalKey32.Length != 32) throw new ArgumentException();
Debug.Assert((pbKeySeed32 != null) && (pbKeySeed32.Length == 32));
if(pbKeySeed32 == null) throw new ArgumentNullException("pbKeySeed32");
if(pbKeySeed32.Length != 32) throw new ArgumentException();
byte[] pbNewKey = new byte[32];
Array.Copy(pbOriginalKey32, pbNewKey, pbNewKey.Length);
try
{
// Try to use the native library first
if (NativeLib.TransformKey256(pbNewKey, pbKeySeed32, uNumRounds))
{
//no need to hash, this is already done in the native library.
byte[] pbKey = new byte[32];
Array.Copy(pbNewKey, pbKey, pbNewKey.Length);
return pbKey;
}
if(TransformKeyManaged(pbNewKey, pbKeySeed32, uNumRounds))
return CryptoUtil.HashSha256(pbNewKey);
}
finally { MemUtil.ZeroByteArray(pbNewKey); }
return null;
}
public static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
ulong uNumRounds)
{
#if KeePassUAP
KeyParameter kp = new KeyParameter(pbKeySeed32);
AesEngine aes = new AesEngine();
aes.Init(true, kp);
for(ulong i = 0; i < uNumRounds; ++i)
{
aes.ProcessBlock(pbNewKey32, 0, pbNewKey32, 0);
aes.ProcessBlock(pbNewKey32, 16, pbNewKey32, 16);
}
#else
byte[] pbIV = new byte[16];
Array.Clear(pbIV, 0, pbIV.Length);
RijndaelManaged r = new RijndaelManaged();
if(r.BlockSize != 128) // AES block size
{
Debug.Assert(false);
r.BlockSize = 128;
}
r.IV = pbIV;
r.Mode = CipherMode.ECB;
r.KeySize = 256;
r.Key = pbKeySeed32;
ICryptoTransform iCrypt = r.CreateEncryptor();
// !iCrypt.CanReuseTransform -- doesn't work with Mono
if((iCrypt == null) || (iCrypt.InputBlockSize != 16) ||
(iCrypt.OutputBlockSize != 16))
{
Debug.Assert(false, "Invalid ICryptoTransform.");
Debug.Assert((iCrypt.InputBlockSize == 16), "Invalid input block size!");
Debug.Assert((iCrypt.OutputBlockSize == 16), "Invalid output block size!");
return false;
}
for(ulong i = 0; i < uNumRounds; ++i)
{
iCrypt.TransformBlock(pbNewKey32, 0, 16, pbNewKey32, 0);
iCrypt.TransformBlock(pbNewKey32, 16, 16, pbNewKey32, 16);
}
#endif
return true;
}
public override KdfParameters GetBestParameters(uint uMilliseconds)
{
const ulong uStep = 3001;
ulong uRounds;
KdfParameters p = GetDefaultParameters();
// Try native method
if(NativeLib.TransformKeyBenchmark256(uMilliseconds, out uRounds))
{
p.SetUInt64(ParamRounds, uRounds);
return p;
}
byte[] pbKey = new byte[32];
byte[] pbNewKey = new byte[32];
for(int i = 0; i < pbKey.Length; ++i)
{
pbKey[i] = (byte)i;
pbNewKey[i] = (byte)i;
}
#if KeePassUAP
KeyParameter kp = new KeyParameter(pbKey);
AesEngine aes = new AesEngine();
aes.Init(true, kp);
#else
byte[] pbIV = new byte[16];
Array.Clear(pbIV, 0, pbIV.Length);
RijndaelManaged r = new RijndaelManaged();
if(r.BlockSize != 128) // AES block size
{
Debug.Assert(false);
r.BlockSize = 128;
}
r.IV = pbIV;
r.Mode = CipherMode.ECB;
r.KeySize = 256;
r.Key = pbKey;
ICryptoTransform iCrypt = r.CreateEncryptor();
// !iCrypt.CanReuseTransform -- doesn't work with Mono
if((iCrypt == null) || (iCrypt.InputBlockSize != 16) ||
(iCrypt.OutputBlockSize != 16))
{
Debug.Assert(false, "Invalid ICryptoTransform.");
Debug.Assert(iCrypt.InputBlockSize == 16, "Invalid input block size!");
Debug.Assert(iCrypt.OutputBlockSize == 16, "Invalid output block size!");
p.SetUInt64(ParamRounds, PwDefs.DefaultKeyEncryptionRounds);
return p;
}
#endif
uRounds = 0;
int tStart = Environment.TickCount;
while(true)
{
for(ulong j = 0; j < uStep; ++j)
{
#if KeePassUAP
aes.ProcessBlock(pbNewKey, 0, pbNewKey, 0);
aes.ProcessBlock(pbNewKey, 16, pbNewKey, 16);
#else
iCrypt.TransformBlock(pbNewKey, 0, 16, pbNewKey, 0);
iCrypt.TransformBlock(pbNewKey, 16, 16, pbNewKey, 16);
#endif
}
uRounds += uStep;
if(uRounds < uStep) // Overflow check
{
uRounds = ulong.MaxValue;
break;
}
uint tElapsed = (uint)(Environment.TickCount - tStart);
if(tElapsed > uMilliseconds) break;
}
p.SetUInt64(ParamRounds, uRounds);
return p;
}
}
}

View File

@@ -1,633 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
// This implementation is based on the official reference C
// implementation by Daniel Dinu and Dmitry Khovratovich (CC0 1.0).
// Relative iterations (* = B2ROUND_ARRAYS \\ G_INLINED):
// * | false true
// ------+-----------
// false | 8885 9618
// true | 9009 9636
#define ARGON2_B2ROUND_ARRAYS
#define ARGON2_G_INLINED
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using KeePassLib.Cryptography.Hash;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.KeyDerivation
{
public sealed partial class Argon2Kdf : KdfEngine
{
private const ulong NbBlockSize = 1024;
private const ulong NbBlockSizeInQW = NbBlockSize / 8UL;
private const ulong NbSyncPoints = 4;
private const int NbPreHashDigestLength = 64;
private const int NbPreHashSeedLength = NbPreHashDigestLength + 8;
#if ARGON2_B2ROUND_ARRAYS
private static int[][] g_vFBCols = null;
private static int[][] g_vFBRows = null;
#endif
private sealed class Argon2Ctx
{
public uint Version = 0;
public ulong Lanes = 0;
public ulong TCost = 0;
public ulong MCost = 0;
public ulong MemoryBlocks = 0;
public ulong SegmentLength = 0;
public ulong LaneLength = 0;
public ulong[] Mem = null;
}
private sealed class Argon2ThreadInfo
{
public Argon2Ctx Context = null;
public ManualResetEvent Finished = new ManualResetEvent(false);
public ulong Pass = 0;
public ulong Lane = 0;
public ulong Slice = 0;
public ulong Index = 0;
public void Release()
{
if(this.Finished != null)
{
this.Finished.Close();
this.Finished = null;
}
else { Debug.Assert(false); }
}
}
private static byte[] Argon2d(byte[] pbMsg, byte[] pbSalt, uint uParallel,
ulong uMem, ulong uIt, int cbOut, uint uVersion, byte[] pbSecretKey,
byte[] pbAssocData)
{
pbSecretKey = (pbSecretKey ?? MemUtil.EmptyByteArray);
pbAssocData = (pbAssocData ?? MemUtil.EmptyByteArray);
#if ARGON2_B2ROUND_ARRAYS
InitB2RoundIndexArrays();
#endif
Argon2Ctx ctx = new Argon2Ctx();
ctx.Version = uVersion;
ctx.Lanes = uParallel;
ctx.TCost = uIt;
ctx.MCost = uMem / NbBlockSize;
ctx.MemoryBlocks = Math.Max(ctx.MCost, 2UL * NbSyncPoints * ctx.Lanes);
ctx.SegmentLength = ctx.MemoryBlocks / (ctx.Lanes * NbSyncPoints);
ctx.MemoryBlocks = ctx.SegmentLength * ctx.Lanes * NbSyncPoints;
ctx.LaneLength = ctx.SegmentLength * NbSyncPoints;
Debug.Assert(NbBlockSize == (NbBlockSizeInQW *
#if KeePassUAP
(ulong)Marshal.SizeOf<ulong>()
#else
(ulong)Marshal.SizeOf(typeof(ulong))
#endif
));
ctx.Mem = new ulong[ctx.MemoryBlocks * NbBlockSizeInQW];
Blake2b h = new Blake2b();
// Initial hash
Debug.Assert(h.HashSize == (NbPreHashDigestLength * 8));
byte[] pbBuf = new byte[4];
MemUtil.UInt32ToBytesEx(uParallel, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
MemUtil.UInt32ToBytesEx((uint)cbOut, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
MemUtil.UInt32ToBytesEx((uint)ctx.MCost, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
MemUtil.UInt32ToBytesEx((uint)uIt, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
MemUtil.UInt32ToBytesEx(uVersion, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
MemUtil.UInt32ToBytesEx(0, pbBuf, 0); // Argon2d type = 0
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
MemUtil.UInt32ToBytesEx((uint)pbMsg.Length, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0);
MemUtil.UInt32ToBytesEx((uint)pbSalt.Length, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
h.TransformBlock(pbSalt, 0, pbSalt.Length, pbSalt, 0);
MemUtil.UInt32ToBytesEx((uint)pbSecretKey.Length, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
h.TransformBlock(pbSecretKey, 0, pbSecretKey.Length, pbSecretKey, 0);
MemUtil.UInt32ToBytesEx((uint)pbAssocData.Length, pbBuf, 0);
h.TransformBlock(pbBuf, 0, pbBuf.Length, pbBuf, 0);
h.TransformBlock(pbAssocData, 0, pbAssocData.Length, pbAssocData, 0);
h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
byte[] pbH0 = h.Hash;
Debug.Assert(pbH0.Length == 64);
byte[] pbBlockHash = new byte[NbPreHashSeedLength];
Array.Copy(pbH0, pbBlockHash, pbH0.Length);
MemUtil.ZeroByteArray(pbH0);
FillFirstBlocks(ctx, pbBlockHash, h);
MemUtil.ZeroByteArray(pbBlockHash);
FillMemoryBlocks(ctx);
byte[] pbOut = FinalHash(ctx, cbOut, h);
h.Clear();
MemUtil.ZeroArray<ulong>(ctx.Mem);
return pbOut;
}
private static void LoadBlock(ulong[] pqDst, ulong uDstOffset, byte[] pbIn)
{
// for(ulong i = 0; i < NbBlockSizeInQW; ++i)
// pqDst[uDstOffset + i] = MemUtil.BytesToUInt64(pbIn, (int)(i << 3));
Debug.Assert((uDstOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue);
int iDstOffset = (int)uDstOffset;
for(int i = 0; i < (int)NbBlockSizeInQW; ++i)
pqDst[iDstOffset + i] = MemUtil.BytesToUInt64(pbIn, i << 3);
}
private static void StoreBlock(byte[] pbDst, ulong[] pqSrc)
{
for(int i = 0; i < (int)NbBlockSizeInQW; ++i)
MemUtil.UInt64ToBytesEx(pqSrc[i], pbDst, i << 3);
}
private static void CopyBlock(ulong[] vDst, ulong uDstOffset, ulong[] vSrc,
ulong uSrcOffset)
{
// for(ulong i = 0; i < NbBlockSizeInQW; ++i)
// vDst[uDstOffset + i] = vSrc[uSrcOffset + i];
// Debug.Assert((uDstOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue);
// Debug.Assert((uSrcOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue);
// int iDstOffset = (int)uDstOffset;
// int iSrcOffset = (int)uSrcOffset;
// for(int i = 0; i < (int)NbBlockSizeInQW; ++i)
// vDst[iDstOffset + i] = vSrc[iSrcOffset + i];
#if KeePassUAP
Array.Copy(vSrc, (int)uSrcOffset, vDst, (int)uDstOffset,
(int)NbBlockSizeInQW);
#else
Array.Copy(vSrc, (long)uSrcOffset, vDst, (long)uDstOffset,
(long)NbBlockSizeInQW);
#endif
}
private static void XorBlock(ulong[] vDst, ulong uDstOffset, ulong[] vSrc,
ulong uSrcOffset)
{
// for(ulong i = 0; i < NbBlockSizeInQW; ++i)
// vDst[uDstOffset + i] ^= vSrc[uSrcOffset + i];
Debug.Assert((uDstOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue);
Debug.Assert((uSrcOffset + NbBlockSizeInQW - 1UL) <= (ulong)int.MaxValue);
int iDstOffset = (int)uDstOffset;
int iSrcOffset = (int)uSrcOffset;
for(int i = 0; i < (int)NbBlockSizeInQW; ++i)
vDst[iDstOffset + i] ^= vSrc[iSrcOffset + i];
}
private static void Blake2bLong(byte[] pbOut, int cbOut,
byte[] pbIn, int cbIn, Blake2b h)
{
Debug.Assert((h != null) && (h.HashSize == (64 * 8)));
byte[] pbOutLen = new byte[4];
MemUtil.UInt32ToBytesEx((uint)cbOut, pbOutLen, 0);
if(cbOut <= 64)
{
Blake2b hOut = ((cbOut == 64) ? h : new Blake2b(cbOut));
if(cbOut == 64) hOut.Initialize();
hOut.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0);
hOut.TransformBlock(pbIn, 0, cbIn, pbIn, 0);
hOut.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
Array.Copy(hOut.Hash, pbOut, cbOut);
if(cbOut < 64) hOut.Clear();
return;
}
h.Initialize();
h.TransformBlock(pbOutLen, 0, pbOutLen.Length, pbOutLen, 0);
h.TransformBlock(pbIn, 0, cbIn, pbIn, 0);
h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
byte[] pbOutBuffer = new byte[64];
Array.Copy(h.Hash, pbOutBuffer, pbOutBuffer.Length);
int ibOut = 64 / 2;
Array.Copy(pbOutBuffer, pbOut, ibOut);
int cbToProduce = cbOut - ibOut;
h.Initialize();
while(cbToProduce > 64)
{
byte[] pbHash = h.ComputeHash(pbOutBuffer);
Array.Copy(pbHash, pbOutBuffer, 64);
Array.Copy(pbHash, 0, pbOut, ibOut, 64 / 2);
ibOut += 64 / 2;
cbToProduce -= 64 / 2;
MemUtil.ZeroByteArray(pbHash);
}
using(Blake2b hOut = new Blake2b(cbToProduce))
{
byte[] pbHash = hOut.ComputeHash(pbOutBuffer);
Array.Copy(pbHash, 0, pbOut, ibOut, cbToProduce);
MemUtil.ZeroByteArray(pbHash);
}
MemUtil.ZeroByteArray(pbOutBuffer);
}
#if !ARGON2_G_INLINED
private static ulong BlaMka(ulong x, ulong y)
{
ulong xy = (x & 0xFFFFFFFFUL) * (y & 0xFFFFFFFFUL);
return (x + y + (xy << 1));
}
private static void G(ulong[] v, int a, int b, int c, int d)
{
ulong va = v[a], vb = v[b], vc = v[c], vd = v[d];
va = BlaMka(va, vb);
vd = MemUtil.RotateRight64(vd ^ va, 32);
vc = BlaMka(vc, vd);
vb = MemUtil.RotateRight64(vb ^ vc, 24);
va = BlaMka(va, vb);
vd = MemUtil.RotateRight64(vd ^ va, 16);
vc = BlaMka(vc, vd);
vb = MemUtil.RotateRight64(vb ^ vc, 63);
v[a] = va;
v[b] = vb;
v[c] = vc;
v[d] = vd;
}
#else
private static void G(ulong[] v, int a, int b, int c, int d)
{
ulong va = v[a], vb = v[b], vc = v[c], vd = v[d];
ulong xy = (va & 0xFFFFFFFFUL) * (vb & 0xFFFFFFFFUL);
va += vb + (xy << 1);
vd = MemUtil.RotateRight64(vd ^ va, 32);
xy = (vc & 0xFFFFFFFFUL) * (vd & 0xFFFFFFFFUL);
vc += vd + (xy << 1);
vb = MemUtil.RotateRight64(vb ^ vc, 24);
xy = (va & 0xFFFFFFFFUL) * (vb & 0xFFFFFFFFUL);
va += vb + (xy << 1);
vd = MemUtil.RotateRight64(vd ^ va, 16);
xy = (vc & 0xFFFFFFFFUL) * (vd & 0xFFFFFFFFUL);
vc += vd + (xy << 1);
vb = MemUtil.RotateRight64(vb ^ vc, 63);
v[a] = va;
v[b] = vb;
v[c] = vc;
v[d] = vd;
}
#endif
#if ARGON2_B2ROUND_ARRAYS
private static void Blake2RoundNoMsg(ulong[] pbR, int[] v)
{
G(pbR, v[0], v[4], v[8], v[12]);
G(pbR, v[1], v[5], v[9], v[13]);
G(pbR, v[2], v[6], v[10], v[14]);
G(pbR, v[3], v[7], v[11], v[15]);
G(pbR, v[0], v[5], v[10], v[15]);
G(pbR, v[1], v[6], v[11], v[12]);
G(pbR, v[2], v[7], v[8], v[13]);
G(pbR, v[3], v[4], v[9], v[14]);
}
#else
private static void Blake2RoundNoMsgCols16i(ulong[] pbR, int i)
{
G(pbR, i, i + 4, i + 8, i + 12);
G(pbR, i + 1, i + 5, i + 9, i + 13);
G(pbR, i + 2, i + 6, i + 10, i + 14);
G(pbR, i + 3, i + 7, i + 11, i + 15);
G(pbR, i, i + 5, i + 10, i + 15);
G(pbR, i + 1, i + 6, i + 11, i + 12);
G(pbR, i + 2, i + 7, i + 8, i + 13);
G(pbR, i + 3, i + 4, i + 9, i + 14);
}
private static void Blake2RoundNoMsgRows2i(ulong[] pbR, int i)
{
G(pbR, i, i + 32, i + 64, i + 96);
G(pbR, i + 1, i + 33, i + 65, i + 97);
G(pbR, i + 16, i + 48, i + 80, i + 112);
G(pbR, i + 17, i + 49, i + 81, i + 113);
G(pbR, i, i + 33, i + 80, i + 113);
G(pbR, i + 1, i + 48, i + 81, i + 96);
G(pbR, i + 16, i + 49, i + 64, i + 97);
G(pbR, i + 17, i + 32, i + 65, i + 112);
}
#endif
private static void FillFirstBlocks(Argon2Ctx ctx, byte[] pbBlockHash,
Blake2b h)
{
byte[] pbBlock = new byte[NbBlockSize];
for(ulong l = 0; l < ctx.Lanes; ++l)
{
MemUtil.UInt32ToBytesEx(0, pbBlockHash, NbPreHashDigestLength);
MemUtil.UInt32ToBytesEx((uint)l, pbBlockHash, NbPreHashDigestLength + 4);
Blake2bLong(pbBlock, (int)NbBlockSize, pbBlockHash,
NbPreHashSeedLength, h);
LoadBlock(ctx.Mem, l * ctx.LaneLength * NbBlockSizeInQW, pbBlock);
MemUtil.UInt32ToBytesEx(1, pbBlockHash, NbPreHashDigestLength);
Blake2bLong(pbBlock, (int)NbBlockSize, pbBlockHash,
NbPreHashSeedLength, h);
LoadBlock(ctx.Mem, (l * ctx.LaneLength + 1UL) * NbBlockSizeInQW, pbBlock);
}
MemUtil.ZeroByteArray(pbBlock);
}
private static ulong IndexAlpha(Argon2Ctx ctx, Argon2ThreadInfo ti,
uint uPseudoRand, bool bSameLane)
{
ulong uRefAreaSize;
if(ti.Pass == 0)
{
if(ti.Slice == 0)
{
Debug.Assert(ti.Index > 0);
uRefAreaSize = ti.Index - 1UL;
}
else
{
if(bSameLane)
uRefAreaSize = ti.Slice * ctx.SegmentLength +
ti.Index - 1UL;
else
uRefAreaSize = ti.Slice * ctx.SegmentLength -
((ti.Index == 0UL) ? 1UL : 0UL);
}
}
else
{
if(bSameLane)
uRefAreaSize = ctx.LaneLength - ctx.SegmentLength +
ti.Index - 1UL;
else
uRefAreaSize = ctx.LaneLength - ctx.SegmentLength -
((ti.Index == 0) ? 1UL : 0UL);
}
Debug.Assert(uRefAreaSize <= (ulong)uint.MaxValue);
ulong uRelPos = uPseudoRand;
uRelPos = (uRelPos * uRelPos) >> 32;
uRelPos = uRefAreaSize - 1UL - ((uRefAreaSize * uRelPos) >> 32);
ulong uStart = 0;
if(ti.Pass != 0)
uStart = (((ti.Slice + 1UL) == NbSyncPoints) ? 0UL :
((ti.Slice + 1UL) * ctx.SegmentLength));
Debug.Assert(uStart <= (ulong)uint.MaxValue);
Debug.Assert(ctx.LaneLength <= (ulong)uint.MaxValue);
return ((uStart + uRelPos) % ctx.LaneLength);
}
private static void FillMemoryBlocks(Argon2Ctx ctx)
{
int np = (int)ctx.Lanes;
Argon2ThreadInfo[] v = new Argon2ThreadInfo[np];
for(ulong r = 0; r < ctx.TCost; ++r)
{
for(ulong s = 0; s < NbSyncPoints; ++s)
{
for(int l = 0; l < np; ++l)
{
Argon2ThreadInfo ti = new Argon2ThreadInfo();
ti.Context = ctx;
ti.Pass = r;
ti.Lane = (ulong)l;
ti.Slice = s;
if(!ThreadPool.QueueUserWorkItem(FillSegmentThr, ti))
{
Debug.Assert(false);
throw new OutOfMemoryException();
}
v[l] = ti;
}
for(int l = 0; l < np; ++l)
{
v[l].Finished.WaitOne();
v[l].Release();
}
}
}
}
private static void FillSegmentThr(object o)
{
Argon2ThreadInfo ti = (o as Argon2ThreadInfo);
if(ti == null) { Debug.Assert(false); return; }
try
{
Argon2Ctx ctx = ti.Context;
if(ctx == null) { Debug.Assert(false); return; }
Debug.Assert(ctx.Version >= MinVersion);
bool bCanXor = (ctx.Version >= 0x13U);
ulong uStart = 0;
if((ti.Pass == 0) && (ti.Slice == 0)) uStart = 2;
ulong uCur = (ti.Lane * ctx.LaneLength) + (ti.Slice *
ctx.SegmentLength) + uStart;
ulong uPrev = (((uCur % ctx.LaneLength) == 0) ?
(uCur + ctx.LaneLength - 1UL) : (uCur - 1UL));
ulong[] pbR = new ulong[NbBlockSizeInQW];
ulong[] pbTmp = new ulong[NbBlockSizeInQW];
for(ulong i = uStart; i < ctx.SegmentLength; ++i)
{
if((uCur % ctx.LaneLength) == 1)
uPrev = uCur - 1UL;
ulong uPseudoRand = ctx.Mem[uPrev * NbBlockSizeInQW];
ulong uRefLane = (uPseudoRand >> 32) % ctx.Lanes;
if((ti.Pass == 0) && (ti.Slice == 0))
uRefLane = ti.Lane;
ti.Index = i;
ulong uRefIndex = IndexAlpha(ctx, ti, (uint)uPseudoRand,
(uRefLane == ti.Lane));
ulong uRefBlockIndex = (ctx.LaneLength * uRefLane +
uRefIndex) * NbBlockSizeInQW;
ulong uCurBlockIndex = uCur * NbBlockSizeInQW;
FillBlock(ctx.Mem, uPrev * NbBlockSizeInQW, uRefBlockIndex,
uCurBlockIndex, ((ti.Pass != 0) && bCanXor), pbR, pbTmp);
++uCur;
++uPrev;
}
MemUtil.ZeroArray<ulong>(pbR);
MemUtil.ZeroArray<ulong>(pbTmp);
}
catch(Exception) { Debug.Assert(false); }
try { ti.Finished.Set(); }
catch(Exception) { Debug.Assert(false); }
}
#if ARGON2_B2ROUND_ARRAYS
private static void InitB2RoundIndexArrays()
{
int[][] vCols = g_vFBCols;
if(vCols == null)
{
vCols = new int[8][];
Debug.Assert(vCols.Length == 8);
int e = 0;
for(int i = 0; i < 8; ++i)
{
vCols[i] = new int[16];
for(int j = 0; j < 16; ++j)
{
vCols[i][j] = e;
++e;
}
}
g_vFBCols = vCols;
}
int[][] vRows = g_vFBRows;
if(vRows == null)
{
vRows = new int[8][];
for(int i = 0; i < 8; ++i)
{
vRows[i] = new int[16];
for(int j = 0; j < 16; ++j)
{
int jh = j / 2;
vRows[i][j] = (2 * i) + (16 * jh) + (j & 1);
}
}
g_vFBRows = vRows;
}
}
#endif
private static void FillBlock(ulong[] pMem, ulong uPrev, ulong uRef,
ulong uNext, bool bXor, ulong[] pbR, ulong[] pbTmp)
{
CopyBlock(pbR, 0, pMem, uRef);
XorBlock(pbR, 0, pMem, uPrev);
CopyBlock(pbTmp, 0, pbR, 0);
if(bXor) XorBlock(pbTmp, 0, pMem, uNext);
#if ARGON2_B2ROUND_ARRAYS
int[][] vCols = g_vFBCols;
int[][] vRows = g_vFBRows;
for(int i = 0; i < 8; ++i)
Blake2RoundNoMsg(pbR, vCols[i]);
for(int i = 0; i < 8; ++i)
Blake2RoundNoMsg(pbR, vRows[i]);
#else
for(int i = 0; i < (8 * 16); i += 16)
Blake2RoundNoMsgCols16i(pbR, i);
for(int i = 0; i < (8 * 2); i += 2)
Blake2RoundNoMsgRows2i(pbR, i);
#endif
CopyBlock(pMem, uNext, pbTmp, 0);
XorBlock(pMem, uNext, pbR, 0);
}
private static byte[] FinalHash(Argon2Ctx ctx, int cbOut, Blake2b h)
{
ulong[] pqBlockHash = new ulong[NbBlockSizeInQW];
CopyBlock(pqBlockHash, 0, ctx.Mem, (ctx.LaneLength - 1UL) *
NbBlockSizeInQW);
for(ulong l = 1; l < ctx.Lanes; ++l)
XorBlock(pqBlockHash, 0, ctx.Mem, (l * ctx.LaneLength +
ctx.LaneLength - 1UL) * NbBlockSizeInQW);
byte[] pbBlockHashBytes = new byte[NbBlockSize];
StoreBlock(pbBlockHashBytes, pqBlockHash);
byte[] pbOut = new byte[cbOut];
Blake2bLong(pbOut, cbOut, pbBlockHashBytes, (int)NbBlockSize, h);
MemUtil.ZeroArray<ulong>(pqBlockHash);
MemUtil.ZeroByteArray(pbBlockHashBytes);
return pbOut;
}
}
}

View File

@@ -1,144 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace KeePassLib.Cryptography.KeyDerivation
{
public sealed partial class Argon2Kdf : KdfEngine
{
private static readonly PwUuid g_uuid = new PwUuid(new byte[] {
0xEF, 0x63, 0x6D, 0xDF, 0x8C, 0x29, 0x44, 0x4B,
0x91, 0xF7, 0xA9, 0xA4, 0x03, 0xE3, 0x0A, 0x0C });
public const string ParamSalt = "S"; // Byte[]
public const string ParamParallelism = "P"; // UInt32
public const string ParamMemory = "M"; // UInt64
public const string ParamIterations = "I"; // UInt64
public const string ParamVersion = "V"; // UInt32
public const string ParamSecretKey = "K"; // Byte[]
public const string ParamAssocData = "A"; // Byte[]
private const uint MinVersion = 0x10;
private const uint MaxVersion = 0x13;
private const int MinSalt = 8;
private const int MaxSalt = int.MaxValue; // .NET limit; 2^32 - 1 in spec
internal const ulong MinIterations = 1;
internal const ulong MaxIterations = uint.MaxValue;
internal const ulong MinMemory = 1024 * 8; // For parallelism = 1
// internal const ulong MaxMemory = (ulong)uint.MaxValue * 1024UL; // Spec
internal const ulong MaxMemory = int.MaxValue; // .NET limit
internal const uint MinParallelism = 1;
internal const uint MaxParallelism = (1 << 24) - 1;
internal const ulong DefaultIterations = 2;
internal const ulong DefaultMemory = 1024 * 1024; // 1 MB
internal const uint DefaultParallelism = 2;
public override PwUuid Uuid
{
get { return g_uuid; }
}
public override string Name
{
get { return "Argon2"; }
}
public Argon2Kdf()
{
}
public override KdfParameters GetDefaultParameters()
{
KdfParameters p = base.GetDefaultParameters();
p.SetUInt32(ParamVersion, MaxVersion);
p.SetUInt64(ParamIterations, DefaultIterations);
p.SetUInt64(ParamMemory, DefaultMemory);
p.SetUInt32(ParamParallelism, DefaultParallelism);
return p;
}
public override void Randomize(KdfParameters p)
{
if(p == null) { Debug.Assert(false); return; }
Debug.Assert(g_uuid.Equals(p.KdfUuid));
byte[] pb = CryptoRandom.Instance.GetRandomBytes(32);
p.SetByteArray(ParamSalt, pb);
}
public override byte[] Transform(byte[] pbMsg, KdfParameters p)
{
if(pbMsg == null) throw new ArgumentNullException("pbMsg");
if(p == null) throw new ArgumentNullException("p");
byte[] pbSalt = p.GetByteArray(ParamSalt);
if(pbSalt == null)
throw new ArgumentNullException("p.Salt");
if((pbSalt.Length < MinSalt) || (pbSalt.Length > MaxSalt))
throw new ArgumentOutOfRangeException("p.Salt");
uint uPar = p.GetUInt32(ParamParallelism, 0);
if((uPar < MinParallelism) || (uPar > MaxParallelism))
throw new ArgumentOutOfRangeException("p.Parallelism");
ulong uMem = p.GetUInt64(ParamMemory, 0);
if((uMem < MinMemory) || (uMem > MaxMemory))
throw new ArgumentOutOfRangeException("p.Memory");
ulong uIt = p.GetUInt64(ParamIterations, 0);
if((uIt < MinIterations) || (uIt > MaxIterations))
throw new ArgumentOutOfRangeException("p.Iterations");
uint v = p.GetUInt32(ParamVersion, 0);
if((v < MinVersion) || (v > MaxVersion))
throw new ArgumentOutOfRangeException("p.Version");
byte[] pbSecretKey = p.GetByteArray(ParamSecretKey);
byte[] pbAssocData = p.GetByteArray(ParamAssocData);
byte[] pbRet = Argon2d(pbMsg, pbSalt, uPar, uMem, uIt,
32, v, pbSecretKey, pbAssocData);
if(uMem > (100UL * 1024UL * 1024UL)) GC.Collect();
return pbRet;
}
public override KdfParameters GetBestParameters(uint uMilliseconds)
{
KdfParameters p = GetDefaultParameters();
Randomize(p);
MaximizeParamUInt64(p, ParamIterations, MinIterations,
MaxIterations, uMilliseconds, true);
return p;
}
}
}

View File

@@ -1,142 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace KeePassLib.Cryptography.KeyDerivation
{
public abstract class KdfEngine
{
public abstract PwUuid Uuid
{
get;
}
public abstract string Name
{
get;
}
public virtual KdfParameters GetDefaultParameters()
{
return new KdfParameters(this.Uuid);
}
/// <summary>
/// Generate random seeds and store them in <paramref name="p" />.
/// </summary>
public virtual void Randomize(KdfParameters p)
{
Debug.Assert(p != null);
Debug.Assert(p.KdfUuid.Equals(this.Uuid));
}
public abstract byte[] Transform(byte[] pbMsg, KdfParameters p);
public virtual KdfParameters GetBestParameters(uint uMilliseconds)
{
throw new NotImplementedException();
}
protected void MaximizeParamUInt64(KdfParameters p, string strName,
ulong uMin, ulong uMax, uint uMilliseconds, bool bInterpSearch)
{
if(p == null) { Debug.Assert(false); return; }
if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return; }
if(uMin > uMax) { Debug.Assert(false); return; }
if(uMax > (ulong.MaxValue >> 1))
{
Debug.Assert(false);
uMax = ulong.MaxValue >> 1;
if(uMin > uMax) { p.SetUInt64(strName, uMin); return; }
}
byte[] pbMsg = new byte[32];
for(int i = 0; i < pbMsg.Length; ++i) pbMsg[i] = (byte)i;
ulong uLow = uMin;
ulong uHigh = uMin + 1UL;
long tLow = 0;
long tHigh = 0;
long tTarget = (long)uMilliseconds;
// Determine range
while(uHigh <= uMax)
{
p.SetUInt64(strName, uHigh);
// GC.Collect();
Stopwatch sw = Stopwatch.StartNew();
Transform(pbMsg, p);
sw.Stop();
tHigh = sw.ElapsedMilliseconds;
if(tHigh > tTarget) break;
uLow = uHigh;
tLow = tHigh;
uHigh <<= 1;
}
if(uHigh > uMax) { uHigh = uMax; tHigh = 0; }
if(uLow > uHigh) uLow = uHigh; // Skips to end
// Find optimal number of iterations
while((uHigh - uLow) >= 2UL)
{
ulong u = (uHigh + uLow) >> 1; // Binary search
// Interpolation search, if possible
if(bInterpSearch && (tLow > 0) && (tHigh > tTarget) &&
(tLow <= tTarget))
{
u = uLow + (((uHigh - uLow) * (ulong)(tTarget - tLow)) /
(ulong)(tHigh - tLow));
if((u >= uLow) && (u <= uHigh))
{
u = Math.Max(u, uLow + 1UL);
u = Math.Min(u, uHigh - 1UL);
}
else
{
Debug.Assert(false);
u = (uHigh + uLow) >> 1;
}
}
p.SetUInt64(strName, u);
// GC.Collect();
Stopwatch sw = Stopwatch.StartNew();
Transform(pbMsg, p);
sw.Stop();
long t = sw.ElapsedMilliseconds;
if(t == tTarget) { uLow = u; break; }
else if(t > tTarget) { uHigh = u; tHigh = t; }
else { uLow = u; tLow = t; }
}
p.SetUInt64(strName, uLow);
}
}
}

View File

@@ -1,80 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using KeePassLib.Collections;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.KeyDerivation
{
public sealed class KdfParameters : VariantDictionary
{
private const string ParamUuid = @"$UUID";
private readonly PwUuid m_puKdf;
public PwUuid KdfUuid
{
get { return m_puKdf; }
}
public KdfParameters(PwUuid puKdf)
{
if(puKdf == null) throw new ArgumentNullException("puKdf");
m_puKdf = puKdf;
SetByteArray(ParamUuid, puKdf.UuidBytes);
}
/// <summary>
/// Unsupported.
/// </summary>
public override object Clone()
{
throw new NotSupportedException();
}
public static byte[] SerializeExt(KdfParameters p)
{
return VariantDictionary.Serialize(p);
}
public static KdfParameters DeserializeExt(byte[] pb)
{
VariantDictionary d = VariantDictionary.Deserialize(pb);
if(d == null) { Debug.Assert(false); return null; }
byte[] pbUuid = d.GetByteArray(ParamUuid);
if((pbUuid == null) || (pbUuid.Length != (int)PwUuid.UuidSize))
{
Debug.Assert(false);
return null;
}
PwUuid pu = new PwUuid(pbUuid);
KdfParameters p = new KdfParameters(pu);
d.CopyTo(p);
return p;
}
}
}

View File

@@ -1,96 +0,0 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
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. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.KeyDerivation
{
public static class KdfPool
{
private static List<KdfEngine> g_l = new List<KdfEngine>();
public static IEnumerable<KdfEngine> Engines
{
get
{
EnsureInitialized();
return g_l;
}
}
private static void EnsureInitialized()
{
if(g_l.Count > 0) return;
g_l.Add(new AesKdf());
g_l.Add(new Argon2Kdf());
}
internal static KdfParameters GetDefaultParameters()
{
EnsureInitialized();
return g_l[0].GetDefaultParameters();
}
public static KdfEngine Get(PwUuid pu)
{
if(pu == null) { Debug.Assert(false); return null; }
EnsureInitialized();
foreach(KdfEngine kdf in g_l)
{
if(pu.Equals(kdf.Uuid)) return kdf;
}
return null;
}
public static KdfEngine Get(string strName)
{
if(string.IsNullOrEmpty(strName)) { Debug.Assert(false); return null; }
EnsureInitialized();
foreach(KdfEngine kdf in g_l)
{
if(strName.Equals(kdf.Name, StrUtil.CaseIgnoreCmp)) return kdf;
}
return null;
}
public static void Add(KdfEngine kdf)
{
if(kdf == null) { Debug.Assert(false); return; }
EnsureInitialized();
if(Get(kdf.Uuid) != null) { Debug.Assert(false); return; }
if(Get(kdf.Name) != null) { Debug.Assert(false); return; }
g_l.Add(kdf);
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -47,7 +47,7 @@ namespace KeePassLib.Cryptography.PasswordGenerator
if(ch == char.MinValue)
{
MemUtil.ZeroArray<char>(vGenerated);
Array.Clear(vGenerated, 0, vGenerated.Length);
return PwgError.TooFewCharacters;
}
@@ -57,7 +57,7 @@ namespace KeePassLib.Cryptography.PasswordGenerator
byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vGenerated);
psOut = new ProtectedString(true, pbUtf8);
MemUtil.ZeroByteArray(pbUtf8);
MemUtil.ZeroArray<char>(vGenerated);
Array.Clear(vGenerated, 0, vGenerated.Length);
return PwgError.Success;
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -121,7 +121,7 @@ namespace KeePassLib.Cryptography.PasswordGenerator
byte[] pbUtf8 = StrUtil.Utf8.GetBytes(vArray);
psOut = new ProtectedString(true, pbUtf8);
MemUtil.ZeroByteArray(pbUtf8);
MemUtil.ZeroArray<char>(vArray);
Array.Clear(vArray, 0, vArray.Length);
vGenerated.Clear();
return PwgError.Success;

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -46,8 +46,6 @@ namespace KeePassLib.Cryptography.PasswordGenerator
public const string Invalid = "\t\r\n";
public const string LookAlike = @"O0l1I|";
internal const string MenuAccels = PwCharSet.LowerCase + PwCharSet.Digits;
private const int CharTabSize = (0x10000 / 8);
private List<char> m_vChars = new List<char>();

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2016 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,12 +19,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
using System.Diagnostics;
using KeePassLib.Security;
using KeePassLib.Utility;
namespace KeePassLib.Cryptography.PasswordGenerator
{
@@ -46,16 +44,16 @@ namespace KeePassLib.Cryptography.PasswordGenerator
CustomPwGeneratorPool pwAlgorithmPool)
{
Debug.Assert(pwProfile != null);
if (pwProfile == null) throw new ArgumentNullException("pwProfile");
if(pwProfile == null) throw new ArgumentNullException("pwProfile");
CryptoRandomStream crs = CreateCryptoStream(pbUserEntropy);
PwgError e = PwgError.Unknown;
if (pwProfile.GeneratorType == PasswordGeneratorType.CharSet)
if(pwProfile.GeneratorType == PasswordGeneratorType.CharSet)
e = CharSetBasedGenerator.Generate(out psOut, pwProfile, crs);
else if (pwProfile.GeneratorType == PasswordGeneratorType.Pattern)
else if(pwProfile.GeneratorType == PasswordGeneratorType.Pattern)
e = PatternBasedGenerator.Generate(out psOut, pwProfile, crs);
else if (pwProfile.GeneratorType == PasswordGeneratorType.Custom)
else if(pwProfile.GeneratorType == PasswordGeneratorType.Custom)
e = GenerateCustom(out psOut, pwProfile, crs, pwAlgorithmPool);
else { Debug.Assert(false); psOut = ProtectedString.Empty; }
@@ -64,33 +62,29 @@ namespace KeePassLib.Cryptography.PasswordGenerator
private static CryptoRandomStream CreateCryptoStream(byte[] pbAdditionalEntropy)
{
byte[] pbKey = CryptoRandom.Instance.GetRandomBytes(128);
byte[] pbKey = CryptoRandom.Instance.GetRandomBytes(256);
// Mix in additional entropy
Debug.Assert(pbKey.Length >= 64);
if ((pbAdditionalEntropy != null) && (pbAdditionalEntropy.Length > 0))
if((pbAdditionalEntropy != null) && (pbAdditionalEntropy.Length > 0))
{
using (SHA512Managed h = new SHA512Managed())
{
byte[] pbHash = h.ComputeHash(pbAdditionalEntropy);
MemUtil.XorArray(pbHash, 0, pbKey, 0, pbHash.Length);
}
for(int nKeyPos = 0; nKeyPos < pbKey.Length; ++nKeyPos)
pbKey[nKeyPos] ^= pbAdditionalEntropy[nKeyPos % pbAdditionalEntropy.Length];
}
return new CryptoRandomStream(CrsAlgorithm.ChaCha20, pbKey);
return new CryptoRandomStream(CrsAlgorithm.Salsa20, pbKey);
}
internal static char GenerateCharacter(PwProfile pwProfile,
PwCharSet pwCharSet, CryptoRandomStream crsRandomSource)
{
if (pwCharSet.Size == 0) return char.MinValue;
if(pwCharSet.Size == 0) return char.MinValue;
ulong uIndex = crsRandomSource.GetRandomUInt64();
uIndex %= (ulong)pwCharSet.Size;
char ch = pwCharSet[(uint)uIndex];
if (pwProfile.NoRepeatingCharacters)
if(pwProfile.NoRepeatingCharacters)
pwCharSet.Remove(ch);
return ch;
@@ -100,21 +94,21 @@ namespace KeePassLib.Cryptography.PasswordGenerator
{
pwCharSet.Remove(PwCharSet.Invalid);
if (pwProfile.ExcludeLookAlike) pwCharSet.Remove(PwCharSet.LookAlike);
if(pwProfile.ExcludeLookAlike) pwCharSet.Remove(PwCharSet.LookAlike);
if (pwProfile.ExcludeCharacters.Length > 0)
if(pwProfile.ExcludeCharacters.Length > 0)
pwCharSet.Remove(pwProfile.ExcludeCharacters);
}
internal static void ShufflePassword(char[] pPassword,
CryptoRandomStream crsRandomSource)
{
Debug.Assert(pPassword != null); if (pPassword == null) return;
Debug.Assert(crsRandomSource != null); if (crsRandomSource == null) return;
Debug.Assert(pPassword != null); if(pPassword == null) return;
Debug.Assert(crsRandomSource != null); if(crsRandomSource == null) return;
if (pPassword.Length <= 1) return; // Nothing to shuffle
if(pPassword.Length <= 1) return; // Nothing to shuffle
for (int nSelect = 0; nSelect < pPassword.Length; ++nSelect)
for(int nSelect = 0; nSelect < pPassword.Length; ++nSelect)
{
ulong uRandomIndex = crsRandomSource.GetRandomUInt64();
uRandomIndex %= (ulong)(pPassword.Length - nSelect);
@@ -132,18 +126,18 @@ namespace KeePassLib.Cryptography.PasswordGenerator
psOut = ProtectedString.Empty;
Debug.Assert(pwProfile.GeneratorType == PasswordGeneratorType.Custom);
if (pwAlgorithmPool == null) return PwgError.UnknownAlgorithm;
if(pwAlgorithmPool == null) return PwgError.UnknownAlgorithm;
string strID = pwProfile.CustomAlgorithmUuid;
if (string.IsNullOrEmpty(strID)) { Debug.Assert(false); return PwgError.UnknownAlgorithm; }
if(string.IsNullOrEmpty(strID)) { Debug.Assert(false); return PwgError.UnknownAlgorithm; }
byte[] pbUuid = Convert.FromBase64String(strID);
PwUuid uuid = new PwUuid(pbUuid);
CustomPwGenerator pwg = pwAlgorithmPool.Find(uuid);
if (pwg == null) { Debug.Assert(false); return PwgError.UnknownAlgorithm; }
if(pwg == null) { Debug.Assert(false); return PwgError.UnknownAlgorithm; }
ProtectedString pwd = pwg.Generate(pwProfile.CloneDeep(), crs);
if (pwd == null) return PwgError.Unknown;
if(pwd == null) return PwgError.Unknown;
psOut = pwd;
return PwgError.Success;

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -265,7 +265,7 @@ namespace KeePassLib.Cryptography.PasswordGenerator
else pcs.Add(ch);
}
MemUtil.ZeroArray<char>(vChars);
Array.Clear(vChars, 0, vChars.Length);
MemUtil.ZeroByteArray(pbUtf8);
return pp;
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -422,7 +422,7 @@ namespace KeePassLib.Cryptography
char[] vChars = StrUtil.Utf8.GetChars(pbUnprotectedUtf8);
uint uResult = EstimatePasswordBits(vChars);
MemUtil.ZeroArray<char>(vChars);
Array.Clear(vChars, 0, vChars.Length);
return uResult;
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,35 +19,34 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Security;
using System.Text;
#if KeePassUAP
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
#else
using System.Security.Cryptography;
#endif
using System.Text;
using System.Globalization;
using System.Diagnostics;
using KeePassLib.Cryptography.Cipher;
using KeePassLib.Cryptography.Hash;
using KeePassLib.Cryptography.KeyDerivation;
using KeePassLib.Keys;
using KeePassLib.Native;
using KeePassLib.Utility;
using KeePassLib.Resources;
using KeePassLib.Security;
using KeePassLib.Utility;
#if (KeePassUAP && KeePassLibSD)
#error KeePassUAP and KeePassLibSD are mutually exclusive.
#endif
namespace KeePassLib.Cryptography
{
/* #pragma warning disable 1591
/// <summary>
/// Return values of the <c>SelfTest.Perform</c> method.
/// </summary>
public enum SelfTestResult
{
Success = 0,
RijndaelEcbError = 1,
Salsa20Error = 2,
NativeKeyTransformationError = 3
}
#pragma warning restore 1591 */
/// <summary>
/// Class containing self-test methods.
/// </summary>
@@ -62,11 +61,7 @@ namespace KeePassLib.Cryptography
TestRijndael();
TestSalsa20();
TestChaCha20();
TestBlake2b();
TestArgon2();
TestHmac();
TestNativeKeyTransform();
TestHmacOtp();
@@ -79,31 +74,28 @@ namespace KeePassLib.Cryptography
Debug.Assert((int)PwIcon.World == 1);
Debug.Assert((int)PwIcon.Warning == 2);
Debug.Assert((int)PwIcon.BlackBerry == 68);
#if KeePassUAP
SelfTestEx.Perform();
#endif
}
internal static void TestFipsComplianceProblems()
{
#if !KeePassUAP
try { using(RijndaelManaged r = new RijndaelManaged()) { } }
#if !KeePassRT
try { new RijndaelManaged(); }
catch(Exception exAes)
{
throw new SecurityException("AES/Rijndael: " + exAes.Message);
}
#endif
try { using(SHA256Managed h = new SHA256Managed()) { } }
try { new SHA256Managed(); }
catch(Exception exSha256)
{
throw new SecurityException("SHA-256: " + exSha256.Message);
}
#endif
}
private static void TestRijndael()
{
#if !KeePassRT
// Test vector (official ECB test vector #356)
byte[] pbIV = new byte[16];
byte[] pbTestKey = new byte[32];
@@ -118,13 +110,6 @@ namespace KeePassLib.Cryptography
for(i = 0; i < 16; ++i) pbTestData[i] = 0;
pbTestData[0] = 0x04;
#if KeePassUAP
AesEngine r = new AesEngine();
r.Init(true, new KeyParameter(pbTestKey));
if(r.GetBlockSize() != pbTestData.Length)
throw new SecurityException("AES (BC)");
r.ProcessBlock(pbTestData, 0, pbTestData, 0);
#else
RijndaelManaged r = new RijndaelManaged();
if(r.BlockSize != 128) // AES block size
@@ -140,17 +125,16 @@ namespace KeePassLib.Cryptography
ICryptoTransform iCrypt = r.CreateEncryptor();
iCrypt.TransformBlock(pbTestData, 0, 16, pbTestData, 0);
#endif
if(!MemUtil.ArraysEqual(pbTestData, pbReferenceCT))
throw new SecurityException("AES");
throw new SecurityException(KLRes.EncAlgorithmAes + ".");
#endif
}
private static void TestSalsa20()
{
#if DEBUG
// Test values from official set 6, vector 3
byte[] pbKey = new byte[32] {
byte[] pbKey= new byte[32] {
0x0F, 0x62, 0xB5, 0x08, 0x5B, 0xAE, 0x01, 0x54,
0xA7, 0xFA, 0x4D, 0xA0, 0xF3, 0x46, 0x99, 0xEC,
0x3F, 0x92, 0xE5, 0x38, 0x8B, 0xDE, 0x31, 0x84,
@@ -165,11 +149,12 @@ namespace KeePassLib.Cryptography
byte[] pb = new byte[16];
Salsa20Cipher c = new Salsa20Cipher(pbKey, pbIV);
c.Encrypt(pb, 0, pb.Length);
c.Encrypt(pb, pb.Length, false);
if(!MemUtil.ArraysEqual(pb, pbExpected))
throw new SecurityException("Salsa20-1");
throw new SecurityException("Salsa20.");
// Extended test
#if DEBUG
// Extended test in debug mode
byte[] pbExpected2 = new byte[16] {
0xAB, 0xF3, 0x9A, 0x21, 0x0E, 0xEE, 0x89, 0x59,
0x8B, 0x71, 0x33, 0x37, 0x70, 0x56, 0xC2, 0xFE
@@ -181,27 +166,15 @@ namespace KeePassLib.Cryptography
Random r = new Random();
int nPos = Salsa20ToPos(c, r, pb.Length, 65536);
Array.Clear(pb, 0, pb.Length);
c.Encrypt(pb, 0, pb.Length);
c.Encrypt(pb, pb.Length, false);
if(!MemUtil.ArraysEqual(pb, pbExpected2))
throw new SecurityException("Salsa20-2");
throw new SecurityException("Salsa20-2.");
nPos = Salsa20ToPos(c, r, nPos + pb.Length, 131008);
Array.Clear(pb, 0, pb.Length);
c.Encrypt(pb, 0, pb.Length);
c.Encrypt(pb, pb.Length, true);
if(!MemUtil.ArraysEqual(pb, pbExpected3))
throw new SecurityException("Salsa20-3");
Dictionary<string, bool> d = new Dictionary<string, bool>();
const int nRounds = 100;
for(int i = 0; i < nRounds; ++i)
{
byte[] z = new byte[32];
c = new Salsa20Cipher(z, MemUtil.Int64ToBytes(i));
c.Encrypt(z, 0, z.Length);
d[MemUtil.ByteArrayToHexString(z)] = true;
}
if(d.Count != nRounds) throw new SecurityException("Salsa20-4");
throw new SecurityException("Salsa20-3.");
#endif
}
@@ -215,7 +188,7 @@ namespace KeePassLib.Cryptography
{
int x = r.Next(1, 513);
int nGen = Math.Min(nTargetPos - nPos, x);
c.Encrypt(pb, 0, nGen);
c.Encrypt(pb, nGen, r.Next(0, 2) == 0);
nPos += nGen;
}
@@ -223,484 +196,6 @@ namespace KeePassLib.Cryptography
}
#endif
private static void TestChaCha20()
{
// ======================================================
// Test vector from RFC 7539, section 2.3.2
byte[] pbKey = new byte[32];
for(int i = 0; i < 32; ++i) pbKey[i] = (byte)i;
byte[] pbIV = new byte[12];
pbIV[3] = 0x09;
pbIV[7] = 0x4A;
byte[] pbExpc = new byte[64] {
0x10, 0xF1, 0xE7, 0xE4, 0xD1, 0x3B, 0x59, 0x15,
0x50, 0x0F, 0xDD, 0x1F, 0xA3, 0x20, 0x71, 0xC4,
0xC7, 0xD1, 0xF4, 0xC7, 0x33, 0xC0, 0x68, 0x03,
0x04, 0x22, 0xAA, 0x9A, 0xC3, 0xD4, 0x6C, 0x4E,
0xD2, 0x82, 0x64, 0x46, 0x07, 0x9F, 0xAA, 0x09,
0x14, 0xC2, 0xD7, 0x05, 0xD9, 0x8B, 0x02, 0xA2,
0xB5, 0x12, 0x9C, 0xD1, 0xDE, 0x16, 0x4E, 0xB9,
0xCB, 0xD0, 0x83, 0xE8, 0xA2, 0x50, 0x3C, 0x4E
};
byte[] pb = new byte[64];
using(ChaCha20Cipher c = new ChaCha20Cipher(pbKey, pbIV))
{
c.Seek(64, SeekOrigin.Begin); // Skip first block
c.Encrypt(pb, 0, pb.Length);
if(!MemUtil.ArraysEqual(pb, pbExpc))
throw new SecurityException("ChaCha20-1");
}
#if DEBUG
// ======================================================
// Test vector from RFC 7539, section 2.4.2
pbIV[3] = 0;
pb = StrUtil.Utf8.GetBytes("Ladies and Gentlemen of the clas" +
@"s of '99: If I could offer you only one tip for " +
@"the future, sunscreen would be it.");
pbExpc = new byte[] {
0x6E, 0x2E, 0x35, 0x9A, 0x25, 0x68, 0xF9, 0x80,
0x41, 0xBA, 0x07, 0x28, 0xDD, 0x0D, 0x69, 0x81,
0xE9, 0x7E, 0x7A, 0xEC, 0x1D, 0x43, 0x60, 0xC2,
0x0A, 0x27, 0xAF, 0xCC, 0xFD, 0x9F, 0xAE, 0x0B,
0xF9, 0x1B, 0x65, 0xC5, 0x52, 0x47, 0x33, 0xAB,
0x8F, 0x59, 0x3D, 0xAB, 0xCD, 0x62, 0xB3, 0x57,
0x16, 0x39, 0xD6, 0x24, 0xE6, 0x51, 0x52, 0xAB,
0x8F, 0x53, 0x0C, 0x35, 0x9F, 0x08, 0x61, 0xD8,
0x07, 0xCA, 0x0D, 0xBF, 0x50, 0x0D, 0x6A, 0x61,
0x56, 0xA3, 0x8E, 0x08, 0x8A, 0x22, 0xB6, 0x5E,
0x52, 0xBC, 0x51, 0x4D, 0x16, 0xCC, 0xF8, 0x06,
0x81, 0x8C, 0xE9, 0x1A, 0xB7, 0x79, 0x37, 0x36,
0x5A, 0xF9, 0x0B, 0xBF, 0x74, 0xA3, 0x5B, 0xE6,
0xB4, 0x0B, 0x8E, 0xED, 0xF2, 0x78, 0x5E, 0x42,
0x87, 0x4D
};
byte[] pb64 = new byte[64];
using(ChaCha20Cipher c = new ChaCha20Cipher(pbKey, pbIV))
{
c.Encrypt(pb64, 0, pb64.Length); // Skip first block
c.Encrypt(pb, 0, pb.Length);
if(!MemUtil.ArraysEqual(pb, pbExpc))
throw new SecurityException("ChaCha20-2");
}
// ======================================================
// Test vector from RFC 7539, appendix A.2 #2
Array.Clear(pbKey, 0, pbKey.Length);
pbKey[31] = 1;
Array.Clear(pbIV, 0, pbIV.Length);
pbIV[11] = 2;
pb = StrUtil.Utf8.GetBytes("Any submission to the IETF inten" +
"ded by the Contributor for publication as all or" +
" part of an IETF Internet-Draft or RFC and any s" +
"tatement made within the context of an IETF acti" +
"vity is considered an \"IETF Contribution\". Such " +
"statements include oral statements in IETF sessi" +
"ons, as well as written and electronic communica" +
"tions made at any time or place, which are addressed to");
pbExpc = MemUtil.HexStringToByteArray(
"A3FBF07DF3FA2FDE4F376CA23E82737041605D9F4F4F57BD8CFF2C1D4B7955EC" +
"2A97948BD3722915C8F3D337F7D370050E9E96D647B7C39F56E031CA5EB6250D" +
"4042E02785ECECFA4B4BB5E8EAD0440E20B6E8DB09D881A7C6132F420E527950" +
"42BDFA7773D8A9051447B3291CE1411C680465552AA6C405B7764D5E87BEA85A" +
"D00F8449ED8F72D0D662AB052691CA66424BC86D2DF80EA41F43ABF937D3259D" +
"C4B2D0DFB48A6C9139DDD7F76966E928E635553BA76C5C879D7B35D49EB2E62B" +
"0871CDAC638939E25E8A1E0EF9D5280FA8CA328B351C3C765989CBCF3DAA8B6C" +
"CC3AAF9F3979C92B3720FC88DC95ED84A1BE059C6499B9FDA236E7E818B04B0B" +
"C39C1E876B193BFE5569753F88128CC08AAA9B63D1A16F80EF2554D7189C411F" +
"5869CA52C5B83FA36FF216B9C1D30062BEBCFD2DC5BCE0911934FDA79A86F6E6" +
"98CED759C3FF9B6477338F3DA4F9CD8514EA9982CCAFB341B2384DD902F3D1AB" +
"7AC61DD29C6F21BA5B862F3730E37CFDC4FD806C22F221");
Random r = new Random();
using(MemoryStream msEnc = new MemoryStream())
{
using(ChaCha20Stream c = new ChaCha20Stream(msEnc, true, pbKey, pbIV))
{
r.NextBytes(pb64);
c.Write(pb64, 0, pb64.Length); // Skip first block
int p = 0;
while(p < pb.Length)
{
int cb = r.Next(1, pb.Length - p + 1);
c.Write(pb, p, cb);
p += cb;
}
Debug.Assert(p == pb.Length);
}
byte[] pbEnc0 = msEnc.ToArray();
byte[] pbEnc = MemUtil.Mid(pbEnc0, 64, pbEnc0.Length - 64);
if(!MemUtil.ArraysEqual(pbEnc, pbExpc))
throw new SecurityException("ChaCha20-3");
using(MemoryStream msCT = new MemoryStream(pbEnc0, false))
{
using(ChaCha20Stream cDec = new ChaCha20Stream(msCT, false,
pbKey, pbIV))
{
byte[] pbPT = MemUtil.Read(cDec, pbEnc0.Length);
if(cDec.ReadByte() >= 0)
throw new SecurityException("ChaCha20-4");
if(!MemUtil.ArraysEqual(MemUtil.Mid(pbPT, 0, 64), pb64))
throw new SecurityException("ChaCha20-5");
if(!MemUtil.ArraysEqual(MemUtil.Mid(pbPT, 64, pbEnc.Length), pb))
throw new SecurityException("ChaCha20-6");
}
}
}
// ======================================================
// Test vector TC8 from RFC draft by J. Strombergson:
// https://tools.ietf.org/html/draft-strombergson-chacha-test-vectors-01
pbKey = new byte[32] {
0xC4, 0x6E, 0xC1, 0xB1, 0x8C, 0xE8, 0xA8, 0x78,
0x72, 0x5A, 0x37, 0xE7, 0x80, 0xDF, 0xB7, 0x35,
0x1F, 0x68, 0xED, 0x2E, 0x19, 0x4C, 0x79, 0xFB,
0xC6, 0xAE, 0xBE, 0xE1, 0xA6, 0x67, 0x97, 0x5D
};
// The first 4 bytes are set to zero and a large counter
// is used; this makes the RFC 7539 version of ChaCha20
// compatible with the original specification by
// D. J. Bernstein.
pbIV = new byte[12] { 0x00, 0x00, 0x00, 0x00,
0x1A, 0xDA, 0x31, 0xD5, 0xCF, 0x68, 0x82, 0x21
};
pb = new byte[128];
pbExpc = new byte[128] {
0xF6, 0x3A, 0x89, 0xB7, 0x5C, 0x22, 0x71, 0xF9,
0x36, 0x88, 0x16, 0x54, 0x2B, 0xA5, 0x2F, 0x06,
0xED, 0x49, 0x24, 0x17, 0x92, 0x30, 0x2B, 0x00,
0xB5, 0xE8, 0xF8, 0x0A, 0xE9, 0xA4, 0x73, 0xAF,
0xC2, 0x5B, 0x21, 0x8F, 0x51, 0x9A, 0xF0, 0xFD,
0xD4, 0x06, 0x36, 0x2E, 0x8D, 0x69, 0xDE, 0x7F,
0x54, 0xC6, 0x04, 0xA6, 0xE0, 0x0F, 0x35, 0x3F,
0x11, 0x0F, 0x77, 0x1B, 0xDC, 0xA8, 0xAB, 0x92,
0xE5, 0xFB, 0xC3, 0x4E, 0x60, 0xA1, 0xD9, 0xA9,
0xDB, 0x17, 0x34, 0x5B, 0x0A, 0x40, 0x27, 0x36,
0x85, 0x3B, 0xF9, 0x10, 0xB0, 0x60, 0xBD, 0xF1,
0xF8, 0x97, 0xB6, 0x29, 0x0F, 0x01, 0xD1, 0x38,
0xAE, 0x2C, 0x4C, 0x90, 0x22, 0x5B, 0xA9, 0xEA,
0x14, 0xD5, 0x18, 0xF5, 0x59, 0x29, 0xDE, 0xA0,
0x98, 0xCA, 0x7A, 0x6C, 0xCF, 0xE6, 0x12, 0x27,
0x05, 0x3C, 0x84, 0xE4, 0x9A, 0x4A, 0x33, 0x32
};
using(ChaCha20Cipher c = new ChaCha20Cipher(pbKey, pbIV, true))
{
c.Decrypt(pb, 0, pb.Length);
if(!MemUtil.ArraysEqual(pb, pbExpc))
throw new SecurityException("ChaCha20-7");
}
#endif
}
private static void TestBlake2b()
{
#if DEBUG
Blake2b h = new Blake2b();
// ======================================================
// From https://tools.ietf.org/html/rfc7693
byte[] pbData = StrUtil.Utf8.GetBytes("abc");
byte[] pbExpc = new byte[64] {
0xBA, 0x80, 0xA5, 0x3F, 0x98, 0x1C, 0x4D, 0x0D,
0x6A, 0x27, 0x97, 0xB6, 0x9F, 0x12, 0xF6, 0xE9,
0x4C, 0x21, 0x2F, 0x14, 0x68, 0x5A, 0xC4, 0xB7,
0x4B, 0x12, 0xBB, 0x6F, 0xDB, 0xFF, 0xA2, 0xD1,
0x7D, 0x87, 0xC5, 0x39, 0x2A, 0xAB, 0x79, 0x2D,
0xC2, 0x52, 0xD5, 0xDE, 0x45, 0x33, 0xCC, 0x95,
0x18, 0xD3, 0x8A, 0xA8, 0xDB, 0xF1, 0x92, 0x5A,
0xB9, 0x23, 0x86, 0xED, 0xD4, 0x00, 0x99, 0x23
};
byte[] pbC = h.ComputeHash(pbData);
if(!MemUtil.ArraysEqual(pbC, pbExpc))
throw new SecurityException("Blake2b-1");
// ======================================================
// Computed using the official b2sum tool
pbExpc = new byte[64] {
0x78, 0x6A, 0x02, 0xF7, 0x42, 0x01, 0x59, 0x03,
0xC6, 0xC6, 0xFD, 0x85, 0x25, 0x52, 0xD2, 0x72,
0x91, 0x2F, 0x47, 0x40, 0xE1, 0x58, 0x47, 0x61,
0x8A, 0x86, 0xE2, 0x17, 0xF7, 0x1F, 0x54, 0x19,
0xD2, 0x5E, 0x10, 0x31, 0xAF, 0xEE, 0x58, 0x53,
0x13, 0x89, 0x64, 0x44, 0x93, 0x4E, 0xB0, 0x4B,
0x90, 0x3A, 0x68, 0x5B, 0x14, 0x48, 0xB7, 0x55,
0xD5, 0x6F, 0x70, 0x1A, 0xFE, 0x9B, 0xE2, 0xCE
};
pbC = h.ComputeHash(MemUtil.EmptyByteArray);
if(!MemUtil.ArraysEqual(pbC, pbExpc))
throw new SecurityException("Blake2b-2");
// ======================================================
// Computed using the official b2sum tool
string strS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.:,;_-\r\n";
StringBuilder sb = new StringBuilder();
for(int i = 0; i < 1000; ++i) sb.Append(strS);
pbData = StrUtil.Utf8.GetBytes(sb.ToString());
pbExpc = new byte[64] {
0x59, 0x69, 0x8D, 0x3B, 0x83, 0xF4, 0x02, 0x4E,
0xD8, 0x99, 0x26, 0x0E, 0xF4, 0xE5, 0x9F, 0x20,
0xDC, 0x31, 0xEE, 0x5B, 0x45, 0xEA, 0xBB, 0xFC,
0x1C, 0x0A, 0x8E, 0xED, 0xAA, 0x7A, 0xFF, 0x50,
0x82, 0xA5, 0x8F, 0xBC, 0x4A, 0x46, 0xFC, 0xC5,
0xEF, 0x44, 0x4E, 0x89, 0x80, 0x7D, 0x3F, 0x1C,
0xC1, 0x94, 0x45, 0xBB, 0xC0, 0x2C, 0x95, 0xAA,
0x3F, 0x08, 0x8A, 0x93, 0xF8, 0x75, 0x91, 0xB0
};
Random r = new Random();
int p = 0;
while(p < pbData.Length)
{
int cb = r.Next(1, pbData.Length - p + 1);
h.TransformBlock(pbData, p, cb, pbData, p);
p += cb;
}
Debug.Assert(p == pbData.Length);
h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
if(!MemUtil.ArraysEqual(h.Hash, pbExpc))
throw new SecurityException("Blake2b-3");
h.Clear();
#endif
}
private static void TestArgon2()
{
#if DEBUG
Argon2Kdf kdf = new Argon2Kdf();
// ======================================================
// From the official Argon2 1.3 reference code package
// (test vector for Argon2d 1.3); also on
// https://tools.ietf.org/html/draft-irtf-cfrg-argon2-00
KdfParameters p = kdf.GetDefaultParameters();
kdf.Randomize(p);
Debug.Assert(p.GetUInt32(Argon2Kdf.ParamVersion, 0) == 0x13U);
byte[] pbMsg = new byte[32];
for(int i = 0; i < pbMsg.Length; ++i) pbMsg[i] = 1;
p.SetUInt64(Argon2Kdf.ParamMemory, 32 * 1024);
p.SetUInt64(Argon2Kdf.ParamIterations, 3);
p.SetUInt32(Argon2Kdf.ParamParallelism, 4);
byte[] pbSalt = new byte[16];
for(int i = 0; i < pbSalt.Length; ++i) pbSalt[i] = 2;
p.SetByteArray(Argon2Kdf.ParamSalt, pbSalt);
byte[] pbKey = new byte[8];
for(int i = 0; i < pbKey.Length; ++i) pbKey[i] = 3;
p.SetByteArray(Argon2Kdf.ParamSecretKey, pbKey);
byte[] pbAssoc = new byte[12];
for(int i = 0; i < pbAssoc.Length; ++i) pbAssoc[i] = 4;
p.SetByteArray(Argon2Kdf.ParamAssocData, pbAssoc);
byte[] pbExpc = new byte[32] {
0x51, 0x2B, 0x39, 0x1B, 0x6F, 0x11, 0x62, 0x97,
0x53, 0x71, 0xD3, 0x09, 0x19, 0x73, 0x42, 0x94,
0xF8, 0x68, 0xE3, 0xBE, 0x39, 0x84, 0xF3, 0xC1,
0xA1, 0x3A, 0x4D, 0xB9, 0xFA, 0xBE, 0x4A, 0xCB
};
byte[] pb = kdf.Transform(pbMsg, p);
if(!MemUtil.ArraysEqual(pb, pbExpc))
throw new SecurityException("Argon2-1");
// ======================================================
// From the official Argon2 1.3 reference code package
// (test vector for Argon2d 1.0)
p.SetUInt32(Argon2Kdf.ParamVersion, 0x10);
pbExpc = new byte[32] {
0x96, 0xA9, 0xD4, 0xE5, 0xA1, 0x73, 0x40, 0x92,
0xC8, 0x5E, 0x29, 0xF4, 0x10, 0xA4, 0x59, 0x14,
0xA5, 0xDD, 0x1F, 0x5C, 0xBF, 0x08, 0xB2, 0x67,
0x0D, 0xA6, 0x8A, 0x02, 0x85, 0xAB, 0xF3, 0x2B
};
pb = kdf.Transform(pbMsg, p);
if(!MemUtil.ArraysEqual(pb, pbExpc))
throw new SecurityException("Argon2-2");
// ======================================================
// From the official 'phc-winner-argon2-20151206.zip'
// (test vector for Argon2d 1.0)
p.SetUInt64(Argon2Kdf.ParamMemory, 16 * 1024);
pbExpc = new byte[32] {
0x57, 0xB0, 0x61, 0x3B, 0xFD, 0xD4, 0x13, 0x1A,
0x0C, 0x34, 0x88, 0x34, 0xC6, 0x72, 0x9C, 0x2C,
0x72, 0x29, 0x92, 0x1E, 0x6B, 0xBA, 0x37, 0x66,
0x5D, 0x97, 0x8C, 0x4F, 0xE7, 0x17, 0x5E, 0xD2
};
pb = kdf.Transform(pbMsg, p);
if(!MemUtil.ArraysEqual(pb, pbExpc))
throw new SecurityException("Argon2-3");
#if SELFTEST_ARGON2_LONG
// ======================================================
// Computed using the official 'argon2' application
// (test vectors for Argon2d 1.3)
p = kdf.GetDefaultParameters();
pbMsg = StrUtil.Utf8.GetBytes("ABC1234");
p.SetUInt64(Argon2Kdf.ParamMemory, (1 << 11) * 1024); // 2 MB
p.SetUInt64(Argon2Kdf.ParamIterations, 2);
p.SetUInt32(Argon2Kdf.ParamParallelism, 2);
pbSalt = StrUtil.Utf8.GetBytes("somesalt");
p.SetByteArray(Argon2Kdf.ParamSalt, pbSalt);
pbExpc = new byte[32] {
0x29, 0xCB, 0xD3, 0xA1, 0x93, 0x76, 0xF7, 0xA2,
0xFC, 0xDF, 0xB0, 0x68, 0xAC, 0x0B, 0x99, 0xBA,
0x40, 0xAC, 0x09, 0x01, 0x73, 0x42, 0xCE, 0xF1,
0x29, 0xCC, 0xA1, 0x4F, 0xE1, 0xC1, 0xB7, 0xA3
};
pb = kdf.Transform(pbMsg, p);
if(!MemUtil.ArraysEqual(pb, pbExpc))
throw new SecurityException("Argon2-4");
p.SetUInt64(Argon2Kdf.ParamMemory, (1 << 10) * 1024); // 1 MB
p.SetUInt64(Argon2Kdf.ParamIterations, 3);
pbExpc = new byte[32] {
0x7A, 0xBE, 0x1C, 0x1C, 0x8D, 0x7F, 0xD6, 0xDC,
0x7C, 0x94, 0x06, 0x3E, 0xD8, 0xBC, 0xD8, 0x1C,
0x2F, 0x87, 0x84, 0x99, 0x12, 0x83, 0xFE, 0x76,
0x00, 0x64, 0xC4, 0x58, 0xA4, 0xDA, 0x35, 0x70
};
pb = kdf.Transform(pbMsg, p);
if(!MemUtil.ArraysEqual(pb, pbExpc))
throw new SecurityException("Argon2-5");
#if SELFTEST_ARGON2_LONGER
p.SetUInt64(Argon2Kdf.ParamMemory, (1 << 20) * 1024); // 1 GB
p.SetUInt64(Argon2Kdf.ParamIterations, 2);
p.SetUInt32(Argon2Kdf.ParamParallelism, 3);
pbExpc = new byte[32] {
0xE6, 0xE7, 0xCB, 0xF5, 0x5A, 0x06, 0x93, 0x05,
0x32, 0xBA, 0x86, 0xC6, 0x1F, 0x45, 0x17, 0x99,
0x65, 0x41, 0x77, 0xF9, 0x30, 0x55, 0x9A, 0xE8,
0x3D, 0x21, 0x48, 0xC6, 0x2D, 0x0C, 0x49, 0x11
};
pb = kdf.Transform(pbMsg, p);
if(!MemUtil.ArraysEqual(pb, pbExpc))
throw new SecurityException("Argon2-6");
#endif // SELFTEST_ARGON2_LONGER
#endif // SELFTEST_ARGON2_LONG
#endif // DEBUG
}
private static void TestHmac()
{
#if DEBUG
// Test vectors from RFC 4231
byte[] pbKey = new byte[20];
for(int i = 0; i < pbKey.Length; ++i) pbKey[i] = 0x0B;
byte[] pbMsg = StrUtil.Utf8.GetBytes("Hi There");
byte[] pbExpc = new byte[32] {
0xB0, 0x34, 0x4C, 0x61, 0xD8, 0xDB, 0x38, 0x53,
0x5C, 0xA8, 0xAF, 0xCE, 0xAF, 0x0B, 0xF1, 0x2B,
0x88, 0x1D, 0xC2, 0x00, 0xC9, 0x83, 0x3D, 0xA7,
0x26, 0xE9, 0x37, 0x6C, 0x2E, 0x32, 0xCF, 0xF7
};
HmacEval(pbKey, pbMsg, pbExpc, "1");
pbKey = new byte[131];
for(int i = 0; i < pbKey.Length; ++i) pbKey[i] = 0xAA;
pbMsg = StrUtil.Utf8.GetBytes(
"This is a test using a larger than block-size key and " +
"a larger than block-size data. The key needs to be " +
"hashed before being used by the HMAC algorithm.");
pbExpc = new byte[32] {
0x9B, 0x09, 0xFF, 0xA7, 0x1B, 0x94, 0x2F, 0xCB,
0x27, 0x63, 0x5F, 0xBC, 0xD5, 0xB0, 0xE9, 0x44,
0xBF, 0xDC, 0x63, 0x64, 0x4F, 0x07, 0x13, 0x93,
0x8A, 0x7F, 0x51, 0x53, 0x5C, 0x3A, 0x35, 0xE2
};
HmacEval(pbKey, pbMsg, pbExpc, "2");
#endif
}
#if DEBUG
private static void HmacEval(byte[] pbKey, byte[] pbMsg,
byte[] pbExpc, string strID)
{
using(HMACSHA256 h = new HMACSHA256(pbKey))
{
h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0);
h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
byte[] pbHash = h.Hash;
if(!MemUtil.ArraysEqual(pbHash, pbExpc))
throw new SecurityException("HMAC-SHA-256-" + strID);
// Reuse the object
h.Initialize();
h.TransformBlock(pbMsg, 0, pbMsg.Length, pbMsg, 0);
h.TransformFinalBlock(MemUtil.EmptyByteArray, 0, 0);
pbHash = h.Hash;
if(!MemUtil.ArraysEqual(pbHash, pbExpc))
throw new SecurityException("HMAC-SHA-256-" + strID + "-R");
}
}
#endif
private static void TestNativeKeyTransform()
{
#if DEBUG
@@ -710,16 +205,16 @@ namespace KeePassLib.Cryptography
byte[] pbManaged = new byte[32];
Array.Copy(pbOrgKey, pbManaged, 32);
if(!AesKdf.TransformKeyManaged(pbManaged, pbSeed, uRounds))
throw new SecurityException("AES-KDF-1");
if(CompositeKey.TransformKeyManaged(pbManaged, pbSeed, uRounds) == false)
throw new SecurityException("Managed transform.");
byte[] pbNative = new byte[32];
Array.Copy(pbOrgKey, pbNative, 32);
if(!NativeLib.TransformKey256(pbNative, pbSeed, uRounds))
if(NativeLib.TransformKey256(pbNative, pbSeed, uRounds) == false)
return; // Native library not available ("success")
if(!MemUtil.ArraysEqual(pbManaged, pbNative))
throw new SecurityException("AES-KDF-2");
throw new SecurityException("Native transform.");
#endif
}
@@ -757,49 +252,12 @@ namespace KeePassLib.Cryptography
pbN = enc.GetBytes("012b");
if(MemUtil.IndexOf<byte>(pb, pbN) >= 0)
throw new InvalidOperationException("MemUtil-7");
byte[] pbRes = MemUtil.ParseBase32("MY======");
byte[] pbExp = Encoding.ASCII.GetBytes("f");
if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-1");
pbRes = MemUtil.ParseBase32("MZXQ====");
pbExp = Encoding.ASCII.GetBytes("fo");
if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-2");
pbRes = MemUtil.ParseBase32("MZXW6===");
pbExp = Encoding.ASCII.GetBytes("foo");
if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-3");
pbRes = MemUtil.ParseBase32("MZXW6YQ=");
pbExp = Encoding.ASCII.GetBytes("foob");
if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-4");
pbRes = MemUtil.ParseBase32("MZXW6YTB");
pbExp = Encoding.ASCII.GetBytes("fooba");
if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-5");
pbRes = MemUtil.ParseBase32("MZXW6YTBOI======");
pbExp = Encoding.ASCII.GetBytes("foobar");
if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-6");
pbRes = MemUtil.ParseBase32("JNSXSIDQOJXXM2LEMVZCAYTBONSWIIDPNYQG63TFFV2GS3LFEBYGC43TO5XXEZDTFY======");
pbExp = Encoding.ASCII.GetBytes("Key provider based on one-time passwords.");
if(!MemUtil.ArraysEqual(pbRes, pbExp)) throw new Exception("Base32-7");
int i = 0 - 0x10203040;
pbRes = MemUtil.Int32ToBytes(i);
if(MemUtil.ByteArrayToHexString(pbRes) != "C0CFDFEF")
throw new Exception("MemUtil-8"); // Must be little-endian
if(MemUtil.BytesToUInt32(pbRes) != (uint)i)
throw new Exception("MemUtil-9");
if(MemUtil.BytesToInt32(pbRes) != i)
throw new Exception("MemUtil-10");
#endif
}
private static void TestHmacOtp()
{
#if (DEBUG && !KeePassLibSD)
#if (DEBUG && !KeePassLibSD && !KeePassRT)
byte[] pbSecret = StrUtil.Utf8.GetBytes("12345678901234567890");
string[] vExp = new string[]{ "755224", "287082", "359152",
"969429", "338314", "254676", "287922", "162583", "399871",
@@ -867,41 +325,6 @@ namespace KeePassLib.Cryptography
throw new SecurityException("ProtectedString-8");
if(!ps.IsProtected) throw new SecurityException("ProtectedString-9");
if(!ps2.IsProtected) throw new SecurityException("ProtectedString-10");
Random r = new Random();
string str = string.Empty;
ps = new ProtectedString();
for(int i = 0; i < 100; ++i)
{
bool bProt = ((r.Next() % 4) != 0);
ps = ps.WithProtection(bProt);
int x = r.Next(str.Length + 1);
int c = r.Next(20);
char ch = (char)r.Next(1, 256);
string strIns = new string(ch, c);
str = str.Insert(x, strIns);
ps = ps.Insert(x, strIns);
if(ps.IsProtected != bProt)
throw new SecurityException("ProtectedString-11");
if(ps.ReadString() != str)
throw new SecurityException("ProtectedString-12");
ps = ps.WithProtection(bProt);
x = r.Next(str.Length);
c = r.Next(str.Length - x + 1);
str = str.Remove(x, c);
ps = ps.Remove(x, c);
if(ps.IsProtected != bProt)
throw new SecurityException("ProtectedString-13");
if(ps.ReadString() != str)
throw new SecurityException("ProtectedString-14");
}
#endif
}
@@ -942,16 +365,10 @@ namespace KeePassLib.Cryptography
throw new InvalidOperationException("StrUtil-V3");
if(StrUtil.VersionToString(0x00FF000000000000UL) != "255")
throw new InvalidOperationException("StrUtil-V4");
if(StrUtil.VersionToString(0x00FF000000000000UL, 2) != "255.0")
if(StrUtil.VersionToString(0x00FF000000000000UL, true) != "255.0")
throw new InvalidOperationException("StrUtil-V5");
if(StrUtil.VersionToString(0x0000000000070000UL) != "0.0.7")
if(StrUtil.VersionToString(0x0000000000070000UL, true) != "0.0.7")
throw new InvalidOperationException("StrUtil-V6");
if(StrUtil.VersionToString(0x0000000000000000UL) != "0")
throw new InvalidOperationException("StrUtil-V7");
if(StrUtil.VersionToString(0x00000000FFFF0000UL, 4) != "0.0.65535.0")
throw new InvalidOperationException("StrUtil-V8");
if(StrUtil.VersionToString(0x0000000000000000UL, 4) != "0.0.0.0")
throw new InvalidOperationException("StrUtil-V9");
if(StrUtil.RtfEncodeChar('\u0000') != "\\u0?")
throw new InvalidOperationException("StrUtil-Rtf1");
@@ -994,22 +411,12 @@ namespace KeePassLib.Cryptography
if(short.MinValue.ToString(NumberFormatInfo.InvariantInfo) !=
"-32768")
throw new InvalidOperationException("StrUtil-Inv4");
if(!string.Equals("abcd", "aBcd", StrUtil.CaseIgnoreCmp))
throw new InvalidOperationException("StrUtil-Case1");
if(string.Equals(@"a<b", @"a>b", StrUtil.CaseIgnoreCmp))
throw new InvalidOperationException("StrUtil-Case2");
#endif
}
private static void TestUrlUtil()
{
#if DEBUG
#if !KeePassUAP
Debug.Assert(Uri.UriSchemeHttp.Equals("http", StrUtil.CaseIgnoreCmp));
Debug.Assert(Uri.UriSchemeHttps.Equals("https", StrUtil.CaseIgnoreCmp));
#endif
if(UrlUtil.GetHost(@"scheme://domain:port/path?query_string#fragment_id") !=
"domain")
throw new InvalidOperationException("UrlUtil-H1");

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -39,18 +39,18 @@ namespace KeePassLib.Interfaces
}
/// <summary>
/// The date/time when the object was last modified.
/// The date/time when the object was last accessed.
/// </summary>
DateTime LastModificationTime
DateTime LastAccessTime
{
get;
set;
}
/// <summary>
/// The date/time when the object was last accessed.
/// The date/time when the object was last modified.
/// </summary>
DateTime LastAccessTime
DateTime LastModificationTime
{
get;
set;
@@ -101,5 +101,19 @@ namespace KeePassLib.Interfaces
/// </summary>
/// <param name="bModified">Update last modification time.</param>
void Touch(bool bModified);
#region Set times lazily
// Passing xml datetime string to be parsed only on demand
void SetLazyLastModificationTime(string xmlDateTime);
void SetLazyCreationTime(string xmlDateTime);
void SetLazyLastAccessTime(string xmlDateTime);
void SetLazyExpiryTime(string xmlDateTime);
void SetLazyLocationChanged(string xmlDateTime);
#endregion
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

Binary file not shown.

View File

@@ -12,7 +12,7 @@
<AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile>
<AndroidResgenClass>Resource</AndroidResgenClass>
<AssemblyName>KeePassLib2Android</AssemblyName>
<TargetFrameworkVersion>v7.1</TargetFrameworkVersion>
<TargetFrameworkVersion>v6.0</TargetFrameworkVersion>
<AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk>
<NuGetPackageImportStamp>8482b288</NuGetPackageImportStamp>
</PropertyGroup>
@@ -55,21 +55,11 @@
<Reference Include="Mono.Android" />
<Reference Include="OpenTK-1.0" />
<Reference Include="Mono.Security" />
<Reference Include="Xamarin.Insights">
<HintPath>..\packages\Xamarin.Insights.1.11.3\lib\MonoAndroid10\Xamarin.Insights.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Collections\ProtectedBinarySet.cs" />
<Compile Include="Collections\VariantDictionary.cs" />
<Compile Include="Cryptography\Cipher\ChaCha20Cipher.cs" />
<Compile Include="Cryptography\Cipher\ChaCha20Engine.cs" />
<Compile Include="Cryptography\Cipher\CtrBlockCipher.cs" />
<Compile Include="Cryptography\CryptoUtil.cs" />
<Compile Include="Cryptography\Hash\Blake2b.cs" />
<Compile Include="Cryptography\KeyDerivation\AesKdf.cs" />
<Compile Include="Cryptography\KeyDerivation\Argon2Kdf.Core.cs" />
<Compile Include="Cryptography\KeyDerivation\Argon2Kdf.cs" />
<Compile Include="Cryptography\KeyDerivation\KdfEngine.cs" />
<Compile Include="Cryptography\KeyDerivation\KdfParameters.cs" />
<Compile Include="Cryptography\KeyDerivation\KdfPool.cs" />
<Compile Include="IDatabaseFormat.cs" />
<Compile Include="Kp2aLog.cs" />
<Compile Include="Resources\Resource.designer.cs" />
@@ -97,6 +87,7 @@
<Compile Include="Cryptography\PasswordGenerator\PwProfile.cs" />
<Compile Include="Cryptography\PopularPasswords.cs" />
<Compile Include="Cryptography\QualityEstimation.cs" />
<Compile Include="Cryptography\SelfTest.cs" />
<Compile Include="Cryptography\PasswordGenerator\PwGenerator.cs" />
<Compile Include="PwCustomIcon.cs" />
<Compile Include="PwDatabase.cs" />
@@ -133,13 +124,9 @@
<Compile Include="Serialization\FileLock.cs" />
<Compile Include="Serialization\FileTransactionEx.cs" />
<Compile Include="Serialization\HashedBlockStream.cs" />
<Compile Include="Serialization\HmacBlockStream.cs" />
<Compile Include="Serialization\IOConnection.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Serialization\IocProperties.cs" />
<Compile Include="Serialization\IocPropertyInfo.cs" />
<Compile Include="Serialization\IocPropertyInfoPool.cs" />
<Compile Include="Serialization\KdbxFile.cs" />
<Compile Include="Serialization\KdbxFile.Read.cs" />
<Compile Include="Serialization\KdbxFile.Read.Streamed.cs" />
@@ -147,6 +134,8 @@
<Compile Include="Serialization\IOConnectionInfo.cs" />
<Compile Include="Serialization\OldFormatException.cs" />
<Compile Include="Serialization\ProtoBuf\KdbpFile.cs" />
<Compile Include="Translation\KPControlCustomization.cs" />
<Compile Include="Translation\KPFormCustomization.cs" />
<Compile Include="Translation\KPStringTable.cs" />
<Compile Include="Translation\KPStringTableItem.cs" />
<Compile Include="Translation\KPTranslation.cs" />
@@ -155,7 +144,6 @@
<Compile Include="Utility\GfxUtil.cs" />
<Compile Include="Utility\MemUtil.cs" />
<Compile Include="Utility\MessageService.cs" />
<Compile Include="Utility\MonoWorkarounds.cs" />
<Compile Include="Utility\StrUtil.cs" />
<Compile Include="Utility\UrlUtil.cs" />
<Compile Include="Utility\TimeUtil.cs" />

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,16 +18,22 @@
*/
using System;
using System.Text;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.IO;
using System.Security.Cryptography;
#if KeePassRT
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Parameters;
#endif
using KeePassLib.Cryptography;
using KeePassLib.Cryptography.KeyDerivation;
using KeePassLib.Native;
using KeePassLib.Resources;
using KeePassLib.Security;
using KeePassLib.Utility;
using keepass2android;
namespace KeePassLib.Keys
{
@@ -103,6 +109,7 @@ namespace KeePassLib.Keys
return m_vUserKeys.Remove(pKey);
}
#if !KeePassRT
/// <summary>
/// Test whether the composite key contains a specific type of
/// user keys (password, key file, ...). If at least one user
@@ -118,15 +125,8 @@ namespace KeePassLib.Keys
foreach(IUserKey pKey in m_vUserKeys)
{
if(pKey == null) { Debug.Assert(false); continue; }
#if KeePassUAP
if(pKey.GetType() == tUserKeyType)
return true;
#else
if(tUserKeyType.IsInstanceOfType(pKey))
return true;
#endif
}
return false;
@@ -145,15 +145,8 @@ namespace KeePassLib.Keys
foreach(IUserKey pKey in m_vUserKeys)
{
if(pKey == null) { Debug.Assert(false); continue; }
#if KeePassUAP
if(pKey.GetType() == tUserKeyType)
return pKey;
#else
if(tUserKeyType.IsInstanceOfType(pKey))
return pKey;
#endif
}
return null;
@@ -163,6 +156,8 @@ namespace KeePassLib.Keys
{
return (T) GetUserKey(typeof (T));
}
#endif
/// <summary>
/// Creates the composite key from the supplied user key sources (password,
/// key file, user account, computer ID, etc.).
@@ -172,31 +167,21 @@ namespace KeePassLib.Keys
ValidateUserKeys();
// Concatenate user key data
List<byte[]> lData = new List<byte[]>();
int cbData = 0;
MemoryStream ms = new MemoryStream();
foreach(IUserKey pKey in m_vUserKeys)
{
ProtectedBinary b = pKey.KeyData;
if(b != null)
{
byte[] pbKeyData = b.ReadData();
lData.Add(pbKeyData);
cbData += pbKeyData.Length;
ms.Write(pbKeyData, 0, pbKeyData.Length);
MemUtil.ZeroByteArray(pbKeyData);
}
}
byte[] pbAllData = new byte[cbData];
int p = 0;
foreach(byte[] pbData in lData)
{
Array.Copy(pbData, 0, pbAllData, p, pbData.Length);
p += pbData.Length;
MemUtil.ZeroByteArray(pbData);
}
Debug.Assert(p == cbData);
byte[] pbHash = CryptoUtil.HashSha256(pbAllData);
MemUtil.ZeroByteArray(pbAllData);
SHA256Managed sha256 = new SHA256Managed();
byte[] pbHash = sha256.ComputeHash(ms.ToArray());
ms.Close();
return pbHash;
}
@@ -207,13 +192,21 @@ namespace KeePassLib.Keys
byte[] pbThis = CreateRawCompositeKey32();
byte[] pbOther = ckOther.CreateRawCompositeKey32();
bool bResult = MemUtil.ArraysEqual(pbThis, pbOther);
MemUtil.ZeroByteArray(pbOther);
MemUtil.ZeroByteArray(pbThis);
Array.Clear(pbOther, 0, pbOther.Length);
Array.Clear(pbThis, 0, pbThis.Length);
return bResult;
}
[Obsolete]
/// <summary>
/// Generate a 32-bit wide key out of the composite key.
/// </summary>
/// <param name="pbKeySeed32">Seed used in the key transformation
/// rounds. Must be a byte array containing exactly 32 bytes; must
/// not be null.</param>
/// <param name="uNumRounds">Number of key transformation rounds.</param>
/// <returns>Returns a protected binary object that contains the
/// resulting 32-bit wide key.</returns>
public ProtectedBinary GenerateKey32(byte[] pbKeySeed32, ulong uNumRounds)
{
Debug.Assert(pbKeySeed32 != null);
@@ -221,43 +214,18 @@ namespace KeePassLib.Keys
Debug.Assert(pbKeySeed32.Length == 32);
if(pbKeySeed32.Length != 32) throw new ArgumentException("pbKeySeed32");
AesKdf kdf = new AesKdf();
KdfParameters p = kdf.GetDefaultParameters();
p.SetUInt64(AesKdf.ParamRounds, uNumRounds);
p.SetByteArray(AesKdf.ParamSeed, pbKeySeed32);
return GenerateKey32(p);
}
/// <summary>
/// Generate a 32-byte (256-bit) key from the composite key.
/// </summary>
public ProtectedBinary GenerateKey32(KdfParameters p)
{
if(p == null) { Debug.Assert(false); throw new ArgumentNullException("p"); }
byte[] pbRaw32 = CreateRawCompositeKey32();
if((pbRaw32 == null) || (pbRaw32.Length != 32))
{ Debug.Assert(false); return null; }
KdfEngine kdf = KdfPool.Get(p.KdfUuid);
if(kdf == null) // CryptographicExceptions are translated to "file corrupted"
throw new Exception(KLRes.UnknownKdf + MessageService.NewParagraph +
KLRes.FileNewVerOrPlgReq + MessageService.NewParagraph +
"UUID: " + p.KdfUuid.ToHexString() + ".");
byte[] pbTrf32 = kdf.Transform(pbRaw32, p);
if(pbTrf32 == null) { Debug.Assert(false); return null; }
if(pbTrf32.Length != 32)
{
Debug.Assert(false);
pbTrf32 = CryptoUtil.HashSha256(pbTrf32);
}
byte[] pbTrf32 = TransformKey(pbRaw32, pbKeySeed32, uNumRounds);
if((pbTrf32 == null) || (pbTrf32.Length != 32))
{ Debug.Assert(false); return null; }
ProtectedBinary pbRet = new ProtectedBinary(true, pbTrf32);
MemUtil.ZeroByteArray(pbTrf32);
MemUtil.ZeroByteArray(pbRaw32);
return pbRet;
}
@@ -277,6 +245,192 @@ namespace KeePassLib.Keys
throw new InvalidOperationException();
}
}
/// <summary>
/// Transform the current key <c>uNumRounds</c> times.
/// </summary>
/// <param name="pbOriginalKey32">The original key which will be transformed.
/// This parameter won't be modified.</param>
/// <param name="pbKeySeed32">Seed used for key transformations. Must not
/// be <c>null</c>. This parameter won't be modified.</param>
/// <param name="uNumRounds">Transformation count.</param>
/// <returns>256-bit transformed key.</returns>
private static byte[] TransformKey(byte[] pbOriginalKey32, byte[] pbKeySeed32,
ulong uNumRounds)
{
Debug.Assert((pbOriginalKey32 != null) && (pbOriginalKey32.Length == 32));
if (pbOriginalKey32 == null)
throw new ArgumentNullException("pbOriginalKey32");
if (pbOriginalKey32.Length != 32)
throw new ArgumentException();
Debug.Assert((pbKeySeed32 != null) && (pbKeySeed32.Length == 32));
if (pbKeySeed32 == null)
throw new ArgumentNullException("pbKeySeed32");
if (pbKeySeed32.Length != 32)
throw new ArgumentException();
byte[] pbNewKey = new byte[32];
Array.Copy(pbOriginalKey32, pbNewKey, pbNewKey.Length);
// Try to use the native library first
Stopwatch sw = new Stopwatch();
sw.Start();
if (NativeLib.TransformKey256(pbNewKey, pbKeySeed32, uNumRounds))
{
sw.Stop();
Kp2aLog.Log("Native transform:" +sw.ElapsedMilliseconds+"ms");
return pbNewKey;
}
sw.Restart();
if(TransformKeyManaged(pbNewKey, pbKeySeed32, uNumRounds) == false)
return null;
sw.Stop();
Kp2aLog.Log("Managed transform:" +sw.ElapsedMilliseconds+"ms");
SHA256Managed sha256 = new SHA256Managed();
return sha256.ComputeHash(pbNewKey);
}
public static bool TransformKeyManaged(byte[] pbNewKey32, byte[] pbKeySeed32,
ulong uNumRounds)
{
#if KeePassRT
KeyParameter kp = new KeyParameter(pbKeySeed32);
AesEngine aes = new AesEngine();
aes.Init(true, kp);
for(ulong i = 0; i < uNumRounds; ++i)
{
aes.ProcessBlock(pbNewKey32, 0, pbNewKey32, 0);
aes.ProcessBlock(pbNewKey32, 16, pbNewKey32, 16);
}
#else
byte[] pbIV = new byte[16];
Array.Clear(pbIV, 0, pbIV.Length);
RijndaelManaged r = new RijndaelManaged();
if(r.BlockSize != 128) // AES block size
{
Debug.Assert(false);
r.BlockSize = 128;
}
r.IV = pbIV;
r.Mode = CipherMode.ECB;
r.KeySize = 256;
r.Key = pbKeySeed32;
ICryptoTransform iCrypt = r.CreateEncryptor();
// !iCrypt.CanReuseTransform -- doesn't work with Mono
if((iCrypt == null) || (iCrypt.InputBlockSize != 16) ||
(iCrypt.OutputBlockSize != 16))
{
Debug.Assert(false, "Invalid ICryptoTransform.");
Debug.Assert((iCrypt.InputBlockSize == 16), "Invalid input block size!");
Debug.Assert((iCrypt.OutputBlockSize == 16), "Invalid output block size!");
return false;
}
for(ulong i = 0; i < uNumRounds; ++i)
{
iCrypt.TransformBlock(pbNewKey32, 0, 16, pbNewKey32, 0);
iCrypt.TransformBlock(pbNewKey32, 16, 16, pbNewKey32, 16);
}
#endif
return true;
}
/// <summary>
/// Benchmark the <c>TransformKey</c> method. Within
/// <paramref name="uMilliseconds"/> ms, random keys will be transformed
/// and the number of performed transformations are returned.
/// </summary>
/// <param name="uMilliseconds">Test duration in ms.</param>
/// <param name="uStep">Stepping.
/// <paramref name="uStep" /> should be a prime number. For fast processors
/// (PCs) a value of <c>3001</c> is recommended, for slower processors (PocketPC)
/// a value of <c>401</c> is recommended.</param>
/// <returns>Number of transformations performed in the specified
/// amount of time. Maximum value is <c>uint.MaxValue</c>.</returns>
public static ulong TransformKeyBenchmark(uint uMilliseconds, ulong uStep)
{
ulong uRounds;
// Try native method
if(NativeLib.TransformKeyBenchmark256(uMilliseconds, out uRounds))
return uRounds;
byte[] pbKey = new byte[32];
byte[] pbNewKey = new byte[32];
for(int i = 0; i < pbKey.Length; ++i)
{
pbKey[i] = (byte)i;
pbNewKey[i] = (byte)i;
}
#if KeePassRT
KeyParameter kp = new KeyParameter(pbKey);
AesEngine aes = new AesEngine();
aes.Init(true, kp);
#else
byte[] pbIV = new byte[16];
Array.Clear(pbIV, 0, pbIV.Length);
RijndaelManaged r = new RijndaelManaged();
if(r.BlockSize != 128) // AES block size
{
Debug.Assert(false);
r.BlockSize = 128;
}
r.IV = pbIV;
r.Mode = CipherMode.ECB;
r.KeySize = 256;
r.Key = pbKey;
ICryptoTransform iCrypt = r.CreateEncryptor();
// !iCrypt.CanReuseTransform -- doesn't work with Mono
if((iCrypt == null) || (iCrypt.InputBlockSize != 16) ||
(iCrypt.OutputBlockSize != 16))
{
Debug.Assert(false, "Invalid ICryptoTransform.");
Debug.Assert(iCrypt.InputBlockSize == 16, "Invalid input block size!");
Debug.Assert(iCrypt.OutputBlockSize == 16, "Invalid output block size!");
return PwDefs.DefaultKeyEncryptionRounds;
}
#endif
uRounds = 0;
int tStart = Environment.TickCount;
while(true)
{
for(ulong j = 0; j < uStep; ++j)
{
#if KeePassRT
aes.ProcessBlock(pbNewKey, 0, pbNewKey, 0);
aes.ProcessBlock(pbNewKey, 16, pbNewKey, 16);
#else
iCrypt.TransformBlock(pbNewKey, 0, 16, pbNewKey, 0);
iCrypt.TransformBlock(pbNewKey, 16, 16, pbNewKey, 16);
#endif
}
uRounds += uStep;
if(uRounds < uStep) // Overflow check
{
uRounds = ulong.MaxValue;
break;
}
uint tElapsed = (uint)(Environment.TickCount - tStart);
if(tElapsed > uMilliseconds) break;
}
return uRounds;
}
}
public sealed class InvalidCompositeKeyException : Exception

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -19,11 +19,12 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.Diagnostics;
using System.Security.Cryptography;
using KeePassLib.Cryptography;
using KeePassLib.Security;
using KeePassLib.Utility;
namespace KeePassLib.Keys
{
@@ -54,7 +55,8 @@ namespace KeePassLib.Keys
if(bPerformHash)
{
byte[] pbRaw = CryptoUtil.HashSha256(pbKeyData);
SHA256Managed sha256 = new SHA256Managed();
byte[] pbRaw = sha256.ComputeHash(pbKeyData);
m_pbKey = new ProtectedBinary(true, pbRaw);
}
else m_pbKey = new ProtectedBinary(true, pbKeyData);

View File

@@ -1,6 +1,8 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,15 +20,12 @@
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Security;
using System.Text;
using System.IO;
using System.Xml;
#if !KeePassUAP
using System.Security;
using System.Security.Cryptography;
#endif
using System.Diagnostics;
using KeePassLib.Cryptography;
using KeePassLib.Resources;
@@ -104,12 +103,12 @@ namespace KeePassLib.Keys
if (pbFileData == null) throw new Java.IO.FileNotFoundException();
m_pbFileData = new ProtectedBinary(true, pbFileData);
if(bThrowIfDbFile && (pbFileData.Length >= 8))
if (bThrowIfDbFile && (pbFileData.Length >= 8))
{
uint uSig1 = MemUtil.BytesToUInt32(MemUtil.Mid(pbFileData, 0, 4));
uint uSig2 = MemUtil.BytesToUInt32(MemUtil.Mid(pbFileData, 4, 4));
if(((uSig1 == KdbxFile.FileSignature1) &&
if (((uSig1 == KdbxFile.FileSignature1) &&
(uSig2 == KdbxFile.FileSignature2)) ||
((uSig1 == KdbxFile.FileSignaturePreRelease1) &&
(uSig2 == KdbxFile.FileSignaturePreRelease2)) ||
@@ -123,9 +122,9 @@ namespace KeePassLib.Keys
}
byte[] pbKey = LoadXmlKeyFile(pbFileData);
if(pbKey == null) pbKey = LoadKeyFile(pbFileData);
if (pbKey == null) pbKey = LoadKeyFile(pbFileData);
if(pbKey == null) throw new InvalidOperationException();
if (pbKey == null) throw new InvalidOperationException();
m_ioc = iocKeyFile;
m_pbKeyData = new ProtectedBinary(true, pbKey);
@@ -138,13 +137,13 @@ namespace KeePassLib.Keys
byte[] pbFileData = IOConnection.ReadFile(iocFile);
Construct(pbFileData, iocFile, bThrowIfDbFile);
}
// public void Clear()
// {
// m_strPath = string.Empty;
// m_pbKeyData = null;
// }
private static byte[] LoadKeyFile(byte[] pbFileData)
{
if(pbFileData == null) { Debug.Assert(false); return null; }
@@ -156,7 +155,10 @@ namespace KeePassLib.Keys
else if(iLength == 64) pbKey = LoadHexKey32(pbFileData);
if(pbKey == null)
pbKey = CryptoUtil.HashSha256(pbFileData);
{
SHA256Managed sha256 = new SHA256Managed();
pbKey = sha256.ComputeHash(pbFileData);
}
return pbKey;
}
@@ -176,15 +178,12 @@ namespace KeePassLib.Keys
try
{
if(!StrUtil.IsHexString(pbFileData, true)) return null;
string strHex = StrUtil.Utf8.GetString(pbFileData, 0, 64);
if(!StrUtil.IsHexString(strHex, true)) return null;
string strHex = StrUtil.Utf8.GetString(pbFileData);
byte[] pbKey = MemUtil.HexStringToByteArray(strHex);
if((pbKey == null) || (pbKey.Length != 32))
{
Debug.Assert(false);
return null;
}
return pbKey;
}
@@ -212,13 +211,13 @@ namespace KeePassLib.Keys
pbFinalKey32 = pbKey32;
else
{
using(MemoryStream ms = new MemoryStream())
{
MemUtil.Write(ms, pbAdditionalEntropy);
MemUtil.Write(ms, pbKey32);
MemoryStream ms = new MemoryStream();
ms.Write(pbAdditionalEntropy, 0, pbAdditionalEntropy.Length);
ms.Write(pbKey32, 0, 32);
pbFinalKey32 = CryptoUtil.HashSha256(ms.ToArray());
}
SHA256Managed sha256 = new SHA256Managed();
pbFinalKey32 = sha256.ComputeHash(ms.ToArray());
ms.Close();
}
CreateXmlKeyFile(strFilePath, pbFinalKey32);
@@ -254,7 +253,7 @@ namespace KeePassLib.Keys
try
{
XmlDocument doc = new XmlDocument() { XmlResolver = null };
XmlDocument doc = new XmlDocument();
doc.Load(ms);
XmlElement el = doc.DocumentElement;
@@ -293,15 +292,7 @@ namespace KeePassLib.Keys
IOConnectionInfo ioc = IOConnectionInfo.FromPath(strFile);
Stream sOut = IOConnection.OpenWrite(ioc);
#if KeePassUAP
XmlWriterSettings xws = new XmlWriterSettings();
xws.Encoding = StrUtil.Utf8;
xws.Indent = false;
XmlWriter xtw = XmlWriter.Create(sOut, xws);
#else
XmlTextWriter xtw = new XmlTextWriter(sOut, StrUtil.Utf8);
#endif
xtw.WriteStartDocument();
xtw.WriteWhitespace("\r\n");
@@ -343,6 +334,6 @@ namespace KeePassLib.Keys
public void ResetIoc(IOConnectionInfo newIoc)
{
m_ioc = newIoc;
}
}
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -18,10 +18,10 @@
*/
using System;
using System.Diagnostics;
using System.Text;
using System.Diagnostics;
using System.Security.Cryptography;
using KeePassLib.Cryptography;
using KeePassLib.Security;
using KeePassLib.Utility;
@@ -68,11 +68,8 @@ namespace KeePassLib.Keys
Debug.Assert(pbPasswordUtf8 != null);
if(pbPasswordUtf8 == null) throw new ArgumentNullException("pbPasswordUtf8");
#if (DEBUG && !KeePassLibSD)
Debug.Assert(ValidatePassword(pbPasswordUtf8));
#endif
byte[] pbRaw = CryptoUtil.HashSha256(pbPasswordUtf8);
SHA256Managed sha256 = new SHA256Managed();
byte[] pbRaw = sha256.ComputeHash(pbPasswordUtf8);
m_psPassword = new ProtectedString(true, pbPasswordUtf8);
m_pbKeyData = new ProtectedBinary(true, pbRaw);
@@ -83,19 +80,5 @@ namespace KeePassLib.Keys
// m_psPassword = null;
// m_pbKeyData = null;
// }
#if (DEBUG && !KeePassLibSD)
private static bool ValidatePassword(byte[] pb)
{
try
{
string str = StrUtil.Utf8.GetString(pb);
return str.IsNormalized(NormalizationForm.FormC);
}
catch(Exception) { Debug.Assert(false); }
return false;
}
#endif
}
}

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2016 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
Modified to be used with Mono for Android. Changes Copyright (C) 2013 Philipp Crocoll
@@ -20,13 +20,9 @@
*/
using System;
using System.Diagnostics;
using System.IO;
using System.Security;
#if !KeePassUAP
using System.Security.Cryptography;
#endif
using System.IO;
using KeePassLib.Cryptography;
using KeePassLib.Resources;
@@ -85,7 +81,7 @@ namespace KeePassLib.Keys
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
strUserDir += PwDefs.ShortProductName;
if (bCreate && !Directory.Exists(strUserDir))
if(bCreate && !Directory.Exists(strUserDir))
Directory.CreateDirectory(strUserDir);
strUserDir = UrlUtil.EnsureTerminatingSeparator(strUserDir, false);
@@ -101,9 +97,9 @@ namespace KeePassLib.Keys
{
throw new NotSupportedException("DataProtection not supported on MonoForAndroid!");
}
catch (Exception exLoad)
catch(Exception exLoad)
{
if (bShowWarning) MessageService.ShowWarning(exLoad);
if(bShowWarning) MessageService.ShowWarning(exLoad);
pbKey = null;
}
@@ -121,7 +117,7 @@ namespace KeePassLib.Keys
{
throw new NotSupportedException("DataProtection not supported on MonoForAndroid!");
}
catch (Exception) { pbKey = null; }
catch(Exception) { pbKey = null; }
#endif
return pbKey;

View File

@@ -1,6 +1,6 @@
/*
KeePass Password Safe - The Open-Source Password Manager
Copyright (C) 2003-2017 Dominik Reichl <dominik.reichl@t-online.de>
Copyright (C) 2003-2013 Dominik Reichl <dominik.reichl@t-online.de>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by

Some files were not shown because too many files have changed in this diff Show More