mirror of
https://github.com/MichaelGrafnetter/DSInternals
synced 2025-04-26 04:48:34 +00:00
Initial support for FIDO2 key manipulation through AAD Graph API.
This commit is contained in:
parent
3df26c9327
commit
e4fb753894
@ -47,6 +47,9 @@
|
||||
<HintPath>..\packages\MSTest.TestFramework.2.0.0\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
|
||||
<Private>True</Private>
|
||||
</Reference>
|
||||
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Numbers, Version=1.5.1.0, Culture=neutral, PublicKeyToken=9cd62db60ea5554c, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\PeterO.Numbers.1.5.1\lib\net40\Numbers.dll</HintPath>
|
||||
<Private>false</Private>
|
||||
@ -73,6 +76,7 @@
|
||||
<Compile Include="KerberosCredentialTester.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Cryptography\SecureStringExtensionsTester.cs" />
|
||||
<Compile Include="SearchableDeviceKeyTester.cs" />
|
||||
<Compile Include="SecurityIdentifierExtensionsTester.cs" />
|
||||
<Compile Include="KeyCredentialTester.cs" />
|
||||
<Compile Include="SupplementalCredentialsTester.cs" />
|
||||
|
96
Src/DSInternals.Common.Test/SearchableDeviceKeyTester.cs
Normal file
96
Src/DSInternals.Common.Test/SearchableDeviceKeyTester.cs
Normal file
@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using DSInternals.Common.Data;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace DSInternals.Common.Test
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains tests for parsing the Azure AD SearchableDeviceKey attribute.
|
||||
/// </summary>
|
||||
[TestClass]
|
||||
public class SearchableDeviceKeyTester
|
||||
{
|
||||
[TestMethod]
|
||||
public void SearchableDeviceKey_Parse_FIDO()
|
||||
{
|
||||
string jsonData = @"{
|
||||
'usage':'FIDO',
|
||||
'keyIdentifier':'GshyINLMaOOwqt1LNUi0gQ==',
|
||||
'keyMaterial':'eyJ2ZXJzaW9uIjoxLCJhdXRoRGF0YSI6Ik5XeWUxS0NUSWJscFh4NnZrWUlEOGJWZmFKMm1IN3lXR0V3VmZkcG9ESUhGQUFBQUdjdHBTQjZQOTBBNWsrd0tKeW1oVktnQUVCckljaURTekdqanNLcmRTelZJdElHbEFRSURKaUFCSVZnZ29uTkNlY2EwZE5LTzlaWXBGdjlvMCtlZ0VGQ1ZTeXJ0UmN1NndrMStoT2dpV0NDNWE3MFI0ZlNFZ0ZpNWxnQTRBVVBmN1Y0Q2p5VWcvb1VWTFEzem5kZnc1YUZyYUcxaFl5MXpaV055WlhUMSIsIng1YyI6WyJNSUlDdlRDQ0FhV2dBd0lCQWdJRUdLeEd3REFOQmdrcWhraUc5dzBCQVFzRkFEQXVNU3d3S2dZRFZRUURFeU5aZFdKcFkyOGdWVEpHSUZKdmIzUWdRMEVnVTJWeWFXRnNJRFExTnpJd01EWXpNVEFnRncweE5EQTRNREV3TURBd01EQmFHQTh5TURVd01Ea3dOREF3TURBd01Gb3diakVMTUFrR0ExVUVCaE1DVTBVeEVqQVFCZ05WQkFvTUNWbDFZbWxqYnlCQlFqRWlNQ0FHQTFVRUN3d1pRWFYwYUdWdWRHbGpZWFJ2Y2lCQmRIUmxjM1JoZEdsdmJqRW5NQ1VHQTFVRUF3d2VXWFZpYVdOdklGVXlSaUJGUlNCVFpYSnBZV3dnTkRFek9UUXpORGc0TUZrd0V3WUhLb1pJemowQ0FRWUlLb1pJemowREFRY0RRZ0FFZWVvN0xIeEpjQkJpSXd6U1ArdGc1U2t4Y2RTRDhRQytoWjFyRDRPWEF3RzFSczNVYnMvSzQrUHpENEhwN1dLOUpvMU1IcjAzczd5K2txakNydXRPT3FOc01Hb3dJZ1lKS3dZQkJBR0N4QW9DQkJVeExqTXVOaTR4TGpRdU1TNDBNVFE0TWk0eExqY3dFd1lMS3dZQkJBR0M1UndDQVFFRUJBTUNCU0F3SVFZTEt3WUJCQUdDNVJ3QkFRUUVFZ1FReTJsSUhvLzNRRG1UN0FvbkthRlVxREFNQmdOVkhSTUJBZjhFQWpBQU1BMEdDU3FHU0liM0RRRUJDd1VBQTRJQkFRQ1huUU9YMkdENEx1RmRNUng1YnJyN0l2cW40SVRadXJUR0c3dFg4K2Ewd1lwSU43aGNQRTdiNUlORDlOYWwyYkhPMm9yaC90U1JLU0Z6Qlk1ZTRjdmRhOXJBZFZmR29PalRhQ1c2Rlo1L3RhMk0ydmdFaG96NURvOGZpdW9Yd0JhMVhDcDYxSmZJbFB0eDExUFhtNXBJUzJ3M2JYSTdtWTB1SFVNR3Z4QXp0YTc0ektYTHNsYUxhU1FpYlNLaldLdDloK1NzWHk0SkdxY1ZlZk9sYVFsSmZYTDFUZ2E2d2NPMFFUdTZYcStVdzdaUE5QbnJwQnJMYXVLRGQyMDJSbE40U1A3b2hMM2Q5Ykc2VjVoVXovM091c05FQlpVbjVXM1ZtUGoxWm5GYXZrTUIzUmtSTU9hNThNWkFPUkpUNGltQVB6cnZKMHZ0djk0L3k3MUM2dFo1Il0sImRpc3BsYXlOYW1lIjoiWXViaUtleSA1In0=',
|
||||
'creationTime':'2019-12-12T09:42:21.2641041Z',
|
||||
'deviceId':'00000000-0000-0000-0000-000000000000',
|
||||
'customKeyInformation':'AQEAAAAAAAAAAAAAAAAA',
|
||||
'fidoAaGuid':'cb69481e-8ff7-4039-93ec-0a2729a154a8',
|
||||
'fidoAuthenticatorVersion':null,
|
||||
'fidoAttestationCertificates':['e7d092ba192fdbbb2f36552832d616126971a269']
|
||||
}";
|
||||
|
||||
// Parse the FIDO key and check all fields
|
||||
var keyCredential = KeyCredential.ParseJson(jsonData);
|
||||
Assert.AreEqual(KeyUsage.FIDO, keyCredential.Usage);
|
||||
Assert.AreEqual("YubiKey 5", keyCredential.FidoKeyMaterial.DisplayName);
|
||||
Assert.AreEqual("GshyINLMaOOwqt1LNUi0gQ==", keyCredential.Identifier);
|
||||
Assert.AreEqual(2019, keyCredential.CreationTime.Year);
|
||||
Assert.IsTrue(keyCredential.CustomKeyInfo.Flags.HasFlag(KeyFlags.Attestation));
|
||||
Assert.AreEqual("e7d092ba192fdbbb2f36552832d616126971a269", keyCredential.FidoKeyMaterial.AttestationCertificates[0].Thumbprint.ToLowerInvariant());
|
||||
Assert.AreEqual("cb69481e-8ff7-4039-93ec-0a2729a154a8", keyCredential.FidoKeyMaterial.AuthenticatorData.AttestedCredentialData.AaGuid.ToString());
|
||||
|
||||
// Serialize the object again and compare with the original
|
||||
Assert.AreEqual(JToken.Parse(jsonData).ToString(Formatting.None), keyCredential.ToJson());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SearchableDeviceKey_Parse_NGC()
|
||||
{
|
||||
string jsonData = @"{
|
||||
'usage':'NGC',
|
||||
'keyIdentifier':'6eHBLoX0uOrd/hOsFVyQK8Rk2iqLTubd5nV80SMh+z4=',
|
||||
'keyMaterial':'UlNBMQAIAAADAAAAAAEAAAAAAAAAAAAAAQAByI8SMTWloiGnJjhv1A3o/n7FquciD7pKgFPcwbuzJK3NhmyCXuKMqrxW2zod4l9juNj9EPV8Y/YaZYvkNX5fTmSvmHihrAcdT6Kugej9GObFW1LH10yQnNYGP9X+te//tsNe90a8ORaDsOEq3gwRo1xyq14MxozgWbyRYA+Y+yfjdS+4cyP/054/pflLDHjSGKyvAaka0nJ5FzaTQ/YSupqVWgRX97BGk8ClpDm/zc0kRS0w3e4uEFcyrlDb8tccZ6lxVl7nJiIUuMEq/kyLn2lL7ISf5U3ter2/MEnU7T4wxMbIG7gUfAr4wh4DT3dI4IhQuhYdHe4s6a9lr4gppQ==',
|
||||
'creationTime':'2015-11-17T08:17:13.7724773Z',
|
||||
'deviceId':'cbad3c94-b480-4fa6-9187-ff1ed42c4479',
|
||||
'customKeyInformation':'AQA=',
|
||||
'fidoAaGuid':null,
|
||||
'fidoAuthenticatorVersion':null,
|
||||
'fidoAttestationCertificates':[]
|
||||
}";
|
||||
|
||||
// Parse the NGC key and check all fields
|
||||
var parsedKey = KeyCredential.ParseJson(jsonData);
|
||||
Assert.AreEqual(KeyUsage.NGC, parsedKey.Usage);
|
||||
Assert.AreEqual("6eHBLoX0uOrd/hOsFVyQK8Rk2iqLTubd5nV80SMh+z4=", parsedKey.Identifier);
|
||||
Assert.AreEqual(2015, parsedKey.CreationTime.Year);
|
||||
Assert.AreEqual(KeyFlags.None, parsedKey.CustomKeyInfo.Flags);
|
||||
Assert.AreEqual(1, parsedKey.CustomKeyInfo.Version);
|
||||
Assert.AreEqual("cbad3c94-b480-4fa6-9187-ff1ed42c4479", parsedKey.DeviceId.Value.ToString().ToLowerInvariant());
|
||||
|
||||
// Serialize the object again and compare with the original
|
||||
Assert.AreEqual(JToken.Parse(jsonData).ToString(Formatting.None), parsedKey.ToJson());
|
||||
|
||||
// Re-generate the identifier and check that it matches the value in AAD.
|
||||
var generatedKey = new KeyCredential(
|
||||
parsedKey.RawKeyMaterial,
|
||||
Guid.Parse("cbad3c94-b480-4fa6-9187-ff1ed42c4479"),
|
||||
"CN=Test",
|
||||
DateTime.Parse("2015-11-17T08:17:13.7724773Z")
|
||||
);
|
||||
Assert.AreEqual(parsedKey.Identifier, generatedKey.Identifier);
|
||||
|
||||
// Serialize the generated object and compare with the original
|
||||
Assert.AreEqual(JToken.Parse(jsonData).ToString(Formatting.None), generatedKey.ToJson());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SearchableDeviceKey_Parse_Null()
|
||||
{
|
||||
Assert.IsNull(KeyCredential.ParseJson(null));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SearchableDeviceKey_Parse_Empty()
|
||||
{
|
||||
Assert.IsNull(KeyCredential.ParseJson(String.Empty));
|
||||
}
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
<packages>
|
||||
<package id="MSTest.TestAdapter" version="2.0.0" targetFramework="net47" />
|
||||
<package id="MSTest.TestFramework" version="2.0.0" targetFramework="net47" />
|
||||
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net47" />
|
||||
<package id="PeterO.Cbor" version="4.1.0" targetFramework="net47" />
|
||||
<package id="PeterO.Numbers" version="1.5.1" targetFramework="net47" />
|
||||
<package id="PeterO.URIUtility" version="1.0.0" targetFramework="net47" />
|
||||
|
@ -46,6 +46,7 @@
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.DirectoryServices" />
|
||||
<Reference Include="System.Numerics" />
|
||||
<Reference Include="System.Runtime.Serialization" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ADSI\AdsiClient.cs" />
|
||||
@ -64,6 +65,7 @@
|
||||
<Compile Include="Data\DPAPI\RoamedCredentialType.cs" />
|
||||
<Compile Include="Cryptography\CngSoftwareProviderTransportBlob.cs" />
|
||||
<Compile Include="Data\Hello\CustomKeyInformation.cs" />
|
||||
<Compile Include="Data\Hello\CustomKeyInformationConverter.cs" />
|
||||
<Compile Include="Data\Hello\FidoAttestedCredentialData.cs" />
|
||||
<Compile Include="Data\Hello\FidoAuthenticatorData.cs" />
|
||||
<Compile Include="Data\Hello\FidoAuthenticatorFlags.cs" />
|
||||
@ -167,6 +169,8 @@
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup />
|
||||
<ItemGroup>
|
||||
<Folder Include="Data\FIDO2\" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace DSInternals.Common.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Converts the CustomKeyInformation class to and from a base 64 string value.
|
||||
/// </summary>
|
||||
public class CustomKeyInformationConverter : JsonConverter<CustomKeyInformation>
|
||||
{
|
||||
public override CustomKeyInformation ReadJson(JsonReader reader, Type objectType, CustomKeyInformation existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if(reader.TokenType == JsonToken.String)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] blob = Convert.FromBase64String((string)reader.Value);
|
||||
return new CustomKeyInformation(blob);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
throw new JsonSerializationException("Cannot convert invalid value to CustomKeyInformation.", e);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new JsonSerializationException("Unexpected token parsing CustomKeyInformation.");
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, CustomKeyInformation value, JsonSerializer serializer)
|
||||
{
|
||||
if(value != null)
|
||||
{
|
||||
writer.WriteValue(value.ToByteArray());
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,16 +2,23 @@
|
||||
{
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
using DSInternals.Common.Data.Fido;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
|
||||
/// <summary>
|
||||
/// This class represents a single credential stored as a series of values, corresponding to the KEYCREDENTIALLINK_BLOB structure.
|
||||
/// This class represents a single AD/AAD key credential.
|
||||
/// </summary>
|
||||
/// <remarks>This structure is stored as the binary portion of the msDS-KeyCredentialLink DN-Binary attribute.</remarks>
|
||||
/// <remarks>
|
||||
/// In Active Directory, this structure is stored as the binary portion of the msDS-KeyCredentialLink DN-Binary attribute
|
||||
/// in the KEYCREDENTIALLINK_BLOB format.
|
||||
/// The Azure Active Directory Graph API represents this structure in JSON format.
|
||||
/// </remarks>
|
||||
/// <see>https://msdn.microsoft.com/en-us/library/mt220505.aspx</see>
|
||||
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
|
||||
public class KeyCredential
|
||||
{
|
||||
/// <summary>
|
||||
@ -36,6 +43,10 @@
|
||||
/// <summary>
|
||||
/// A SHA256 hash of the Value field of the RawKeyMaterial entry.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Version 1 keys had a guid in this field instead if a hash.
|
||||
/// </remarks>
|
||||
[JsonProperty("keyIdentifier", Order = 2)]
|
||||
public string Identifier
|
||||
{
|
||||
get;
|
||||
@ -51,6 +62,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("usage", Order = 1)]
|
||||
[JsonConverter(typeof(StringEnumConverter))]
|
||||
public KeyUsage Usage
|
||||
{
|
||||
get;
|
||||
@ -72,6 +85,7 @@
|
||||
/// <summary>
|
||||
/// Key material of the credential.
|
||||
/// </summary>
|
||||
[JsonProperty("keyMaterial", Order = 3)]
|
||||
public byte[] RawKeyMaterial
|
||||
{
|
||||
get;
|
||||
@ -159,12 +173,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
[JsonProperty("customKeyInformation", Order = 6)]
|
||||
[JsonConverter(typeof(CustomKeyInformationConverter))]
|
||||
public CustomKeyInformation CustomKeyInfo
|
||||
{
|
||||
get;
|
||||
private set;
|
||||
}
|
||||
|
||||
[JsonProperty("deviceId", Order = 5)]
|
||||
public Guid? DeviceId
|
||||
{
|
||||
get;
|
||||
@ -174,6 +191,7 @@
|
||||
/// <summary>
|
||||
/// The approximate time this key was created.
|
||||
/// </summary>
|
||||
[JsonProperty("creationTime", Order = 4)]
|
||||
public DateTime CreationTime
|
||||
{
|
||||
get;
|
||||
@ -198,6 +216,58 @@
|
||||
private set;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FIDO AAGUID. For JSON deserialization only.
|
||||
/// </summary>
|
||||
[JsonProperty("fidoAaGuid", Order = 7)]
|
||||
private Guid? FidoAaGuid
|
||||
{
|
||||
get
|
||||
{
|
||||
var fido = this.FidoKeyMaterial;
|
||||
if (fido != null && fido.AuthenticatorData != null && fido.AuthenticatorData.AttestedCredentialData != null)
|
||||
{
|
||||
return fido.AuthenticatorData.AttestedCredentialData.AaGuid;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FIDO authenticator version. For JSON deserialization only.
|
||||
/// </summary>
|
||||
[JsonProperty("fidoAuthenticatorVersion", Order = 8)]
|
||||
private string FidoAuthenticatorVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of thumbprints of FIDO Attestation Certificates. For JSON deserialization only.
|
||||
/// </summary>
|
||||
[JsonProperty("fidoAttestationCertificates", Order = 9)]
|
||||
private string[] FidoAttestationCertificates
|
||||
{
|
||||
get
|
||||
{
|
||||
var fido = this.FidoKeyMaterial;
|
||||
if(fido != null && fido.AttestationCertificates != null)
|
||||
{
|
||||
return fido.AttestationCertificates.Cast<X509Certificate2>().Select(cer => cer.Thumbprint.ToLowerInvariant()).ToArray();
|
||||
}
|
||||
else
|
||||
{
|
||||
return new string[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public KeyCredential(X509Certificate2 certificate, Guid? deviceId, string holderDN, DateTime? currentTime = null, bool isComputerKey = false)
|
||||
{
|
||||
Validator.AssertNotNull(certificate, nameof(certificate));
|
||||
@ -222,9 +292,7 @@
|
||||
// Initialize the Key Credential based on requirements stated in MS-KPP Processing Details:
|
||||
this.Version = KeyCredentialVersion.Version2;
|
||||
this.Identifier = ComputeKeyIdentifier(publicKey, this.Version);
|
||||
this.CreationTime = currentTime.HasValue ? currentTime.Value : DateTime.Now;
|
||||
|
||||
|
||||
this.CreationTime = currentTime.HasValue ? currentTime.Value.ToUniversalTime() : DateTime.UtcNow;
|
||||
this.RawKeyMaterial = publicKey;
|
||||
this.Usage = KeyUsage.NGC;
|
||||
this.Source = KeySource.AD;
|
||||
@ -324,6 +392,16 @@
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This constructor is only used for JSON deserialization.
|
||||
/// </summary>
|
||||
[JsonConstructor]
|
||||
private KeyCredential()
|
||||
{
|
||||
this.Source = KeySource.AzureAD;
|
||||
this.Version = KeyCredentialVersion.Version2;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format(
|
||||
@ -427,16 +505,34 @@
|
||||
return new DNWithBinary(this.HolderDN, this.ToByteArray()).ToString();
|
||||
}
|
||||
|
||||
public static KeyCredential Parse(string dnWithBinary)
|
||||
public string ToJson()
|
||||
{
|
||||
return JsonConvert.SerializeObject(this);
|
||||
}
|
||||
|
||||
public static KeyCredential ParseDNBinary(string dnWithBinary)
|
||||
{
|
||||
Validator.AssertNotNullOrEmpty(dnWithBinary, nameof(dnWithBinary));
|
||||
var parsed = DNWithBinary.Parse(dnWithBinary);
|
||||
return new KeyCredential(parsed.Binary, parsed.DistinguishedName);
|
||||
}
|
||||
|
||||
public static KeyCredential ParseJson(string jsonData)
|
||||
{
|
||||
if(String.IsNullOrEmpty(jsonData))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return JsonConvert.DeserializeObject<KeyCredential>(jsonData);
|
||||
}
|
||||
}
|
||||
|
||||
private static DateTime ConvertFromBinaryTime(byte[] binaryTime, KeySource source, KeyCredentialVersion version)
|
||||
{
|
||||
long timeStamp = BitConverter.ToInt64(binaryTime, 0);
|
||||
|
||||
// AD and AAD use a different time encoding.
|
||||
switch (version)
|
||||
{
|
||||
|
@ -38,7 +38,7 @@
|
||||
DeviceId = 0x06,
|
||||
|
||||
/// <summary>
|
||||
/// Custom key identifier.
|
||||
/// Custom key information.
|
||||
/// </summary>
|
||||
CustomKeyInformation = 0x07,
|
||||
|
||||
|
@ -4,6 +4,7 @@ using Newtonsoft.Json;
|
||||
|
||||
namespace DSInternals.Common.Data
|
||||
{
|
||||
[JsonObject(MemberSerialization = MemberSerialization.OptIn)]
|
||||
public class KeyMaterialFido
|
||||
{
|
||||
/// <summary>
|
||||
|
@ -37,6 +37,11 @@
|
||||
/// <summary>
|
||||
/// File Encryption Key (KEY_USAGE_FEK)
|
||||
/// </summary>
|
||||
FEK = 0x08
|
||||
FEK = 0x08,
|
||||
|
||||
/// <summary>
|
||||
/// DPAPI Key
|
||||
/// </summary>
|
||||
DPAPI // TODO: The DPAPI enum needs to be mapped to a proper integer value.
|
||||
}
|
||||
}
|
||||
|
@ -125,7 +125,7 @@
|
||||
case ParamSetFromDNBinary:
|
||||
foreach (string singleValue in this.DNWithBinaryData)
|
||||
{
|
||||
keyCredential = KeyCredential.Parse(singleValue);
|
||||
keyCredential = KeyCredential.ParseDNBinary(singleValue);
|
||||
this.WriteObject(keyCredential);
|
||||
}
|
||||
break;
|
||||
|
Loading…
Reference in New Issue
Block a user