Skip to content

Commit a555bdb

Browse files
committed
misc: consistency
consistent naming and public key hierarchy
1 parent ee2051e commit a555bdb

39 files changed

+618
-537
lines changed

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPrivateKeyReader.cs renamed to Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPrivateKeyDecoder.cs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
namespace Yubico.YubiKey.Cryptography;
2222

23-
internal class AsnPrivateKeyReader
23+
internal class AsnPrivateKeyDecoder
2424
{
2525
public static IPrivateKey CreatePrivateKey(ReadOnlyMemory<byte> pkcs8EncodedKey)
2626
{
@@ -102,12 +102,13 @@ public static (byte[], KeyType) GetCurve25519PrivateKeyData(ReadOnlyMemory<byte>
102102
{
103103
throw new CryptographicException("Invalid Curve25519 private key: incorrect length");
104104
}
105-
seqPrivateKeyInfo.ThrowIfNotEmpty();
106105

106+
seqPrivateKeyInfo.ThrowIfNotEmpty();
107107

108108
var keyDefinition = KeyDefinitions.GetByOid(algorithmOid);
109109
return (privateKey, keyDefinition.KeyType);
110110
}
111+
111112
public static ECParameters CreateECParameters(ReadOnlyMemory<byte> pkcs8EncodedKey)
112113
{
113114
var reader = new AsnReader(pkcs8EncodedKey, AsnEncodingRules.DER);
@@ -261,7 +262,7 @@ public static RSAParameters CreateRSAParameters(ReadOnlyMemory<byte> pkcs8Encode
261262
DQ = exponent2.ToArray(),
262263
InverseQ = coefficient.ToArray()
263264
};
264-
265+
265266
return rsaParameters.NormalizeParameters();
266267
}
267268
}

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPrivateKeyWriter.cs renamed to Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPrivateKeyEncoder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace Yubico.YubiKey.Cryptography;
2121
/// <summary>
2222
/// A class that converts private key parameters to ASN.1 DER encoding.
2323
/// </summary>
24-
internal static class AsnPrivateKeyWriter
24+
internal static class AsnPrivateKeyEncoder
2525
{
2626
/// <summary>
2727
/// Converts a private key and its corresponding public point to ASN.1 DER encoded format.

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPublicKeyReader.cs renamed to Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPublicKeyDecoder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
namespace Yubico.YubiKey.Cryptography;
2121

22-
internal class AsnPublicKeyReader
22+
internal class AsnPublicKeyDecoder
2323
{
2424
public static IPublicKey CreatePublicKey(ReadOnlyMemory<byte> pkcs8EncodedKey)
2525
{

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPublicKeyWriter.cs renamed to Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPublicKeyEncoder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ namespace Yubico.YubiKey.Cryptography;
2121
/// <summary>
2222
/// A class that converts public key parameters to ASN.1 DER encoding.
2323
/// </summary>
24-
internal static class AsnPublicKeyWriter
24+
internal static class AsnPublicKeyEncoder
2525
{
2626
/// <summary>
2727
/// Converts a public point and key type to ASN.1 DER encoded format.

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/Curve25519PrivateKey.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ private Curve25519PrivateKey(
5858
public override byte[] ExportPkcs8PrivateKey()
5959
{
6060
ThrowIfDisposed();
61-
return AsnPrivateKeyWriter.EncodeToPkcs8(_privateKey, KeyType);
61+
return AsnPrivateKeyEncoder.EncodeToPkcs8(_privateKey, KeyType);
6262
}
6363
/// <summary>
6464
/// Clears the private key.
@@ -86,7 +86,7 @@ public override byte[] ExportPkcs8PrivateKey()
8686
/// <exception cref="CryptographicException">Thrown if privateKey does not match expected format.</exception>
8787
public static Curve25519PrivateKey CreateFromPkcs8(ReadOnlyMemory<byte> pkcs8EncodedKey)
8888
{
89-
(byte[] privateKey, var keyType) = AsnPrivateKeyReader.GetCurve25519PrivateKeyData(pkcs8EncodedKey);
89+
(byte[] privateKey, var keyType) = AsnPrivateKeyDecoder.GetCurve25519PrivateKeyData(pkcs8EncodedKey);
9090
using var privateKeyHandle = new ZeroingMemoryHandle(privateKey);
9191
return new Curve25519PrivateKey(privateKeyHandle.Data, keyType);
9292
}

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/Curve25519PublicKey.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
namespace Yubico.YubiKey.Cryptography;
2121

22-
public sealed class Curve25519PublicKey : IPublicKey
22+
public sealed class Curve25519PublicKey : PublicKey
2323
{
2424
private readonly Memory<byte> _publicPoint;
2525

@@ -32,7 +32,7 @@ public sealed class Curve25519PublicKey : IPublicKey
3232
public KeyDefinition KeyDefinition { get; }
3333

3434
/// <inheritdoc />
35-
public KeyType KeyType => KeyDefinition.KeyType;
35+
public override KeyType KeyType => KeyDefinition.KeyType;
3636

3737
/// <summary>
3838
/// Gets the bytes representing the public key coordinates as a compressed point.
@@ -59,8 +59,8 @@ private Curve25519PublicKey(
5959
/// <returns>
6060
/// A byte array containing the ASN.1 DER encoded public key.
6161
/// </returns>
62-
public byte[] ExportSubjectPublicKeyInfo() =>
63-
AsnPublicKeyWriter.EncodeToSubjectPublicKeyInfo(_publicPoint, KeyDefinition.KeyType);
62+
public override byte[] ExportSubjectPublicKeyInfo() =>
63+
AsnPublicKeyEncoder.EncodeToSubjectPublicKeyInfo(_publicPoint, KeyDefinition.KeyType);
6464

6565
/// <summary>
6666
/// Creates a new instance of <see cref="Curve25519PublicKey"/> from a DER-encoded public key.

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/ECPrivateKey.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ public ECPrivateKey(ECDsa ecdsaObject)
9191
public override byte[] ExportPkcs8PrivateKey()
9292
{
9393
ThrowIfDisposed();
94-
return AsnPrivateKeyWriter.EncodeToPkcs8(Parameters);
94+
return AsnPrivateKeyEncoder.EncodeToPkcs8(Parameters);
9595
}
9696

9797
/// <inheritdoc/>
@@ -116,7 +116,7 @@ public override void Clear()
116116
/// </exception>
117117
public static ECPrivateKey CreateFromPkcs8(ReadOnlyMemory<byte> encodedKey)
118118
{
119-
var parameters = AsnPrivateKeyReader.CreateECParameters(encodedKey);
119+
var parameters = AsnPrivateKeyDecoder.CreateECParameters(encodedKey);
120120
return CreateFromParameters(parameters);
121121
}
122122

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
// Copyright 2024 Yubico AB
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License").
4+
// You may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
using System;
16+
using System.Security.Cryptography;
17+
18+
namespace Yubico.YubiKey.Cryptography;
19+
20+
/// <summary>
21+
/// Represents the parameters for an Elliptic Curve (EC) public key.
22+
/// </summary>
23+
/// <remarks>
24+
/// This class encapsulates the parameters specific to EC public keys,
25+
/// ensuring that the key only contains necessary public key components.
26+
/// </remarks>
27+
public class ECPublicKey : PublicKey
28+
{
29+
private readonly byte[] _publicPointBytes;
30+
31+
/// <summary>
32+
/// Gets the key definition associated with this RSA private key.
33+
/// </summary>
34+
/// <value>
35+
/// A <see cref="KeyDefinition"/> object that describes the key's properties, including its type and length.
36+
/// </value>
37+
public KeyDefinition KeyDefinition { get; }
38+
39+
/// <summary>
40+
/// Gets the Elliptic Curve parameters associated with this instance.
41+
/// </summary>
42+
/// <value>
43+
/// An <see cref="ECParameters"/> structure containing the curve parameters, key, and other
44+
/// cryptographic elements needed for EC operations.
45+
/// </value>
46+
public ECParameters Parameters { get; }
47+
48+
/// <summary>
49+
/// Gets the bytes representing the public key coordinates.
50+
/// </summary>
51+
/// <returns>A <see cref="ReadOnlyMemory{T}"/> containing the public key bytes with the format 0x04 || X || Y.</returns>
52+
public ReadOnlyMemory<byte> PublicPoint => _publicPointBytes;
53+
54+
/// <inheritdoc />
55+
public override KeyType KeyType => KeyDefinition.KeyType;
56+
57+
/// <summary>
58+
/// Initializes a new instance of the <see cref="ECPublicKey"/> class.
59+
/// It is a wrapper for the <see cref="ECParameters"/> class.
60+
/// </summary>
61+
/// <remarks>
62+
/// This constructor is used to create an instance from a <see cref="ECParameters"/> object.
63+
/// It will deep copy the parameters from the <see cref="ECParameters"/> object.
64+
/// </remarks>
65+
/// <param name="parameters"></param>
66+
/// <exception cref="ArgumentException">Thrown when the parameters contain private key data (D value).</exception>
67+
protected ECPublicKey(ECParameters parameters)
68+
{
69+
if (parameters.D != null)
70+
{
71+
throw new ArgumentException(
72+
"Parameters must not contain private key data (D value)", nameof(parameters));
73+
}
74+
75+
Parameters = parameters.DeepCopy();
76+
KeyDefinition = KeyDefinitions.GetByOid(Parameters.Curve.Oid);
77+
78+
// Format identifier (uncompressed point): 0x04
79+
_publicPointBytes = [0x4, .. Parameters.Q.X, .. Parameters.Q.Y];
80+
}
81+
82+
/// <summary>
83+
/// Initializes a new instance of the <see cref="ECPublicKey"/> class.
84+
/// </summary>
85+
/// <param name="ecdsa"></param>
86+
protected ECPublicKey(ECDsa ecdsa)
87+
{
88+
if (ecdsa == null)
89+
{
90+
throw new ArgumentNullException(nameof(ecdsa));
91+
}
92+
93+
Parameters = ecdsa.ExportParameters(false);
94+
KeyDefinition = KeyDefinitions.GetByOid(Parameters.Curve.Oid);
95+
96+
// Format identifier (uncompressed point): 0x04
97+
_publicPointBytes = [0x4, .. Parameters.Q.X, .. Parameters.Q.Y];
98+
}
99+
100+
/// <inheritdoc />
101+
public override byte[] ExportSubjectPublicKeyInfo() => AsnPublicKeyEncoder.EncodeToSubjectPublicKeyInfo(Parameters);
102+
103+
104+
/// <summary>
105+
/// Creates an instance of <see cref="ECPublicKey"/> from the given <paramref name="parameters"/>.
106+
/// </summary>
107+
/// <param name="parameters">The parameters to create the key from.</param>
108+
/// <returns>An instance of <see cref="ECPublicKey"/>.</returns>
109+
public static ECPublicKey CreateFromParameters(ECParameters parameters) => new(parameters);
110+
111+
/// <summary>
112+
/// Creates an instance of <see cref="ECPublicKey"/> from the given
113+
/// <paramref name="publicPoint"/> and <paramref name="keyType"/>.
114+
/// </summary>
115+
/// <param name="publicPoint">The raw public key data, formatted as an compressed point.</param>
116+
/// <param name="keyType">The type of key this is.</param>
117+
/// <returns>An instance of <see cref="ECPublicKey"/>.</returns>
118+
/// <exception cref="ArgumentException">
119+
/// Thrown if the key type is not a valid EC key.
120+
/// </exception>
121+
public static IPublicKey CreateFromValue(ReadOnlyMemory<byte> publicPoint, KeyType keyType)
122+
{
123+
var keyDefinition = KeyDefinitions.GetByKeyType(keyType);
124+
if (keyDefinition.AlgorithmOid is not Oids.ECDSA)
125+
{
126+
throw new ArgumentException("Only P-256, P-384 and P-521 are supported.", nameof(keyType));
127+
}
128+
129+
int coordinateLength = keyDefinition.LengthInBytes;
130+
var curve = ECCurve.CreateFromValue(keyDefinition.CurveOid);
131+
var ecParameters = new ECParameters
132+
{
133+
Curve = curve,
134+
Q = new ECPoint
135+
{
136+
X = publicPoint.Slice(1, coordinateLength).ToArray(),
137+
Y = publicPoint.Slice(coordinateLength + 1, coordinateLength).ToArray()
138+
}
139+
};
140+
141+
return CreateFromParameters(ecParameters);
142+
}
143+
144+
/// <summary>
145+
/// Creates an instance of <see cref="IPublicKey"/> from a DER-encoded public key.
146+
/// </summary>
147+
/// <param name="encodedKey">The DER-encoded public key.</param>
148+
/// <returns>An instance of <see cref="IPublicKey"/>.</returns>
149+
/// <exception cref="CryptographicException">
150+
/// Thrown if the public key is invalid.
151+
/// </exception>
152+
public static IPublicKey CreateFromPkcs8(ReadOnlyMemory<byte> encodedKey) =>
153+
AsnPublicKeyDecoder.CreatePublicKey(encodedKey);
154+
155+
/// <summary>
156+
/// Gets the bytes representing the public key coordinates.
157+
/// </summary>
158+
/// <returns>A <see cref="ReadOnlyMemory{T}"/> containing the public key bytes with the format 0x04 || X || Y.</returns>
159+
[Obsolete("Use PublicPoint instead")]
160+
public ReadOnlyMemory<byte> GetBytes() => _publicPointBytes;
161+
}

0 commit comments

Comments
 (0)