/// <summary> /// CTAP-Command ClientPIN - changePIN /// </summary> public async Task <ResponseClientPIN> ClientPINchangePINAsync(string newpin, string currentpin) { var ret = await ClientPINgetKeyAgreementAsync(); if (ret.DeviceStatus != DeviceStatus.Ok || ret.CTAPResponse == null || ret.CTAPResponse.Status != 0) { return(new ResponseClientPIN(ret.DeviceStatus, ret.CTAPResponse)); } COSE_Key myKeyAgreement; var sharedSecret = CTAPCommandClientPIN.CreateSharedSecret(ret.CTAPResponse.KeyAgreement, out myKeyAgreement); // pinAuth: // LEFT(HMAC-SHA-256(sharedSecret, newPinEnc || pinHashEnc), 16). var pinAuth = CTAPCommandClientPIN.CreatePinAuthforChangePin(sharedSecret, newpin, currentpin); // newPinEnc: AES256-CBC(sharedSecret, IV = 0, newPin) byte[] newPinEnc = CTAPCommandClientPIN.CreateNewPinEnc(sharedSecret, newpin); // pinHashEnc: // Encrypted first 16 bytes of SHA - 256 hash of curPin using sharedSecret: // AES256-CBC(sharedSecret, IV = 0, LEFT(SHA-256(curPin), 16)). var pinHashEnc = CTAPCommandClientPIN.CreatePinHashEnc(currentpin, sharedSecret); var ret2 = await sendCommandandResponseAsync(new CTAPCommandClientPIN_changePIN(myKeyAgreement, pinAuth, newPinEnc, pinHashEnc), new CTAPResponseClientPIN()); return(new ResponseClientPIN(ret2.devSt, ret2.ctapRes)); }
/// <summary> /// CTAP-Command ClientPIN - getPINToken use PIN string /// </summary> public async Task <ResponseClientPIN_getPINToken> ClientPINgetPINTokenAsync(string pin) { var ret = await ClientPINgetKeyAgreementAsync(); if (ret.DeviceStatus != DeviceStatus.Ok || ret.CTAPResponse == null || ret.CTAPResponse.Status != 0) { return(new ResponseClientPIN_getPINToken(ret.DeviceStatus, ret.CTAPResponse)); } COSE_Key myKeyAgreement; var sharedSecret = CTAPCommandClientPIN.CreateSharedSecret(ret.CTAPResponse.KeyAgreement, out myKeyAgreement); var pinHashEnc = CTAPCommandClientPIN.CreatePinHashEnc(pin, sharedSecret); return(await ClientPINgetPINTokenAsync(myKeyAgreement, pinHashEnc, sharedSecret)); }
/// <summary> /// CTAP-Command ClientPIN - setPIN /// </summary> public async Task <ResponseClientPIN> ClientPINsetPINAsync(string newpin) { var ret = await ClientPINgetKeyAgreementAsync(); if (ret.DeviceStatus != DeviceStatus.Ok || ret.CTAPResponse == null || ret.CTAPResponse.Status != 0) { return(new ResponseClientPIN(ret.DeviceStatus, ret.CTAPResponse)); } COSE_Key myKeyAgreement; var sharedSecret = CTAPCommandClientPIN.CreateSharedSecret(ret.CTAPResponse.KeyAgreement, out myKeyAgreement); // pinAuth = LEFT(HMAC-SHA-256(sharedSecret, newPinEnc), 16) var pinAuth = CTAPCommandClientPIN.CreatePinAuthforSetPin(sharedSecret, newpin); // newPinEnc: AES256-CBC(sharedSecret, IV = 0, newPin) byte[] newPinEnc = CTAPCommandClientPIN.CreateNewPinEnc(sharedSecret, newpin); var ret2 = await sendCommandandResponseAsync(new CTAPCommandClientPIN_setPIN(myKeyAgreement, pinAuth, newPinEnc), new CTAPResponseClientPIN()); return(new ResponseClientPIN(ret2.devSt, ret2.ctapRes)); }
/// <summary> /// CTAP-Command GetAssertion use PIN string /// </summary> public async Task <ResponseGetAssertion> GetAssertionAsync(CTAPCommandGetAssertionParam param, string pin) { byte[] pinAuth = null; byte[] sharedSecret = null; COSE_Key myKeyAgreement = null; if (!string.IsNullOrEmpty(pin)) { var token = await ClientPINgetPINTokenAsync(pin); if (token.DeviceStatus != DeviceStatus.Ok || token.CTAPResponse == null || token.CTAPResponse.Status != 0) { return(new ResponseGetAssertion(token.DeviceStatus, token.CTAPResponse)); } //The platform gets sharedSecret from the authenticator. sharedSecret = CTAPCommandClientPIN.CreateSharedSecret(token.KeyAgreementPublicKey, out myKeyAgreement); pinAuth = CTAPCommandClientPIN.CreatePinAuth(param.ClientDataHash, token.CTAPResponse.PinToken); if (pinAuth == null) { return(new ResponseGetAssertion(token.DeviceStatus, token.CTAPResponse)); } } var ctapResponseGetAssertion = new CTAPResponseGetAssertion(); var ret = await sendCommandandResponseAsync(new CTAPCommandGetAssertion(param, pinAuth, myKeyAgreement, sharedSecret), ctapResponseGetAssertion); //Resolve the hmac-secret extension if (param.UseHmacExtension && ctapResponseGetAssertion.Assertion.ExtensionData?.Length > 0) { var data = ctapResponseGetAssertion.Assertion.ExtensionData; var decoded = AES256CBC.Decrypt(sharedSecret, data.ToArray()); Logger.Log($"GOT SYMMETRIC KEY: {decoded.ToHexString()}"); } return(new ResponseGetAssertion(ret.devSt, ret.ctapRes)); }