Skip to content

Commit cbfce51

Browse files
committed
refactor: common methods for base class PrivateKey
1 parent b518ded commit cbfce51

File tree

9 files changed

+138
-200
lines changed

9 files changed

+138
-200
lines changed

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

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@
1717

1818
namespace Yubico.YubiKey.Cryptography;
1919

20-
public sealed class Curve25519PrivateKey : IPrivateKey
20+
public sealed class Curve25519PrivateKey : PrivateKey
2121
{
2222
private readonly Memory<byte> _privateKey;
23-
private bool _disposed;
2423

2524
/// <inheritdoc />
26-
public KeyType KeyType => KeyDefinition.KeyType;
25+
public override KeyType KeyType => KeyDefinition.KeyType;
2726

2827
/// <summary>
2928
/// Gets the key definition associated with this RSA private key.
@@ -56,7 +55,7 @@ private Curve25519PrivateKey(
5655
}
5756

5857
/// <inheritdoc />
59-
public byte[] ExportPkcs8PrivateKey()
58+
public override byte[] ExportPkcs8PrivateKey()
6059
{
6160
ThrowIfDisposed();
6261
return AsnPrivateKeyWriter.EncodeToPkcs8(_privateKey, KeyType);
@@ -67,37 +66,9 @@ public byte[] ExportPkcs8PrivateKey()
6766
/// <remarks>
6867
/// This method securely zeroes out the private key data.
6968
/// </remarks>
70-
public void Clear() => CryptographicOperations.ZeroMemory(_privateKey.Span);
69+
public override void Clear() => CryptographicOperations.ZeroMemory(_privateKey.Span);
7170

72-
/// <summary>
73-
/// Clears private key buffers and disposes the resources used by this instance.
74-
/// </summary>
75-
public void Dispose()
76-
{
77-
Dispose(true);
78-
GC.SuppressFinalize(this);
79-
}
80-
81-
void Dispose(bool disposing)
82-
{
83-
if (!_disposed)
84-
{
85-
if (disposing)
86-
{
87-
Clear();
88-
}
89-
90-
_disposed = true;
91-
}
92-
}
9371

94-
private void ThrowIfDisposed()
95-
{
96-
if (_disposed)
97-
{
98-
throw new ObjectDisposedException(nameof(Curve25519PrivateKey));
99-
}
100-
}
10172

10273
/// <summary>
10374
/// Creates an instance of <see cref="Curve25519PrivateKey"/> from a PKCS#8

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

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@ namespace Yubico.YubiKey.Cryptography
2424
/// This class encapsulates the parameters specific to EC private keys and
2525
/// contains the necessary private key data.
2626
/// </remarks>
27-
public class ECPrivateKey : IPrivateKey
27+
public class ECPrivateKey : PrivateKey
2828
{
29-
private bool _disposed;
30-
3129
/// <summary>
3230
/// Gets the Elliptic Curve parameters associated with this instance.
3331
/// </summary>
@@ -45,8 +43,8 @@ public class ECPrivateKey : IPrivateKey
4543
/// </value>
4644
public KeyDefinition KeyDefinition { get; }
4745

48-
/// <inheritdoc/>
49-
public KeyType KeyType => KeyDefinition.KeyType;
46+
/// <inheritdoc />
47+
public override KeyType KeyType => KeyDefinition.KeyType;
5048

5149
/// <summary>
5250
/// Initializes a new instance of the <see cref="ECPrivateKey"/> class.
@@ -88,58 +86,22 @@ public ECPrivateKey(ECDsa ecdsaObject)
8886
Parameters = ecdsaObject.ExportParameters(true);
8987
KeyDefinition = KeyDefinitions.GetByOid(Parameters.Curve.Oid);
9088
}
91-
89+
9290
/// <inheritdoc/>
93-
public byte[] ExportPkcs8PrivateKey()
91+
public override byte[] ExportPkcs8PrivateKey()
9492
{
9593
ThrowIfDisposed();
9694
return AsnPrivateKeyWriter.EncodeToPkcs8(Parameters);
9795
}
9896

9997
/// <inheritdoc/>
100-
public void Clear()
98+
public override void Clear()
10199
{
102100
CryptographicOperations.ZeroMemory(Parameters.Q.Y);
103101
CryptographicOperations.ZeroMemory(Parameters.Q.X);
104102
CryptographicOperations.ZeroMemory(Parameters.D);
105103
}
106104

107-
/// <summary>
108-
/// Disposes the resources used by this instance.
109-
/// </summary>
110-
public void Dispose()
111-
{
112-
Dispose(true);
113-
GC.SuppressFinalize(this);
114-
}
115-
116-
/// <summary>
117-
/// Disposes the resources used by this instance.
118-
/// </summary>
119-
/// <param name="disposing">
120-
/// True to release both managed and unmanaged resources; false to release only unmanaged resources.
121-
/// </param>
122-
private void Dispose(bool disposing)
123-
{
124-
if (!_disposed)
125-
{
126-
if (disposing)
127-
{
128-
Clear();
129-
}
130-
131-
_disposed = true;
132-
}
133-
}
134-
135-
private void ThrowIfDisposed()
136-
{
137-
if (_disposed)
138-
{
139-
throw new ObjectDisposedException(nameof(Curve25519PrivateKey));
140-
}
141-
}
142-
143105
/// <summary>
144106
/// Creates a new instance of <see cref="ECPrivateKey"/> from a DER-encoded private key.
145107
/// </summary>

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/IPrivateKey.cs

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
namespace Yubico.YubiKey.Cryptography;
1818

19-
public interface IPrivateKey : IKeyBase, IDisposable
19+
public interface IPrivateKey : IKeyBase
2020
{
2121
/// <summary>
2222
/// Exports the current key in the PKCS#8 PrivateKeyInfo format.
@@ -25,15 +25,45 @@ public interface IPrivateKey : IKeyBase, IDisposable
2525
/// A byte array containing the PKCS#8 PrivateKeyInfo representation of this key.
2626
/// </returns>
2727
public byte[] ExportPkcs8PrivateKey();
28-
28+
2929
/// <summary>
3030
/// Clears the buffers containing private key data.
3131
/// </summary>
3232
public void Clear();
3333
}
3434

35-
public static class IPrivateKeyExtensions
35+
public abstract class PrivateKey : IPrivateKey, IDisposable
3636
{
37-
public static T Cast<T>(this IPrivateKey key) where T : class, IPrivateKey
38-
=> key as T ?? throw new InvalidCastException($"Cannot cast {key.GetType()} to {typeof(T)}");
37+
private bool _disposed;
38+
39+
/// <inheritdoc />
40+
public abstract KeyType KeyType { get; }
41+
42+
/// <inheritdoc />
43+
public abstract byte[] ExportPkcs8PrivateKey();
44+
45+
/// <inheritdoc />
46+
public abstract void Clear();
47+
48+
/// <summary>
49+
/// Clears the private key data and disposes the object
50+
/// </summary>
51+
public void Dispose()
52+
{
53+
if (!_disposed)
54+
{
55+
Clear();
56+
_disposed = true;
57+
}
58+
59+
GC.SuppressFinalize(this);
60+
}
61+
62+
protected void ThrowIfDisposed()
63+
{
64+
if (_disposed)
65+
{
66+
throw new ObjectDisposedException(GetType().Name);
67+
}
68+
}
3969
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
17+
namespace Yubico.YubiKey.Cryptography;
18+
19+
public static class IPrivateKeyExtensions
20+
{
21+
/// <summary>
22+
/// Casts the key to the specified type.
23+
/// </summary>
24+
/// <param name="key"></param>
25+
/// <typeparam name="T"></typeparam>
26+
/// <returns></returns>
27+
/// <exception cref="InvalidCastException"></exception>
28+
public static T Cast<T>(this IPrivateKey key) where T : class, IPrivateKey =>
29+
key as T ?? throw new InvalidCastException($"Cannot cast {key.GetType()} to {typeof(T)}");
30+
}

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/IPublicKey.cs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15-
using System;
16-
1715
namespace Yubico.YubiKey.Cryptography;
1816

1917
public interface IPublicKey : IKeyBase
@@ -26,9 +24,3 @@ public interface IPublicKey : IKeyBase
2624
/// </returns>
2725
public byte[] ExportSubjectPublicKeyInfo();
2826
}
29-
30-
public static class IPublicKeyExtensions
31-
{
32-
public static T Cast<T>(this IPublicKey key) where T : class, IPublicKey
33-
=> key as T ?? throw new InvalidCastException($"Cannot cast {key.GetType()} to {typeof(T)}");
34-
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
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+
17+
namespace Yubico.YubiKey.Cryptography;
18+
19+
public static class IPublicKeyExtensions
20+
{
21+
/// <summary>
22+
/// Casts the given <see cref="IPublicKey"/> to the specified type.
23+
/// </summary>
24+
/// <param name="key"></param>
25+
/// <typeparam name="T"></typeparam>
26+
/// <returns></returns>
27+
/// <exception cref="InvalidCastException"></exception>
28+
public static T Cast<T>(this IPublicKey key) where T : class, IPublicKey
29+
=> key as T ?? throw new InvalidCastException($"Cannot cast {key.GetType()} to {typeof(T)}");
30+
}

Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/RSAPrivateKey.cs

Lines changed: 5 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717

1818
namespace Yubico.YubiKey.Cryptography;
1919

20-
public sealed class RSAPrivateKey : IPrivateKey
20+
public sealed class RSAPrivateKey : PrivateKey
2121
{
22-
private bool _disposed;
2322

2423
/// <summary>
2524
/// Gets the RSA cryptographic parameters required for the private key operations.
@@ -40,9 +39,9 @@ public sealed class RSAPrivateKey : IPrivateKey
4039
/// A <see cref="KeyDefinition"/> object that describes the key's properties, including its type and length.
4140
/// </value>
4241
public KeyDefinition KeyDefinition { get; }
43-
42+
4443
/// <inheritdoc />
45-
public KeyType KeyType => KeyDefinition.KeyType;
44+
public override KeyType KeyType => KeyDefinition.KeyType;
4645

4746
private RSAPrivateKey(RSAParameters parameters)
4847
{
@@ -56,7 +55,7 @@ private RSAPrivateKey(RSAParameters parameters)
5655
/// Exports the RSA private key in PKCS#8 DER encoded format.
5756
/// </summary>
5857
/// <returns>A byte array containing the DER encoded private key.</returns>
59-
public byte[] ExportPkcs8PrivateKey()
58+
public override byte[] ExportPkcs8PrivateKey()
6059
{
6160
ThrowIfDisposed();
6261
return AsnPrivateKeyWriter.EncodeToPkcs8(Parameters);
@@ -65,7 +64,7 @@ public byte[] ExportPkcs8PrivateKey()
6564
/// <summary>
6665
/// Securely clears the RSA private key by zeroing out all parameters.
6766
/// </summary>
68-
public void Clear()
67+
public override void Clear()
6968
{
7069
CryptographicOperations.ZeroMemory(Parameters.Modulus);
7170
CryptographicOperations.ZeroMemory(Parameters.Exponent);
@@ -77,36 +76,6 @@ public void Clear()
7776
CryptographicOperations.ZeroMemory(Parameters.InverseQ);
7877
}
7978

80-
/// <summary>
81-
/// Clears private key buffers and disposes the resources used by this instance.
82-
/// </summary>
83-
public void Dispose()
84-
{
85-
Dispose(true);
86-
GC.SuppressFinalize(this);
87-
}
88-
89-
private void Dispose(bool disposing)
90-
{
91-
if (!_disposed)
92-
{
93-
if (disposing)
94-
{
95-
Clear();
96-
}
97-
98-
_disposed = true;
99-
}
100-
}
101-
102-
private void ThrowIfDisposed()
103-
{
104-
if (_disposed)
105-
{
106-
throw new ObjectDisposedException(nameof(Curve25519PrivateKey));
107-
}
108-
}
109-
11079
/// <summary>
11180
/// Creates a new instance of <see cref="RSAPrivateKey"/> from a DER-encoded
11281
/// PKCS#8 private key.

0 commit comments

Comments
 (0)