Skip to content

Commit a4b897f

Browse files
committed
refactor: use KeyDefinition lookup for PivEccPrivateKey
1 parent 5b1352d commit a4b897f

File tree

2 files changed

+29
-18
lines changed

2 files changed

+29
-18
lines changed

Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivEccPrivateKey.cs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
// limitations under the License.
1414

1515
using System;
16-
using System.Diagnostics.CodeAnalysis;
16+
using System.Collections.Generic;
1717
using System.Globalization;
18+
using System.Linq;
1819
using System.Security.Cryptography;
1920
using Yubico.Core.Tlv;
21+
using Yubico.YubiKey.Cryptography;
2022

2123
namespace Yubico.YubiKey.Piv
2224
{
@@ -28,12 +30,11 @@ namespace Yubico.YubiKey.Piv
2830
/// of a point on the curve. So for ECC P-256, each coordinate is 32 bytes
2931
/// (256 bits), so the private value will be 32 bytes.
3032
/// </remarks>
31-
[Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)]
33+
[Obsolete(
34+
"Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead",
35+
false)]
3236
public sealed class PivEccPrivateKey : PivPrivateKey
3337
{
34-
private const int EccP256PrivateKeySize = 32;
35-
private const int EccP384PrivateKeySize = 48;
36-
3738
private Memory<byte> _privateValue;
3839

3940
// <summary>
@@ -70,12 +71,12 @@ private PivEccPrivateKey()
7071
/// </exception>
7172
[Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use ECPublicKey, ECPrivateKey instead", false)]
7273
public PivEccPrivateKey(
73-
ReadOnlySpan<byte> privateValue,
74+
ReadOnlySpan<byte> privateValue,
7475
PivAlgorithm? algorithm = null)
7576
{
7677
if (algorithm.HasValue)
7778
{
78-
ValidateSize(privateValue, algorithm);
79+
ValidateSize(privateValue, algorithm.Value);
7980
Algorithm = algorithm.Value;
8081
}
8182
else
@@ -89,17 +90,17 @@ public PivEccPrivateKey(
8990
PivAlgorithm.EccX25519 => PivConstants.PrivateECX25519Tag,
9091
_ => PivConstants.PrivateECDsaTag
9192
};
92-
93+
9394
var tlvWriter = new TlvWriter();
9495
tlvWriter.WriteValue(tag, privateValue);
9596
EncodedKey = tlvWriter.Encode();
9697
_privateValue = new Memory<byte>(privateValue.ToArray());
9798
}
9899

99-
private static void ValidateSize(ReadOnlySpan<byte> privateValue, [DisallowNull] PivAlgorithm? algorithm)
100+
private static void ValidateSize(ReadOnlySpan<byte> privateValue, PivAlgorithm algorithm)
100101
{
101-
int expectedSize = algorithm.Value.GetPivKeyDefinition().KeyDefinition.LengthInBytes;
102-
if(privateValue.Length != expectedSize)
102+
int expectedSize = algorithm.GetPivKeyDefinition().KeyDefinition.LengthInBytes;
103+
if (privateValue.Length != expectedSize)
103104
{
104105
throw new ArgumentException(
105106
string.Format(
@@ -109,13 +110,16 @@ private static void ValidateSize(ReadOnlySpan<byte> privateValue, [DisallowNull]
109110

110111
private static PivAlgorithm GetBySize(ReadOnlySpan<byte> privateValue)
111112
{
112-
return privateValue.Length switch
113+
int privateValueSize = privateValue.Length;
114+
var allowed = new List<KeyDefinition> { KeyDefinitions.P256, KeyDefinitions.P384 };
115+
if (allowed.SingleOrDefault(kd => kd.LengthInBytes == privateValueSize) is { } keyDefinition)
113116
{
114-
EccP256PrivateKeySize => PivAlgorithm.EccP256,
115-
EccP384PrivateKeySize => PivAlgorithm.EccP384,
116-
_ => throw new ArgumentException(string.Format(
117-
CultureInfo.CurrentCulture, ExceptionMessages.InvalidPrivateKeyData))
118-
};
117+
return keyDefinition.GetPivKeyDefinition().Algorithm;
118+
}
119+
120+
throw new ArgumentException(
121+
string.Format(
122+
CultureInfo.CurrentCulture, ExceptionMessages.InvalidPrivateKeyData));
119123
}
120124

121125
/// <summary>

Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivPrivateKeyTests.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,17 @@ public class PivPrivateKeyTests
2525
{
2626
[Theory]
2727
[InlineData(KeyType.ECP256)]
28+
[InlineData(KeyType.ECP384)]
2829
[InlineData(KeyType.Ed25519)]
2930
public void Constructor_with_Algorithm_SetsAlgorithm(KeyType keyType)
3031
{
31-
var pk = new PivEccPrivateKey(new byte[32], keyType.GetPivAlgorithm());
32+
var keyBytes = keyType switch
33+
{
34+
KeyType.ECP384 => new byte[48],
35+
_ => new byte[32],
36+
};
37+
38+
var pk = new PivEccPrivateKey(keyBytes, keyType.GetPivAlgorithm());
3239
Assert.Equal(keyType.GetPivAlgorithm(), pk.Algorithm);
3340
Assert.Equal(keyType, pk.KeyType);
3441
}

0 commit comments

Comments
 (0)