public static ulong? ParseCounter(string strCounter, OtpDataFmt fmt) { byte[] pb = ParseKey(strCounter, fmt); if(pb == null) return null; if(pb.Length > 8) return null; Array.Reverse(pb); // Big endian -> little endian byte[] pb8 = new byte[8]; Array.Copy(pb, 0, pb8, 0, pb.Length); return MemUtil.BytesToUInt64(pb8); // Little endian }
public static byte[] ParseKey(string strKey, OtpDataFmt fmt) { if(strKey == null) { Debug.Assert(false); return null; } strKey = strKey.Trim(); if(strKey.Length == 0) return null; // No assert if(fmt == OtpDataFmt.Hex) { strKey = strKey.Replace(" ", string.Empty); strKey = strKey.Replace("\t", string.Empty); strKey = strKey.Replace("\r", string.Empty); strKey = strKey.Replace("\n", string.Empty); if((strKey.Length % 2) == 1) strKey = "0" + strKey; return MemUtil.HexStringToByteArray(strKey); } else if(fmt == OtpDataFmt.Base64) { try { return Convert.FromBase64String(strKey); } catch(Exception) { } } else if(fmt == OtpDataFmt.Base32) return ParseBase32(strKey); else if(fmt == OtpDataFmt.Utf8) { try { return StrUtil.Utf8.GetBytes(strKey); } catch(Exception) { } } else if(fmt == OtpDataFmt.Dec) { ulong u; if(ulong.TryParse(strKey, out u)) { byte[] pb = MemUtil.UInt64ToBytes(u); Array.Reverse(pb); // Little endian -> big endian return pb; } } return null; }
/* private static byte[] Open(KeyProviderQueryContext ctx, OtpInfo otpInfo) { if(otpInfo.Type != ProvType) { MessageService.ShowWarning("Unknown OTP generator type!"); return null; } OtpKeyPromptForm dlg = new OtpKeyPromptForm(); dlg.InitEx(otpInfo, ctx); if(UIUtil.ShowDialogAndDestroy(dlg) != DialogResult.OK) return null; if(!CreateAuxFile(otpInfo, ctx)) return null; return otpInfo.Secret; } * */ /// <summary> /// Sets the "Secret" field in otpInfo based on the list of entered OTPs (lOtps) or the entered secret itself which is in format fmt /// </summary> /// based on the code in OtpKeyPromptForm.cs public void SetSecret(OtpInfo otpInfo, List<string> lOtps, string secret, OtpDataFmt? fmt) { byte[] pbSecret = EncodingUtil.ParseKey(secret, (fmt.HasValue ? fmt.Value : OtpDataFmt.Hex)); if (pbSecret != null) { otpInfo.Secret = pbSecret; return; } if (!string.IsNullOrEmpty(otpInfo.EncryptedSecret)) // < v2.0 { byte[] pbKey32 = OtpUtil.KeyFromOtps(lOtps.ToArray(), 0, lOtps.Count, Convert.FromBase64String( otpInfo.TransformationKey), otpInfo.TransformationRounds); if (pbKey32 == null) throw new InvalidOperationException(); pbSecret = OtpUtil.DecryptData(otpInfo.EncryptedSecret, pbKey32, Convert.FromBase64String(otpInfo.EncryptionIV)); if (pbSecret == null) throw new InvalidOperationException(); otpInfo.Secret = pbSecret; otpInfo.Counter += (ulong) otpInfo.OtpsRequired; } else // >= v2.0, supporting look-ahead { bool bSuccess = false; for (int i = 0; i < otpInfo.EncryptedSecrets.Count; ++i) { OtpEncryptedData d = otpInfo.EncryptedSecrets[i]; pbSecret = OtpUtil.DecryptSecret(d, lOtps.ToArray(), 0, lOtps.Count); if (pbSecret != null) { otpInfo.Secret = pbSecret; otpInfo.Counter += ((ulong) otpInfo.OtpsRequired + (ulong) i); bSuccess = true; break; } } if (!bSuccess) throw new InvalidOperationException(); } }