This repository has been archived by the owner on Sep 19, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
11 changed files
with
526 additions
and
118 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,46 @@ | ||
namespace DataManager.Classes | ||
{ | ||
public class OnewheelApiCredentials | ||
{ | ||
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\ | ||
#region --Attributes-- | ||
public string DEVICE_NAME; | ||
public string apiKey; | ||
public string apiToken; | ||
|
||
#endregion | ||
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\ | ||
#region --Constructors-- | ||
public OnewheelApiCredentials(string deviceName) | ||
{ | ||
DEVICE_NAME = deviceName; | ||
} | ||
|
||
#endregion | ||
//--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ | ||
#region --Set-, Get- Methods-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ | ||
#region --Misc Methods (Public)-- | ||
|
||
|
||
#endregion | ||
|
||
#region --Misc Methods (Private)-- | ||
|
||
|
||
#endregion | ||
|
||
#region --Misc Methods (Protected)-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Events:---------------------------------------------------------------------\\ | ||
#region --Events-- | ||
|
||
|
||
#endregion | ||
} | ||
} |
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,87 @@ | ||
using Logging; | ||
using System; | ||
using System.Collections.Generic; | ||
using Windows.Security.Credentials; | ||
|
||
namespace DataManager.Classes | ||
{ | ||
public static class Vault | ||
{ | ||
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\ | ||
#region --Attributes-- | ||
private static readonly PasswordVault PASSWORD_VAULT = new PasswordVault(); | ||
|
||
#endregion | ||
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\ | ||
#region --Constructors-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ | ||
#region --Set-, Get- Methods-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ | ||
#region --Misc Methods (Public)-- | ||
public static bool LoadCredentials(OnewheelApiCredentials credentials) | ||
{ | ||
try | ||
{ | ||
IReadOnlyList<PasswordCredential> pwCredentials = PASSWORD_VAULT.FindAllByResource(credentials.DEVICE_NAME); | ||
if (pwCredentials.Count >= 1) | ||
{ | ||
pwCredentials[0].RetrievePassword(); | ||
credentials.apiKey = pwCredentials[0].UserName; | ||
credentials.apiToken = pwCredentials[0].Password; | ||
return !string.IsNullOrEmpty(credentials.apiKey) && !string.IsNullOrEmpty(credentials.apiToken); | ||
} | ||
} | ||
catch (Exception e) | ||
{ | ||
Logger.Error("Failed to retrieve credentials for: " + credentials.DEVICE_NAME, e); | ||
} | ||
return false; | ||
} | ||
|
||
public static void StoreCredentials(OnewheelApiCredentials credentials) | ||
{ | ||
// Delete existing password vaults: | ||
DeleteAllVaults(); | ||
|
||
// Store the new password: | ||
if (!string.IsNullOrEmpty(credentials.apiToken)) | ||
{ | ||
PASSWORD_VAULT.Add(new PasswordCredential(credentials.DEVICE_NAME, credentials.apiKey, credentials.apiToken)); | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Deletes all vaults. | ||
/// </summary> | ||
public static void DeleteAllVaults() | ||
{ | ||
foreach (PasswordCredential item in PASSWORD_VAULT.RetrieveAll()) | ||
{ | ||
PASSWORD_VAULT.Remove(item); | ||
} | ||
} | ||
|
||
#endregion | ||
|
||
#region --Misc Methods (Private)-- | ||
|
||
|
||
#endregion | ||
|
||
#region --Misc Methods (Protected)-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Events:---------------------------------------------------------------------\\ | ||
#region --Events-- | ||
|
||
|
||
#endregion | ||
} | ||
} |
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
54 changes: 54 additions & 0 deletions
54
OnewheelBluetooth/Classes/UnlockHelper/AbstractOnewheelUnlock.cs
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,54 @@ | ||
using System.Collections.Generic; | ||
using System.Threading.Tasks; | ||
|
||
namespace OnewheelBluetooth.Classes.UnlockHelper | ||
{ | ||
public abstract class AbstractOnewheelUnlock | ||
{ | ||
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\ | ||
#region --Attributes-- | ||
/// <summary> | ||
/// The first three bytes of a challenge message from the Onewheel. | ||
/// </summary> | ||
protected readonly byte[] CHALLENGE_FIRST_BYTES = new byte[] { 0x43, 0x52, 0x58 }; | ||
|
||
#endregion | ||
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\ | ||
#region --Constructors-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ | ||
#region --Set-, Get- Methods-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ | ||
#region --Misc Methods (Public)-- | ||
public abstract Task CalcAndSendResponseAsync(List<byte> serialReadCache, OnewheelBoard onewheel); | ||
|
||
public bool CheckIfFirstChallengeBytesMatch(List<byte> serialReadCache) | ||
{ | ||
return serialReadCache.Count >= 3 | ||
&& serialReadCache[0] == CHALLENGE_FIRST_BYTES[0] | ||
&& serialReadCache[1] == CHALLENGE_FIRST_BYTES[1] | ||
&& serialReadCache[2] == CHALLENGE_FIRST_BYTES[2]; | ||
} | ||
#endregion | ||
|
||
#region --Misc Methods (Private)-- | ||
|
||
|
||
#endregion | ||
|
||
#region --Misc Methods (Protected)-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Events:---------------------------------------------------------------------\\ | ||
#region --Events-- | ||
|
||
|
||
#endregion | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
OnewheelBluetooth/Classes/UnlockHelper/DefaultGeminiUnlock.cs
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,89 @@ | ||
using Logging; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Security.Cryptography; | ||
using System.Threading.Tasks; | ||
|
||
namespace OnewheelBluetooth.Classes.UnlockHelper | ||
{ | ||
public class DefaultGeminiUnlock : AbstractOnewheelUnlock | ||
{ | ||
//--------------------------------------------------------Attributes:-----------------------------------------------------------------\\ | ||
#region --Attributes-- | ||
/// <summary> | ||
/// The android challenge response password. | ||
/// Source: https://github.com/ponewheel/android-ponewheel/issues/86#issuecomment-440809066 | ||
/// </summary> | ||
private readonly byte[] CHALLENGE_RESPONSE_PASSWORD = new byte[] { 0xD9, 0x25, 0x5F, 0x0F, 0x23, 0x35, 0x4E, 0x19, 0xBA, 0x73, 0x9C, 0xCD, 0xC4, 0xA9, 0x17, 0x65 }; | ||
|
||
#endregion | ||
//--------------------------------------------------------Constructor:----------------------------------------------------------------\\ | ||
#region --Constructors-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Set-, Get- Methods:---------------------------------------------------------\\ | ||
#region --Set-, Get- Methods-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Misc Methods:---------------------------------------------------------------\\ | ||
#region --Misc Methods (Public)-- | ||
public override async Task CalcAndSendResponseAsync(List<byte> serialReadCache, OnewheelBoard onewheel) | ||
{ | ||
byte[] challenge = serialReadCache.ToArray(); | ||
byte[] response = CalcResponse(challenge); | ||
|
||
await onewheel.WriteBytesAsync(OnewheelCharacteristicsCache.CHARACTERISTIC_UART_SERIAL_WRITE, response); | ||
Logger.Info("Sent Gemini unlock response to Onewheel challenge."); | ||
} | ||
|
||
/// <summary> | ||
/// Calculates the response for the given challenge. | ||
/// Source: https://github.com/ponewheel/android-ponewheel/issues/86#issuecomment-440809066 | ||
/// </summary> | ||
/// <param name="challenge">The challenge send by the Onewheel.</param> | ||
/// <returns>The response for the given challenge.</returns> | ||
public byte[] CalcResponse(byte[] challenge) | ||
{ | ||
List<byte> response = new List<byte>(20); | ||
response.AddRange(CHALLENGE_FIRST_BYTES); | ||
|
||
byte[] md5In = new byte[16 + CHALLENGE_RESPONSE_PASSWORD.Length]; | ||
Buffer.BlockCopy(challenge, 3, md5In, 0, 16); | ||
Buffer.BlockCopy(CHALLENGE_RESPONSE_PASSWORD, 0, md5In, 16, CHALLENGE_RESPONSE_PASSWORD.Length); | ||
|
||
MD5 md5 = MD5.Create(); | ||
byte[] md5Out = md5.ComputeHash(md5In); | ||
response.AddRange(md5Out); | ||
|
||
// Calculate the validation byte: | ||
byte checkByte = 0; | ||
for (int i = 0; i < response.Count; i++) | ||
{ | ||
checkByte = ((byte)(response[i] ^ checkByte)); | ||
} | ||
response.Add(checkByte); | ||
|
||
return response.ToArray(); | ||
} | ||
|
||
#endregion | ||
|
||
#region --Misc Methods (Private)-- | ||
|
||
|
||
#endregion | ||
|
||
#region --Misc Methods (Protected)-- | ||
|
||
|
||
#endregion | ||
//--------------------------------------------------------Events:---------------------------------------------------------------------\\ | ||
#region --Events-- | ||
|
||
|
||
|
||
#endregion | ||
} | ||
} |
Oops, something went wrong.