Skip to content

Commit 476b8df

Browse files
committed
worked on keyparameterspivhelper
1 parent 792a5b8 commit 476b8df

File tree

1 file changed

+70
-47
lines changed

1 file changed

+70
-47
lines changed

Yubico.YubiKey/src/Yubico/YubiKey/Piv/KeyParametersPivHelper.cs

Lines changed: 70 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -25,46 +25,36 @@ namespace Yubico.YubiKey.Piv;
2525

2626
public static class KeyParametersPivHelper
2727
{
28-
// PIV TLV Encoding ---> IPrivateKeyParameters
29-
public static T CreatePrivateParametersFromPivEncoding<T>(ReadOnlyMemory<byte> pivEncodingBytes)
30-
where T : IPrivateKeyParameters
31-
{
32-
if (pivEncodingBytes.IsEmpty)
28+
public static IPublicKeyParameters CreatePublicKeyParameters(ReadOnlyMemory<byte> pivEncodedKey, KeyType keyType) =>
29+
keyType switch
3330
{
34-
throw new ArgumentException(
31+
KeyType.Ed25519 or KeyType.X25519 => KeyParametersPivHelper
32+
.CreatePublicCurve25519FromPivEncoding(pivEncodedKey, keyType),
33+
KeyType.P256 or KeyType.P384 or KeyType.P521 => KeyParametersPivHelper
34+
.CreatePublicEcFromPivEncoding(pivEncodedKey),
35+
KeyType.RSA1024 or KeyType.RSA2048 or KeyType.RSA3072 or KeyType.RSA4096 => KeyParametersPivHelper
36+
.CreatePublicRsaFromPivEncoding(pivEncodedKey),
37+
_ => throw new InvalidOperationException(
3538
string.Format(
3639
CultureInfo.CurrentCulture,
37-
ExceptionMessages.InvalidPrivateKeyData));
38-
}
39-
40-
byte tag = pivEncodingBytes.Span[0];
41-
IPrivateKeyParameters pkp = tag switch
42-
{
43-
_ when PivConstants.IsValidPrivateECTag(tag) => CreatePrivateEcFromPivEncoding(pivEncodingBytes),
44-
_ when PivConstants.IsValidPrivateRSATag(tag) => CreatePrivateRsaFromPivEncoding(pivEncodingBytes),
45-
_ => throw new ArgumentException(
46-
string.Format(CultureInfo.CurrentCulture, ExceptionMessages.InvalidPrivateKeyData))
40+
ExceptionMessages.InvalidApduResponseData))
4741
};
48-
49-
return (T)pkp;
50-
}
5142

52-
public static IPublicKeyParameters CreatePublicParameters(ReadOnlyMemory<byte> value, KeyType keyType)
53-
{
54-
return keyType switch
43+
// TODO Is this needed?
44+
public static IPrivateKeyParameters CreatePrivateKeyParameters(ReadOnlyMemory<byte> value, KeyType keyType) =>
45+
keyType switch
5546
{
5647
KeyType.Ed25519 or KeyType.X25519 => KeyParametersPivHelper
57-
.CreatePublicCurve25519FromPivEncoding(value, keyType),
48+
.CreatePrivateCurve25519FromPivEncoding(value, keyType),
5849
KeyType.P256 or KeyType.P384 or KeyType.P521 => KeyParametersPivHelper
59-
.CreatePublicEcFromPivEncoding(value),
50+
.CreatePrivateEcFromPivEncoding(value),
6051
KeyType.RSA1024 or KeyType.RSA2048 or KeyType.RSA3072 or KeyType.RSA4096 => KeyParametersPivHelper
61-
.CreatePublicRsaFromPivEncoding(value),
52+
.CreatePrivateRsaFromPivEncoding(value),
6253
_ => throw new InvalidOperationException(
6354
string.Format(
6455
CultureInfo.CurrentCulture,
6556
ExceptionMessages.InvalidApduResponseData))
6657
};
67-
}
6858

