/* * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ using System; using System.Threading.Tasks; using Tizen.Internals.Errors; namespace Tizen.Account.FidoClient { /// /// The FIDO UAF Client APIs /// /// 3 public static class UafClient { private static string _vendorName = null; private static int _majorVersion; private static int _minorVersion; static UafClient() { int ret = Interop.UafClient.FidoGetClientVendor(out _vendorName); if (ret != (int)FidoErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]"); throw ErrorFactory.GetException(ret); } ret = Interop.UafClient.FidoGetClientVersion(out _majorVersion, out _minorVersion); if (ret != (int)FidoErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]"); throw ErrorFactory.GetException(ret); } } /// /// The FIDO Client vendor name /// /// 3 public static string VendorName { get { return _vendorName; } } /// /// The FIDO Client Major version /// /// 3 public static int MajorVersion { get { return _majorVersion; } } /// /// The FIDO Client Minor version /// /// 3 public static int MinorVersion { get { return _minorVersion; } } /// /// The FIDO Server response for successfull interaction. /// /// 3 public static int StautsOk { get { return 1200; } } /// /// Checks whether the FIDO message can be processed /// /// 3 /// The FIDO UAF message which is received from the relying party server /// True if the message can be handled by the device, else false /// http://tizen.org/privilege/fido.client /// http://tizen.org/feature/fido.uaf /// In case of invalid parameter /// Thrown when the application does not have privilege to access this method /// FIDO is not supported /// /// /// UafMessage uafRequest = new UafMessage() /// { /// Operation = "UafRequestJson" /// }; /// bool response = await UafClient.CheckPolicyAsync(uafRequest); /// /// public static async Task CheckPolicyAsync(UafMessage uafMessage) { if (uafMessage == null) { Log.Error(ErrorFactory.LogTag, "Invalid request or request is null"); throw ErrorFactory.GetException((int)FidoErrorCode.InvalidParameter); } bool result = false; await Task.Run(() => result = CheckPolicy(uafMessage.Operation)); return result; } /// /// Processes the given FIDO UAF message. /// /// 3 /// The FIDO UAF message which is received from the relying party server /// The channel binding data in JSON format which is received from the relying party server /// FIDO response message /// http://tizen.org/privilege/fido.client /// http://tizen.org/feature/fido.uaf /// In case of invalid parameter /// Thrown when the application does not have privilege to access this method /// FIDO is not supported /// /// /// UafMessage uafRequest = new UafMessage() /// { /// Operation = "UafAuthRequestJson" /// }; /// /// var response = await UafClient.ProcessRequestAsync(uafRequest, null); /// /// public static async Task ProcessRequestAsync(UafMessage uafMessage, string channelBindng) { if (uafMessage == null) { Log.Error(ErrorFactory.LogTag, "Invalid request or request is null"); throw ErrorFactory.GetException((int)FidoErrorCode.InvalidParameter); } TaskCompletionSource tcs = new TaskCompletionSource(); Interop.UafClient.FidoUafResponseMessageCallback cb = (int errorCode, string uafResponseJson, IntPtr userData) => { if (uafMessage == null) { Log.Error(ErrorFactory.LogTag, "Invalid request or request is null"); tcs.SetException(ErrorFactory.GetException((int)FidoErrorCode.InvalidParameter)); } if (errorCode != (int)FidoErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Interop callback failed with error code: [" + errorCode + "]"); tcs.SetException(ErrorFactory.GetException(errorCode)); } tcs.SetResult(new UafResponse() { Response = uafResponseJson }); }; int ret = Interop.UafClient.FidoUafGetResponseMessage(uafMessage.Operation, channelBindng, cb, IntPtr.Zero); if (ret != (int)FidoErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]"); throw ErrorFactory.GetException(ret); } return await tcs.Task; } /// /// Notifies the FIDO client about the server result. FIDO Server sends the result of processing a UAF message to FIDO client. /// /// 3 /// The status code received from Server.(StautsOk implies success) /// The FIDO response message sent to server in JSON format /// http://tizen.org/privilege/fido.client /// http://tizen.org/feature/fido.uaf /// /// This is especially important for cases when a new registration may be considered by the client to be in a pending state until it is communicated that the server accepted it /// /// In case of invalid parameter /// Thrown when the application does not have privilege to access this method /// FIDO is not supported /// /// /// UafResponse response = new UafResponse() /// { /// Response = "Responsejson" /// }; /// /// await UafClient.NotifyResultAsync(UafClient.StautsOk, response); /// /// public static async Task NotifyResultAsync(int responseCode, UafResponse response) { if (response == null) { Log.Error(ErrorFactory.LogTag, "Invalid parameter"); throw ErrorFactory.GetException((int)FidoErrorCode.InvalidParameter); } await Task.Run(() => NotifyResult(responseCode, response.Response)); } private static bool CheckPolicy(string uafOperation) { bool isSupported; int ret = Interop.UafClient.FidoUafIsSupported(uafOperation, out isSupported); if (ret != (int)FidoErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ret + "]"); throw ErrorFactory.GetException(ret); } return isSupported; } private static void NotifyResult(int responseCode, string response) { int ret = Interop.UafClient.FidoUafSetServerResult(responseCode, response); if (ret != (int)FidoErrorCode.None) { Log.Error(ErrorFactory.LogTag, "Interop API failed with error code: [" + ErrorFacts.GetErrorMessage(ret) + "]"); throw ErrorFactory.GetException(ret); } } } }