diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/InitializeAuthenticateManagementKeyCommand.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/InitializeAuthenticateManagementKeyCommand.cs index 7270fc7fc..7b9c3ec46 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/InitializeAuthenticateManagementKeyCommand.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/InitializeAuthenticateManagementKeyCommand.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; using Yubico.Core.Iso7816; namespace Yubico.YubiKey.Piv.Commands @@ -306,18 +307,25 @@ public sealed class InitializeAuthenticateManagementKeyCommand : IYubiKeyCommand /// public YubiKeyApplication Application => YubiKeyApplication.Piv; + + [Obsolete("This constructor is deprecated. Users must specify management key algorithm type, as it cannot be assumed.")] + public InitializeAuthenticateManagementKeyCommand() + : this(true) + { + } + /// /// Initializes a new instance of the InitializeAuthenticateManagementKeyCommand class for - /// Mutual Authentication, and a Triple-DES management key. + /// Mutual Authentication. /// /// /// Using this constructor is equivalent to /// - /// new InitializeAuthenticateManagementKeyCommand(true); + /// new InitializeAuthenticateManagementKeyCommand(true, PivAlgorithm.AES192); /// /// - public InitializeAuthenticateManagementKeyCommand() - : this(true) + public InitializeAuthenticateManagementKeyCommand(PivAlgorithm algorithm) + : this(true, algorithm) { } @@ -335,6 +343,7 @@ public InitializeAuthenticateManagementKeyCommand() /// /// True for mutual authentication, false for single. /// + [Obsolete("This constructor is deprecated. Users must specify management key algorithm type, as it cannot be assumed.")] public InitializeAuthenticateManagementKeyCommand(bool mutualAuthentication) : this(mutualAuthentication, PivAlgorithm.TripleDes) { diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/InitializeAuthenticateManagementKeyResponse.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/InitializeAuthenticateManagementKeyResponse.cs index 0cdc6146a..c2303d24d 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/InitializeAuthenticateManagementKeyResponse.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/InitializeAuthenticateManagementKeyResponse.cs @@ -61,16 +61,7 @@ public sealed class InitializeAuthenticateManagementKeyResponse : PivResponse, I // ResponseApdu.Data. It will be 8 bytes. private readonly byte[]? _clientAuthenticationChallenge; - /// - /// Constructs an InitializeAuthenticateManagementKeyResponse based on a ResponseApdu - /// received from the YubiKey for the Triple-DES algorithm. - /// - /// - /// The object containing the Response APDU
returned by the YubiKey. - /// - /// - /// Thrown when the data provided does not meet the expectations, and cannot be parsed. - /// + [Obsolete("This constructor is deprecated. Users must specify management key algorithm type, as it cannot be assumed.")] public InitializeAuthenticateManagementKeyResponse(ResponseApdu responseApdu) : this(responseApdu, PivAlgorithm.TripleDes) { @@ -90,8 +81,8 @@ public InitializeAuthenticateManagementKeyResponse(ResponseApdu responseApdu) /// /// Thrown when the data provided does not meet the expectations, and cannot be parsed. /// - public InitializeAuthenticateManagementKeyResponse(ResponseApdu responseApdu, PivAlgorithm algorithm) : - base(responseApdu) + public InitializeAuthenticateManagementKeyResponse(ResponseApdu responseApdu, PivAlgorithm algorithm) + : base(responseApdu) { Algorithm = algorithm; diff --git a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/SetManagementKeyCommand.cs b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/SetManagementKeyCommand.cs index 9300984d0..8341772d5 100644 --- a/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/SetManagementKeyCommand.cs +++ b/Yubico.YubiKey/src/Yubico/YubiKey/Piv/Commands/SetManagementKeyCommand.cs @@ -159,6 +159,12 @@ private SetManagementKeyCommand() throw new NotImplementedException(); } + [Obsolete("This constructor is deprecated. Users must specify management key algorithm type, as it cannot be assumed.")] + public SetManagementKeyCommand(ReadOnlyMemory newKey) + : this(newKey, PivTouchPolicy.Default, PivAlgorithm.TripleDes) + { + } + /// /// Initializes a new instance of the SetManagementKeyCommand class. /// This command takes the new management key as input and will set the @@ -176,11 +182,9 @@ private SetManagementKeyCommand() /// }; /// /// - /// The default algorithm is TripleDes. If you do not set the - /// Algorithm property after instantiating with this constructor, - /// the SDK will expect the key to be TripleDES. Valid algorithms are - /// PivAlgorithm.TripleDes, PivAlgorithm.Aes128, - /// PivAlgorithm.Aes192, and PivAlgorithm.Aes256. + /// Valid algorithms are PivAlgorithm.TripleDes, + /// PivAlgorithm.Aes128, PivAlgorithm.Aes192, and + /// PivAlgorithm.Aes256. FIPS YubiKeys versions 5.7 and greater require PivAlgorithm.Aes192. /// /// /// Note that you need to authenticate the current PIV management key before @@ -190,36 +194,15 @@ private SetManagementKeyCommand() /// /// The bytes that make up the new management key. /// - public SetManagementKeyCommand(ReadOnlyMemory newKey) - : this(newKey, PivTouchPolicy.Default, PivAlgorithm.TripleDes) + /// + /// The algorithm of the new management key. + /// + public SetManagementKeyCommand(ReadOnlyMemory newKey, PivAlgorithm algorithm) + : this(newKey, PivTouchPolicy.Default, algorithm) { } - /// - /// Initializes a new instance of the SetManagementKeyCommand class. This - /// command takes the new management key and the touch policy as input. - /// - /// - /// Note that a touchPolicy of PivTouchPolicy.Default or - /// None is equivalent to Never. - /// - /// The default algorithm is TripleDes. If you do not set the - /// Algorithm property after instantiating with this constructor, - /// the SDK will expect the key to be TripleDES. Valid algorithms are - /// PivAlgorithm.TripleDes, PivAlgorithm.Aes128, - /// PivAlgorithm.Aes192, and PivAlgorithm.Aes256. - /// - /// - /// Note also that you need to authenticate the current PIV management - /// key before setting it to a new value with this command. - /// - /// - /// - /// The bytes that make up the new management key. - /// - /// - /// The touch policy for the management key. - /// + [Obsolete("This constructor is deprecated. Users must specify management key algorithm type, as it cannot be assumed.")] public SetManagementKeyCommand(ReadOnlyMemory newKey, PivTouchPolicy touchPolicy) : this(newKey, touchPolicy, PivAlgorithm.TripleDes) { @@ -236,7 +219,7 @@ public SetManagementKeyCommand(ReadOnlyMemory newKey, PivTouchPolicy touch /// /// Valid algorithms are PivAlgorithm.TripleDes, /// PivAlgorithm.Aes128, PivAlgorithm.Aes192, and - /// PivAlgorithm.Aes256, + /// PivAlgorithm.Aes256. FIPS YubiKeys versions 5.7 and greater require PivAlgorithm.Aes192. /// /// /// Note also that you need to authenticate the current PIV management diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/CompleteAuthMgmtKeyCommandTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/CompleteAuthMgmtKeyCommandTests.cs index 173873556..857c37d13 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/CompleteAuthMgmtKeyCommandTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/CompleteAuthMgmtKeyCommandTests.cs @@ -148,13 +148,13 @@ public void CreateCommandApdu_GetInsProperty_ReturnsHex87(bool isMutual) [Theory] [InlineData(true)] [InlineData(false)] - public void CreateCommandApdu_GetP1Property_ReturnsThree(bool isMutual) + public void CreateCommandApdu_GetP1Property_Returns10ForAes192(bool isMutual) { CommandApdu cmdApdu = GetCommandApdu(isMutual, true); byte P1 = cmdApdu.P1; - Assert.Equal(3, P1); + Assert.Equal(10, P1); } [Theory] @@ -257,10 +257,7 @@ private static CompleteAuthenticateManagementKeyCommand GetCommandObject(bool is } finally { - if (!(replacement is null)) - { - replacement.RestoreRandomProvider(); - } + replacement?.RestoreRandomProvider(); } } @@ -332,7 +329,7 @@ private static InitializeAuthenticateManagementKeyResponse GetInitResponse(bool 0x7C, 0x0A, tag1, 0x08, 0x39, 0xA0, 0xA8, 0xE9, 0xF5, 0x28, 0x87, 0x75, sw1, sw2 }); - return new InitializeAuthenticateManagementKeyResponse(responseApdu); + return new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.TripleDes); } } } diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/InitAuthMgmtKeyCommandTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/InitAuthMgmtKeyCommandTests.cs index d0d375c71..9ffce8570 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/InitAuthMgmtKeyCommandTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/InitAuthMgmtKeyCommandTests.cs @@ -23,7 +23,7 @@ public class InitializeAuthenticateManagementKeyCommandTests [Fact] public void ClassType_DerivedFromPivCommand_IsTrue() { - var command = new InitializeAuthenticateManagementKeyCommand(); + var command = new InitializeAuthenticateManagementKeyCommand(PivAlgorithm.Aes192); Assert.True(command is IYubiKeyCommand); } @@ -31,7 +31,7 @@ public void ClassType_DerivedFromPivCommand_IsTrue() [Fact] public void Constructor_Application_Piv() { - var command = new InitializeAuthenticateManagementKeyCommand(); + var command = new InitializeAuthenticateManagementKeyCommand(PivAlgorithm.Aes192); YubiKeyApplication application = command.Application; @@ -146,7 +146,7 @@ public void CreateResponseForApdu_ReturnsCorrectType() byte sw2 = unchecked((byte)SWConstants.Success); var responseApdu = new ResponseApdu( new byte[] { 0x7C, 0x0A, 0x81, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, sw1, sw2 }); - var command = new InitializeAuthenticateManagementKeyCommand(); + var command = new InitializeAuthenticateManagementKeyCommand(PivAlgorithm.Aes192); InitializeAuthenticateManagementKeyResponse? response = command.CreateResponseForApdu(responseApdu); @@ -164,9 +164,9 @@ private static CommandApdu GetInitAuthMgmtKeyCommandApdu(int constructor) { InitializeAuthenticateManagementKeyCommand command = constructor switch { - 0 => new InitializeAuthenticateManagementKeyCommand(false), - 1 => new InitializeAuthenticateManagementKeyCommand(true), - _ => new InitializeAuthenticateManagementKeyCommand(), + 0 => new InitializeAuthenticateManagementKeyCommand(false, PivAlgorithm.Aes192), + 1 => new InitializeAuthenticateManagementKeyCommand(true, PivAlgorithm.Aes192), + _ => new InitializeAuthenticateManagementKeyCommand(PivAlgorithm.Aes192), }; return command.CreateCommandApdu(); diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/InitAuthMgmtKeyResponseTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/InitAuthMgmtKeyResponseTests.cs index 15b9e7fd8..be9db4859 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/InitAuthMgmtKeyResponseTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/InitAuthMgmtKeyResponseTests.cs @@ -26,7 +26,7 @@ public class InitAuthMgmtKeyResponseTests public void Constructor_GivenNullResponseApdu_ThrowsArgumentNullExceptionFromBase() { #pragma warning disable CS8625 // testing null input, disable warning that null is passed to non-nullable arg. - _ = Assert.Throws(() => new InitializeAuthenticateManagementKeyResponse(null)); + _ = Assert.Throws(() => new InitializeAuthenticateManagementKeyResponse(null, PivAlgorithm.Aes192)); #pragma warning restore CS8625 } @@ -39,7 +39,7 @@ public void Constructor_InvalidLength_CorrectException() new byte[] { 0x7C, 0x09, 0x81, 0x07, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, sw1, sw2 }); _ = Assert.Throws(() => - new InitializeAuthenticateManagementKeyResponse(responseApdu)); + new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192)); } [Fact] @@ -51,7 +51,7 @@ public void Constructor_InvalidT0_CorrectException() new byte[] { 0x78, 0x0A, 0x81, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, sw1, sw2 }); _ = Assert.Throws(() => - new InitializeAuthenticateManagementKeyResponse(responseApdu)); + new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192)); } [Fact] @@ -63,7 +63,7 @@ public void Constructor_InvalidT2_CorrectException() new byte[] { 0x7C, 0x0A, 0x82, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, sw1, sw2 }); _ = Assert.Throws(() => - new InitializeAuthenticateManagementKeyResponse(responseApdu)); + new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192)); } [Fact] @@ -75,7 +75,7 @@ public void Constructor_InvalidL1_CorrectException() new byte[] { 0x7C, 0x0A, 0x81, 0x07, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, sw1, sw2 }); _ = Assert.Throws(() => - new InitializeAuthenticateManagementKeyResponse(responseApdu)); + new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192)); } [Fact] @@ -86,7 +86,7 @@ public void Constructor_SuccessResponseApdu_SetsStatusWordCorrectly() var responseApdu = new ResponseApdu( new byte[] { 0x7C, 0x0A, 0x81, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, sw1, sw2 }); - var response = new InitializeAuthenticateManagementKeyResponse(responseApdu); + var response = new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192); Assert.Equal(SWConstants.Success, response.StatusWord); } @@ -99,7 +99,7 @@ public void Constructor_SuccessResponseApdu_SetsStatusCorrectly() var responseApdu = new ResponseApdu( new byte[] { 0x7C, 0x0A, 0x81, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, sw1, sw2 }); - var response = new InitializeAuthenticateManagementKeyResponse(responseApdu); + var response = new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192); Assert.Equal(ResponseStatus.Success, response.Status); } @@ -120,7 +120,7 @@ public void Constructor_SuccessResponseApdu_GetDataCorrectBool(bool isMutual) var responseApdu = new ResponseApdu( new byte[] { 0x7C, 0x0A, tag2, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, sw1, sw2 }); - var response = new InitializeAuthenticateManagementKeyResponse(responseApdu); + var response = new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192); (bool isMutualAuth, ReadOnlyMemory clientAuthenticationChallenge) = response.GetData(); @@ -138,7 +138,7 @@ public void Constructor_SuccessResponseApdu_GetDataCorrectBytes() var responseApdu = new ResponseApdu( new byte[] { 0x7C, 0x0A, 0x81, 0x08, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, sw1, sw2 }); - var response = new InitializeAuthenticateManagementKeyResponse(responseApdu); + var response = new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192); (bool isMutualAuth, ReadOnlyMemory clientAuthenticationChallenge) = response.GetData(); @@ -155,7 +155,7 @@ public void Constructor_FailResponseApdu_SetsStatusWordCorrectly() byte sw2 = unchecked((byte)SWConstants.ConditionsNotSatisfied); var responseApdu = new ResponseApdu(new byte[] { sw1, sw2 }); - var response = new InitializeAuthenticateManagementKeyResponse(responseApdu); + var response = new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192); Assert.Equal(SWConstants.ConditionsNotSatisfied, response.StatusWord); } @@ -167,7 +167,7 @@ public void Constructor_FailResponseApdu_SetsStatusCorrectly() byte sw2 = unchecked((byte)SWConstants.ConditionsNotSatisfied); var responseApdu = new ResponseApdu(new byte[] { sw1, sw2 }); - var response = new InitializeAuthenticateManagementKeyResponse(responseApdu); + var response = new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192); Assert.Equal(ResponseStatus.ConditionsNotSatisfied, response.Status); } @@ -179,7 +179,7 @@ public void Constructor_FailResponseApdu_ThrowOnGetData() byte sw2 = unchecked((byte)SWConstants.ConditionsNotSatisfied); var responseApdu = new ResponseApdu(new byte[] { sw1, sw2 }); - var response = new InitializeAuthenticateManagementKeyResponse(responseApdu); + var response = new InitializeAuthenticateManagementKeyResponse(responseApdu, PivAlgorithm.Aes192); _ = Assert.Throws(() => response.GetData()); } diff --git a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/SetManagementKeyCommandTests.cs b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/SetManagementKeyCommandTests.cs index 386bdf179..536d62d94 100644 --- a/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/SetManagementKeyCommandTests.cs +++ b/Yubico.YubiKey/tests/unit/Yubico/YubiKey/Piv/Commands/SetManagementKeyCommandTests.cs @@ -24,7 +24,7 @@ public class SetManagementKeyCommandTests public void ClassType_DerivedFromPivCommand_IsTrue() { byte[] mgmtKey = GetMgmtKeyArray(); - var command = new SetManagementKeyCommand(mgmtKey, PivTouchPolicy.Always); + var command = new SetManagementKeyCommand(mgmtKey, PivTouchPolicy.Always, PivAlgorithm.TripleDes); Assert.True(command is IYubiKeyCommand); } @@ -33,7 +33,7 @@ public void ClassType_DerivedFromPivCommand_IsTrue() public void Constructor_Application_Piv() { byte[] mgmtKey = GetMgmtKeyArray(); - var command = new SetManagementKeyCommand(mgmtKey, PivTouchPolicy.Always); + var command = new SetManagementKeyCommand(mgmtKey, PivTouchPolicy.Always, PivAlgorithm.TripleDes); YubiKeyApplication application = command.Application; @@ -45,7 +45,7 @@ public void Constructor_Property_TouchPolicy() { byte[] mgmtKey = GetMgmtKeyArray(); PivTouchPolicy touchPolicy = PivTouchPolicy.Always; - var command = new SetManagementKeyCommand(mgmtKey, touchPolicy); + var command = new SetManagementKeyCommand(mgmtKey, touchPolicy, PivAlgorithm.TripleDes); PivTouchPolicy getPolicy = command.TouchPolicy; @@ -206,11 +206,11 @@ private static SetManagementKeyCommand GetCommandObject(int cStyle, PivTouchPoli switch (cStyle) { default: - cmd = new SetManagementKeyCommand(mgmtKey, touchPolicy); + cmd = new SetManagementKeyCommand(mgmtKey, touchPolicy, PivAlgorithm.TripleDes); break; case 2: - cmd = new SetManagementKeyCommand(mgmtKey) + cmd = new SetManagementKeyCommand(mgmtKey, PivAlgorithm.TripleDes) { TouchPolicy = touchPolicy, }; @@ -219,13 +219,13 @@ private static SetManagementKeyCommand GetCommandObject(int cStyle, PivTouchPoli case 3: #pragma warning disable IDE0017 // Specifically testing this construction - cmd = new SetManagementKeyCommand(mgmtKey); + cmd = new SetManagementKeyCommand(mgmtKey, PivAlgorithm.TripleDes); cmd.TouchPolicy = touchPolicy; break; #pragma warning restore IDE0017 case 4: - cmd = new SetManagementKeyCommand(mgmtKey); + cmd = new SetManagementKeyCommand(mgmtKey, PivAlgorithm.TripleDes); break; }