Skip to content

Commit

Permalink
Working version with both xml file and user entered challenge
Browse files Browse the repository at this point in the history
  • Loading branch information
whinis committed Oct 28, 2020
1 parent 523e96d commit fd77cf9
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 55 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,7 @@ $RECYCLE.BIN/
/KeeChallenge/src/PLGXUtil.pdb
/PlgxTemp
/KeeChallenge.plgx
/KeeChallenge/KeeChallenge/src
/KeeChallenge/src/PLGXUtil.vshost.exe.manifest
/KeeChallenge/src/PLGXUtil.vshost.exe.config
/KeeChallenge/src/PLGXUtil.vshost.exe
6 changes: 5 additions & 1 deletion KeeChallenge/src/ChallengeEntry.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,15 @@ namespace KeeChallenge
public partial class ChallengeEntry : Form
{
private byte[] m_response;
public bool newKey
{
set { promptLabel.Text = "Reenter Challenge"; }
}

public byte[] Response
{
get { return m_response; }
private set { m_response = value; }
set { m_response = value; }
}

public ChallengeEntry(KeeChallengeProv parent)
Expand Down
118 changes: 66 additions & 52 deletions KeeChallenge/src/KeeChallenge.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public bool UserChallenge

public KeeChallengeProv()
{
YubikeySlot = YubiSlot.AUTO;
YubikeySlot = YubiSlot.SLOT2;
}

private IOConnectionInfo mInfo;
Expand Down Expand Up @@ -140,14 +140,12 @@ public byte[] GenerateResponse(byte[] challenge, byte[] key)

private bool EncryptAndSave(byte[] secret)
{

//generate a random challenge for use next time
byte[] challenge = GenerateChallenge();

//generate the expected HMAC-SHA1 response for the challenge based on the secret
byte[] resp = GenerateResponse(challenge, secret);


//use the response to encrypt the secret
SHA256 sha = SHA256Managed.Create();
byte[] key = sha.ComputeHash(resp); // get a 256 bit key from the 160 bit hmac response
Expand All @@ -161,13 +159,11 @@ private bool EncryptAndSave(byte[] secret)
byte[] iv = aes.IV;

byte[] encrypted;

ICryptoTransform enc = aes.CreateEncryptor();
using (MemoryStream msEncrypt = new MemoryStream())
{
using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, enc, CryptoStreamMode.Write))
{

csEncrypt.Write(secret, 0, secret.Length);
csEncrypt.FlushFinalBlock();

Expand Down Expand Up @@ -209,9 +205,9 @@ private bool EncryptAndSave(byte[] secret)

xml.WriteEndElement();
xml.WriteEndDocument();
xml.Close();

ft.CommitWrite();
xml.Close();
ft.CommitWrite();
}
catch (Exception)
{
Expand Down Expand Up @@ -239,7 +235,6 @@ private static bool DecryptSecret(byte[] encryptedSecret, byte[] yubiResp, byte[
aes.Padding = PaddingMode.PKCS7;

secret = new byte[keyLenBytes];

ICryptoTransform dec = aes.CreateDecryptor();
using (MemoryStream msDecrypt = new MemoryStream(encryptedSecret))
{
Expand All @@ -262,20 +257,22 @@ private static bool DecryptSecret(byte[] encryptedSecret, byte[] yubiResp, byte[
return false;
}
}

//return the secret
sha.Clear();
aes.Clear();
return true;
}

private bool ReadEncryptedSecret(out byte[] encryptedSecret, out byte[] challenge, out byte[] iv, out byte[] verification)
{
encryptedSecret = null;
iv = null;
challenge = null;
verification = null;

LT64 = false; //default to false if not found

XmlReader xml = null;
Stream s = null;
try
Expand All @@ -287,7 +284,7 @@ private bool ReadEncryptedSecret(out byte[] encryptedSecret, out byte[] challeng
XmlReaderSettings settings = new XmlReaderSettings();
settings.CloseInput = true;
xml = XmlReader.Create(s, settings);

while (xml.Read())
{
if (xml.IsStartElement())
Expand Down Expand Up @@ -338,66 +335,89 @@ private bool ReadEncryptedSecret(out byte[] encryptedSecret, out byte[] challeng

private byte[] Create(KeyProviderQueryContext ctx)
{

byte[] challenge = GenerateChallenge();
byte[] resp = new byte[YubiWrapper.yubiRespLen];

KeyEntrySelection keySelectionForm = new KeyEntrySelection(this);

UserChallenge = keySelectionForm.ShowDialog() == System.Windows.Forms.DialogResult.OK;

if (UserChallenge)
{
String xmlFilePath = mInfo.Path;
String xmlAddtion = "";
if (File.Exists(xmlFilePath))
{ //if XML does exists rename it so its not detected anymore
int i = 0;
xmlFilePath = xmlFilePath + ".bak";
while (File.Exists(xmlFilePath + xmlAddtion))
{
xmlAddtion = i.ToString();
i++;
}
File.Move(mInfo.Path, xmlFilePath + xmlAddtion);
}

byte[] resp = new byte[YubiWrapper.yubiRespLen];

ChallengeEntry challengeForm = new ChallengeEntry(this);

if (challengeForm.ShowDialog() != System.Windows.Forms.DialogResult.OK) return null;

challenge = new byte[64];
byte[] challenge = new byte[64];
byte[] challengeText = new byte[256];
byte[] challengeTextRepeat = new byte[256];
challengeForm.Response.CopyTo(challengeText, 0);

Array.Clear(challengeForm.Response, 0, 256); //clear our memory to prevent snooping later

challengeForm = new ChallengeEntry(this);
challengeForm.newKey = true;

if (challengeForm.ShowDialog() != System.Windows.Forms.DialogResult.OK) return null;
challengeForm.Response.CopyTo(challengeTextRepeat, 0);

Array.Clear(challengeForm.Response, 0, 256); //clear our memory to prevent snooping later
if (!challengeTextRepeat.SequenceEqual(challengeText))
{
MessageService.ShowWarning("Error: Challenges did not match");
return null;
}
Array.Clear(challengeTextRepeat, 0, 256);

SHA512 chall512 = SHA512Managed.Create();
challenge = chall512.ComputeHash(challengeText);

Array.Clear(challengeText, 0, 256); //clear our memory to prevent snooping later

}
KeyEntry entryForm = new KeyEntry(this, challenge);

KeyEntry entryForm = new KeyEntry(this, challenge);

if (entryForm.ShowDialog() != System.Windows.Forms.DialogResult.OK) return null;

SHA256 sha = SHA256Managed.Create();
byte[] hashedSecret;
if (entryForm.ShowDialog() != System.Windows.Forms.DialogResult.OK) return null;

//If user challenge was selected then just hash the yubikey response and return it.
if (UserChallenge)
{
SHA256 sha = SHA256Managed.Create();
entryForm.Response.CopyTo(resp, 0);
Array.Clear(entryForm.Response, 0, entryForm.Response.Length);
hashedSecret = sha.ComputeHash(resp);

byte[] hashedSecret = sha.ComputeHash(resp);

return hashedSecret;
}

byte[] secret = GenerateChallenge();

//show the entry dialog for the secret
//get the secret
KeyCreation creator = new KeyCreation(this);

entryForm.Response.CopyTo(resp, 0);
Array.Clear(entryForm.Response, 0, entryForm.Response.Length);
if (creator.ShowDialog() != System.Windows.Forms.DialogResult.OK) return null;

byte[] secret = new byte[creator.Secret.Length];

Array.Copy(creator.Secret, secret, creator.Secret.Length); //probably paranoid here, but not a big performance hit
Array.Clear(creator.Secret, 0, creator.Secret.Length);

if (!EncryptAndSave(secret))
{
return null;
}

//store the encrypted secret, the iv, and the challenge to disk
hashedSecret = sha.ComputeHash(secret);
return hashedSecret;

return secret;
}

private byte[] Get(KeyProviderQueryContext ctx)
Expand All @@ -409,10 +429,6 @@ private byte[] Get(KeyProviderQueryContext ctx)
byte[] verification = null;
byte[] secret = null;


//show the dialog box prompting user to press yubikey button
byte[] resp = new byte[YubiWrapper.yubiRespLen];

if (UserChallenge)
{
ChallengeEntry challengeForm = new ChallengeEntry(this);
Expand All @@ -437,23 +453,20 @@ private byte[] Get(KeyProviderQueryContext ctx)
{
secret = RecoveryMode();
EncryptAndSave(secret);
SHA256 sha = SHA256Managed.Create();
byte[] hashedSecret = sha.ComputeHash(secret);
return hashedSecret;
return secret;
}
}

//show the dialog box prompting user to press yubikey button
byte[] resp = new byte[YubiWrapper.yubiRespLen];
KeyEntry entryForm = new KeyEntry(this, challenge);

if (entryForm.ShowDialog() != System.Windows.Forms.DialogResult.OK)
{
if (entryForm.RecoveryMode)
{
secret = RecoveryMode();
EncryptAndSave(secret);
SHA256 sha = SHA256Managed.Create();
byte[] hashedSecret = sha.ComputeHash(secret);
return hashedSecret;
return secret;
}

else return null;
Expand All @@ -470,16 +483,17 @@ private byte[] Get(KeyProviderQueryContext ctx)
return hashedSecret;
}
//otherwise attempt to decrypt a secret from our XML file
else if (DecryptSecret(encryptedSecret, resp, iv, verification, out secret))
else
if (DecryptSecret(encryptedSecret, resp, iv, verification, out secret))
{
SHA256 sha = SHA256Managed.Create();
byte[] hashedSecret = sha.ComputeHash(secret);
return hashedSecret;
if (EncryptAndSave(secret))
return secret;
else return null;
}
else
{
return null;
}
}
}

private byte[] RecoveryMode()
Expand Down
2 changes: 1 addition & 1 deletion KeeChallenge/src/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.6")]
[assembly: AssemblyVersion("2.0")]
//[assembly: AssemblyFileVersion("1.1.*")]
5 changes: 4 additions & 1 deletion KeeChallenge/src/app.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
<section name="KeeChallenge.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false"/>
</sectionGroup>
</configSections>
<startup><supportedRuntime version="v2.0.50727"/></startup><userSettings>
<startup>
<supportedRuntime version="v2.0.50727"/>
</startup>
<userSettings>
<KeeChallenge.Properties.Settings>
<setting name="YubikeySlot" serializeAs="String">
<value>0</value>
Expand Down

0 comments on commit fd77cf9

Please sign in to comment.