6959
public static RSAPublicKeyParameters CreatePublicRsaFromPivEncoding(ReadOnlyMemory<byte> pivEncodingBytes)
7060
{
@@ -108,30 +98,63 @@ public static Curve25519PublicKeyParameters CreatePublicCurve25519FromPivEncodin
10898
var publicPoint = PivEncodingReader.GetECPublicPointValues(pivEncodingBytes);
10999
return Curve25519PublicKeyParameters.CreateFromValue(publicPoint, keyType);
110100
}
101+
102+
public static Curve25519PrivateKeyParameters CreatePrivateCurve25519FromPivEncoding(
103+
ReadOnlyMemory<byte> pivEncodingBytes,
104+
KeyType keyType)
105+
{
106+
if (!TlvObject.TryParse(pivEncodingBytes.Span, out var tlv) || !PivConstants.IsValidPrivateECTag(tlv.Tag))
107+
{
108+
throw new ArgumentException(
109+
string.Format(
110+
CultureInfo.CurrentCulture,
111+
ExceptionMessages.InvalidPrivateKeyData));
112+
}
113+
114+
using var privateValueHandle = new ZeroingMemoryHandle(tlv.Value.ToArray());
115+
116+
return tlv.Tag switch
117+
{
118+
PivConstants.PrivateECEd25519Tag when keyType == KeyType.Ed25519 => Curve25519PrivateKeyParameters.CreateFromValue(
119+
privateValueHandle.Data, KeyType.Ed25519),
120+
121+
PivConstants.PrivateECX25519Tag when keyType == KeyType.X25519 => Curve25519PrivateKeyParameters.CreateFromValue(
122+
privateValueHandle.Data, KeyType.X25519),
123+
124+
_ => throw new ArgumentException(
125+
string.Format(
126+
CultureInfo.CurrentCulture,
127+
ExceptionMessages.InvalidPrivateKeyData))
128+
};
129+
}
111130

112131
public static ECPrivateKeyParameters CreatePrivateEcFromPivEncoding(ReadOnlyMemory<byte> pivEncodingBytes)
113132
{
114-
if (TlvObject.TryParse(pivEncodingBytes.Span, out var tlv) && PivConstants.IsValidPrivateECTag(tlv.Tag))
133+
if (!TlvObject.TryParse(pivEncodingBytes.Span, out var tlv) || tlv.Tag != PivConstants.PrivateECDsaTag)
115134
{
116-
switch (tlv.Tag)
117-
{
118-
case PivConstants.PrivateECDsaTag:
119-
List<KeyDefinition> allowed =
120-
[KeyDefinitions.P256, KeyDefinitions.P384, KeyDefinitions.P521];
121-
122-
var keyDefinition = allowed.Single(kd => kd.LengthInBytes == tlv.Value.Span.Length);
123-
return ECPrivateKeyParameters.CreateFromValue(tlv.Value.Span.ToArray(), keyDefinition.KeyType);
124-
case PivConstants.PrivateECEd25519Tag:
125-
return ECPrivateKeyParameters.CreateFromValue(tlv.Value.ToArray(), KeyType.Ed25519);
126-
case PivConstants.PrivateECX25519Tag:
127-
return ECPrivateKeyParameters.CreateFromValue(tlv.Value.ToArray(), KeyType.X25519);
128-
}
135+
throw new ArgumentException(
136+
string.Format(
137+
CultureInfo.CurrentCulture,
138+
ExceptionMessages.InvalidPrivateKeyData));
139+
}
140+
141+
var allowedKeyDefinitions = KeyDefinitions
142+
.GetEcKeyDefinitions()
143+
.Where(kd => kd.AlgorithmOid == KeyDefinitions.CryptoOids.ECDSA);
144+
try
145+
{
146+
var keyDefinition = allowedKeyDefinitions
147+
.Single(kd => kd.LengthInBytes == tlv.Value.Span.Length);
148+
ReadOnlyMemory<byte> value = tlv.Value;
149+
return ECPrivateKeyParameters.CreateFromValue(value, keyDefinition.KeyType);
150+
}
151+
catch (InvalidOperationException)
152+
{
153+
throw new ArgumentException(
154+
string.Format(
155+
CultureInfo.CurrentCulture,
156+
ExceptionMessages.InvalidPrivateKeyData));
129157
}
130-
131-
throw new ArgumentException(
132-
string.Format(
133-
CultureInfo.CurrentCulture,
134-
ExceptionMessages.InvalidPrivateKeyData));
135158
}
136159

137160
public static RSAPrivateKeyParameters CreatePrivateRsaFromPivEncoding(ReadOnlyMemory<byte> pivEncodingBytes)
@@ -177,7 +200,7 @@ public static RSAPrivateKeyParameters CreatePrivateRsaFromPivEncoding(ReadOnlyMe
177200
var exponentQ = valueArray[PivConstants.PrivateRSAExponentQTag - 1].Span;
178201
var coefficient = valueArray[PivConstants.PrivateRSACoefficientTag - 1].Span;
179202

180-
var rsaParameters = new RSAParameters
203+
var parameters = new RSAParameters
181204
{
182205
P = primeP.ToArray(),
183206
Q = primeQ.ToArray(),
@@ -191,6 +214,6 @@ public static RSAPrivateKeyParameters CreatePrivateRsaFromPivEncoding(ReadOnlyMe
191214
Exponent = Array.Empty<byte>(),
192215
};
193216

194-
return RSAPrivateKeyParameters.CreateFromParameters(rsaParameters);
217+
return RSAPrivateKeyParameters.CreateFromParameters(parameters);
195218
}
196219
}

0 commit comments

Comments
 (0)