Update DETERMINISTIC spec
This commit is contained in:
parent
dcefece799
commit
a6bec75bb2
@ -4,7 +4,7 @@
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.0.14</Version>
|
||||
<Version>1.0.15</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<LangVersion>10.0</LangVersion>
|
||||
<Nullable>enable</Nullable>
|
||||
<Version>1.0.15</Version>
|
||||
<Version>1.0.16</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
@ -8,35 +8,24 @@ using System.Threading.Tasks;
|
||||
namespace BTCPayServer.NTag424;
|
||||
public record CardKey(AESKey AESKey)
|
||||
{
|
||||
public static CardKey Random() => new CardKey(AESKey.Random());
|
||||
public CardKey(byte[] bytes) : this(new AESKey(bytes))
|
||||
public AESKey DeriveAuthenticationKey()
|
||||
{
|
||||
|
||||
}
|
||||
public AESKey DeriveAuthenticationKey(byte[] uid)
|
||||
{
|
||||
Helpers.ValidateUID(uid);
|
||||
return AESKey.Derive(Helpers.Concat(
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x78 },
|
||||
uid));
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x78 }));
|
||||
}
|
||||
public BoltcardKeys DeriveBoltcardKeys(IssuerKey issuerKey, byte[] uid)
|
||||
public BoltcardKeys DeriveBoltcardKeys(IssuerKey issuerKey)
|
||||
{
|
||||
return DeriveBoltcardKeys(issuerKey.DeriveEncryptionKey(), uid);
|
||||
return DeriveBoltcardKeys(issuerKey.DeriveEncryptionKey());
|
||||
}
|
||||
public BoltcardKeys DeriveBoltcardKeys(AESKey encryptionKey, byte[] uid)
|
||||
public BoltcardKeys DeriveBoltcardKeys(AESKey encryptionKey)
|
||||
{
|
||||
Helpers.ValidateUID(uid);
|
||||
var appMasterKey = AESKey.Derive(Helpers.Concat(
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x76 },
|
||||
uid));
|
||||
var authKey = DeriveAuthenticationKey(uid);
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x76 }));
|
||||
var authKey = DeriveAuthenticationKey();
|
||||
var k1 = AESKey.Derive(Helpers.Concat(
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x79 },
|
||||
uid));
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x79 }));
|
||||
var k2 = AESKey.Derive(Helpers.Concat(
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x7a },
|
||||
uid));
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x7a }));
|
||||
|
||||
return new BoltcardKeys(appMasterKey, encryptionKey, authKey, k1, k2);
|
||||
}
|
||||
@ -45,14 +34,10 @@ public record CardKey(AESKey AESKey)
|
||||
{
|
||||
if (!PICCData.ExtractPC(uri, out _, out var c))
|
||||
return false;
|
||||
return this.DeriveAuthenticationKey(piccData.Uid).CheckSunMac(c, piccData, payload);
|
||||
return this.DeriveAuthenticationKey().CheckSunMac(c, piccData, payload);
|
||||
}
|
||||
public bool CheckSunMac([NotNullWhen(true)] string? c, BoltcardPICCData piccData, byte[]? payload = null)
|
||||
{
|
||||
return this.DeriveAuthenticationKey(piccData.Uid).CheckSunMac(c, piccData, payload);
|
||||
}
|
||||
public byte[] ToBytes()
|
||||
{
|
||||
return AESKey.ToBytes();
|
||||
return this.DeriveAuthenticationKey().CheckSunMac(c, piccData, payload);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.RegularExpressions;
|
||||
using static BTCPayServer.NTag424.Helpers;
|
||||
using static BTCPayServer.NTag424.Ntag424;
|
||||
|
||||
namespace BTCPayServer.NTag424;
|
||||
|
||||
@ -18,12 +19,37 @@ public record IssuerKey(AESKey AESKey)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public CardKey CreateCardKey(byte[] uid, int version)
|
||||
{
|
||||
Helpers.ValidateUID(uid);
|
||||
if (version < 0)
|
||||
throw new ArgumentOutOfRangeException(nameof(version));
|
||||
var k = AESKey.Derive(Helpers.Concat(
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x75 },
|
||||
uid,
|
||||
Helpers.UIntToBytesLE((uint)version)));
|
||||
return new CardKey(k);
|
||||
}
|
||||
|
||||
public AESKey DeriveEncryptionKey()
|
||||
{
|
||||
return AESKey.Derive(Helpers.Concat(
|
||||
new byte[] { 0x2d, 0x00, 0x3f, 0x77 }));
|
||||
}
|
||||
|
||||
public bool CheckSunMac([NotNullWhen(true)] Uri? uri, BoltcardPICCData piccData, int version, byte[]? payload = null)
|
||||
{
|
||||
if (!PICCData.ExtractPC(uri, out _, out var c))
|
||||
return false;
|
||||
return CheckSunMac(c, piccData, version, payload);
|
||||
}
|
||||
public bool CheckSunMac([NotNullWhen(true)] string? c, BoltcardPICCData piccData, int version, byte[]? payload = null)
|
||||
{
|
||||
var cardKey = CreateCardKey(piccData.Uid, version);
|
||||
return cardKey.CheckSunMac(c, piccData, payload);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the ID from the UID
|
||||
/// </summary>
|
||||
|
||||
@ -400,13 +400,7 @@ public class Ntag424
|
||||
/// <returns></returns>
|
||||
public async Task ResetCard(IssuerKey issuerKey, CardKey cardKey)
|
||||
{
|
||||
var encryptionKey = issuerKey.DeriveEncryptionKey();
|
||||
if (CurrentSession is null)
|
||||
await AuthenticateEV2First(1, encryptionKey);
|
||||
if (encryptionKey != CurrentSession!.Key)
|
||||
await AuthenticateEV2NonFirst(1, encryptionKey);
|
||||
var uid = await GetCardUID();
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey, uid);
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey);
|
||||
await ResetCard(keys);
|
||||
}
|
||||
|
||||
|
||||
@ -79,14 +79,15 @@ public class UnitTest1
|
||||
{
|
||||
var uid = "04a39493cc8680".HexToBytes();
|
||||
var issuerKey = new IssuerKey("00000000000000000000000000000001".HexToBytes());
|
||||
var cardKey = new CardKey("00000000000000000000000000000002".HexToBytes());
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey, uid);
|
||||
var cardKey = issuerKey.CreateCardKey(uid, 1);
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey);
|
||||
Logs.WriteLine("K0: " + keys.AppMasterKey.ToBytes().ToHex());
|
||||
Logs.WriteLine("K1: " + keys.EncryptionKey.ToBytes().ToHex());
|
||||
Logs.WriteLine("K2: " + keys.AuthenticationKey.ToBytes().ToHex());
|
||||
Logs.WriteLine("K3: " + keys.K3.ToBytes().ToHex());
|
||||
Logs.WriteLine("K4: " + keys.K4.ToBytes().ToHex());
|
||||
Logs.WriteLine("ID: " + issuerKey.GetId(uid).ToHex());
|
||||
Logs.WriteLine("CardKey: " + cardKey.AESKey.ToBytes().ToHex());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
@ -180,13 +181,13 @@ public class UnitTest1
|
||||
using var ctx = await PCSCContext.WaitForCard();
|
||||
var ntag = ctx.CreateNTag424();
|
||||
var issuerKey = new IssuerKey("00000000000000000000000000000001".HexToBytes());
|
||||
var cardKey = new CardKey("00000000000000000000000000000002".HexToBytes());
|
||||
|
||||
// First time authenticate is with the default 00.000 key
|
||||
await ntag.AuthenticateEV2First(0, AESKey.Default);
|
||||
var uid = await ntag.GetCardUID();
|
||||
var cardKey = issuerKey.CreateCardKey(uid, 0);
|
||||
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey, uid);
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey);
|
||||
await ntag.SetupBoltcard("lnurlw://blahblah.com", BoltcardKeys.Default, keys);
|
||||
|
||||
var uri = await ntag.TryReadNDefURI();
|
||||
@ -207,13 +208,14 @@ public class UnitTest1
|
||||
public async Task Reset()
|
||||
{
|
||||
var issuerKey = new IssuerKey("00000000000000000000000000000001".HexToBytes());
|
||||
var cardKey = new CardKey("00000000000000000000000000000002".HexToBytes());
|
||||
|
||||
using var ctx = PCSCContext.Create();
|
||||
|
||||
var ntag = ctx.CreateNTag424();
|
||||
await ntag.AuthenticateEV2First(0, AESKey.Default);
|
||||
var uid = await ntag.GetCardUID();
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey, uid);
|
||||
var cardKey = issuerKey.CreateCardKey(uid, 1);
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey);
|
||||
await ntag.SetupBoltcard("lnurlw://test.com", BoltcardKeys.Default, keys);
|
||||
|
||||
await ntag.ResetCard(issuerKey, cardKey);
|
||||
@ -270,14 +272,13 @@ public class UnitTest1
|
||||
using var ctx = PCSCContext.Create();
|
||||
var ntag = ctx.CreateNTag424();
|
||||
var issuerKey = new IssuerKey("00000000000000000000000000000001".HexToBytes());
|
||||
var cardKey = new CardKey("00000000000000000000000000000002".HexToBytes());
|
||||
|
||||
var nonce = "00010000000000000000000000000000".HexToBytes();
|
||||
//await ntag.ResetCard(issuerKey, nonce);
|
||||
await ntag.AuthenticateEV2First(0, AESKey.Default);
|
||||
var uid = await ntag.GetCardUID();
|
||||
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey, uid);
|
||||
var cardKey = issuerKey.CreateCardKey(uid, 1);
|
||||
var keys = cardKey.DeriveBoltcardKeys(issuerKey);
|
||||
await ntag.SetupBoltcard("http://test.com", BoltcardKeys.Default, keys);
|
||||
var uri = await ntag.TryReadNDefURI();
|
||||
issuerKey.TryDecrypt(uri);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user