diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPrivateKeyEncoder.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPrivateKeyEncoder.cs index 05c44561e..607c16e4c 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPrivateKeyEncoder.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/AsnPrivateKeyEncoder.cs @@ -190,7 +190,7 @@ private static byte[] EncodeECKey( writer.PopSequence(); // PrivateKey as OCTET STRING - writer.WriteOctetString(ecPrivateKeyHandle.Data); + writer.WriteOctetString(ecPrivateKeyHandle.Data.Span); writer.PopSequence(); return writer.Encode(); @@ -237,7 +237,7 @@ private static byte[] EncodeCurve25519Key(ReadOnlySpan privateKey, string privateKeyWriter.WriteOctetString(privateKey); using var privateKeyBytesHandle = new ZeroingMemoryHandle(privateKeyWriter.Encode()); - writer.WriteOctetString(privateKeyBytesHandle.Data); + writer.WriteOctetString(privateKeyBytesHandle.Data.Span); // End PrivateKeyInfo SEQUENCE writer.PopSequence(); diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/EcdsaVerify.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/EcdsaVerify.cs index 6c3b696d2..d495a043f 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/EcdsaVerify.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/EcdsaVerify.cs @@ -158,6 +158,7 @@ public EcdsaVerify(ECDsa ecdsa) /// /// The key is not for a supported algorithm or curve, or is malformed. /// + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public EcdsaVerify(PivPublicKey pivPublicKey) { if (pivPublicKey is null) @@ -171,6 +172,21 @@ public EcdsaVerify(PivPublicKey pivPublicKey) ECDsa = ConvertPublicKey(publicPointSpan.ToArray()); } + + public EcdsaVerify(ECPublicKey publicKey) + { + if (publicKey is null) + { + throw new ArgumentNullException(nameof(publicKey)); + } + + if (!publicKey.KeyType.IsECDsa()) + { + throw new ArgumentException("Invalid key type", nameof(publicKey)); + } + + ECDsa = ConvertPublicKey(publicKey.PublicPoint); + } /// /// Create an instance of the class using the @@ -331,7 +347,8 @@ public bool VerifyDigestedData( private static ECDsa ConvertPublicKey(ReadOnlyMemory encodedEccPoint) { - int minEncodedPointLength = (KeyDefinitions.P256.LengthInBytes * 2) + 1; // This is the minimum length for an encoded point on P-256 (0x04 || x || y) + // This is the minimum length for an encoded point on P-256 (0x04 || x || y) + int minEncodedPointLength = (KeyDefinitions.P256.LengthInBytes * 2) + 1; if (encodedEccPoint.Length < minEncodedPointLength || encodedEccPoint.Span[0] != EncodedPointTag) { throw new ArgumentException(ExceptionMessages.UnsupportedAlgorithm); diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/ZeroingMemoryHandle.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/ZeroingMemoryHandle.cs index c4c61167d..4072b24fb 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/ZeroingMemoryHandle.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Cryptography/ZeroingMemoryHandle.cs @@ -13,68 +13,26 @@ // limitations under the License. using System; -using System.Collections; -using System.Collections.Generic; using System.Security.Cryptography; namespace Yubico.YubiKey.Cryptography; -#pragma warning disable CA1710 -internal class ZeroingMemoryHandle : IDisposable, IReadOnlyCollection, IEnumerable -#pragma warning restore CA1710 +internal class ZeroingMemoryHandle : IDisposable { - private readonly byte[] _data; + private readonly Memory _data; private bool _disposed; - public int Length => _disposed ? 0 : _data.Length; - public int Count => Length; // For IReadOnlyCollection - - public byte this[int index] => _disposed - ? throw new ObjectDisposedException(nameof(ZeroingMemoryHandle)) - : _data[index]; + public int Count => Length; - public ZeroingMemoryHandle(byte[] data) + public ZeroingMemoryHandle(Memory data) { - _data = data ?? throw new ArgumentNullException(nameof(data)); + _data = data; } - public ReadOnlySpan AsSpan() => _disposed - ? ReadOnlySpan.Empty - : _data.AsSpan(); - - public byte[] Data => _disposed + public Memory Data => _disposed ? throw new ObjectDisposedException(nameof(ZeroingMemoryHandle)) : _data; - - public void CopyTo(byte[] destination, int destinationIndex = 0) - { - if (_disposed) - { - throw new ObjectDisposedException(nameof(ZeroingMemoryHandle)); - } - - Buffer.BlockCopy(_data, 0, destination, destinationIndex, _data.Length); - } - - public ReadOnlySpan Slice(int start, int length) => _disposed - ? ReadOnlySpan.Empty - : _data.AsSpan(start, length); - - public IEnumerator GetEnumerator() - { - if (_disposed) - { - throw new ObjectDisposedException(nameof(ZeroingMemoryHandle)); - } - - for (int i = 0; i < _data.Length; i++) - { - yield return _data[i]; - } - } - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - + public void Dispose() { if (_disposed) @@ -82,7 +40,7 @@ public void Dispose() return; } - CryptographicOperations.ZeroMemory(_data); + CryptographicOperations.ZeroMemory(_data.Span); _disposed = true; GC.SuppressFinalize(this); } diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/GenerateKeyPairResponse.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/GenerateKeyPairResponse.cs index 936b64c68..c9690acfe 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/GenerateKeyPairResponse.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/GenerateKeyPairResponse.cs @@ -85,7 +85,9 @@ namespace Yubico.YubiKey.Piv.Commands /// PivPublicKey pubKey = generateKeyPairResponse.GetData(); /// /// + #pragma warning disable CS0618 // Type or member is obsolete public class GenerateKeyPairResponse : PivResponse, IYubiKeyResponseWithData + #pragma warning restore CS0618 // Type or member is obsolete { private byte _slotNumber; private PivAlgorithm _algorithm; @@ -190,11 +192,14 @@ public GenerateKeyPairResponse( /// /// Thrown when is not . /// + #pragma warning disable CS0618 // Type or member is obsolete public PivPublicKey GetData() => Status switch { ResponseStatus.Success => PivPublicKey.Create(ResponseApdu.Data, Algorithm), _ => throw new InvalidOperationException(StatusMessage), }; + #pragma warning restore CS0618 // Type or member is obsolete + } } diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/ImportAsymmetricKeyCommand.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/ImportAsymmetricKeyCommand.cs index 64d2602a0..0e8688ec1 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/ImportAsymmetricKeyCommand.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/ImportAsymmetricKeyCommand.cs @@ -215,7 +215,8 @@ private ImportAsymmetricKeyCommand() /// /// The privateKey argument does not contain a key. /// - [Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use IPublicKey, IPrivateKey instead", false)] + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] + public ImportAsymmetricKeyCommand( PivPrivateKey privateKey, byte slotNumber, @@ -274,7 +275,8 @@ public ImportAsymmetricKeyCommand( /// /// The privateKey argument does not contain a key. /// - [Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use IPublicKey, IPrivateKey instead", false)] + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] + public ImportAsymmetricKeyCommand(PivPrivateKey privateKey) { if (privateKey is null) diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Converters/KeyExtensions.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Converters/KeyExtensions.cs index 7600a7b38..9194013eb 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Converters/KeyExtensions.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Converters/KeyExtensions.cs @@ -33,31 +33,38 @@ public static class KeyExtensions /// The public key parameters to encode. /// A BER encoded byte array containing the encoded public key. /// Thrown when the key type is not supported. - public static Memory EncodeAsPiv(this IPublicKey parameters) - { - return parameters switch + public static Memory EncodeAsPiv(this IPublicKey parameters) => + parameters switch { ECPublicKey p => PivKeyEncoder.EncodeECPublicKey(p), RSAPublicKey p => PivKeyEncoder.EncodeRSAPublicKey(p), Curve25519PublicKey p => PivKeyEncoder.EncodeCurve25519PublicKey(p), - _ => throw new ArgumentException("The type conversion for the specified key type is not supported", nameof(parameters)) + + #pragma warning disable CS0618 // Type or member is obsolete + PivPublicKey p => p.PivEncodedPublicKey.ToArray(), + #pragma warning restore CS0618 // Type or member is obsolete + _ => throw new ArgumentException( + "The type conversion for the specified key type is not supported", nameof(parameters)) }; - } - + /// /// Encodes a private key into the PIV format. /// /// The private key parameters to encode. /// A BER encoded byte array containing the encoded private key. /// Thrown when the key type is not supported or when RSA key components have invalid lengths. - public static Memory EncodeAsPiv(this IPrivateKey parameters) - { - return parameters switch + /// This method returns a newly allocated array containing sensitive information. + public static Memory EncodeAsPiv(this IPrivateKey parameters) => + parameters switch { ECPrivateKey p => PivKeyEncoder.EncodeECPrivateKey(p), RSAPrivateKey p => PivKeyEncoder.EncodeRSAPrivateKey(p), Curve25519PrivateKey p => PivKeyEncoder.EncodeCurve25519PrivateKey(p), - _ => throw new ArgumentException("The type conversion for the specified key type is not supported", nameof(parameters)) + + #pragma warning disable CS0618 // Type or member is obsolete + PivPrivateKey p => p.EncodedPrivateKey.ToArray(), + #pragma warning restore CS0618 // Type or member is obsolete + _ => throw new ArgumentException( + "The type conversion for the specified key type is not supported", nameof(parameters)) }; - } } diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Converters/PivKeyEncoder.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Converters/PivKeyEncoder.cs index 9ba76fd67..2a8f0c147 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Converters/PivKeyEncoder.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Converters/PivKeyEncoder.cs @@ -20,11 +20,11 @@ namespace Yubico.YubiKey.Piv.Converters; /// -/// This class converts from a Piv Encoded Key to either instances of the common IPublicKey and IPrivateKey -/// or concrete the concrete types that inherit these interfaces. +/// This class converts from IPublicKey, IPrivateKey and implementations of either to a PIV-encoded key. /// -internal class PivKeyEncoder +internal static class PivKeyEncoder { + [Obsolete("KeyExtensions instead", false)] public static Memory EncodePublicKey(IPublicKey publicKey) { return publicKey switch @@ -35,7 +35,7 @@ public static Memory EncodePublicKey(IPublicKey publicKey) _ => throw new ArgumentException("Unsupported public key type."), }; } - + public static Memory EncodeRSAPublicKey(RSAPublicKey publicKey) { var rsaParameters = publicKey.Parameters; @@ -70,17 +70,17 @@ public static Memory EncodeECPublicKey(ECPublicKey publicKey) return tlvWriter.Encode(); } - - public static Memory EncodePrivateKey(IPrivateKey publicKey) - { - return publicKey switch + + [Obsolete("KeyExtensions instead", false)] + public static Memory EncodePrivateKey(IPrivateKey publicKey) => + publicKey switch { Curve25519PrivateKey curve25519PrivateKey => EncodeCurve25519PrivateKey(curve25519PrivateKey), ECPrivateKey ecPrivateKey => EncodeECPrivateKey(ecPrivateKey), RSAPrivateKey rsaPrivateKey => EncodeRSAPrivateKey(rsaPrivateKey), + _ => throw new ArgumentException("Unsupported public key type."), }; - } public static Memory EncodeECPrivateKey(ECPrivateKey privateKey) { diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivEccPrivateKey.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivEccPrivateKey.cs index ee58def59..0ed8cb76e 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivEccPrivateKey.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivEccPrivateKey.cs @@ -13,9 +13,12 @@ // limitations under the License. using System; +using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Security.Cryptography; using Yubico.Core.Tlv; +using Yubico.YubiKey.Cryptography; namespace Yubico.YubiKey.Piv { @@ -27,11 +30,11 @@ namespace Yubico.YubiKey.Piv /// of a point on the curve. So for ECC P-256, each coordinate is 32 bytes /// (256 bits), so the private value will be 32 bytes. /// + [Obsolete( + "Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", + false)] public sealed class PivEccPrivateKey : PivPrivateKey { - private const int EccP256PrivateKeySize = 32; - private const int EccP384PrivateKeySize = 48; - private Memory _privateValue; // @@ -66,29 +69,19 @@ private PivEccPrivateKey() /// /// The size of the private value is not supported by the YubiKey. /// + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use ECPublicKey, ECPrivateKey instead", false)] public PivEccPrivateKey( - ReadOnlySpan privateValue, + ReadOnlySpan privateValue, PivAlgorithm? algorithm = null) { if (algorithm.HasValue) { - int expectedSize = algorithm.Value.GetPivKeyDefinition().KeyDefinition.LengthInBytes; - if(privateValue.Length != expectedSize) - { - throw new ArgumentException( - string.Format( - CultureInfo.CurrentCulture, ExceptionMessages.InvalidPrivateKeyData)); - } + ValidateSize(privateValue, algorithm.Value); + Algorithm = algorithm.Value; } else { - Algorithm = privateValue.Length switch - { - EccP256PrivateKeySize => PivAlgorithm.EccP256, - EccP384PrivateKeySize => PivAlgorithm.EccP384, - _ => throw new ArgumentException(string.Format( - CultureInfo.CurrentCulture, ExceptionMessages.InvalidPrivateKeyData)) - }; + Algorithm = GetBySize(privateValue); } int tag = Algorithm switch @@ -97,13 +90,38 @@ public PivEccPrivateKey( PivAlgorithm.EccX25519 => PivConstants.PrivateECX25519Tag, _ => PivConstants.PrivateECDsaTag }; - + var tlvWriter = new TlvWriter(); tlvWriter.WriteValue(tag, privateValue); EncodedKey = tlvWriter.Encode(); _privateValue = new Memory(privateValue.ToArray()); } + private static void ValidateSize(ReadOnlySpan privateValue, PivAlgorithm algorithm) + { + int expectedSize = algorithm.GetPivKeyDefinition().KeyDefinition.LengthInBytes; + if (privateValue.Length != expectedSize) + { + throw new ArgumentException( + string.Format( + CultureInfo.CurrentCulture, ExceptionMessages.InvalidPrivateKeyData)); + } + } + + private static PivAlgorithm GetBySize(ReadOnlySpan privateValue) + { + int privateValueSize = privateValue.Length; + var allowed = new List { KeyDefinitions.P256, KeyDefinitions.P384 }; + if (allowed.SingleOrDefault(kd => kd.LengthInBytes == privateValueSize) is { } keyDefinition) + { + return keyDefinition.GetPivKeyDefinition().Algorithm; + } + + throw new ArgumentException( + string.Format( + CultureInfo.CurrentCulture, ExceptionMessages.InvalidPrivateKeyData)); + } + /// /// Create a new instance of an ECC private key object based on the /// encoding. diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivEccPublicKey.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivEccPublicKey.cs index 422b637fe..7b858c75c 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivEccPublicKey.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivEccPublicKey.cs @@ -46,6 +46,7 @@ namespace Yubico.YubiKey.Piv /// examine the encoding. /// /// + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public sealed class PivEccPublicKey : PivPublicKey { private const int EccP256PublicKeySize = 65; @@ -83,7 +84,7 @@ private PivEccPublicKey() /// /// The format of the public point is not supported. /// - [Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use IPublicKey, IPrivateKey instead", false)] + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public PivEccPublicKey(ReadOnlySpan publicPoint, PivAlgorithm? algorithm = null) { if (!LoadEccPublicKey(publicPoint, algorithm)) @@ -213,9 +214,6 @@ private bool LoadEccPublicKey(ReadOnlySpan publicPoint, PivAlgorithm? algo } PivEncodedKey = tlvWriter.Encode(); - - // The Metadate encoded key is the contents of the nested. So set - // that to be a slice of the EncodedKey. YubiKeyEncodedKey = PivEncodedKey[SliceIndex..]; _publicPoint = new Memory(publicPoint.ToArray()); diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivMetadata.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivMetadata.cs index 7188fc838..ed77dd8e8 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivMetadata.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivMetadata.cs @@ -314,7 +314,8 @@ private void ParseResponseData(ReadOnlyMemory responseData) /// /// The public key associated with the private key in the given slot. /// - [Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use IPublicKey, IPrivateKey instead", false)] + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] + public PivPublicKey PublicKey { get; private set; } /// diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivPrivateKey.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivPrivateKey.cs index 88260bed8..5a10443c6 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivPrivateKey.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivPrivateKey.cs @@ -62,6 +62,7 @@ namespace Yubico.YubiKey.Piv /// /// /// + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public class PivPrivateKey : PrivateKey { protected Memory EncodedKey { get; set; } @@ -107,6 +108,8 @@ public PivPrivateKey() /// /// The key data supplied is not a supported encoding. /// + + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public static PivPrivateKey Create(ReadOnlyMemory encodedPrivateKey, PivAlgorithm? pivAlgorithm = null) { byte tag = 0; diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivPublicKey.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivPublicKey.cs index ecbeb1609..b352b52f6 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivPublicKey.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivPublicKey.cs @@ -14,6 +14,8 @@ using System; using System.Globalization; +using Yubico.YubiKey.Cryptography; +using Yubico.YubiKey.Piv.Converters; namespace Yubico.YubiKey.Piv { @@ -68,7 +70,8 @@ namespace Yubico.YubiKey.Piv /// without the nested 7F49 tag. /// /// - public class PivPublicKey + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] + public class PivPublicKey : PublicKey { /// /// The algorithm of the key in this object. @@ -78,6 +81,8 @@ public class PivPublicKey /// public PivAlgorithm Algorithm { get; protected set; } + public override KeyType KeyType => Algorithm.GetKeyType(); + protected Memory PivEncodedKey { get; set; } protected Memory YubiKeyEncodedKey { get; set; } @@ -124,21 +129,28 @@ public PivPublicKey() /// public static PivPublicKey Create(ReadOnlyMemory encodedPublicKey, PivAlgorithm? algorithm = null) { - // Try to decode as an RSA public key. If that works, we're done. If - // not, try ECC. If that doesn't work, exception. bool isCreated = PivRsaPublicKey.TryCreate(out var publicKeyObject, encodedPublicKey); - if (!isCreated) + if (isCreated) + { + return publicKeyObject; + } + + isCreated = PivEccPublicKey.TryCreate(out publicKeyObject, encodedPublicKey, algorithm); + if (isCreated) { - if (PivEccPublicKey.TryCreate(out publicKeyObject, encodedPublicKey, algorithm) == false) - { - throw new ArgumentException( - string.Format( - CultureInfo.CurrentCulture, - ExceptionMessages.InvalidPublicKeyData)); - } + return publicKeyObject; } - return publicKeyObject; + throw new ArgumentException( + string.Format( + CultureInfo.CurrentCulture, + ExceptionMessages.InvalidPublicKeyData)); + } + + public override byte[] ExportSubjectPublicKeyInfo() + { + var publicKey = PivKeyDecoder.CreatePublicKey(PivEncodedPublicKey, Algorithm.GetKeyType()); + return publicKey.ExportSubjectPublicKeyInfo(); } } } diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivRsaPrivateKey.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivRsaPrivateKey.cs index f59fdc964..705f87651 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivRsaPrivateKey.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivRsaPrivateKey.cs @@ -49,6 +49,7 @@ namespace Yubico.YubiKey.Piv /// then then examine the encoding. /// /// + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public sealed class PivRsaPrivateKey : PivPrivateKey { private Memory _primeP; diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivRsaPublicKey.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivRsaPublicKey.cs index 2bcf72459..c98d25803 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivRsaPublicKey.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivRsaPublicKey.cs @@ -59,6 +59,7 @@ namespace Yubico.YubiKey.Piv /// and public exponent, then examine the encoding. /// /// + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public sealed class PivRsaPublicKey : PivPublicKey { private readonly byte[] _exponentF4 = { 0x01, 0x00, 0x01 }; diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.Attestation.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.Attestation.cs index 1463b791e..d574f88b7 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.Attestation.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.Attestation.cs @@ -202,7 +202,8 @@ public X509Certificate2 GetAttestationCertificate() } - [Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use IPublicKey, IPrivateKey instead", false)] + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] + public void ReplaceAttestationKeyAndCertificate(PivPrivateKey privateKey, X509Certificate2 certificate) { byte[] certDer = CheckVersionKeyAndCertRequirements(privateKey.Algorithm.GetKeyType(), certificate); diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.Crypto.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.Crypto.cs index 1623cac06..fd0dd183d 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.Crypto.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.Crypto.cs @@ -267,7 +267,8 @@ public byte[] Decrypt(byte slotNumber, ReadOnlyMemory dataToDecrypt) ExceptionMessages.IncorrectCiphertextLength)); } - [Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use IPublicKey, IPrivateKey instead", false)] + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] + public byte[] KeyAgree(byte slotNumber, PivPublicKey correspondentPublicKey) { if (correspondentPublicKey is null) diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.KeyPairs.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.KeyPairs.cs index 1bc7ea485..489e6ee9d 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.KeyPairs.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/PivSession.KeyPairs.cs @@ -43,7 +43,7 @@ public sealed partial class PivSession : IDisposable /// private const byte CompressedCert = 1; - [Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use IPublicKey, IPrivateKey instead", false)] + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public PivPublicKey GenerateKeyPair( byte slotNumber, PivAlgorithm algorithm, @@ -266,7 +266,7 @@ public IPublicKey GenerateKeyPair( /// /// If the specified is not supported by the provided . /// - [Obsolete("Usage of PivEccPublic/PivEccPrivateKey is deprecated. Use IPublicKey, IPrivateKey instead", false)] + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey, PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public void ImportPrivateKey( byte slotNumber, PivPrivateKey privateKey, @@ -400,8 +400,9 @@ public void ImportPrivateKey( RefreshManagementKeyAuthentication(); + using var pivEncodedKeyHandle = new ZeroingMemoryHandle(privateKey.EncodeAsPiv()); var command = new ImportAsymmetricKeyCommand( - privateKey.EncodeAsPiv(), + pivEncodedKeyHandle.Data, privateKey.KeyType, slotNumber, pinPolicy, diff --git a/Yubico.YubiKey/tests/integration/Yubico/YubiKey/Piv/ImportTests.cs b/Yubico.YubiKey/tests/integration/Yubico/YubiKey/Piv/ImportTests.cs index 8ca667810..389ba093e 100644 --- a/Yubico.YubiKey/tests/integration/Yubico/YubiKey/Piv/ImportTests.cs +++ b/Yubico.YubiKey/tests/integration/Yubico/YubiKey/Piv/ImportTests.cs @@ -38,7 +38,9 @@ public void ImportPrivateKey_with_PrivateKey_Succeeds_and_HasExpectedValues( { // Arrange var (testPublicKey, testPrivateKey) = TestKeys.GetKeyPair(keyType); +#pragma warning disable CS0618 // Type or member is obsolete var testPivPublicKey = testPublicKey.AsPivPublicKey(); +#pragma warning restore CS0618 // Type or member is obsolete var keyParameters = AsnPrivateKeyDecoder.CreatePrivateKey(testPrivateKey.EncodedKey); const PivPinPolicy expectedPinPolicy = PivPinPolicy.Once; @@ -104,6 +106,21 @@ public void Import_KeyAndMatchingCert( pivSession.ImportPrivateKey(0x90, privateKey); pivSession.ImportCertificate(0x90, testCert.AsX509Certificate2()); } + + + [SkippableTheory(typeof(NotSupportedException), typeof(DeviceNotFoundException))] + [InlineData(KeyType.ECP256, StandardTestDevice.Fw5)] + [InlineData(KeyType.Ed25519, StandardTestDevice.Fw5)] + [Obsolete()] + public void Import_with_PivEccPrivateKey_Succeeds( + KeyType keyType, + StandardTestDevice testDeviceType) + { + using var pivSession = GetSession(testDeviceType); + var testPrivateKey = TestKeys.GetTestPrivateKey(keyType); + var piv = new PivEccPrivateKey(testPrivateKey.GetPrivateKey(), keyType.GetPivAlgorithm()); + pivSession.ImportPrivateKey(0x90, piv); + } [SkippableTheory(typeof(NotSupportedException), typeof(DeviceNotFoundException))] [InlineData(KeyType.RSA1024, false)] diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ECPrivateKeyTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ECPrivateKeyTests.cs index a997ec304..6b10713e1 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ECPrivateKeyTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ECPrivateKeyTests.cs @@ -29,7 +29,9 @@ public void CreateFromPivEncoding_WithValidParameters_CreatesInstance() { // Arrange var testKey = TestKeys.GetTestPrivateKey(KeyType.ECP256); +#pragma warning disable CS0618 // Type or member is obsolete var pivPrivateKey = testKey.AsPivPrivateKey(); +#pragma warning restore CS0618 // Type or member is obsolete var pivPrivateKeyEncoded = pivPrivateKey.EncodedPrivateKey; // Act diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ECPublicKeyTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ECPublicKeyTests.cs index 08ba4f9ad..8426e6a1d 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ECPublicKeyTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ECPublicKeyTests.cs @@ -16,7 +16,9 @@ public void CreateFromPivEncoding_WithValidParameters_CreatesInstance(KeyType ke { // Arrange var testKey = TestKeys.GetTestPublicKey(keyType); +#pragma warning disable CS0618 // Type or member is obsolete var pivPublicKey = testKey.AsPivPublicKey(); +#pragma warning restore CS0618 // Type or member is obsolete var pivPublicKeyEncoded = pivPublicKey.PivEncodedPublicKey; // Act diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/RSAPrivateKeyTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/RSAPrivateKeyTests.cs index 73a46ef3b..4ff7b9314 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/RSAPrivateKeyTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/RSAPrivateKeyTests.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; using System.Linq; using System.Security.Cryptography; using Xunit; @@ -44,6 +45,7 @@ public void Dispose_DisposesResources() } [Fact] + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public void CreateFromPivEncoding_WithValidParameters_CreatesInstance() { // Arrange diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/RsaPublicKeyTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/RsaPublicKeyTests.cs index 2f099208b..03c028c04 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/RsaPublicKeyTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/RsaPublicKeyTests.cs @@ -15,7 +15,9 @@ public void CreateFromPivEncoding_WithValidParameters_CreatesInstance() { // Arrange var testKey = TestKeys.GetTestPublicKey(KeyType.RSA2048); +#pragma warning disable CS0618 // Type or member is obsolete var pivPublicKey = testKey.AsPivPublicKey(); +#pragma warning restore CS0618 // Type or member is obsolete var pivPublicKeyEncoded = pivPublicKey.PivEncodedPublicKey; // Act diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ZeroingMemoryHandleTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ZeroingMemoryHandleTests.cs index 00b0638e5..7eda370b1 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ZeroingMemoryHandleTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Cryptography/ZeroingMemoryHandleTests.cs @@ -65,7 +65,7 @@ public void NestedUsage_ZeroesAllArraysWhenDisposed() // Simulate combining key and IV for an operation for (int i = 0; i < 5; i++) { - resultData[i] = (byte)(keyHandle.Data[i] ^ ivHandle.Data[i]); + resultData[i] = (byte)(keyHandle.Data.Span[i] ^ ivHandle.Data.Span[i]); } } @@ -148,14 +148,14 @@ public void MultiLayerComponent_MaintainsSecurityThroughLayers() Assert.All(sensitiveData, b => Assert.Equal(0, b)); } -// Mock processors for testing + // Mock processors for testing private static class FirstLayerProcessor { public static byte[] Process(ZeroingMemoryHandle handle) { // Simulate processing var result = new byte[handle.Data.Length]; - Buffer.BlockCopy(handle.Data, 0, result, 0, handle.Data.Length); + handle.Data.CopyTo(result); return result; } } @@ -167,7 +167,7 @@ public static byte[] Process(ZeroingMemoryHandle originalHandle, byte[] intermed // Simulate more processing for (int i = 0; i < originalHandle.Data.Length; i++) { - intermediateResult[i] ^= originalHandle.Data[i]; + intermediateResult[i] ^= originalHandle.Data.Span[i]; } return intermediateResult; } diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/GenPairResponseTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/GenPairResponseTests.cs index fdfe6de9d..b91b9feca 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/GenPairResponseTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/GenPairResponseTests.cs @@ -141,7 +141,9 @@ public void GetData_AuthenticationRequiredResponse_ThrowsException(KeyType keyTy byte[] keyData = GetCorrectEncodingForAlgorithm(keyType); var response = new GenerateKeyPairResponse(responseApdu, 0x8F, keyType.GetPivAlgorithm()); +#pragma warning disable CS0618 // Type or member is obsolete PivPublicKey getData = response.GetData(); +#pragma warning restore CS0618 // Type or member is obsolete var keyDataSpan = new ReadOnlySpan(keyData); bool compareResult = keyDataSpan.SequenceEqual(getData.PivEncodedPublicKey.Span); diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivEncoderDecoderTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivEncoderDecoderTests.cs index 91c9ac486..67fa413ec 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivEncoderDecoderTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivEncoderDecoderTests.cs @@ -92,7 +92,9 @@ public void PivAndPkcsEncodedKeys_AreEqual( var testKey = TestKeys.GetTestPublicKey(keyType); // Get test key as PivPublicKey +#pragma warning disable CS0618 // Type or member is obsolete var testPivPublicKey = testKey.AsPivPublicKey(); +#pragma warning restore CS0618 // Type or member is obsolete Assert.NotNull(testPivPublicKey); // Convert from PivEncoding to PublicKey using Key Converter. diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivPrivateKeyTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivPrivateKeyTests.cs index a374528d0..1539864bd 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivPrivateKeyTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivPrivateKeyTests.cs @@ -13,7 +13,6 @@ // limitations under the License. using System; -using System.Linq; using System.Security.Cryptography; using Xunit; using Yubico.YubiKey.Cryptography; @@ -21,8 +20,26 @@ namespace Yubico.YubiKey.Piv { + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public class PivPrivateKeyTests { + [Theory] + [InlineData(KeyType.ECP256)] + [InlineData(KeyType.ECP384)] + [InlineData(KeyType.Ed25519)] + public void Constructor_with_Algorithm_SetsAlgorithm(KeyType keyType) + { + var keyBytes = keyType switch + { + KeyType.ECP384 => new byte[48], + _ => new byte[32], + }; + + var pk = new PivEccPrivateKey(keyBytes, keyType.GetPivAlgorithm()); + Assert.Equal(keyType.GetPivAlgorithm(), pk.Algorithm); + Assert.Equal(keyType, pk.KeyType); + } + [Theory] [InlineData(KeyType.RSA1024)] [InlineData(KeyType.RSA2048)] @@ -241,6 +258,7 @@ public void RsaConstructor_Components_BuildsEncoding( [Theory] [InlineData(KeyType.ECP256)] [InlineData(KeyType.ECP384)] + [Obsolete("Obsolete")] public void EccConstructor_Components_BuildsEncoding( KeyType keyType) { @@ -305,7 +323,9 @@ public void RsaConstructor_BadPrimeQ_ThrowsExcpetion( [Fact] public void EccConstructor_NullData_ThrowsExcpetion() { +#pragma warning disable CS0618 // Type or member is obsolete _ = Assert.Throws(() => new PivEccPrivateKey(null)); +#pragma warning restore CS0618 // Type or member is obsolete } [Theory] @@ -382,7 +402,9 @@ public void GetPivPrivateKey_FromPem( offset = keySize - eccParams.D!.Length; Array.Copy(eccParams.D, 0, privateValue, offset, eccParams.D.Length); +#pragma warning disable CS0618 // Type or member is obsolete var eccPriKey = new PivEccPrivateKey(privateValue); +#pragma warning restore CS0618 // Type or member is obsolete privateKey = (PivPrivateKey)eccPriKey; } diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivPublicKeyTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivPublicKeyTests.cs index 82574fa84..2ad0168e8 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivPublicKeyTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/PivPublicKeyTests.cs @@ -20,8 +20,24 @@ namespace Yubico.YubiKey.Piv { - public class PivPublicKeyTests + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] + public class PivPublicKeyTests // TODO add test to verify interface implementations { + + [Fact] + public void ExportSubjectPublicKeyInfo_ReturnsSubjectPublicKeyInfo() + { + var testKey = TestKeys.GetTestPublicKey(KeyType.ECP256); + var tlvPublicKey = testKey.AsPivPublicKey(); + var subjectPublicKeyInfo = tlvPublicKey.ExportSubjectPublicKeyInfo(); + var ecPublicKey = ECPublicKey.CreateFromPkcs8(subjectPublicKeyInfo); + + Assert.Equal(KeyType.ECP256, tlvPublicKey.KeyType); + Assert.NotEmpty(subjectPublicKeyInfo); + Assert.Equal(testKey.EncodedKey, subjectPublicKeyInfo); + Assert.Equal(subjectPublicKeyInfo, ecPublicKey.ExportSubjectPublicKeyInfo()); + } + [Theory] [InlineData(KeyType.RSA1024)] [InlineData(KeyType.RSA2048)] diff --git a/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/KeyConverter.cs b/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/KeyConverter.cs index 055703ceb..97a3545d6 100644 --- a/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/KeyConverter.cs +++ b/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/KeyConverter.cs @@ -63,6 +63,7 @@ namespace Yubico.YubiKey.TestUtilities // Build an object from a PivPublicKey object and get a PEM string or RSA or // ECDsa object. // It is also possible to get a public key from a private key. + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public class KeyConverter { private const string RequestedKeyMessage = "Requested key was unavailable."; @@ -768,7 +769,9 @@ private void BuildPivPrivateKey( // var eccOid = eccParams.Curve.Oid.Value!; // var keyDefinition = KeyDefinitions.GetByOid(eccOid); // var eccPriKey = new PivEccPrivateKey(privateValue, keyDefinition.KeyType.GetPivAlgorithm()); +#pragma warning disable CS0618 // Type or member is obsolete var eccPriKey = new PivEccPrivateKey(privateValue); +#pragma warning restore CS0618 // Type or member is obsolete _pivPrivateKey = eccPriKey; } diff --git a/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/PivKeyExtensions.cs b/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/PivKeyExtensions.cs index a8d355223..544686627 100644 --- a/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/PivKeyExtensions.cs +++ b/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/PivKeyExtensions.cs @@ -12,12 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; using Yubico.YubiKey.Cryptography; using Yubico.YubiKey.Piv; using Yubico.YubiKey.Piv.Converters; namespace Yubico.YubiKey.TestUtilities; +[Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public static class PivKeyExtensions { public static RSAPrivateKey ConvertToGeneric( diff --git a/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/SampleKeyPairs.cs b/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/SampleKeyPairs.cs index e3909569c..e49cee211 100644 --- a/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/SampleKeyPairs.cs +++ b/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/SampleKeyPairs.cs @@ -15,6 +15,7 @@ using System.Security.Cryptography.X509Certificates; using Yubico.YubiKey.Cryptography; using Yubico.YubiKey.Piv; +#pragma warning disable CS0618 // Type or member is obsolete namespace Yubico.YubiKey.TestUtilities { diff --git a/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/TestKeyExtensions.cs b/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/TestKeyExtensions.cs index f607bfbf5..47ff33112 100644 --- a/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/TestKeyExtensions.cs +++ b/Yubico.YubiKey/tests/utilities/Yubico/YubiKey/TestUtilities/TestKeyExtensions.cs @@ -11,6 +11,7 @@ public static class TestKeyExtensions /// Converts the key to a PIV private key format. /// /// PivPrivateKey instance + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public static PivPrivateKey AsPivPrivateKey( this TestKey key) { @@ -38,6 +39,7 @@ public static PivPrivateKey AsPivPrivateKey( /// Converts the key to a PIV public key format. /// /// PivPublicKey instance + [Obsolete("Usage of PivEccPublic/PivEccPrivateKey PivRsaPublic/PivRsaPrivateKey is deprecated. Use implementations of ECPublicKey, ECPrivateKey and RSAPublicKey, RSAPrivateKey instead", false)] public static PivPublicKey AsPivPublicKey( this TestKey key) {