This repository has been archived by the owner on Nov 2, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
-WARNING: Major Breaking Change! All App Settings now default as Loca…
…l, with a boolean Property to make them Roam. This might cause issues if you don't realise it and invert it if set (It use to be all properties roam unless IsLocal = true). -Removed GetSettingsContainer from Helpers, getting the RoamingSettingsContainer automatically returns Local Settings if not supported. -You can now find out the Current Services Platform by checking AppServices.ServicePlatform, and UI Platform with AppServices.UI.UIPlatform. -Default Creation Collision options can now be changed with IOBindings.DefaultFileCreationCollision and IOBindings.DefaultFolderCreationCollision. -Created IPathResolver as a way for different Layers to check if the provided path from IOBindings.GetFile and IOBindings.GetFolder returns a Valid StorageItem from their service. This is to produce SMBFileContainers from SMB Paths, if a path string is provided. This will also be used to determine Android SAF Files and Folders from a Path. -Renamed CreateContainer to GetContainer for ISettingsContainer as it will return existing containers. -Moved Picker Functions out of IOBindings into new Abstract FileSystemPickers Class, as well as FutureAccess Methods into IFutureAccessManager. This reduces the length of the class for Platforms that don't support picking or Future Access. It also makes checking support easier. -Removed ICredentialManager Update Function, use Store to get back the Platform Credential Container, which will self update. -CredentialContainers now have platform specific implementations to handle automatic value updating. -Added more Abstractions to IOBindings, Local/RoamingSettings are now properties instead of methods, renamed OpenFile/Folder to OpenFile/FolderForDisplay as it is more understandable. It is now easier to implement IOBindings due to these changes. -Added RequestTextFromUserAsync method, a way to request text from the user in a Modal Dialog. -SMBFile/FolderContainers now use SMB Paths instead of UNC Paths as the path property. -To use the SMB Extension, you now need to call SMBService.Register(). -Added Type Checking on the UWPSettingsContainer, so that exception don't occur if the value is the wrong type. -UWP File/Folder Pickers and PromptUser methods are now Background Thread safe, as they will automatically go on the UI thread to work. -Fixed Android Dialog prompts not working from background threads. -AndroidSAFFile/Folders now display their paths correctly. -AndroidSettingsContainer now works properly, creating Settings Containers now produces the Preference Store on the Device, fetching All Subcontainers also works now, GetValue now has Type Safety. -Created AndroidCredentialManager and AndroidCredentialContainer, Stores credentials in a hidden SettingsContainer, using Encryption. You can replace the IKeyGenerator in AndroidAppSettings to provide a stronger, more secure Credential Encryption. -Created AndroidFutureAccessManager, Grants permissions and redeemable token. -Created TestPageGenerators, a cross platform way to generate Test Buttons, and Result Properties quickly. -Converted most Test Models to TestPages, created Settings and Credential Manager Test Pages.
- Loading branch information
1 parent
1b552ee
commit 642a259
Showing
109 changed files
with
2,685 additions
and
1,125 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,215 @@ | ||
using System; | ||
using PlatformBindings.Models.Settings; | ||
using Javax.Crypto; | ||
using Java.Security; | ||
using Javax.Crypto.Spec; | ||
using System.Text; | ||
using System.Runtime.InteropServices; | ||
using System.Security; | ||
using Java.IO; | ||
|
||
namespace PlatformBindings.Models | ||
{ | ||
internal class AndroidCredentialContainer : CredentialContainer | ||
{ | ||
public AndroidCredentialContainer(ISettingsContainer Container, CredentialContainer Credentials) : this() | ||
{ | ||
this.Container = Container; | ||
var newheader = $"{Credentials.ResourceName}^R^{Credentials.Username}"; | ||
EncryptedHeader = Encrypt(newheader, writer); | ||
SetHeaderData(newheader); | ||
|
||
Password = Credentials.Password; | ||
} | ||
|
||
public AndroidCredentialContainer(ISettingsContainer Container, string Header) : this() | ||
{ | ||
this.Container = Container; | ||
EncryptedHeader = Header; | ||
try | ||
{ | ||
var decryptedHeader = Decrypt(Header); | ||
SetHeaderData(decryptedHeader); | ||
} | ||
catch | ||
{ | ||
Container.RemoveKey(Header); | ||
HeaderData = new string[] { DecryptionError, DecryptionError }; | ||
} | ||
} | ||
|
||
private void SetHeaderData(string DecryptedHeader) | ||
{ | ||
HeaderData = DecryptedHeader.Split(new string[] { "^R^" }, StringSplitOptions.None); | ||
} | ||
|
||
public override string ResourceName { get => HeaderData[0]; } | ||
public override string Username { get => HeaderData[1]; } | ||
|
||
public override string Password | ||
{ | ||
get | ||
{ | ||
try | ||
{ | ||
var encryptedVal = Container.GetValue<string>(EncryptedHeader); | ||
return Decrypt(encryptedVal); | ||
} | ||
catch { return null; } | ||
} | ||
set | ||
{ | ||
var encryptedVal = Encrypt(value, writer); | ||
Container.SetValue(EncryptedHeader, encryptedVal); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Decrypted HeaderData | ||
/// </summary> | ||
private string[] HeaderData { get; set; } | ||
|
||
internal string EncryptedHeader { get; } | ||
internal ISettingsContainer Container { get; } | ||
|
||
/* | ||
Copyright (C) 2012 Sveinung Kval Bakken, [email protected] | ||
Permission is hereby granted, free of charge, to any person obtaining | ||
a copy of this software and associated documentation files (the | ||
"Software"), to deal in the Software without restriction, including | ||
without limitation the rights to use, copy, modify, merge, publish, | ||
distribute, sublicense, and/or sell copies of the Software, and to | ||
permit persons to whom the Software is furnished to do so, subject to | ||
the following conditions: | ||
The above copyright notice and this permission notice shall be | ||
included in all copies or substantial portions of the Software. | ||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | ||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE | ||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION | ||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION | ||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
*/ | ||
// Converted to C# for PlatformBindings-Android. | ||
#region Encryption | ||
|
||
private AndroidCredentialContainer() | ||
{ | ||
try | ||
{ | ||
writer = Cipher.GetInstance(TRANSFORMATION); | ||
reader = Cipher.GetInstance(TRANSFORMATION); | ||
Encoding = Encoding.GetEncoding(CHARSET); | ||
|
||
using (var key = AndroidAppServices.KeyGenerator.GetSecureKey()) | ||
{ | ||
InitCiphers(key); | ||
} | ||
} | ||
catch (GeneralSecurityException e) | ||
{ | ||
throw new SecurityException(e.Message); | ||
} | ||
catch (UnsupportedEncodingException e) | ||
{ | ||
throw new SecurityException(e.Message); | ||
} | ||
} | ||
|
||
private readonly string TRANSFORMATION = "AES/CBC/PKCS5Padding"; | ||
private readonly string SECRET_KEY_HASH_TRANSFORMATION = "SHA-256"; | ||
private readonly string CHARSET = "UTF-8"; | ||
public static readonly string DecryptionError = "ERR_DECRYPT"; | ||
|
||
private Encoding Encoding; | ||
private Cipher writer; | ||
private Cipher reader; | ||
|
||
protected void InitCiphers(SecureString secureKey) | ||
{ | ||
var bstr = Marshal.SecureStringToBSTR(secureKey); | ||
var key = Marshal.PtrToStringBSTR(bstr); | ||
|
||
IvParameterSpec ivSpec = GetIv(); | ||
SecretKeySpec secretKey = GetSecretKey(key); | ||
|
||
writer.Init(CipherMode.EncryptMode, secretKey, ivSpec); | ||
reader.Init(CipherMode.DecryptMode, secretKey, ivSpec); | ||
} | ||
|
||
protected IvParameterSpec GetIv() | ||
{ | ||
byte[] iv = new byte[writer.BlockSize]; | ||
Array.Copy(Encoding.GetBytes("fldsjfodasjifudslfjdsaofshaufihadsf"), 0, iv, 0, writer.BlockSize); | ||
return new IvParameterSpec(iv); | ||
} | ||
|
||
protected SecretKeySpec GetSecretKey(string key) | ||
{ | ||
byte[] keyBytes = CreateKeyBytes(key); | ||
return new SecretKeySpec(keyBytes, TRANSFORMATION); | ||
} | ||
|
||
protected byte[] CreateKeyBytes(string key) | ||
{ | ||
MessageDigest md = MessageDigest.GetInstance(SECRET_KEY_HASH_TRANSFORMATION); | ||
md.Reset(); | ||
var keyBytes = md.Digest(Encoding.GetBytes(key)); | ||
return keyBytes; | ||
} | ||
|
||
protected String Encrypt(string value, Cipher writer) | ||
{ | ||
byte[] secureValue; | ||
try | ||
{ | ||
secureValue = Convert(writer, Encoding.GetEncoding(CHARSET).GetBytes(value)); | ||
} | ||
catch (UnsupportedEncodingException e) | ||
{ | ||
throw new SecurityException(e.Message); | ||
} | ||
var secureValueEncoded = System.Convert.ToBase64String(secureValue); | ||
return secureValueEncoded; | ||
} | ||
|
||
protected string Decrypt(string securedEncodedValue) | ||
{ | ||
byte[] securedValue = System.Convert.FromBase64String(securedEncodedValue); | ||
byte[] value = Convert(reader, securedValue); | ||
try | ||
{ | ||
return Encoding.GetString(value); | ||
} | ||
catch (UnsupportedEncodingException e) | ||
{ | ||
throw new SecurityException(e.Message); | ||
} | ||
} | ||
|
||
private static byte[] Convert(Cipher cipher, byte[] bs) | ||
{ | ||
try | ||
{ | ||
return cipher.DoFinal(bs); | ||
} | ||
catch (Exception e) | ||
{ | ||
throw new SecurityException(e.Message); | ||
} | ||
} | ||
|
||
~AndroidCredentialContainer() | ||
{ | ||
writer?.Dispose(); | ||
reader?.Dispose(); | ||
} | ||
|
||
#endregion Encryption | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
using Android.App; | ||
using PlatformBindings.Common; | ||
using System.Security; | ||
|
||
namespace PlatformBindings.Models.Encryption | ||
{ | ||
public class DefaultKeyGenerator : IKeyGenerator | ||
{ | ||
public SecureString GetSecureKey() | ||
{ | ||
var raw = Application.Context.PackageName + Application.Context.ApplicationInfo.Uid.ToString(); | ||
var data = PlatformBindingHelpers.ConvertToBase64(raw); | ||
|
||
var secure = new SecureString(); | ||
foreach (var c in data) | ||
{ | ||
secure.AppendChar(c); | ||
} | ||
return secure; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
using System.Security; | ||
|
||
namespace PlatformBindings.Models.Encryption | ||
{ | ||
/// <summary> | ||
/// Generates a Key to Encrypt/Decrypt the Credential Data, this key must be the same during Encryption/Decryption otherwise you will not be able to read any of the credentials. | ||
/// </summary> | ||
public interface IKeyGenerator | ||
{ | ||
SecureString GetSecureKey(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace PlatformBindings.Models.FileSystem | ||
{ | ||
public interface IAndroidSAFContainer | ||
{ | ||
Android.Net.Uri Uri { get; } | ||
} | ||
} |
Oops, something went wrong.